无忧启动论坛

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

WinPE 驱动程序最终解决方案

[复制链接]
跳转到指定楼层
1#
发表于 2007-1-4 21:21:58 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
终于搞定了……!完美!

对于 WinPE 驱动程序外置或打包,chenall 已经作了 BAT 方式的解决方式。但是这依赖于繁琐的外部程序和BAT命令,效率不高且不适合定制。今天女里搞了一下,终于搞定了最终解决方案:

1. 把每种驱动放在一个目录中(每个 INF 文件名前,加上“_”开头,作为起始标志),然后把所有的驱动程序打包成为一个 CAB 文件(可能由于 INF 是 TXT 的关系,CAB 压缩率比 7Z 还高一点,且不需要使用固实压缩,解压缩单个文件时速度大大提高)。

2. 用下面的程序代码(完成功能和源代码稍后提供在其它的帖子中),指定 CAB 路径,即可自动从 CAB 安装驱动:

1) 代码会自动检测所有 PCI 设备;
2) 然后遍历 CAB 内的一个 INF 文件内容;
3) 如果找到匹配的硬件,则解压缩 INF 所在目录中随后的 所有文件到 %TEMP% 中;
4) 安装驱动程序;
5) 转跳到 2,继续遍历下一个 INF。

优点:
1) 支持把各种类型的驱动放在一个 CAB 中,如显卡 + 网卡,等。
2) 高压缩。经测试,12M 的所有网卡 驱动,压缩后为 2.9M。
3) 硬盘(或 RAMDISK 盘)空间要求少,不匹配的驱动不会被解压缩。
4) 安装驱动后,可以删除 CAB 文件,腾出空间。这样 RAMDISK 启动的WinPE就能腾出空间,不必使用 RAMDRV 和 FBWF。
5) CAB 解压缩不需要而外程序的支持,SetupAPI 是 Windows 内置的接口。(如何生成CAB,推荐用 RAR 等压缩工具压缩为 RAR 等,然后用 ArcConvert 转换即可)

