无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 7192|回复: 12
打印 上一主题 下一主题

[分享] 基于WIMGAPI编写的WININSTALL源码

[复制链接]
跳转到指定楼层
1#
发表于 2012-4-2 20:34:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
采用VC6编写,纯SDK,不用MFC,目的是实现能安装WIM封装的XP,当然也支持VISTA/WIN7/2008等,由于水平有限,很难将程序完善,现在把源码公布,让更多的人来帮忙修改,不过希望完善了能再分享改善的代码给我,前提是基于SDK修改的,如果改用MFC就不必了。也希望能对那些想写基于WIMGAPI程序的爱好者有一点帮助,这是开源的一个主要原因吧。
      本程序实用到了WIMGAPI中的几个API,有WIMCreateFile,WIMGetImageCount,MyGetWimImageInfo,
WIMRegisterMessageCallback,WIMSetTemporaryPath,WIMLoadImage,WIMApplyImage,
WIMUnregisterMessageCallback,WIMCloseHandle这几个函数,另外还用到了管道通讯,写出资源到文件
等等。我也是通过网络参考组织起来编程的,并不是高手。
      目前我遇到的问题是:
1.ListView控件的问题,我不知道怎么实现选中一行,而且事件处理好像还有点问题(MFC的话就好办,但
我喜欢用资源模板来实现界面,减少导入的dll库)
2.处理引导文件还不完善
3.没有条件多环境测试
4.暂时没有发现的问题

