// InstallWDFDriver.cpp : Defines the entry point for the console application.
// #include "stdafx.h"
#include "Shlwapi.h" #pragma comment(lib,"Shlwapi.lib")
#pragma comment (lib,"setupapi.lib")
#pragma comment(lib, "newdev.lib")
///////////////////////////////////////////////////////////////////////////////////// BOOL IsDeviceInstallInProgress(VOID);
int RemoveDriver(_TCHAR *HardwareID);
VOID UninstallWDMDriver(LPCTSTR theHardware);
BOOL UnicodeToAnsi(LPCWSTR Source, const WORD wLen, LPSTR Destination, const WORD sLen);
BOOL AnsiToUnicode(LPCSTR Source, const WORD sLen, LPWSTR Destination, const WORD wLen);
BOOL GetINFData(FILE *pFile);
VOID FindComma(LPSTR szData);
BOOL GetSectionData(FILE* pFile, const char* szKey, const char bIsVender);
BOOL IsInstalled();
BOOL InstallClassDriver(LPCTSTR theINFName);
BOOL StartInstallWDMDriver(LPCTSTR theInfName) ; BOOL FindExistingDevice(IN LPTSTR HardwareId); VOID InitialGlobalVar(); ////////////////////////////////////////////////////////////////////////////// WORD g_wVender = ;
WORD g_wHardware = ;
TCHAR g_strVender[][] = {};
TCHAR g_strHardware[][] = {};
TCHAR g_strHID[MAX_PATH+] = {};
///////////////////////////////////////////////////////////////////////////// int _tmain(int argc, _TCHAR* argv[])
{
WCHAR Wlp_USB_PATH[] = L"C:\\Windows\\System32\\drivers\\WLP_USB_Driver.sys";
WCHAR New_Inf_Path[] = L"D:\\wlp driver\\WDF Driver _new\\win7\\x64\\cyusb3.inf";
CHAR szInfPath[] = {};
FILE *fp = NULL; printf("This Process is Driver Installtion Program...\n"); if(PathFileExists(Wlp_USB_PATH))
{
printf("Exists WLP_USB_Driver.sys!\n"); UninstallWDMDriver(L"USB\\VID_0451&PID_AF32&REV_0000"); if(DeleteFile(L"C:\\Windows\\System32\\drivers\\WLP_USB_Driver.sys"))
{
printf("WLP_USB_Driver.sys File has Deleted!\n");
} /* if(FindExistingDevice(L"USB\\VID_0451&PID_AF32&REV_0000"))
{
printf("找打了!\n"); getch();
}
else
{
printf("没找到!\n");
getch();
}*/ printf("Get Started Install the New DLF Driver...\n"); // RemoveDriver(L"USB\\VID_0451&PID_AF32&REV_0000");
while(IsDeviceInstallInProgress())
{
printf("Has Driver Installtion Program is Processing!\n");
} printf("Get Started analyse inf File!\n"); UnicodeToAnsi(New_Inf_Path, _tcslen(New_Inf_Path), szInfPath, ); if ((fopen_s(&fp, szInfPath, "r"))!=)
{
_tprintf(_T("can not open file %s\n"), New_Inf_Path);
return ;
} GetINFData(fp);
fclose(fp); // 安装WDM驱动 if (StartInstallWDMDriver(New_Inf_Path) == FALSE)
{
_tprintf(_T("Start Install WDF Driver failed\n"));
getch();
return ;
} //if(CopyFile(L"D:\\wlp driver\\WDF Driver _new\\win7\\x64\\cyusb3.sys",L"C:\\Windows\\System32\\drivers\\cyusb3.sys",TRUE))
// printf("New DLF Driver successed!\n");
getch(); }
else
{
printf("No Exists WLP_USB_Driver.sys!\n"); printf("Get Started Install the New DLF Driver...\n"); // RemoveDriver(L"USB\\VID_0451&PID_AF32&REV_0000");
//while(IsDeviceInstallInProgress())
//{
// printf("Has Driver Installtion Program is Processing!\n");
//} printf("Get Started analyse inf File!\n"); UnicodeToAnsi(New_Inf_Path, _tcslen(New_Inf_Path), szInfPath, ); if ((fopen_s(&fp, szInfPath, "r"))!=)
{
_tprintf(_T("can not open file %s\n"), New_Inf_Path);
return ;
} GetINFData(fp);
fclose(fp); // 安装WDM驱动 if (StartInstallWDMDriver(New_Inf_Path) == FALSE)
{
_tprintf(_T("Start Install WDF Driver failed\n"));
getch();
return ;
} // if(CopyFile(L"D:\\wlp driver\\WDF Driver _new\\win7\\x64\\cyusb3.sys",L"C:\\Windows\\System32\\drivers\\cyusb3.sys",TRUE))
// printf("New DLF Driver successed!\n");
getch(); } return ;
} BOOL IsDeviceInstallInProgress (VOID)
{
return !(CM_WaitNoPendingInstallEvents() == WAIT_OBJECT_0);
} int RemoveDriver(_TCHAR *HardwareID)
{
HDEVINFO DeviceInfoSet;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i,err;
//GUID devGUID ={36fc9e60-c465-11cf-8056-444553540000}; DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes
,
,
DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system if (DeviceInfoSet == INVALID_HANDLE_VALUE)
{
printf("GetClassDevs(All Present Devices)\n");
return ;
} //
// Enumerate through all Devices.
//
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)
{
DWORD DataT;
LPTSTR p,buffer = NULL;
DWORD buffersize = ; //
// We won't know the size of the HardwareID buffer until we call
// this function. So call it with a null to begin with, and then
// use the required buffer size to Alloc the nessicary space.
// Keep calling we have success or an unknown failure.
//
while (!SetupDiGetDeviceRegistryProperty(
DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA)
{
//
// May be a Legacy Device with no HardwareID. Continue.
//
break;
}
else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
//
// We need to change the buffer size.
//
if (buffer)
LocalFree(buffer);
buffer = (LPTSTR)LocalAlloc(LPTR,buffersize);
}
else
{
//
// Unknown Failure.
//
printf("GetDeviceRegistryProperty");
goto cleanup_DeviceInfo;
}
} if (GetLastError() == ERROR_INVALID_DATA)
continue; //
// Compare each entry in the buffer multi-sz list with our HardwareID. //
for (p = buffer; *p && (p < &buffer[buffersize]);p+=lstrlen(p)*sizeof(TCHAR) + ) {
//_tprintf(TEXT("Compare device ID: [%s]/n"),p); if (!_tcscmp(HardwareID,p))
{
//_tprintf(TEXT("Found! [%s]/n"),p); //
// Worker function to remove device.
//
//if (SetupDiCallClassInstaller(DIF_REMOVE,
// DeviceInfoSet,
// &DeviceInfoData)) if (SetupDiRemoveDevice(DeviceInfoSet, &DeviceInfoData)) {
printf("CallClassInstaller(REMOVE)\n");
}
else
printf("Remove Driver Fail\n");
break;
} //printf("TTTTTTTTTTTTTTTTT is %s\n",p);
//getch();
} if (buffer) LocalFree(buffer);
} if ((GetLastError()!=NO_ERROR)&&(GetLastError()!=ERROR_NO_MORE_ITEMS))
{
printf("EnumDeviceInfo\n");
} //
// Cleanup.
//
cleanup_DeviceInfo:
err = GetLastError();
SetupDiDestroyDeviceInfoList(DeviceInfoSet); return err;
} VOID UninstallWDMDriver(LPCTSTR theHardware)
{
SP_DEVINFO_DATA spDevInfoData = {};
HDEVINFO hDevInfo = 0L;
WORD wIdx, wCount = ; //得到设备信息结构的句柄
hDevInfo = SetupDiGetClassDevs(0L, 0L, 0L, DIGCF_ALLCLASSES | DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
printf("Fail!\n");
return;
} wIdx = ;
while (TRUE)
{
spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
//找到所有的硬件设备,并且可以得到所有的硬件设备的详细信息
if (SetupDiEnumDeviceInfo(hDevInfo, wIdx, &spDevInfoData))
{
char Buffer[] = {}; //可以在前面得到的指向某一个具体设备信息集合的指针中取出某一项信息
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData, SPDRP_HARDWAREID,
0L, (PBYTE)Buffer, , 0L))
{
if (!_tcscmp(theHardware, (LPTSTR)Buffer))
{
//从系统中删除一个注册的设备接口
if (!SetupDiRemoveDevice(hDevInfo, &spDevInfoData))
printf("Remove Fail is %d!\n",GetLastError());
wCount++;
}
}
}
else
break;
wIdx++;
} if (wCount != )
_tprintf(_T("UnInstall Successed...\n")); //销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo);
//InitialGlobalVar();
return;
} BOOL UnicodeToAnsi(LPCWSTR Source, const WORD wLen, LPSTR Destination, const WORD sLen)
{
return WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, Source, wLen, Destination,
sLen, 0L, 0L);
} BOOL AnsiToUnicode(LPCSTR Source, const WORD sLen, LPWSTR Destination, const WORD wLen)
{
return MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Source, sLen, Destination, wLen);
} BOOL GetINFData(FILE *pFile)
{
WORD wLoop; if (!g_wVender || !g_wHardware)
InitialGlobalVar();
if (GetSectionData(pFile, "[Manufacturer]", TRUE) == FALSE)
return FALSE; for (wLoop = ; wLoop < g_wVender; wLoop++)
{
CHAR szVender[] = {};
UnicodeToAnsi(g_strVender[wLoop], _tcslen(g_strVender[wLoop]), szVender, );
GetSectionData(pFile, szVender, FALSE);
}
if (g_wHardware != )
{
if (IsInstalled() == TRUE)//如果已经安装
return FALSE;
else
return TRUE;
}
return FALSE;
} VOID InitialGlobalVar()
{
WORD wLoop; g_wVender = g_wHardware = ;
for (wLoop = ; wLoop < ; wLoop++)
{
RtlZeroMemory(g_strVender[wLoop], sizeof(TCHAR)*);
RtlZeroMemory(g_strHardware[wLoop], sizeof(TCHAR)*);
}
} VOID FindComma(LPSTR szData)
{
WORD wLen = (WORD)strlen(szData);
WORD wIdx;
WORD wLoop;
CHAR szTmp[] = {}; for (wIdx = , wLoop = ; wLoop < wLen; wLoop++)
{
if (szData[wLoop] == ',')
szData[wLoop] = '.';
else if (szData[wLoop] == ' ')
continue;
szTmp[wIdx++] = szData[wLoop];
}
memcpy(szData, szTmp, wIdx*sizeof(char));
szData[wIdx] = ;
} VOID StrLTrim(LPSTR szData)
{
LPSTR ptr = szData;
//判断是否为空格
while (isspace(*ptr))
ptr++; if (strcmp(ptr, szData))
{
WORD wLen = (WORD)(strlen(szData) - (ptr - szData));
memmove(szData, ptr, (wLen+)*sizeof(char));
}
} VOID StrRTrim(LPSTR szData)
{
LPSTR ptr = szData;
LPSTR pTmp = NULL; //debug模式下 使用isspace判断中文 需要设置编码
#if defined(WIN32) && defined(_DEBUG)
char* locale = setlocale( LC_ALL, ".OCP" );
#endif while (*ptr != )
{
//判断是否为空格
if (isspace(*ptr))
{
if (!pTmp)
pTmp = ptr;
}
else
pTmp = NULL;
ptr++;
} if (pTmp)
{
*pTmp = ;
memmove(szData, szData, strlen(szData) - strlen(pTmp));
}
} //从字符串右边开始截取字符串
VOID StrRight(LPSTR szData, WORD wCount)
{
WORD wLen = (WORD)strlen(szData) - wCount; if (wCount > 0x7FFF)//负数
wCount = ;
if (wCount >= (WORD)strlen(szData))
return; memmove(szData, szData + wLen, wCount * sizeof(char));
szData[wCount] = ;
} VOID ConvertGUIDToString(const GUID guid, LPSTR pData)
{
CHAR szData[] = {};
CHAR szTmp[] = {};
WORD wLoop; sprintf_s(pData, _countof(szData), "%04X-%02X-%02X-", guid.Data1, guid.Data2, guid.Data3);
for (wLoop = ; wLoop < ; wLoop++)
{
if (wLoop == )
strcat_s(szData, "-");
sprintf_s(szTmp, _countof(szTmp), "%02X", guid.Data4[wLoop]);
strcat_s(szData, szTmp);
} memcpy(pData + strlen(pData), szData, strlen(szData));
} BOOL IsInstalled()
{
HDEVINFO hDevInfo = 0L;
SP_DEVINFO_DATA spDevInfoData = {0L};
WORD wIdx;
BOOL bIsFound; //得到设备信息结构的句柄
hDevInfo = SetupDiGetClassDevs(0L, , , DIGCF_ALLCLASSES | DIGCF_PRESENT);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
printf("SetupDiGetClassDevs is %d",GetLastError());
return FALSE;
} spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
wIdx = ;
bIsFound = ;
while (++wIdx)
{
//找到所有的硬件设备,并且可以得到所有的硬件设备的详细信息
if (SetupDiEnumDeviceInfo(hDevInfo, wIdx, &spDevInfoData))
{
LPTSTR ptr;
LPBYTE pBuffer = NULL;
DWORD dwData = 0L;
DWORD dwRetVal;
DWORD dwBufSize = 0L; while (TRUE)
{
//可以在前面得到的指向某一个具体设备信息集合的指针中取出某一项信息
dwRetVal = SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData, SPDRP_HARDWAREID,
&dwData, (PBYTE)pBuffer, dwBufSize, &dwBufSize);
if (!dwRetVal)
dwRetVal = GetLastError();
else
break;
if (dwRetVal == ERROR_INVALID_DATA)
break;
else if (dwRetVal == ERROR_INSUFFICIENT_BUFFER)
{
if (pBuffer)
LocalFree(pBuffer);
pBuffer = (LPBYTE)LocalAlloc(LPTR, dwBufSize);
}
else
{
printf("SetupDiGetDeviceRegistryProperty is %d",dwRetVal);
//销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo);
return FALSE;
}
} if (dwRetVal == ERROR_INVALID_DATA)
continue; for (ptr = (LPTSTR)pBuffer; *ptr && (ptr < (LPTSTR)&pBuffer[dwBufSize]); ptr += _tcslen(ptr) + sizeof(TCHAR))
{
WORD wLoop; for (wLoop = ; wLoop < g_wHardware; wLoop++)
{
if (!_tcscmp(g_strHardware[wLoop], ptr))
{
bIsFound = TRUE;
break;
}
}
}
if (pBuffer)
LocalFree(pBuffer);
if (bIsFound)
break;
}
}
//销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo);
return bIsFound;
} //寻找指定的节名 如果找到返回TRUE 反之返回FALSE
BOOL FindSectionName(FILE *pFile, const char *szKey)
{
char szData[] = {}; if (!pFile)
return FALSE; //将文件内部的位置指针重新指向一个流(数据流/文件)的开头
rewind(pFile);
//循环读取文件内容
while (!feof(pFile))
{
//读取一行
fgets(szData, , pFile);
//去除前后空格
StrLTrim(szData);
StrRTrim(szData); if (strcmp(szKey, szData) == )
return TRUE;
}
return FALSE;
} //得到INF文件中节的数量
BOOL GetSectionData(FILE* pFile, const char* szKey, const char bIsVender)
{
char szData[] = {}; if (bIsVender)
strcpy_s(szData, szKey);
else
sprintf_s(szData, _countof(szData), "[%s]", szKey); if (FindSectionName(pFile, szData) == FALSE)
return FALSE; RtlZeroMemory(szData, sizeof(char)*);
while (!feof(pFile))
{
char *str = NULL;
fgets(szData, , pFile);
szData[strlen(szData)-] = ;
StrLTrim(szData);
StrRTrim(szData);
if (!*szData)
continue;
if (szData[] == ';')
continue; if (strchr(szData, '['))
{
StrLTrim(szData);
if (szData[] != ';')
return ;
else
continue;
} if (bIsVender)
str = strchr(szData, '=');
else
str = strchr(szData, ','); if (*str)
{
char szTmp[] = {};
WORD pos = (WORD)(str - szData + ); StrRight(szData, (short)(strlen(szData)-pos));
StrLTrim(szData);
StrRTrim(szData);
FindComma(szData);
if (bIsVender)
{
AnsiToUnicode(szData, strlen(szData), g_strVender[g_wVender++], );
}
else
{
AnsiToUnicode(szData, strlen(szData), g_strHardware[g_wHardware++], );
}
}/* end if */
}
return TRUE;
} //实质性的安装驱动
BOOL InstallClassDriver(LPCTSTR theINFName)
{
GUID guid = {};
SP_DEVINFO_DATA spDevData = {};
HDEVINFO hDevInfo = 0L;
TCHAR className[MAX_CLASS_NAME_LEN] = {};
LPTSTR pHID = NULL;
WORD wLoop;
BOOL bRebootRequired; //取得此驱动的GUID值
if (!SetupDiGetINFClass(theINFName, &guid, className, MAX_CLASS_NAME_LEN, ))
{
printf( "SetupDiGetINFClass is %d\n",GetLastError());
return FALSE;
} //创建设备信息块列表
hDevInfo = SetupDiCreateDeviceInfoList(&guid, );
if (hDevInfo == INVALID_HANDLE_VALUE)
{
printf("SetupDiCreateDeviceInfoList is %d\n",GetLastError());
return FALSE;
} spDevData.cbSize = sizeof(SP_DEVINFO_DATA);
//创建设备信息块
if (!SetupDiCreateDeviceInfo(hDevInfo, className, &guid, 0L, 0L, DICD_GENERATE_ID, &spDevData))
{
printf("SetupDiCreateDeviceInfo is %d",GetLastError());
//销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo);
return FALSE;
} //for (wLoop = 0; wLoop < g_wHardware; wLoop++)
//{
if (pHID)
LocalFree(pHID); pHID = (LPTSTR)LocalAlloc(LPTR, _tcslen(L"USB\\VID_0451&PID_AF32")**sizeof(TCHAR));
if (!pHID)
{
printf("LocalAlloc is %d",GetLastError());
//销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo);
return FALSE;
} _tcscpy_s(pHID, _tcslen(L"USB\\VID_0451&PID_AF32")*,
L"USB\\VID_0451&PID_AF32");
//设定硬件ID
if (!SetupDiSetDeviceRegistryProperty(hDevInfo, &spDevData, SPDRP_HARDWAREID, (PBYTE)pHID,
(DWORD)(_tcslen(L"USB\\VID_0451&PID_AF32")**sizeof(TCHAR))))
{
printf("SetupDiSetDeviceRegistryProperty is %d",GetLastError());
//销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo);
LocalFree(pHID);
return FALSE;
}
//调用相应的类程序来注册设备
if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDevInfo, &spDevData))
{
printf("SetupDiCallClassInstaller is %d", GetLastError());
//销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo);
LocalFree(pHID);
return FALSE;
} bRebootRequired = FALSE;
//安装更新和硬件ID相匹配的驱动程序
if (!UpdateDriverForPlugAndPlayDevices(0L, L"USB\\VID_0451&PID_AF32"
, theINFName,
INSTALLFLAG_FORCE, &bRebootRequired))
{
DWORD dwErrorCode = GetLastError();
//调用相应的类程序来移除设备
if (!SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, &spDevData))
printf("SetupDiCallClassInstaller(Remove) is %d",GetLastError());
printf("UpdateDriverForPlugAndPlayDevices is %d",(WORD)dwErrorCode);
//销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo);
LocalFree(pHID); getch();
return FALSE;
}
LocalFree(pHID);
pHID = NULL; //}
//销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo);
_tprintf(_T("Install Successed\n"));
return TRUE;
} // 安装WDM驱动的测试工作
BOOL StartInstallWDMDriver(LPCTSTR theInfName)
{
HDEVINFO hDevInfo = 0L;
GUID guid = {0L};
SP_DEVINSTALL_PARAMS spDevInst = {0L};
TCHAR strClass[MAX_CLASS_NAME_LEN] = {0L}; //取得此驱动的GUID值
if (!SetupDiGetINFClass(theInfName, &guid, strClass, MAX_CLASS_NAME_LEN, ))
{
printf("SetupDiGetINFClass is %d",GetLastError());
return FALSE;
} //得到设备信息结构的句柄
hDevInfo = SetupDiGetClassDevs(&guid, 0L, 0L, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_PROFILE);
if (!hDevInfo)
{
printf("SetupDiGetClassDevs is %d",GetLastError());
return FALSE;
} spDevInst.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
//获得指定设备的安装信息
if (!SetupDiGetDeviceInstallParams(hDevInfo, 0L, &spDevInst))
{
printf("SetupDiGetDeviceInstallParams is %d",GetLastError());
return FALSE;
} spDevInst.Flags = DI_ENUMSINGLEINF;
spDevInst.FlagsEx = DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
_tcscpy_s(spDevInst.DriverPath, _countof(spDevInst.DriverPath), theInfName); //为设备信息集或者是一个实际的设备信息单元设置或清除类安装参数
if (!SetupDiSetDeviceInstallParams(hDevInfo, , &spDevInst))
{ printf("SetupDiSetDeviceInstallParams is %d",GetLastError());
return FALSE;
} //获取这个设备的驱动程序信息列表
if (!SetupDiBuildDriverInfoList(hDevInfo, , SPDIT_CLASSDRIVER))
{ printf("SetupDiDeviceInstallParams is %d",GetLastError());
return FALSE;
} //销毁一个设备信息集合
SetupDiDestroyDeviceInfoList(hDevInfo); //进入安装设备驱动函数
return InstallClassDriver(theInfName);
} BOOL FindExistingDevice(IN LPTSTR HardwareId)
{
HDEVINFO DeviceInfoSet;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i,err;
BOOL Found; //
// Create a Device Information Set with all present devices.
//
DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes
,
,
DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system if (DeviceInfoSet == INVALID_HANDLE_VALUE)
{
return printf("GetClassDevs(All Present Devices)"); } //_tprintf(TEXT("Search for Device ID: [%s]/n"),HardwareId); //
// Enumerate through all Devices.
//
Found = FALSE;
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)
{
DWORD DataT;
LPTSTR p,buffer = NULL;
DWORD buffersize = ; //
// We won't know the size of the HardwareID buffer until we call
// this function. So call it with a null to begin with, and then
// use the required buffer size to Alloc the nessicary space.
// Keep calling we have success or an unknown failure.
//
while (!SetupDiGetDeviceRegistryProperty(
DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA)
{
//
// May be a Legacy Device with no HardwareID. Continue.
//
break;
}
else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
//
// We need to change the buffer size.
//
if (buffer)
LocalFree(buffer);
buffer = (LPTSTR)LocalAlloc(LPTR,buffersize);
}
else
{
//
// Unknown Failure.
//
printf("GetDeviceRegistryProperty");
goto cleanup_DeviceInfo;
}
} if (GetLastError() == ERROR_INVALID_DATA)
continue; //
// Compare each entry in the buffer multi-sz list with our HardwareID. //
for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR)) {
//_tprintf(TEXT("Compare device ID: [%s]/n"),p); if (!_tcscmp(HardwareId,p))
{
//_tprintf(TEXT("Found! [%s]/n"),p);
Found = TRUE;
break;
}
} if (buffer) LocalFree(buffer);
if (Found) break;
} if (GetLastError() != NO_ERROR)
{
printf("EnumDeviceInfo");
} //
// Cleanup.
//
cleanup_DeviceInfo:
err = GetLastError();
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
SetLastError(err); return err == NO_ERROR; //???
}