代码片段如下,如有需要可以定制,想怎么样就怎么样:


  1. // Header
  2. #include <SetupAPI.h>
  3. #include <DevGuid.h>
  4. #include <RegStr.h>
  5. #include <CfgMgr32.h>
  6. #pragma comment(lib, "SetupAPI.lib")
  7. #ifdef _UNICODE
  8. #define STR_UpdateDriverForPlugAndPlayDevices "UpdateDriverForPlugAndPlayDevicesW"
  9. #else
  10. #define STR_UpdateDriverForPlugAndPlayDevices "UpdateDriverForPlugAndPlayDevicesA"
  11. #endif
  12. typedef BOOL (WINAPI* PUPNP)(HWND  hWnd, PCTSTR ptzID, PCTSTR ptzPath, DWORD dwFlags, PBOOL bReboot);

  13. // Compare device
  14. PSTR DevCmp(PSTR pszStr1, PSTR pszStr2)
  15. {
  16.     PSTR p = pszStr2;
  17.     for (UINT i = 0; *p; p++)
  18.     {
  19.         if ((*p == '&') && (++i == 2))
  20.         {
  21.             break;
  22.         }
  23.     }
  24.     UINT uCmp = (UINT) (p - pszStr2);

  25.     p = pszStr1;
  26.     while (*p)
  27.     {
  28.         if (UMemCmp(p, pszStr2, uCmp) == 0)
  29.         {
  30.             return p;
  31.         }
  32.         p++;
  33.     }
  34.     return NULL;
  35. }

  36. // CAB callback
  37. UINT CALLBACK DevProc(PVOID pvContext, UINT uMsg, UINT_PTR upParam1, UINT_PTR upParam2)
  38. {
  39.     static BOOL s_bExtract = FALSE;
  40.     static TCHAR s_tzDevID[MAX_NAME] = {0};
  41.     static TCHAR s_tzInfPath[MAX_PATH] = {0};
  42.     if (uMsg == SPFILENOTIFY_FILEINCABINET)
  43.     {
  44.         // Is INF file or followed by INF file
  45.         FILE_IN_CABINET_INFO *p = (FILE_IN_CABINET_INFO*) upParam1;
  46.         PCTSTR q = UStrRChr(p->NameInCabinet, '\\');
  47.         q = q ? (q + 1) : p->NameInCabinet;
  48.         if ((*q == '_') || s_bExtract)
  49.         {
  50.             // Extract INF or driver file
  51.             if (*q == '_')
  52.             {
  53.                 q++;
  54.             }
  55.             UStrCopy(p->FullTargetName + GetTempPath(MAX_PATH, p->FullTargetName), q);
  56.             return FILEOP_DOIT;
  57.         }
  58.         else
  59.         {
  60.             // Skip
  61.             return FILEOP_SKIP;
  62.         }
  63.     }
  64.     else if (uMsg == SPFILENOTIFY_FILEEXTRACTED)
  65.     {
  66.         PCTSTR ptzTarget = ((FILEPATHS*) upParam1)->Target;
  67.         if (UStrStr(ptzTarget, TEXT(".INF")) == NULL)
  68.         {
  69.             // Not INF
  70.             return NO_ERROR;
  71.         }

  72.         // Open INF
  73.         PSTR pszFile = (PSTR) UFileLoad(ptzTarget, NULL);
  74.         if (pszFile == NULL)
  75.         {
  76.             return NO_ERROR;
  77.         }

  78.         for (PSTR p = (PSTR) pvContext; *p; p += UAStrLen(p) + 1)
  79.         {
  80.             if ((*p != '#') && DevCmp(pszFile, p))
  81.             {
  82.                 // Found Device
  83.                 UAStrToStr(s_tzDevID, p, MAX_NAME);
  84.                 UStrCopy(s_tzInfPath, ptzTarget);
  85.                 //UTrack(TEXT("\r\nFound %s: %s\r\n\r\n"), s_tzDevID, s_tzInfPath);
  86.                 s_bExtract = TRUE;
  87.                 *p = '#';
  88.                 return NO_ERROR;
  89.             }
  90.         }

  91.         // This is next INF
  92.         if (s_bExtract)
  93.         {
  94.             // Previous is uses INF
  95.             s_bExtract = FALSE;
  96.             HMODULE hLib = LoadLibrary(TEXT("NewDev"));
  97.             if (hLib)
  98.             {
  99.                 // Install INF
  100.                 PUPNP p = (PUPNP) GetProcAddress(hLib, STR_UpdateDriverForPlugAndPlayDevices);
  101.                 if (p)
  102.                 {
  103.                     BOOL bReboot = FALSE;
  104.                     p(NULL, s_tzDevID, s_tzInfPath, 3, &bReboot);
  105.                     UTrack(TEXT("\r\nInstall %s: %s\r\n\r\n"), s_tzDevID, s_tzInfPath);
  106.                 }
  107.                 FreeLibrary(hLib);
  108.             }
  109.         }
  110.         
  111.         // Delete INF
  112.         UFileDelete(ptzTarget);
  113.     }
  114.     return NO_ERROR;
  115. }

  116. #define MAX_DevID (MAX_STR * 4)
  117. UINT DevEnum(PSTR pszDev, PCTSTR ptzClass = REGSTR_KEY_PCIENUM)
  118. {
  119.     // Lookup device
  120.     HDEVINFO hDev = SetupDiGetClassDevs(NULL, ptzClass, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES );
  121.     if (hDev == INVALID_HANDLE_VALUE)
  122.     {
  123.         return E_FAIL;
  124.     }

  125.     // Lookup Device ID
  126.     UINT uSize = 0;
  127.     SP_DEVINFO_DATA sdDev = {sizeof(SP_DEVINFO_DATA)};
  128.     for (UINT i = 0; (uSize < MAX_DevID) && SetupDiEnumDeviceInfo(hDev, i, &sdDev); i++)
  129.     {
  130.         DWORD dwData;
  131.         DWORD dwSize = MAX_DevID- uSize;
  132.         if (SetupDiGetDeviceRegistryPropertyA(hDev, &sdDev, SPDRP_HARDWAREID, &dwData, (PBYTE) pszDev + uSize, dwSize, &dwSize))
  133.         {
  134. #ifndef _DEBUG
  135.             // List problem device only
  136.             ULONG uProblem = 0;
  137.             ULONG uStatus = DN_HAS_PROBLEM;
  138.             CM_Get_DevNode_Status(&uStatus, &uProblem, sdDev.DevInst, 0);
  139.             if (uProblem)
  140. #endif
  141.             {
  142.                 uSize += UAStrLen(pszDev + uSize) + 1;
  143.             }
  144.         }
  145.     }

  146.     SetupDiDestroyDeviceInfoList(hDev);
  147.     pszDev[uSize] = pszDev[uSize + 1] = 0;
  148.     return uSize;
  149. }

  150. // Install device
  151. HRESULT Devi(PTSTR ptzCmd)
  152. {
  153.     // Skip if Control Key pressed.
  154.     if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
  155.     {
  156.         return S_FALSE;
  157.     }

  158.     // Enum device ID
  159.     CHAR szDev[MAX_DevID];
  160.     UINT uSize = DevEnum(szDev, TEXT("PCI"));
  161.     uSize +=  DevEnum(szDev + uSize, TEXT("USB"));
  162.     if (uSize == 0)
  163.     {
  164.         // No device
  165.         return ERROR_DEVICE_NOT_CONNECTED;
  166.     }

  167. #ifdef _DEBUG
  168.     for (PSTR p = szDev; *p; p += UAStrLen(p) + 1)
  169.     {
  170.         UTrack(TEXT("%hs\r\n"), p);
  171.     }
  172. #endif

  173.     // Lookup CAB file
  174.     TCHAR tzPath[MAX_PATH];
  175.     ExpandEnvironmentStrings(ptzCmd, tzPath, MAX_PATH);
  176.     SetupIterateCabinet(tzPath, 0, DevProc, szDev);

  177.     return S_OK;
  178. }