本想长篇大论的,但表达能力有限,就写那么多了,总之,希望这个程序有用!
附件请下载后把wiminstall - 20120402.z01.zip 和wiminstall - 20120402.z02.zip 后面的.zip去掉,这是论坛限制了扩展名
,图片上传不了,怪了
帖上主要代码,方便编程爱好者参考
  1. // wiminstall.cpp :
  2. ///////////////////////////////////////////////////////////////////////
  3. //                  WimInstall 2012.4.2                              //
  4. //                              by fly2sky     QQ:659090695          //
  5. //                                                                   //
  6. ///////////////////////////////////////////////////////////////////////
  7. #include "stdafx.h"
  8. #include "resource.h"
  9. #include "wimgapi.h"
  10. #define WIM_APPLY_FINISH WM_USER+100
  11. #define WIM_PROGRESS_INFO WM_USER+101
  12. #define WIM_MSG_ERROR_INFO WM_USER+102
  13. /////////////////////定义结构////////////////////////
  14. //镜像列表信息
  15. typedef struct _listinfo
  16. {
  17. int index;//索引
  18. char szName[_MAX_PATH];//镜像名
  19. char szDiscript[_MAX_PATH];//描述
  20. }LISTINFO, *LPLISTINFO;
  21. //驱动器信息
  22. typedef struct _mydriverinfo
  23. {
  24. int index;//索引
  25. char szDrive[5];//驱动盘符
  26. char szVolume[20];//卷标
  27. char szFileSystem[10];//文件系统
  28. //DWORD64 szSize;
  29. //DWORD64 szFreeSize;
  30. float szSize;//容量
  31. float szFreeSize;//可用空间
  32. }MYDRIVERINFO, *LPMYDRIVERINFO;
  33. /////////////////定义结构结束//////////////////////
  34. ///////////////以下是全局变量定义//////////////////
  35. HINSTANCE hInst;
  36. HWND hDlgMainWnd;
  37. HWND m_progress=NULL;
  38. HWND hSelDrvWnd=NULL;
  39. HWND hInstallWnd=NULL;
  40. HWND m_list,m_listview;
  41. WCHAR *lpwimfile=new WCHAR[WCHAR_MAX];
  42. WCHAR *lpath=new WCHAR[WCHAR_MAX];
  43. char szBootSectFile[MAX_PATH]={0};
  44. char szBCDTool[MAX_PATH]={0};
  45. DWORD dwThreadID=0;
  46. HANDLE hThread;
  47. HANDLE hWim,hImg;
  48. DWORD nImageCount,nDriverIndex;


  49. DWORD nImageIndex;                      //镜像索引
  50. char szBootDrive[5]={0};        //启动分区
  51. char szDestDrive[5]={0};        //目标分区
  52. bool bFormatDestDrive=false; //是否格式化目标分区
  53. bool bNT60Sect=true;
  54. ///////////////////////////////////////////////////
  55. LISTINFO ListInfo[50]={0};//只处理最多50个镜像
  56. MYDRIVERINFO mdi[26]={0};//最多支持26个盘符
  57. ////////////////全局变量定义结束///////////////////
  58. /////////////////以下是过程函数///////////////////
  59. BOOL SaveResToFile(char *pFileName,int ResID,char *ResName)
  60. {
  61. //该子程序实现将本身程序中含有的资源写出到文件,其中pFileName是指定要写
  62. //的文件名,ResID是资源的ID号、ResName是资源名称。
  63. //1.取出资源
  64. HRSRC hSndResource = FindResource(NULL, MAKEINTRESOURCE(ResID),ResName);
  65. HGLOBAL hGlobalMem = LoadResource(NULL,hSndResource);
  66. DWORD dwSize = SizeofResource(NULL,hSndResource);//大小
  67. LPCTSTR lpMemMain=(LPCSTR)LockResource(hGlobalMem);
  68. //2.写出资源
  69. HANDLE hFile=CreateFile(pFileName,GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  70. if(INVALID_HANDLE_VALUE==hFile)
  71. {
  72. FreeResource(hGlobalMem);
  73. return FALSE;
  74. }
  75. DWORD nBytesWritten;
  76. int ret=WriteFile(hFile,lpMemMain,dwSize,&nBytesWritten,NULL);
  77. if (0==ret)
  78. {
  79. FreeResource(hGlobalMem);
  80. return FALSE;
  81. }
  82. CloseHandle(hFile);
  83. //3.释放资源
  84. FreeResource(hGlobalMem);
  85. return TRUE;
  86. }
  87. ///////////////////////////////////////////////////
  88. bool IsNT60Bootsect(char *szText)
  89. {
  90. if(strstr(szText,"Windows XP")!=NULL)
  91. {
  92.   return false;
  93. }
  94. if(strstr(szText,"Windows 2003")!=NULL)
  95. {
  96.   return false;
  97. }
  98. //返回真表示是NT60的引导,否则就是NT52
  99. return true;
  100. }
  101. ///////////////////////////////////////////////////
  102. //取磁盘信息
  103. int GetDiver_Information(LPMYDRIVERINFO mydriverinfo)
  104. {
  105. CHAR szLogicalDriveStrings[MAX_PATH];
  106. PCHAR szDrive;//用来指向字符数组
  107. //将上面申请的CHar数组用O填充
  108.   ZeroMemory(szLogicalDriveStrings,MAX_PATH);
  109.   //获取逻辑驱动器卷标名  写入数组
  110.   GetLogicalDriveStrings(MAX_PATH-1,szLogicalDriveStrings);
  111.   //指向字符数组
  112.   szDrive=(PCHAR)szLogicalDriveStrings;
  113.      int i=0;
  114. //循环每个卷
  115.   do
  116. {
  117.   if(DRIVE_FIXED == GetDriveType(szDrive))//只显示固定盘
  118.   {
  119.    strcpy(mydriverinfo[i].szDrive,szDrive);
  120.    mydriverinfo[i].szDrive[2]='\x0';
  121.    mydriverinfo[i].index=i;
  122.    DWORD aa,bb,cc,dd;
  123.    GetDiskFreeSpace( mydriverinfo[i].szDrive,&aa,&bb,&cc,&dd );
  124.    //mydriverinfo[i].szFreeSize =(DWORD64)aa * (DWORD64)bb * (DWORD64)cc/(1024*1024*1024);
  125.    //mydriverinfo[i].szSize =(DWORD64)aa * (DWORD64)bb * (DWORD64)dd/(1024*1024*1024) ;
  126.    mydriverinfo[i].szFreeSize =(float)aa * bb * cc/(1024*1024*1024);
  127.    mydriverinfo[i].szSize =(float)aa * bb * dd/(1024*1024*1024) ;
  128.    //char Volumelabel[20];
  129.    DWORD SerialNumber;
  130.    DWORD MaxCLength;
  131.    DWORD FileSysFlag;
  132.    //char FileSysName[10];
  133.    GetVolumeInformation( mydriverinfo[i].szDrive,mydriverinfo[i].szVolume,255,&SerialNumber,&MaxCLength,&FileSysFlag,mydriverinfo[i].szFileSystem,255);
  134.    i++;
  135.   }
  136.   szDrive +=(lstrlen(szDrive)+1);
  137. }
  138.   while(*szDrive!='\x00');

  139.      return i;
  140. }
  141. ///////////////////////////////////////////////////
  142. //宽字节wchar_t* 转换为 单字节char*  WCHAR *unicodestr,
  143. char* Unicode2Ansi(const wchar_t* unicodestr, UINT codepage=CP_ACP)
  144. {
  145. int nLen = wcstombs(NULL,unicodestr,0);
  146. if (nLen == 0)
  147. {
  148.   return NULL;
  149. }
  150. char* pResult = new char[nLen];
  151. WideCharToMultiByte( codepage, 0, unicodestr, -1, pResult, nLen+1, NULL, NULL );
  152. return pResult;
  153. };
  154. ///////////////////////////////////////////////////
  155. wchar_t * Ansi2Unicode(char *ansistr )
  156. {
  157.     int result = 0;
  158.     int needlen = mbstowcs(NULL,ansistr,0);
  159.     if( needlen < 0 )
  160.     {
  161.         return NULL;
  162.     }
  163. wchar_t *unicodestr=new wchar_t [needlen];
  164.     MultiByteToWideChar(CP_ACP,0,  ansistr, -1,unicodestr, needlen+1 );
  165.     return unicodestr;
  166. }
  167. ///////////////////////////////////////////////////
  168. //打开文件对话框
  169. char * ChooseFile(char szFile[_MAX_PATH])
  170. {
  171. OPENFILENAME ofn;
  172. char strFile[MAX_PATH];
  173. memset(&ofn,0,sizeof(OPENFILENAME));
  174. memset(strFile,0,sizeof(char)*MAX_PATH);
  175. ofn.lStructSize=sizeof(OPENFILENAME);
  176. ofn.lpstrFilter="WIM镜像文件(*.wim)\0*.wim\0所有文件(*.*)\0*.*\0\0";
  177. ofn.lpstrFile=szFile;
  178. ofn.nMaxFile=MAX_PATH;
  179. ofn.Flags=OFN_FILEMUSTEXIST;
  180. if(GetOpenFileName(&ofn))
  181. {
  182.   return szFile;
  183. }
  184. else
  185. {
  186.   return NULL;
  187. }
  188. }
  189. ///////////////////////////////////////////////////
  190. //实现从XML取镜像信息
  191. BOOL MyGetWimImageInfo(const WCHAR *ImgInfoBuf,DWORD nIndex,char * szImageName,char * szImageDiscript)
  192. {
  193. char *pXML =new char[wcslen(ImgInfoBuf)+1];
  194. char tmp[260]={0};
  195. sprintf(tmp,"<IMAGE INDEX="%d">",nIndex);
  196. pXML=Unicode2Ansi(ImgInfoBuf);
  197. //取镜像名称、描述等
  198. char * strpos1=strstr(pXML,tmp);
  199. if (strpos1==NULL) return FALSE;
  200. char * strpos2=strstr(strpos1,"<NAME>");
  201. if(strpos2!=NULL)
  202. {
  203.   char * strpos3=strstr(strpos1,"</NAME>");
  204.   int len1=strpos3-strpos2-6;
  205.   memcpy(szImageName,strpos2+6,len1);
  206.   memcpy(szImageName+len1,"\x0",1);
  207. }
  208. else
  209. {
  210.   return FALSE;
  211. }
  212. //================================
  213. char * strpos4=strstr(strpos1,"<DESCRIPTION>");
  214. if(strpos4!=NULL)
  215. {
  216.   char * strpos5=strstr(strpos4,"</DESCRIPTION>");
  217.   int len2=strpos5-strpos4-13;
  218.   memcpy(szImageDiscript,strpos4+13,len2);
  219.   memcpy(szImageDiscript+len2,"\x0",1);
  220. }
  221. else
  222. {
  223.   szImageDiscript=NULL;
  224. }
  225. return TRUE;
  226. }
  227. ///////////////////////////////////////////////////
  228. int MyShell(const char * cmdline,char *strOutput)
  229. {
  230.   //返回0表示执行成功
  231.   SECURITY_ATTRIBUTES sa;
  232.   HANDLE hRead,hWrite;
  233.   
  234.   sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  235.   sa.lpSecurityDescriptor = NULL;  //使用系统默认的安全描述符
  236.   sa.bInheritHandle = TRUE;  //创建的进程继承句柄

  237.   if (!CreatePipe(&hRead,&hWrite,&sa,0))  //创建匿名管道
  238.   {   
  239.    return 1;
  240.   }

  241.   STARTUPINFO si;
  242.   PROCESS_INFORMATION pi;

  243.   ZeroMemory(&si,sizeof(STARTUPINFO));
  244.   si.cb = sizeof(STARTUPINFO);
  245.   GetStartupInfo(&si);
  246.   si.hStdError = hWrite;
  247.   si.hStdOutput = hWrite;  //新创建进程的标准输出连在写管道一端
  248.   si.wShowWindow = SW_HIDE;  //隐藏窗口
  249.   si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;

  250.   if (!CreateProcess(NULL,(char *)cmdline,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))  //创建子进程
  251.   {
  252.    //MessageBox("执行程序失败!","提示",MB_OK | MB_ICONWARNING);  
  253.    return 2;
  254.   }
  255.   CloseHandle(hWrite);  //关闭管道句柄

  256.   char buffer[4096] = {0};
  257.   DWORD bytesRead;
  258.   
  259.   while (true)
  260.   {
  261.    if (ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL)  //读取管道
  262.     break;
  263.   
  264.    strcat(strOutput,buffer);
  265.    Sleep(100);
  266.   }
  267.   CloseHandle(hRead);
  268.   return 0;
  269. }
  270. ////////////////////////////////////////////////////
  271. void MyExitProcess()
  272. {
  273. WIMCloseHandle (hWim);
  274. ExitProcess(0);
  275. }
  276. ///////////////////////////////////////////////////
  277. //WIM回调消息
  278. DWORD CALLBACK MyWIMMessageCallback(DWORD  dwMessageId,WPARAM wParam,LPARAM lParam,LPVOID lpvUserData)
  279. {
  280. HWND hWnd=(HWND)lpvUserData;
  281. switch (dwMessageId)
  282. {
  283. case WIM_MSG_ALIGNMENT:
  284.   break;
  285. case WIM_MSG_COMPRESS:
  286.   break;
  287. case WIM_MSG_ERROR:
  288.   PostMessage(hWnd,WIM_MSG_ERROR_INFO,wParam,lParam);
  289.   break;
  290. case WIM_MSG_PROCESS:
  291.   break;
  292. case WIM_MSG_SCANNING:
  293.   break;
  294. case WIM_MSG_SETPOS:
  295.   break;
  296. case WIM_MSG_SETRANGE:
  297.   break;
  298. case WIM_MSG_PROGRESS:
  299. {
  300.   //UINT dwPercent =(UINT)wParam;
  301.   //UINT dwTicksRemaining=(UINT)lParam;
  302.   PostMessage(hWnd,WIM_PROGRESS_INFO,wParam,lParam);
  303.   break;
  304. }
  305. default:
  306.   break;
  307. }
  308. return WIM_MSG_SUCCESS;
  309. }
  310. ///////////////////////////////////////////////////
  311. //工作线程
  312. DWORD WINAPI MyThread(PVOID lParam)
  313. {
  314. char szApplyPath[MAX_PATH]={0};
  315. strcpy(szApplyPath,szDestDrive);
  316. strcat(szApplyPath,"\");
  317. if(WIMApplyImage(hImg,Ansi2Unicode(szApplyPath),WIM_FLAG_VERIFY))
  318. {
  319.    WIMCloseHandle(hImg);
  320.    PostMessage(hInstallWnd,WIM_APPLY_FINISH,0,0);
  321. }
  322. WIMUnregisterMessageCallback(hWim,(FARPROC)MyWIMMessageCallback);
  323. return 0;
  324. }
  325. ///////////////////////////////////////////////////

  326. BOOL CALLBACK DlgInstallProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
  327. {
  328. hInstallWnd=hDlg;
  329. WORD wmId,wmEvent;
  330.     switch(message)
  331.     {
  332.     case WIM_MSG_ERROR_INFO:
  333.      MessageBox(hDlg,"解压出现错误","错误",MB_OK|MB_ICONERROR);
  334.       return FALSE;
  335.     case WIM_PROGRESS_INFO:
  336.      {
  337.     UINT dwPercent =(UINT)wParam;
  338.     UINT dwTicksRemaining=(UINT)lParam;
  339.     PostMessage(m_progress,PBM_SETPOS,wParam,0);
  340.     char szInfo[200]={0};
  341.     int MN,SC;
  342.     MN=dwTicksRemaining/1000/60;
  343.     SC=dwTicksRemaining/1000%60;
  344.     if (!MN && !SC && dwPercent < 100)
  345.      sprintf(szInfo,"解压进度%3d%%  ,剩余时间:计算中",dwPercent);
  346.     else
  347.        sprintf(szInfo,"解压进度%3d%%  ,剩余时间:%d分%d秒",dwPercent,MN,SC);
  348.     SetDlgItemText(hDlg,IDC_LBPROGRESSINFO,szInfo);
  349.     return FALSE;
  350.      }
  351.     case WIM_APPLY_FINISH:
  352.      {
  353.    char szBuffer[4096]={0};
  354.    char szCmdLine[200];
  355.       CloseHandle(hThread);
  356.    SetDlgItemText(hDlg,IDC_LBSTEP2,"2. 展开数据到分区 OK");
  357.    //修复引导扇区
  358.    SetDlgItemText(hDlg,IDC_LBSTEP3,"3. 修复引导信息 ...");
  359.    
  360.    if (bNT60Sect)
  361.     sprintf(szCmdLine,"cmd /c "%s /nt60 %s"",szBootSectFile,szBootDrive);
  362.    else
  363.     sprintf(szCmdLine,"cmd /c "%s /nt52 %s"",szBootSectFile,szBootDrive);
  364.    
  365.    //MessageBox(hDlg,szCmdLine,"",0);
  366.    if(0==MyShell((const char *)szCmdLine,szBuffer))
  367.    {
  368.     //MessageBox(hDlg,szBuffer,"",0);
  369.     if(strstr(szBuffer,"Bootcode was successfully updated on all targeted volumes."))
  370.      SetDlgItemText(hDlg,IDC_LBSTEP3,"3. 修复引导信息 OK");
  371.     else
  372.      MessageBox(hDlg,"修复引导信息失败","错误",MB_OK|MB_ICONERROR);
  373.    }
  374.    else
  375.    {
  376.     MessageBox(hDlg,"修复引导信息失败","错误",MB_OK|MB_ICONERROR);
  377.    }
  378.    //修复引导文件
  379.    //NT60则用BCDBOOT修复
  380.    
  381.    if (bNT60Sect)
  382.    {
  383.     SetDlgItemText(hDlg,IDC_LBSTEP4,"4. 修复引导文件 ...");
  384.     sprintf(szCmdLine,"cmd /c "%s %s\\WINDOWS /s %s /l zh-CN"",szBCDTool,szDestDrive,szBootDrive);
  385.     if(0==MyShell((const char *)szCmdLine,szBuffer))
  386.     {
  387.      if(strstr(szBuffer,"已成功创建启动文件"))
  388.       SetDlgItemText(hDlg,IDC_LBSTEP4,"4. 修复引导文件 OK");
  389.      else
  390.       MessageBox(hDlg,"修复引导文件失败","错误",MB_OK|MB_ICONERROR);
  391.     }
  392.     else
  393.     {
  394.      MessageBox(hDlg,"修复引导文件失败","错误",MB_OK|MB_ICONERROR);
  395.     }
  396.    }
  397.    else
  398.    {
  399.     SetDlgItemText(hDlg,IDC_LBSTEP4,"4. 修复引导文件 NG");
  400.    }
  401.    SetDlgItemText(hDlg,IDC_LBSTEP5,"-> 5.准备重启");
  402.    if(IDYES==MessageBox(hDlg,"解压文件完成,是否要重启进入安装过程?","提示",MB_YESNO|MB_ICONQUESTION))
  403.    {
  404.     WinExec("shutdown -r -t 0",SW_HIDE);
  405.    }
  406.    SendMessage(hDlg,WM_CLOSE,0,0);
  407.    return FALSE;
  408.      }
  409.     case WM_SHOWWINDOW:
  410.      {
  411.     char szTmp[4096]={0};
  412.     char szInfo[4096]={0};
  413.     sprintf(szTmp,"镜像文件:%s\n\n",Unicode2Ansi(lpwimfile));
  414.     strcat(szInfo,szTmp);
  415.     sprintf(szTmp,"镜像编号:%d\n\n",nImageIndex);
  416.     strcat(szInfo,szTmp);
  417.     sprintf(szTmp,"镜像名称:%s\n\n",ListInfo[nImageIndex].szName);
  418.     strcat(szInfo,szTmp);
  419.     sprintf(szTmp,"镜像描述:%s\n\n",ListInfo[nImageIndex].szDiscript);
  420.     strcat(szInfo,szTmp);
  421.     sprintf(szTmp,"目标分区:%s\n\n",szDestDrive);
  422.     strcat(szInfo,szTmp);
  423.     if(bFormatDestDrive)
  424.      strcat(szInfo,"格式化目标分区:是\n\n");
  425.     else
  426.      strcat(szInfo,"格式化目标分区:否\n\n");

  427.     sprintf(szTmp,"启动分区:%s\n\n",szBootDrive);
  428.     strcat(szInfo,szTmp);
  429.     bNT60Sect=IsNT60Bootsect(ListInfo[nImageIndex].szName);
  430.     if(bNT60Sect)
  431.      strcat(szInfo,"引导类型:NT60\n\n");
  432.     else
  433.      strcat(szInfo,"引导类型:NT52\n\n");
  434.     SetDlgItemText(hDlg,IDC_LBINFORMATION,szInfo);
  435.       return FALSE;
  436.      }
  437.        case WM_INITDIALOG:
  438.      {
  439.     m_progress=GetDlgItem(hDlg,IDC_PROGRESS1);
  440.     SendMessage(m_progress,PBM_SETRANGE,0,MAKELPARAM(0,100));
  441.     SendMessage(m_progress,PBM_SETSTEP,1,0);
  442.    
  443.       return FALSE;
  444.      }
  445.    
  446.        case WM_COMMAND:
  447.      {
  448.    wmId    = LOWORD(wParam);
  449.    wmEvent = HIWORD(wParam);
  450.    switch (wmId)
  451.    {
  452.    case IDC_BTNNEXT3:
  453.     if(IDYES==MessageBox(hDlg,"是否开始解压文件?","提示",MB_YESNO|MB_ICONQUESTION))
  454.     {
  455.      if(bFormatDestDrive) SHFormatDrive(hDlg,szDestDrive[0]-'A',SHFMT_ID_DEFAULT,SHFMT_OPT_FULL);
  456.      SetDlgItemText(hDlg,IDC_LBSTEP1,"1. 准备环境 ...");
  457.      //设置回调消息过程
  458.      if(INVALID_CALLBACK_VALUE!=WIMRegisterMessageCallback(hWim,(FARPROC)MyWIMMessageCallback,(LPVOID)hInstallWnd))
  459.      {
  460.       //MessageBox(hDlg,"注册成功","",MB_OK);
  461.       SetDlgItemText(hDlg,IDC_LBSTEP1,"1. 准备环境 OK");
  462.       char szTemp[MAX_PATH]={0};
  463.       GetTempPath(MAX_PATH,szTemp);
  464.       WIMSetTemporaryPath(hWim,Ansi2Unicode(szTemp));
  465.       hImg=WIMLoadImage(hWim,nImageIndex);
  466.       if(hImg)
  467.       {
  468.        SECURITY_ATTRIBUTES sa={0};
  469.        hThread=CreateThread(&sa,NULL,(LPTHREAD_START_ROUTINE)MyThread,NULL,0,&dwThreadID);
  470.        EnableWindow(GetDlgItem(hDlg,IDC_BTNNEXT3),FALSE);
  471.        EnableWindow(GetDlgItem(hDlg,IDC_BTNPREP2),FALSE);
  472.        SetDlgItemText(hDlg,IDC_LBSTEP2,"2. 展开数据到分区 ...");
  473.        SetDlgItemText(hDlg,IDC_LBPROGRESSINFO,"解压进度  0%  ,剩余时间:计算中");
  474.       }
  475.       else
  476.       {
  477.        MessageBox(hDlg,"载入镜像失败","提示",MB_OK|MB_ICONERROR);
  478.        //GetLastError();
  479.       }
  480.      }
  481.      else
  482.      {
  483.       MessageBox(hDlg,"注册回调消息失败","提示",MB_OK|MB_ICONERROR);
  484.      }
  485.     }
  486.     return FALSE;
  487.      case IDC_BTNCLOSE3:
  488.     SendMessage(hDlg,WM_CLOSE,0,0);
  489.     return FALSE;
  490.    case IDC_BTNPREP2:
  491.     ShowWindow(hDlg,SW_HIDE);
  492.     ShowWindow(hSelDrvWnd,SW_NORMAL);
  493.     SetFocus (hSelDrvWnd);
  494.     return FALSE;
  495.    }
  496.    }
  497.     case WM_CLOSE:
  498.      {
  499.       DWORD code;
  500.       GetExitCodeThread(hThread,&code);
  501.       if(code==STILL_ACTIVE)
  502.       {
  503.        if(IDYES==MessageBox(hDlg,"解压正在进行中,是否要退出?","提示",MB_YESNO|MB_ICONQUESTION))
  504.        {
  505.          DestroyWindow(hDlg);
  506.       MyExitProcess();
  507.        }
  508.       }
  509.       else
  510.       {
  511.        DestroyWindow(hDlg);
  512.        MyExitProcess();
  513.       }
  514.       return FALSE;
  515.      }
  516.    default:
  517.    return FALSE;
  518. }
  519. return FALSE;
  520. }
  521. ///////////////////////////////////////////////////
  522. BOOL CALLBACK DlgSelDriveProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
  523. {
  524. hSelDrvWnd=hDlg;
  525. WORD wmId,wmEvent;
  526. DWORD nItem=0;
  527.     switch(message)
  528.     {
  529.   case WM_SHOWWINDOW:
  530.      {
  531.   
  532.     return FALSE;
  533.      }
  534.        case WM_INITDIALOG:
  535.      {
  536.       m_listview=GetDlgItem(hDlg,IDC_LISTVIEW);
  537.       //加入驱动器列表
  538.       ListView_DeleteAllItems(m_listview);
  539.     LV_ITEM item;       // 项
  540.     LV_COLUMN colmn;     // 列
  541.     ZeroMemory(&item, sizeof(LV_ITEM));
  542.     ZeroMemory(&colmn, sizeof(LV_COLUMN));
  543.     colmn.mask = LVCF_TEXT|LVCF_WIDTH|LVCF_SUBITEM; // 风格
  544.     colmn.cx = 0x60;
  545.     colmn.pszText = "盘符"; // 文字
  546.     colmn.iOrder=0;
  547.     // 后面列
  548.     SendMessage(m_listview, LVM_INSERTCOLUMN, 0, (LPARAM)&colmn);
  549.     colmn.cx = 0x80;
  550.     colmn.pszText = "卷标";
  551.     SendMessage(m_listview, LVM_INSERTCOLUMN, 1, (LPARAM)&colmn);
  552.     colmn.cx = 0x80;
  553.     colmn.pszText = "文件系统";
  554.     SendMessage(m_listview, LVM_INSERTCOLUMN, 2, (LPARAM)&colmn);
  555.     colmn.cx = 0x80;
  556.     colmn.pszText = "容量";
  557.     SendMessage(m_listview, LVM_INSERTCOLUMN, 3, (LPARAM)&colmn);
  558.     colmn.cx = 0x80;
  559.     colmn.pszText = "可用空间";
  560.     SendMessage(m_listview, LVM_INSERTCOLUMN, 4, (LPARAM)&colmn);
  561.    
  562.     int nDrvCount=GetDiver_Information(mdi);
  563.     for (int i=0;i<nDrvCount;i++)
  564.     {
  565.      SendMessage(m_listview, LVM_GETITEMCOUNT, 0, (LPARAM)&colmn);
  566.      item.mask = LVIF_TEXT;       // 文字
  567.      item.cchTextMax = MAX_PATH;  // 文字长度
  568.      item.iItem = ListView_GetItemCount(m_listview);
  569.      item.iSubItem = 0;
  570.      item.pszText = mdi[i].szDrive ;
  571.      //插入行
  572.      ListView_InsertItem(m_listview, &item);
  573.      //第二列文本
  574.      ListView_SetItemText(m_listview,i,1,mdi[i].szVolume);
  575.      //第三列文本
  576.      ListView_SetItemText(m_listview,i,2,mdi[i].szFileSystem);
  577.      char tmp[64];
  578.      sprintf(tmp,"%10.1fG",mdi[i].szSize);
  579.      //第四列文本
  580.      ListView_SetItemText(m_listview,i,3,tmp);
  581.      sprintf(tmp,"%10.1fG",mdi[i].szFreeSize);
  582.      //第五列文本
  583.      ListView_SetItemText(m_listview,i,4,tmp);
  584.     }
  585.        return FALSE;
  586.      }
  587.   
  588.        case WM_COMMAND:
  589.     {
  590.    wmId    = LOWORD(wParam);
  591.    wmEvent = HIWORD(wParam);
  592.    switch (wmId)
  593.    {
  594.     case IDC_BTNNEXT2:
  595.     {
  596.      bFormatDestDrive=SendMessage(GetDlgItem(hDlg,IDC_CHKFORMAT),BM_GETCHECK,0,0);
  597.      if(!hInstallWnd)
  598.      {
  599.      
  600.       //MessageBox(hDlg,szDestDrive,"",0);
  601.       ShowWindow(hDlg,SW_HIDE);
  602.       DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_INSTALLFORM),NULL,(DLGPROC)DlgInstallProc,NULL);
  603.      }
  604.      else
  605.      {
  606.       ShowWindow(hDlg,SW_HIDE);
  607.       ShowWindow(hInstallWnd,SW_SHOW);
  608.       SetFocus (hInstallWnd);
  609.       return FALSE;
  610.      }
  611.     }
  612.     case IDC_BTNPREP1:
  613.     {
  614.      ShowWindow(hDlg,SW_HIDE);
  615.      ShowWindow(hDlgMainWnd,SW_SHOW);
  616.      SetFocus (hDlgMainWnd);
  617.      return FALSE;
  618.     }
  619.     case IDC_BTNSETBOOT:
  620.     {
  621.      
  622.      strcpy(szBootDrive,mdi[nDriverIndex].szDrive);
  623.      char szInfo[100]={0};
  624.      wsprintf(szInfo,"当前选择的目标盘是%s  ,当前引导盘为%s",szDestDrive,szBootDrive);
  625.      SetDlgItemText(hDlg,IDC_LBBOOTINFO,szInfo);
  626.      return FALSE;
  627.     }
  628.     case IDC_BTNCLOSE2:
  629.     {
  630.        SendMessage(hDlg,WM_CLOSE,0,0);
  631.        return FALSE;
  632.     }
  633.     default:
  634.      return FALSE;
  635.    }
  636.    }
  637.     case WM_NOTIFY:
  638.    switch (((LPNMHDR)lParam)->code)
  639.    {
  640.     case LVN_ITEMCHANGED:
  641.     {
  642.      NMLISTVIEW *pnmv = (NMLISTVIEW*)lParam;
  643.      if (pnmv->uNewState & LVIS_SELECTED)
  644.      {
  645.       nDriverIndex=pnmv->iItem;
  646.       strcpy(szDestDrive,mdi[nDriverIndex].szDrive);
  647.       char szInfo[100]={0};
  648.       wsprintf(szInfo,"当前选择的目标盘是%s  ,当前引导盘为%s",szDestDrive,szBootDrive);
  649.       SetDlgItemText(hDlg,IDC_LBBOOTINFO,szInfo);
  650.       if(nItem!=-1)
  651.       {
  652.        EnableWindow(GetDlgItem(hDlg,IDC_BTNNEXT2),TRUE);
  653.        EnableWindow(GetDlgItem(hDlg,IDC_BTNSETBOOT),TRUE);
  654.       }
  655.      }
  656.      return FALSE;
  657.     }
  658.     default:
  659.      return FALSE;
  660.    }
  661.   case WM_CLOSE:
  662.    DestroyWindow(hDlg);
  663.    MyExitProcess();
  664.    return FALSE;
  665.   default:
  666.    return FALSE;
  667. }   

  668. return FALSE;
  669. }
  670. ///////////////////////////////////////////////////
  671. BOOL CALLBACK DlgMainProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
  672. {
  673. hDlgMainWnd=hDlg;
  674. DWORD dwCreationResult,nItem;
  675. WORD wmId,wmEvent;
  676.     switch(message)
  677.     {
  678.        case WM_INITDIALOG:
  679.     {
  680.      m_list=GetDlgItem(hDlg,IDC_LIST1);
  681.      char szTmp[MAX_PATH]={0};
  682.      GetTempPath(MAX_PATH,szTmp);
  683.      strcpy(szBootSectFile,szTmp);
  684.      strcat(szBootSectFile,"bootsect.exe");
  685.      strcpy(szBCDTool,szTmp);
  686.      strcat(szBCDTool,"bcdboot.exe");
  687.      //MessageBox(hDlg,szBootSectFile,"",0);
  688.      //MessageBox(hDlg,szBCDTool,"",0);
  689.      SaveResToFile(szBCDTool,IDR_BCDTOOL,"TOOLS");
  690.      SaveResToFile(szBootSectFile,IDR_BOOTSECT,"TOOLS");
  691.      return FALSE;
  692.     }
  693.        case WM_COMMAND:
  694.    wmId    = LOWORD(wParam);
  695.    wmEvent = HIWORD(wParam);
  696.    switch (wmId)
  697.    {
  698.     case IDC_BTNNEXT1:
  699.     {
  700.      nImageIndex=SendMessage(m_list,LB_GETCURSEL,0,0)+1;
  701.      //显示下一个选择驱动窗口
  702.      if(!hSelDrvWnd)
  703.      {
  704.       ShowWindow(hDlg,SW_HIDE);
  705.       DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_SELECTDRIVEFORM),NULL,(DLGPROC)DlgSelDriveProc,NULL);
  706.      }
  707.      else
  708.      {
  709.       ShowWindow(hDlg,SW_HIDE);
  710.       ShowWindow(hSelDrvWnd,SW_SHOW);
  711.       SetFocus (hSelDrvWnd);
  712.      }
  713.      return FALSE;
  714.     }
  715.     case IDC_BTNCHOOSE:
  716.     {
  717.      char szPathName[_MAX_PATH]={0};
  718.      if(NULL!=ChooseFile(szPathName))//打开文件
  719.      {
  720.       if(hWim)
  721.       {
  722.        WIMCloseHandle(hWim);
  723.        hWim=NULL;
  724.       }
  725.       lpwimfile=Ansi2Unicode(szPathName);
  726.       SetDlgItemText(hDlg,IDC_EDIT1,szPathName);
  727.       WCHAR * ImgInfoBuf = new WCHAR(WCHAR_MAX);
  728.       DWORD ImgInfoBufSize;
  729.       hWim=WIMCreateFile(lpwimfile,WIM_GENERIC_READ,WIM_OPEN_EXISTING,WIM_FLAG_VERIFY,WIM_COMPRESS_XPRESS,&dwCreationResult);
  730.       if(hWim==0)
  731.       {
  732.        MessageBox(hDlg,"打开WIM文件失败!","错误",MB_OK|MB_ICONERROR);
  733.        return FALSE;
  734.       }
  735.       SendMessage(m_list,LB_RESETCONTENT,0,0);
  736.       nImageCount=WIMGetImageCount(hWim);//取得镜像数
  737.       if(nImageCount>50) nImageCount=50;//最多只显示50个镜像
  738.       WIMGetImageInformation(hWim, (LPVOID *)&ImgInfoBuf,&ImgInfoBufSize);//取WIM信息
  739.       char *szName=new char[260];
  740.       char *szDiscript=new char[260];
  741.       memset (ListInfo,0,sizeof(ListInfo));
  742.       //MessageBoxW(hDlg,ImgInfoBuf,L"",MB_OK);
  743.       for(DWORD index=1;index<=nImageCount;index++)
  744.       {
  745.        MyGetWimImageInfo(ImgInfoBuf,index,szName,szDiscript);
  746.        ListInfo[index].index=index;
  747.        strcpy(ListInfo[index].szName,szName);
  748.        strcpy(ListInfo[index].szDiscript,szDiscript);
  749.        SendMessage(m_list,LB_ADDSTRING,0,(LPARAM)szName);
  750.       }
  751.      }
  752.      return FALSE;
  753.     }
  754.     case IDC_BTNCLOSE1:
  755.     {
  756.      SendMessage(hDlg,WM_CLOSE,0,0);
  757.      return FALSE;
  758.     }
  759.     case IDC_LIST1:
  760.     {
  761.      switch (wmEvent)
  762.      {
  763.       case LBN_SELCHANGE:
  764.       {
  765.        nItem=SendMessage(m_list,LB_GETCURSEL,0,0);
  766.        //显示描述
  767.        SetWindowText(GetDlgItem(hDlg,IDC_STATIC1),ListInfo[nItem+1].szDiscript);
  768.        //下一步可用
  769.        if(nItem!=-1)
  770.        {
  771.         nImageIndex=nItem;
  772.         EnableWindow(GetDlgItem(hDlg,IDC_BTNNEXT1),TRUE);
  773.        }
  774.        return FALSE;
  775.       }
  776.       default:
  777.        return FALSE;
  778.      }
  779.     }
  780.     default:
  781.      return FALSE;
  782.    }
  783.        case WM_CLOSE:
  784.            DestroyWindow(hDlg);
  785.      MyExitProcess();
  786.      return FALSE;
  787.     default:
  788.      return FALSE;
  789.     }
  790.     return FALSE;
  791. }
  792. ///////////////////////////////////////////////////
  793. int APIENTRY WinMain(HINSTANCE hInstance,
  794.                      HINSTANCE hPrevInstance,
  795.                      LPSTR     lpCmdLine,
  796.                      int       nCmdShow)
  797. {
  798. hInst=hInstance;
  799. strcpy(szBootDrive,"C:");
  800. DialogBoxParam(hInst,MAKEINTRESOURCE(IDD_MAINFORM),NULL,(DLGPROC)DlgMainProc,NULL);
  801. return 0;
  802. }