遇到的问题:mainifest文件要改为管理员权限,或者点击exe要为管理员权限才能正确安装

硬件ID有两个,可能是不一样的用途??至今仍未搞明白,我用同一个硬件ID,卸载了之后,就不能安装了。

UpdateDriverForPlugAndPlayDevices function

发生

ERROR_NO_SUCH_DEVINST错误码,意思是找不到此硬件ID的设备,是不是把硬件ID的名字空间删了?

但是我用同一个硬件的另一个硬件ID(因为有两个:USB\VID_0451&PID_AF32&REV_0000

,USB\VID_0451&PID_AF32

)就能安装了。

用Setup系列函数完成驱动卸载安装[驱动安装卸载程序]的更多相关文章

  1. Inno Setup 系列之先卸载之后再安装

    需求使用Inno Setup打包程序之后,很多时候我们需要在安装文件之前卸载原有的程序而不是覆盖安装,本文的Code就是实现了这样的功能.如果想要在安装前先卸载,那么需要加下面代码,需要注意的是双星号 ...

  2. INF 右键安装驱动以及卸载

    INF 右键安装驱动以及卸载 之前写过一篇文章是关于INF文件详解的,大家可以参看INF文件详解,这次写的是关于INF右键安装,这样比较方便.卸载的话也是一句话,可以大大减少安装时间: 先将INF文件 ...

  3. 玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理

    Windows服务Debug版本 注册 Services.exe -regserver 卸载 Services.exe -unregserver Windows服务Release版本 注册 Servi ...

  4. Linux代码的重用与强行卸载Linux驱动

    (一)Linux代码的重用 重用=静态重用(将要重用的代码放到其他的文件的头文件中声明)+动态重用(使用另外一个Linux驱动中的资源,例如函数.变量.宏等) 1.编译是由多个文件组成的Linux驱动 ...

  5. Inno Setup入门(十一)——完成安装后执行某些程序

    Inno Setup入门(十一)——完成安装后执行某些程序 2011-02-16 16:24:23|  分类: Inno Setup |  标签:inno  setup   |举报 |字号 订阅   ...

  6. 玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理

    原文:玩转Windows服务系列——Debug.Release版本的注册和卸载,及其原理 Windows服务Debug版本 注册 Services.exe -regserver 卸载 Services ...

  7. Ubuntu系统---安NVIDIA 驱动后 CUDA+cuDNN 安装

    Ubuntu系统---安NVIDIA 驱动后  CUDA+cuDNN 安装 --------------------------------------------@20190726--------- ...

  8. R的卸载和更新安装

      R包经常会遇到各种版本不兼容的毛病,比如当前的版本相较于包,新了/旧了都是麻烦 而升级R软件呢,最麻烦的就是之前安装的包怎么办? 搜罗了以下几种方法:   方法1: (1)直接安装新版本 (2)然 ...

  9. Cygwin的安装,卸载,以及安装gdb

    转载来源 http://10000001.blog.51cto.com/4600383/1341484   1.安装 其实Cygwin的安装时很简单的,需要的安装相应的就可以了,要详细的去网上找,很多 ...