复制代码

[ 本帖最后由 Yonsm 于 2007-1-5 12:33 AM 编辑 ]
92#
发表于 2010-8-31 00:02:48 | 只看该作者
留个记号.......
回复

使用道具 举报

91#
发表于 2010-8-11 12:37:12 | 只看该作者
这个得支持,以后可以用光盘,而 不是用硬盘,这样就不怕中毒了。
回复

使用道具 举报

90#
发表于 2007-7-31 12:15:42 | 只看该作者
自动检测硬件ID,查找匹配的INF安装相关驱动,可以做成智能驱动安装软件啊:lol
回复

使用道具 举报

89#
发表于 2007-7-31 02:55:12 | 只看该作者
真的很棒,,,期待佳作
回复

使用道具 举报

88#
发表于 2007-7-29 18:45:38 | 只看该作者
貌似还不错。。。。。。。。。。。。。。。。。。。
回复

使用道具 举报

87#
发表于 2007-7-29 16:57:59 | 只看该作者
CELETASK  的作者,想不到也来这里混了,,支持一个
回复

使用道具 举报

86#
发表于 2007-7-29 13:49:43 | 只看该作者
不是很懂 不过还是支持的说
小弟现在只会在一个U盘装PE 然后加点东西
回复

使用道具 举报

85#
发表于 2007-7-29 13:03:14 | 只看该作者
:D :D 应该有成果了吧
回复

使用道具 举报

84#
发表于 2007-7-29 12:23:13 | 只看该作者
你太猛了,手机软件,电脑系统,你都会啊,厉害
回复

使用道具 举报

83#
发表于 2007-6-9 01:13:28 | 只看该作者
学习。作品发出来让大家测试
回复

