pe修复linux驱动,WinPE 驱动程序最终解决方案

// Header

#include

#include

#include

#include

#pragma comment(lib, "SetupAPI.lib")

#ifdef _UNICODE

#define STR_UpdateDriverForPlugAndPlayDevices "UpdateDriverForPlugAndPlayDevicesW"

#else

#define STR_UpdateDriverForPlugAndPlayDevices "UpdateDriverForPlugAndPlayDevicesA"

#endif

typedef BOOL (WINAPI* PUPNP)(HWND  hWnd, PCTSTR ptzID, PCTSTR ptzPath, DWORD dwFlags, PBOOL bReboot);

// Compare device

PSTR DevCmp(PSTR pszStr1, PSTR pszStr2)

{

PSTR p = pszStr2;

for (UINT i = 0; *p; p++)

{

if ((*p == '&') && (++i == 2))

{

break;

}

}

UINT uCmp = (UINT) (p - pszStr2);

p = pszStr1;

while (*p)

{

if (UMemCmp(p, pszStr2, uCmp) == 0)

{

return p;

}

p++;

}

return NULL;

}

// CAB callback

UINT CALLBACK DevProc(PVOID pvContext, UINT uMsg, UINT_PTR upParam1, UINT_PTR upParam2)

{

static BOOL s_bExtract = FALSE;

static TCHAR s_tzDevID[MAX_NAME] = {0};

static TCHAR s_tzInfPath[MAX_PATH] = {0};

if (uMsg == SPFILENOTIFY_FILEINCABINET)

{

// Is INF file or followed by INF file

FILE_IN_CABINET_INFO *p = (FILE_IN_CABINET_INFO*) upParam1;

PCTSTR q = UStrRChr(p->NameInCabinet, '\\');

q = q ? (q + 1) : p->NameInCabinet;

if ((*q == '_') || s_bExtract)

{

// Extract INF or driver file

if (*q == '_')

{

q++;

}

UStrCopy(p->FullTargetName + GetTempPath(MAX_PATH, p->FullTargetName), q);

return FILEOP_DOIT;

}

else

{

// Skip

return FILEOP_SKIP;

}

}

else if (uMsg == SPFILENOTIFY_FILEEXTRACTED)

{

PCTSTR ptzTarget = ((FILEPATHS*) upParam1)->Target;

if (UStrStr(ptzTarget, TEXT(".INF")) == NULL)

{

// Not INF

return NO_ERROR;

}

// Open INF

PSTR pszFile = (PSTR) UFileLoad(ptzTarget, NULL);

if (pszFile == NULL)

{

return NO_ERROR;

}

for (PSTR p = (PSTR) pvContext; *p; p += UAStrLen(p) + 1)

{

if ((*p != '#') && DevCmp(pszFile, p))

{

// Found Device

UAStrToStr(s_tzDevID, p, MAX_NAME);

UStrCopy(s_tzInfPath, ptzTarget);

//UTrack(TEXT("\r\nFound %s: %s\r\n\r\n"), s_tzDevID, s_tzInfPath);

s_bExtract = TRUE;

*p = '#';

return NO_ERROR;

}

}

// This is next INF

if (s_bExtract)

{

// Previous is uses INF

s_bExtract = FALSE;

HMODULE hLib = LoadLibrary(TEXT("NewDev"));

if (hLib)

{

// Install INF

PUPNP p = (PUPNP) GetProcAddress(hLib, STR_UpdateDriverForPlugAndPlayDevices);

if (p)

{

BOOL bReboot = FALSE;

p(NULL, s_tzDevID, s_tzInfPath, 3, &bReboot);

UTrack(TEXT("\r\nInstall %s: %s\r\n\r\n"), s_tzDevID, s_tzInfPath);

}

FreeLibrary(hLib);

}

}

// Delete INF

UFileDelete(ptzTarget);

}

return NO_ERROR;

}

#define MAX_DevID (MAX_STR * 4)

UINT DevEnum(PSTR pszDev, PCTSTR ptzClass = REGSTR_KEY_PCIENUM)

{

// Lookup device

HDEVINFO hDev = SetupDiGetClassDevs(NULL, ptzClass, 0, DIGCF_PRESENT | DIGCF_ALLCLASSES );

if (hDev == INVALID_HANDLE_VALUE)

{

return E_FAIL;

}

// Lookup Device ID

UINT uSize = 0;

SP_DEVINFO_DATA sdDev = {sizeof(SP_DEVINFO_DATA)};

for (UINT i = 0; (uSize < MAX_DevID) && SetupDiEnumDeviceInfo(hDev, i, &sdDev); i++)

{

DWORD dwData;

DWORD dwSize = MAX_DevID- uSize;

if (SetupDiGetDeviceRegistryPropertyA(hDev, &sdDev, SPDRP_HARDWAREID, &dwData, (PBYTE) pszDev + uSize, dwSize, &dwSize))

{

#ifndef _DEBUG

// List problem device only

ULONG uProblem = 0;

ULONG uStatus = DN_HAS_PROBLEM;

CM_Get_DevNode_Status(&uStatus, &uProblem, sdDev.DevInst, 0);

if (uProblem)

#endif

{

uSize += UAStrLen(pszDev + uSize) + 1;

}

}

}

SetupDiDestroyDeviceInfoList(hDev);

pszDev[uSize] = pszDev[uSize + 1] = 0;

return uSize;

}

// Install device

HRESULT Devi(PTSTR ptzCmd)

{

// Skip if Control Key pressed.

if (GetAsyncKeyState(VK_CONTROL) & 0x8000)

{

return S_FALSE;

}

// Enum device ID

CHAR szDev[MAX_DevID];

UINT uSize = DevEnum(szDev, TEXT("PCI"));

uSize +=  DevEnum(szDev + uSize, TEXT("USB"));

if (uSize == 0)

{

// No device

return ERROR_DEVICE_NOT_CONNECTED;

}

#ifdef _DEBUG

for (PSTR p = szDev; *p; p += UAStrLen(p) + 1)

{

UTrack(TEXT("%hs\r\n"), p);

}

#endif

// Lookup CAB file

TCHAR tzPath[MAX_PATH];

ExpandEnvironmentStrings(ptzCmd, tzPath, MAX_PATH);

SetupIterateCabinet(tzPath, 0, DevProc, szDev);

return S_OK;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值