随机推荐

  1. jquery表单实时验证

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. escape encodeURI encodeURIComponent区别

    escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串.使用unescape来解码. 有效的URI(统一资源标示符)是不能包含某些字符的,如空格,所以需要进行编码,编码方法有 ...

  3. ZOJ1221 && UVA567:Risk(Floyd)

    Risk is a board game in which several opposing players attempt to conquer the world. The gameboard c ...

  4. android动画效果编程基础--Android Animation

    动画效果编程基础--Android Animation 动画类型 Android的animation由四种类型组成 XML中 alpha 渐变透明度动画效果 scale 渐变尺寸伸缩动画效果 tran ...

  5. 《网络编程》先进 I/O

    这部分是高级插座 I/O . 设置套接字超时报警,使用更方便的数据传输功能. 套接字 I/O 设置操作超时有三种方法: 转让 alarm 性能,制作时,它指定超时 SIGALRM 信号: 在 sele ...

  6. SQL优化(Oracle)

    (转)SQL优化原则 一.问题的提出 在应用系统开发初期.因为开发数据库数据比較少.对于查询SQL语句,复杂视图的的编写等体会不出SQL语句各种写法的性能优劣,可是假设将应用系统提交实际应用后,随着数 ...

  7. ViewPager 详解(二)---详解四大函数

    前言:上篇中我们讲解了如何快速实现了一个滑动页面,但问题在于,PageAdapter必须要重写的四个函数,它们都各有什么意义,在上节的函数内部为什么要这么实现,下面我们就结合Android的API说明 ...

  8. sessionstorage,localstorage和cookie之间的区别

    sessionStorage 和 localStorage 是HTML5 Web Storage API 提供的,可以方便的在web请求之间保存数据.有了本地数据,就可以避免数据在浏览器和服务器间不必 ...

  9. [转]《深度探索C++对象模型》读书笔记[一]

    前 言 Stanley B.Lippman1.   任何对象模型都需要的三种转换风味: ü        与编译器息息相关的转换 ü        语言语义转换 ü        程序代码和对象模型的 ...

  10. css样式-ime-mode text-transform

    今天遇到一个新的css样式: ime-mode   text-transform  有效小作用 取值:auto : 默认值.不影响ime的状态.与不指定 ime-mode 属性时相同 active : ...