使用道具 举报

82#
发表于 2007-6-9 01:08:22 | 只看该作者
学习。作品发出来让大家测试
回复

使用道具 举报

81#
发表于 2007-6-8 18:38:12 | 只看该作者
学习了,进步了!
回复

使用道具 举报

80#
发表于 2007-6-7 20:30:16 | 只看该作者
支持,请把作品发出来让大家测试
回复

使用道具 举报

79#
发表于 2007-6-7 11:32:09 | 只看该作者
看了有点头大。代码好多。
回复

使用道具 举报

78#
发表于 2007-5-31 13:05:46 | 只看该作者
试用版还未出现吗?
帖子都沉了啦。。。。。
回复

使用道具 举报

77#
发表于 2007-5-21 23:40:45 | 只看该作者
:) 谢谢分享哦,下来看看看看
回复

使用道具 举报

76#
发表于 2007-5-21 23:17:16 | 只看该作者
又有新突破了!!试试~~~
回复

使用道具 举报

75#
发表于 2007-5-21 22:49:46 | 只看该作者
期待佳作!!!!:lol
回复

使用道具 举报

74#
发表于 2007-5-18 01:29:23 | 只看该作者
唉,要好好学习,很多都不懂。
回复

使用道具 举报

73#
发表于 2007-1-9 04:28:16 | 只看该作者
确实先进啊,没有了B盘,空闲内存又多10兆,开心:lol:lol

真是好东西!!!
回复

使用道具 举报

72#
发表于 2007-1-7 19:51:28 | 只看该作者
真是好东东啊
回复

使用道具 举报

71#
发表于 2007-1-7 19:10:39 | 只看该作者
我帮你顶吧,因为这个想法却是不错,但是linux早已经可以了,ubuntu啊
回复

使用道具 举报

70#
发表于 2007-1-7 12:05:45 | 只看该作者
好贴没人顶?
我顶
回复

使用道具 举报

69#
发表于 2007-1-7 09:21:07 | 只看该作者
严重期待呀
回复

使用道具 举报

68#
发表于 2007-1-7 00:55:38 | 只看该作者
原帖由 Yonsm 于 2007-1-6 05:34 PM 发表

另一个帖子里有人说了结果的,在 REBOOT 的贴子里。

另外,马上就发现了一些问题,晚上我尽快修正:INF中 Device 是小写的话将无法匹配。


测试了,可以(我的是8139网络卡)

iso启动也没问题,研究了一下,功能强的没话说了,不过要出一分详细说明才行。

另外提出了个bt的想法,写到你的网站上了。。
回复

使用道具 举报

67#
发表于 2007-1-7 00:43:03 | 只看该作者
期待不断突破
回复

使用道具 举报

66#
发表于 2007-1-6 22:36:26 | 只看该作者
我也下载了! 慢慢研究! 楼上的不要理他,个人观点不同,他意识跟不上!
回复

使用道具 举报

65#
 楼主| 发表于 2007-1-6 22:36:03 | 只看该作者
原帖由 acoa 于 2007-1-6 05:44 PM 发表
请老大记得把Ctrl+Alt+Del 这个命令加进去啊
越来越体会到老大这个工具的强大。


已经加上去了,晚上睡觉前我会更新的。还在做其它的测试和检查。
回复

使用道具 举报

64#
发表于 2007-1-6 22:26:23 | 只看该作者
原帖由 wgykk 于 2007-1-6 09:06 PM 发表
下载下来看了一下,不是我想要的东西。还不如CHENALL的批处理来得方便准确。我想要的是可以搜索并直接安装驱动,PE系统下直接可以使用。楼主的东西好象只能将驱动放到PE系统相应文件夹,不知道能否安装好驱动?我 ...

真是不识货。
回复

使用道具 举报

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

本版积分规则

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

闽公网安备 35020302032614号

GMT+8, 2025-3-5 00:57

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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