复制代码

[ 本帖最后由 fly2sky 于 2012-4-2 21:11 编辑 ]

wiminstall - 20120402.zip

177.28 KB, 下载次数: 247, 下载积分: 无忧币 -2

wiminstall - 20120402.z01.zip

200 KB, 下载次数: 251, 下载积分: 无忧币 -2

wiminstall - 20120402.z02.zip

200 KB, 下载次数: 260, 下载积分: 无忧币 -2

wiminstall编译好的(测试).rar

102.96 KB, 下载次数: 254, 下载积分: 无忧币 -2

2#
发表于 2012-4-3 07:51:45 | 只看该作者
虽然看不懂,但要支持楼主的开源精神。
回复

使用道具 举报

3#
发表于 2012-4-3 08:50:51 | 只看该作者
强烈支持楼主  辛苦了
回复

使用道具 举报

4#
发表于 2012-4-3 15:29:12 | 只看该作者
很不错的代码收了,补丁
回复

使用道具 举报

5#
发表于 2012-8-25 23:35:29 | 只看该作者
纯技术贴,看来支持的人不多啊  呵呵   感谢你,代码收下了...
回复

使用道具 举报

6#
发表于 2012-9-28 23:28:39 | 只看该作者
感谢你,代码收下了...
回复

使用道具 举报

7#
发表于 2013-7-6 11:30:06 | 只看该作者
不顶不行!!!
回复

使用道具 举报

8#
发表于 2013-8-23 08:27:01 | 只看该作者
你好楼主,有没有能够实现进度显示的代码呢?我用VB.NET也实现了装载卸载镜像,但就是不知道怎么显示进度。我知道有相关函数,但不知道怎么用。
回复

使用道具 举报

9#
发表于 2013-8-24 19:20:23 | 只看该作者
路过  。。

16piyle.com 十六浦娱乐|城 lijibyl.com 立即|博  
回复

使用道具 举报

10#
发表于 2013-8-25 18:51:47 | 只看该作者
看到代码头大啊

boybylc.com
eshboylc.com
回复

使用道具 举报

11#
发表于 2023-9-26 23:33:27 | 只看该作者
子过程不太懂,请问下怎么翻译成易语言?
WIMCreateFile 此函数成功了,
WIMLoadImage 这个未成功,返回句柄一直为零,
不知道是哪里错了,还望大哥们指点一下咯。
回复

使用道具 举报

12#
发表于 2023-9-26 23:44:56 | 只看该作者
不顶不行!!!
回复

使用道具 举报

13#
发表于 2023-10-27 12:48:02 | 只看该作者
不顶不行!!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-11-25 12:57

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表