用Setup系列函数完成驱动卸载安装[驱动安装卸载程序]
1 // InstallWDFDriver.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include "Shlwapi.h" 6 7 #pragma comment(lib,"Shlwapi.lib") 8 #pragma comment (lib,"setupapi.lib") 9 #pragma comment(lib, "newdev.lib") 10 ///////////////////////////////////////////////////////////////////////////////////// 11 12 BOOL IsDeviceInstallInProgress(VOID); 13 int RemoveDriver(_TCHAR *HardwareID); 14 VOID UninstallWDMDriver(LPCTSTR theHardware); 15 BOOL UnicodeToAnsi(LPCWSTR Source, const WORD wLen, LPSTR Destination, const WORD sLen); 16 BOOL AnsiToUnicode(LPCSTR Source, const WORD sLen, LPWSTR Destination, const WORD wLen); 17 BOOL GetINFData(FILE *pFile); 18 VOID FindComma(LPSTR szData); 19 BOOL GetSectionData(FILE* pFile, const char* szKey, const char bIsVender); 20 BOOL IsInstalled(); 21 BOOL InstallClassDriver(LPCTSTR theINFName); 22 BOOL StartInstallWDMDriver(LPCTSTR theInfName) ; 23 24 BOOL FindExistingDevice(IN LPTSTR HardwareId); 25 26 VOID InitialGlobalVar(); 27 28 29 ////////////////////////////////////////////////////////////////////////////// 30 31 WORD g_wVender = 0; 32 WORD g_wHardware = 0; 33 TCHAR g_strVender[20][64] = {0}; 34 TCHAR g_strHardware[20][64] = {0}; 35 TCHAR g_strHID[MAX_PATH+1] = {0}; 36 ///////////////////////////////////////////////////////////////////////////// 37 38 int _tmain(int argc, _TCHAR* argv[]) 39 { 40 WCHAR Wlp_USB_PATH[] = L"C:\\Windows\\System32\\drivers\\WLP_USB_Driver.sys"; 41 WCHAR New_Inf_Path[] = L"D:\\wlp driver\\WDF Driver _new\\win7\\x64\\cyusb3.inf"; 42 CHAR szInfPath[215] = {0}; 43 FILE *fp = NULL; 44 45 46 printf("This Process is Driver Installtion Program...\n"); 47 48 if(PathFileExists(Wlp_USB_PATH)) 49 { 50 printf("Exists WLP_USB_Driver.sys!\n"); 51 52 UninstallWDMDriver(L"USB\\VID_0451&PID_AF32&REV_0000"); 53 54 55 56 if(DeleteFile(L"C:\\Windows\\System32\\drivers\\WLP_USB_Driver.sys")) 57 { 58 printf("WLP_USB_Driver.sys File has Deleted!\n"); 59 } 60 61 /* if(FindExistingDevice(L"USB\\VID_0451&PID_AF32&REV_0000")) 62 { 63 printf("找打了!\n"); 64 65 getch(); 66 } 67 else 68 { 69 printf("没找到!\n"); 70 getch(); 71 }*/ 72 73 printf("Get Started Install the New DLF Driver...\n"); 74 75 // RemoveDriver(L"USB\\VID_0451&PID_AF32&REV_0000"); 76 while(IsDeviceInstallInProgress()) 77 { 78 printf("Has Driver Installtion Program is Processing!\n"); 79 } 80 81 printf("Get Started analyse inf File!\n"); 82 83 UnicodeToAnsi(New_Inf_Path, _tcslen(New_Inf_Path), szInfPath, 215); 84 85 if ((fopen_s(&fp, szInfPath, "r"))!=0) 86 { 87 _tprintf(_T("can not open file %s\n"), New_Inf_Path); 88 return 0; 89 } 90 91 GetINFData(fp); 92 fclose(fp); 93 94 // 安装WDM驱动 95 96 if (StartInstallWDMDriver(New_Inf_Path) == FALSE) 97 { 98 _tprintf(_T("Start Install WDF Driver failed\n")); 99 getch(); 100 return 0; 101 } 102 103 //if(CopyFile(L"D:\\wlp driver\\WDF Driver _new\\win7\\x64\\cyusb3.sys",L"C:\\Windows\\System32\\drivers\\cyusb3.sys",TRUE)) 104 // printf("New DLF Driver successed!\n"); 105 getch(); 106 107 108 } 109 else 110 { 111 printf("No Exists WLP_USB_Driver.sys!\n"); 112 113 printf("Get Started Install the New DLF Driver...\n"); 114 115 // RemoveDriver(L"USB\\VID_0451&PID_AF32&REV_0000"); 116 //while(IsDeviceInstallInProgress()) 117 //{ 118 // printf("Has Driver Installtion Program is Processing!\n"); 119 //} 120 121 printf("Get Started analyse inf File!\n"); 122 123 UnicodeToAnsi(New_Inf_Path, _tcslen(New_Inf_Path), szInfPath, 215); 124 125 if ((fopen_s(&fp, szInfPath, "r"))!=0) 126 { 127 _tprintf(_T("can not open file %s\n"), New_Inf_Path); 128 return 0; 129 } 130 131 GetINFData(fp); 132 fclose(fp); 133 134 // 安装WDM驱动 135 136 if (StartInstallWDMDriver(New_Inf_Path) == FALSE) 137 { 138 _tprintf(_T("Start Install WDF Driver failed\n")); 139 getch(); 140 return 0; 141 } 142 143 // if(CopyFile(L"D:\\wlp driver\\WDF Driver _new\\win7\\x64\\cyusb3.sys",L"C:\\Windows\\System32\\drivers\\cyusb3.sys",TRUE)) 144 // printf("New DLF Driver successed!\n"); 145 getch(); 146 147 148 } 149 150 return 0; 151 } 152 153 154 155 BOOL IsDeviceInstallInProgress (VOID) 156 { 157 return !(CM_WaitNoPendingInstallEvents(0) == WAIT_OBJECT_0); 158 } 159 160 int RemoveDriver(_TCHAR *HardwareID) 161 { 162 HDEVINFO DeviceInfoSet; 163 SP_DEVINFO_DATA DeviceInfoData; 164 DWORD i,err; 165 //GUID devGUID ={36fc9e60-c465-11cf-8056-444553540000}; 166 167 DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes 168 0, 169 0, 170 DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system 171 172 if (DeviceInfoSet == INVALID_HANDLE_VALUE) 173 { 174 printf("GetClassDevs(All Present Devices)\n"); 175 return 1; 176 } 177 178 // 179 // Enumerate through all Devices. 180 // 181 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 182 for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++) 183 { 184 DWORD DataT; 185 LPTSTR p,buffer = NULL; 186 DWORD buffersize = 0; 187 188 // 189 // We won't know the size of the HardwareID buffer until we call 190 // this function. So call it with a null to begin with, and then 191 // use the required buffer size to Alloc the nessicary space. 192 // Keep calling we have success or an unknown failure. 193 // 194 while (!SetupDiGetDeviceRegistryProperty( 195 DeviceInfoSet, 196 &DeviceInfoData, 197 SPDRP_HARDWAREID, 198 &DataT, 199 (PBYTE)buffer, 200 buffersize, 201 &buffersize)) 202 { 203 if (GetLastError() == ERROR_INVALID_DATA) 204 { 205 // 206 // May be a Legacy Device with no HardwareID. Continue. 207 // 208 break; 209 } 210 else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 211 { 212 // 213 // We need to change the buffer size. 214 // 215 if (buffer) 216 LocalFree(buffer); 217 buffer = (LPTSTR)LocalAlloc(LPTR,buffersize); 218 } 219 else 220 { 221 // 222 // Unknown Failure. 223 // 224 printf("GetDeviceRegistryProperty"); 225 goto cleanup_DeviceInfo; 226 } 227 } 228 229 if (GetLastError() == ERROR_INVALID_DATA) 230 continue; 231 232 // 233 // Compare each entry in the buffer multi-sz list with our HardwareID. 234 235 236 // 237 for (p = buffer; *p && (p < &buffer[buffersize]);p+=lstrlen(p)*sizeof(TCHAR) + 2) 238 239 240 { 241 //_tprintf(TEXT("Compare device ID: [%s]/n"),p); 242 243 if (!_tcscmp(HardwareID,p)) 244 { 245 //_tprintf(TEXT("Found! [%s]/n"),p); 246 247 // 248 // Worker function to remove device. 249 // 250 //if (SetupDiCallClassInstaller(DIF_REMOVE, 251 // DeviceInfoSet, 252 // &DeviceInfoData)) 253 254 if (SetupDiRemoveDevice(DeviceInfoSet, &DeviceInfoData)) 255 256 257 { 258 printf("CallClassInstaller(REMOVE)\n"); 259 } 260 else 261 printf("Remove Driver Fail\n"); 262 break; 263 } 264 265 //printf("TTTTTTTTTTTTTTTTT is %s\n",p); 266 //getch(); 267 } 268 269 if (buffer) LocalFree(buffer); 270 } 271 272 if ((GetLastError()!=NO_ERROR)&&(GetLastError()!=ERROR_NO_MORE_ITEMS)) 273 { 274 printf("EnumDeviceInfo\n"); 275 } 276 277 // 278 // Cleanup. 279 // 280 cleanup_DeviceInfo: 281 err = GetLastError(); 282 SetupDiDestroyDeviceInfoList(DeviceInfoSet); 283 284 return err; 285 } 286 287 VOID UninstallWDMDriver(LPCTSTR theHardware) 288 { 289 SP_DEVINFO_DATA spDevInfoData = {0}; 290 HDEVINFO hDevInfo = 0L; 291 WORD wIdx, wCount = 0; 292 293 //得到设备信息结构的句柄 294 hDevInfo = SetupDiGetClassDevs(0L, 0L, 0L, DIGCF_ALLCLASSES | DIGCF_PRESENT); 295 if (hDevInfo == INVALID_HANDLE_VALUE) 296 { 297 printf("Fail!\n"); 298 return; 299 } 300 301 wIdx = 0; 302 while (TRUE) 303 { 304 spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 305 //找到所有的硬件设备,并且可以得到所有的硬件设备的详细信息 306 if (SetupDiEnumDeviceInfo(hDevInfo, wIdx, &spDevInfoData)) 307 { 308 char Buffer[2048] = {0}; 309 310 //可以在前面得到的指向某一个具体设备信息集合的指针中取出某一项信息 311 if (SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData, SPDRP_HARDWAREID, 312 0L, (PBYTE)Buffer, 2048, 0L)) 313 { 314 if (!_tcscmp(theHardware, (LPTSTR)Buffer)) 315 { 316 //从系统中删除一个注册的设备接口 317 if (!SetupDiRemoveDevice(hDevInfo, &spDevInfoData)) 318 printf("Remove Fail is %d!\n",GetLastError()); 319 wCount++; 320 } 321 } 322 } 323 else 324 break; 325 wIdx++; 326 } 327 328 if (wCount != 0) 329 _tprintf(_T("UnInstall Successed...\n")); 330 331 332 333 334 //销毁一个设备信息集合 335 SetupDiDestroyDeviceInfoList(hDevInfo); 336 //InitialGlobalVar(); 337 return; 338 } 339 340 BOOL UnicodeToAnsi(LPCWSTR Source, const WORD wLen, LPSTR Destination, const WORD sLen) 341 { 342 return WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, Source, wLen, Destination, 343 sLen, 0L, 0L); 344 } 345 346 BOOL AnsiToUnicode(LPCSTR Source, const WORD sLen, LPWSTR Destination, const WORD wLen) 347 { 348 return MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, Source, sLen, Destination, wLen); 349 } 350 351 352 BOOL GetINFData(FILE *pFile) 353 { 354 WORD wLoop; 355 356 if (!g_wVender || !g_wHardware) 357 InitialGlobalVar(); 358 if (GetSectionData(pFile, "[Manufacturer]", TRUE) == FALSE) 359 return FALSE; 360 361 for (wLoop = 0; wLoop < g_wVender; wLoop++) 362 { 363 CHAR szVender[64] = {0}; 364 UnicodeToAnsi(g_strVender[wLoop], _tcslen(g_strVender[wLoop]), szVender, 64); 365 GetSectionData(pFile, szVender, FALSE); 366 } 367 if (g_wHardware != 0) 368 { 369 if (IsInstalled() == TRUE)//如果已经安装 370 return FALSE; 371 else 372 return TRUE; 373 } 374 return FALSE; 375 } 376 377 VOID InitialGlobalVar() 378 { 379 WORD wLoop; 380 381 g_wVender = g_wHardware = 0; 382 for (wLoop = 0; wLoop < 20; wLoop++) 383 { 384 RtlZeroMemory(g_strVender[wLoop], sizeof(TCHAR)*64); 385 RtlZeroMemory(g_strHardware[wLoop], sizeof(TCHAR)*64); 386 } 387 } 388 389 VOID FindComma(LPSTR szData) 390 { 391 WORD wLen = (WORD)strlen(szData); 392 WORD wIdx; 393 WORD wLoop; 394 CHAR szTmp[128] = {0}; 395 396 for (wIdx = 0, wLoop = 0; wLoop < wLen; wLoop++) 397 { 398 if (szData[wLoop] == ',') 399 szData[wLoop] = '.'; 400 else if (szData[wLoop] == ' ') 401 continue; 402 szTmp[wIdx++] = szData[wLoop]; 403 } 404 memcpy(szData, szTmp, wIdx*sizeof(char)); 405 szData[wIdx] = 0; 406 } 407 408 VOID StrLTrim(LPSTR szData) 409 { 410 LPSTR ptr = szData; 411 //判断是否为空格 412 while (isspace(*ptr)) 413 ptr++; 414 415 if (strcmp(ptr, szData)) 416 { 417 WORD wLen = (WORD)(strlen(szData) - (ptr - szData)); 418 memmove(szData, ptr, (wLen+1)*sizeof(char)); 419 } 420 } 421 422 VOID StrRTrim(LPSTR szData) 423 { 424 LPSTR ptr = szData; 425 LPSTR pTmp = NULL; 426 427 //debug模式下 使用isspace判断中文 需要设置编码 428 #if defined(WIN32) && defined(_DEBUG) 429 char* locale = setlocale( LC_ALL, ".OCP" ); 430 #endif 431 432 while (*ptr != 0) 433 { 434 //判断是否为空格 435 if (isspace(*ptr)) 436 { 437 if (!pTmp) 438 pTmp = ptr; 439 } 440 else 441 pTmp = NULL; 442 ptr++; 443 } 444 445 if (pTmp) 446 { 447 *pTmp = 0; 448 memmove(szData, szData, strlen(szData) - strlen(pTmp)); 449 } 450 } 451 452 //从字符串右边开始截取字符串 453 VOID StrRight(LPSTR szData, WORD wCount) 454 { 455 WORD wLen = (WORD)strlen(szData) - wCount; 456 457 if (wCount > 0x7FFF)//负数 458 wCount = 0; 459 if (wCount >= (WORD)strlen(szData)) 460 return; 461 462 memmove(szData, szData + wLen, wCount * sizeof(char)); 463 szData[wCount] = 0; 464 } 465 466 VOID ConvertGUIDToString(const GUID guid, LPSTR pData) 467 { 468 CHAR szData[30] = {0}; 469 CHAR szTmp[3] = {0}; 470 WORD wLoop; 471 472 sprintf_s(pData, _countof(szData), "%04X-%02X-%02X-", guid.Data1, guid.Data2, guid.Data3); 473 for (wLoop = 0; wLoop < 8; wLoop++) 474 { 475 if (wLoop == 2) 476 strcat_s(szData, "-"); 477 sprintf_s(szTmp, _countof(szTmp), "%02X", guid.Data4[wLoop]); 478 strcat_s(szData, szTmp); 479 } 480 481 memcpy(pData + strlen(pData), szData, strlen(szData)); 482 } 483 484 BOOL IsInstalled() 485 { 486 HDEVINFO hDevInfo = 0L; 487 SP_DEVINFO_DATA spDevInfoData = {0L}; 488 WORD wIdx; 489 BOOL bIsFound; 490 491 //得到设备信息结构的句柄 492 hDevInfo = SetupDiGetClassDevs(0L, 0, 0, DIGCF_ALLCLASSES | DIGCF_PRESENT); 493 if (hDevInfo == INVALID_HANDLE_VALUE) 494 { 495 printf("SetupDiGetClassDevs is %d",GetLastError()); 496 return FALSE; 497 } 498 499 spDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 500 wIdx = 0; 501 bIsFound = 0; 502 while (++wIdx) 503 { 504 //找到所有的硬件设备,并且可以得到所有的硬件设备的详细信息 505 if (SetupDiEnumDeviceInfo(hDevInfo, wIdx, &spDevInfoData)) 506 { 507 LPTSTR ptr; 508 LPBYTE pBuffer = NULL; 509 DWORD dwData = 0L; 510 DWORD dwRetVal; 511 DWORD dwBufSize = 0L; 512 513 while (TRUE) 514 { 515 //可以在前面得到的指向某一个具体设备信息集合的指针中取出某一项信息 516 dwRetVal = SetupDiGetDeviceRegistryProperty(hDevInfo, &spDevInfoData, SPDRP_HARDWAREID, 517 &dwData, (PBYTE)pBuffer, dwBufSize, &dwBufSize); 518 if (!dwRetVal) 519 dwRetVal = GetLastError(); 520 else 521 break; 522 if (dwRetVal == ERROR_INVALID_DATA) 523 break; 524 else if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) 525 { 526 if (pBuffer) 527 LocalFree(pBuffer); 528 pBuffer = (LPBYTE)LocalAlloc(LPTR, dwBufSize); 529 } 530 else 531 { 532 printf("SetupDiGetDeviceRegistryProperty is %d",dwRetVal); 533 //销毁一个设备信息集合 534 SetupDiDestroyDeviceInfoList(hDevInfo); 535 return FALSE; 536 } 537 } 538 539 if (dwRetVal == ERROR_INVALID_DATA) 540 continue; 541 542 for (ptr = (LPTSTR)pBuffer; *ptr && (ptr < (LPTSTR)&pBuffer[dwBufSize]); ptr += _tcslen(ptr) + sizeof(TCHAR)) 543 { 544 WORD wLoop; 545 546 for (wLoop = 0; wLoop < g_wHardware; wLoop++) 547 { 548 if (!_tcscmp(g_strHardware[wLoop], ptr)) 549 { 550 bIsFound = TRUE; 551 break; 552 } 553 } 554 } 555 if (pBuffer) 556 LocalFree(pBuffer); 557 if (bIsFound) 558 break; 559 } 560 } 561 //销毁一个设备信息集合 562 SetupDiDestroyDeviceInfoList(hDevInfo); 563 return bIsFound; 564 } 565 566 //寻找指定的节名 如果找到返回TRUE 反之返回FALSE 567 BOOL FindSectionName(FILE *pFile, const char *szKey) 568 { 569 char szData[256] = {0}; 570 571 if (!pFile) 572 return FALSE; 573 574 //将文件内部的位置指针重新指向一个流(数据流/文件)的开头 575 rewind(pFile); 576 //循环读取文件内容 577 while (!feof(pFile)) 578 { 579 //读取一行 580 fgets(szData, 255, pFile); 581 //去除前后空格 582 StrLTrim(szData); 583 StrRTrim(szData); 584 585 if (strcmp(szKey, szData) == 0) 586 return TRUE; 587 } 588 return FALSE; 589 } 590 591 //得到INF文件中节的数量 592 BOOL GetSectionData(FILE* pFile, const char* szKey, const char bIsVender) 593 { 594 char szData[128] = {0}; 595 596 if (bIsVender) 597 strcpy_s(szData, szKey); 598 else 599 sprintf_s(szData, _countof(szData), "[%s]", szKey); 600 601 if (FindSectionName(pFile, szData) == FALSE) 602 return FALSE; 603 604 RtlZeroMemory(szData, sizeof(char)*128); 605 while (!feof(pFile)) 606 { 607 char *str = NULL; 608 fgets(szData, 127, pFile); 609 szData[strlen(szData)-1] = 0; 610 StrLTrim(szData); 611 StrRTrim(szData); 612 if (!*szData) 613 continue; 614 if (szData[0] == ';') 615 continue; 616 617 if (strchr(szData, '[')) 618 { 619 StrLTrim(szData); 620 if (szData[0] != ';') 621 return 1; 622 else 623 continue; 624 } 625 626 if (bIsVender) 627 str = strchr(szData, '='); 628 else 629 str = strchr(szData, ','); 630 631 if (*str) 632 { 633 char szTmp[128] = {0}; 634 WORD pos = (WORD)(str - szData + 1); 635 636 StrRight(szData, (short)(strlen(szData)-pos)); 637 StrLTrim(szData); 638 StrRTrim(szData); 639 FindComma(szData); 640 if (bIsVender) 641 { 642 AnsiToUnicode(szData, strlen(szData), g_strVender[g_wVender++], 64); 643 } 644 else 645 { 646 AnsiToUnicode(szData, strlen(szData), g_strHardware[g_wHardware++], 64); 647 } 648 }/* end if */ 649 } 650 return TRUE; 651 } 652 653 //实质性的安装驱动 654 BOOL InstallClassDriver(LPCTSTR theINFName) 655 { 656 GUID guid = {0}; 657 SP_DEVINFO_DATA spDevData = {0}; 658 HDEVINFO hDevInfo = 0L; 659 TCHAR className[MAX_CLASS_NAME_LEN] = {0}; 660 LPTSTR pHID = NULL; 661 WORD wLoop; 662 BOOL bRebootRequired; 663 664 //取得此驱动的GUID值 665 if (!SetupDiGetINFClass(theINFName, &guid, className, MAX_CLASS_NAME_LEN, 0)) 666 { 667 printf( "SetupDiGetINFClass is %d\n",GetLastError()); 668 return FALSE; 669 } 670 671 //创建设备信息块列表 672 hDevInfo = SetupDiCreateDeviceInfoList(&guid, 0); 673 if (hDevInfo == INVALID_HANDLE_VALUE) 674 { 675 printf("SetupDiCreateDeviceInfoList is %d\n",GetLastError()); 676 return FALSE; 677 } 678 679 spDevData.cbSize = sizeof(SP_DEVINFO_DATA); 680 //创建设备信息块 681 if (!SetupDiCreateDeviceInfo(hDevInfo, className, &guid, 0L, 0L, DICD_GENERATE_ID, &spDevData)) 682 { 683 printf("SetupDiCreateDeviceInfo is %d",GetLastError()); 684 //销毁一个设备信息集合 685 SetupDiDestroyDeviceInfoList(hDevInfo); 686 return FALSE; 687 } 688 689 //for (wLoop = 0; wLoop < g_wHardware; wLoop++) 690 //{ 691 if (pHID) 692 LocalFree(pHID); 693 694 695 pHID = (LPTSTR)LocalAlloc(LPTR, _tcslen(L"USB\\VID_0451&PID_AF32")*2*sizeof(TCHAR)); 696 if (!pHID) 697 { 698 printf("LocalAlloc is %d",GetLastError()); 699 //销毁一个设备信息集合 700 SetupDiDestroyDeviceInfoList(hDevInfo); 701 return FALSE; 702 } 703 704 _tcscpy_s(pHID, _tcslen(L"USB\\VID_0451&PID_AF32")*2, 705 L"USB\\VID_0451&PID_AF32"); 706 //设定硬件ID 707 if (!SetupDiSetDeviceRegistryProperty(hDevInfo, &spDevData, SPDRP_HARDWAREID, (PBYTE)pHID, 708 (DWORD)(_tcslen(L"USB\\VID_0451&PID_AF32")*2*sizeof(TCHAR)))) 709 { 710 printf("SetupDiSetDeviceRegistryProperty is %d",GetLastError()); 711 //销毁一个设备信息集合 712 SetupDiDestroyDeviceInfoList(hDevInfo); 713 LocalFree(pHID); 714 return FALSE; 715 } 716 //调用相应的类程序来注册设备 717 if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE, hDevInfo, &spDevData)) 718 { 719 printf("SetupDiCallClassInstaller is %d", GetLastError()); 720 //销毁一个设备信息集合 721 SetupDiDestroyDeviceInfoList(hDevInfo); 722 LocalFree(pHID); 723 return FALSE; 724 } 725 726 bRebootRequired = FALSE; 727 //安装更新和硬件ID相匹配的驱动程序 728 if (!UpdateDriverForPlugAndPlayDevices(0L, L"USB\\VID_0451&PID_AF32" 729 , theINFName, 730 INSTALLFLAG_FORCE, &bRebootRequired)) 731 { 732 DWORD dwErrorCode = GetLastError(); 733 //调用相应的类程序来移除设备 734 if (!SetupDiCallClassInstaller(DIF_REMOVE, hDevInfo, &spDevData)) 735 printf("SetupDiCallClassInstaller(Remove) is %d",GetLastError()); 736 printf("UpdateDriverForPlugAndPlayDevices is %d",(WORD)dwErrorCode); 737 //销毁一个设备信息集合 738 SetupDiDestroyDeviceInfoList(hDevInfo); 739 LocalFree(pHID); 740 741 getch(); 742 return FALSE; 743 } 744 LocalFree(pHID); 745 pHID = NULL; 746 747 //} 748 //销毁一个设备信息集合 749 SetupDiDestroyDeviceInfoList(hDevInfo); 750 _tprintf(_T("Install Successed\n")); 751 return TRUE; 752 } 753 754 // 安装WDM驱动的测试工作 755 BOOL StartInstallWDMDriver(LPCTSTR theInfName) 756 { 757 HDEVINFO hDevInfo = 0L; 758 GUID guid = {0L}; 759 SP_DEVINSTALL_PARAMS spDevInst = {0L}; 760 TCHAR strClass[MAX_CLASS_NAME_LEN] = {0L}; 761 762 //取得此驱动的GUID值 763 if (!SetupDiGetINFClass(theInfName, &guid, strClass, MAX_CLASS_NAME_LEN, 0)) 764 { 765 printf("SetupDiGetINFClass is %d",GetLastError()); 766 return FALSE; 767 } 768 769 //得到设备信息结构的句柄 770 hDevInfo = SetupDiGetClassDevs(&guid, 0L, 0L, DIGCF_PRESENT | DIGCF_ALLCLASSES | DIGCF_PROFILE); 771 if (!hDevInfo) 772 { 773 printf("SetupDiGetClassDevs is %d",GetLastError()); 774 return FALSE; 775 } 776 777 778 spDevInst.cbSize = sizeof(SP_DEVINSTALL_PARAMS); 779 //获得指定设备的安装信息 780 if (!SetupDiGetDeviceInstallParams(hDevInfo, 0L, &spDevInst)) 781 { 782 printf("SetupDiGetDeviceInstallParams is %d",GetLastError()); 783 return FALSE; 784 } 785 786 spDevInst.Flags = DI_ENUMSINGLEINF; 787 spDevInst.FlagsEx = DI_FLAGSEX_ALLOWEXCLUDEDDRVS; 788 _tcscpy_s(spDevInst.DriverPath, _countof(spDevInst.DriverPath), theInfName); 789 790 //为设备信息集或者是一个实际的设备信息单元设置或清除类安装参数 791 if (!SetupDiSetDeviceInstallParams(hDevInfo, 0, &spDevInst)) 792 { 793 794 printf("SetupDiSetDeviceInstallParams is %d",GetLastError()); 795 return FALSE; 796 } 797 798 //获取这个设备的驱动程序信息列表 799 if (!SetupDiBuildDriverInfoList(hDevInfo, 0, SPDIT_CLASSDRIVER)) 800 { 801 802 printf("SetupDiDeviceInstallParams is %d",GetLastError()); 803 return FALSE; 804 } 805 806 //销毁一个设备信息集合 807 SetupDiDestroyDeviceInfoList(hDevInfo); 808 809 //进入安装设备驱动函数 810 return InstallClassDriver(theInfName); 811 } 812 813 BOOL FindExistingDevice(IN LPTSTR HardwareId) 814 { 815 HDEVINFO DeviceInfoSet; 816 SP_DEVINFO_DATA DeviceInfoData; 817 DWORD i,err; 818 BOOL Found; 819 820 // 821 // Create a Device Information Set with all present devices. 822 // 823 DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes 824 0, 825 0, 826 DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system 827 828 if (DeviceInfoSet == INVALID_HANDLE_VALUE) 829 { 830 return printf("GetClassDevs(All Present Devices)"); 831 832 833 } 834 835 //_tprintf(TEXT("Search for Device ID: [%s]/n"),HardwareId); 836 837 // 838 // Enumerate through all Devices. 839 // 840 Found = FALSE; 841 DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 842 for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++) 843 { 844 DWORD DataT; 845 LPTSTR p,buffer = NULL; 846 DWORD buffersize = 0; 847 848 // 849 // We won't know the size of the HardwareID buffer until we call 850 // this function. So call it with a null to begin with, and then 851 // use the required buffer size to Alloc the nessicary space. 852 // Keep calling we have success or an unknown failure. 853 // 854 while (!SetupDiGetDeviceRegistryProperty( 855 DeviceInfoSet, 856 &DeviceInfoData, 857 SPDRP_HARDWAREID, 858 &DataT, 859 (PBYTE)buffer, 860 buffersize, 861 &buffersize)) 862 { 863 if (GetLastError() == ERROR_INVALID_DATA) 864 { 865 // 866 // May be a Legacy Device with no HardwareID. Continue. 867 // 868 break; 869 } 870 else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) 871 { 872 // 873 // We need to change the buffer size. 874 // 875 if (buffer) 876 LocalFree(buffer); 877 buffer = (LPTSTR)LocalAlloc(LPTR,buffersize); 878 } 879 else 880 { 881 // 882 // Unknown Failure. 883 // 884 printf("GetDeviceRegistryProperty"); 885 goto cleanup_DeviceInfo; 886 } 887 } 888 889 if (GetLastError() == ERROR_INVALID_DATA) 890 continue; 891 892 // 893 // Compare each entry in the buffer multi-sz list with our HardwareID. 894 895 896 // 897 for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR)) 898 899 900 { 901 //_tprintf(TEXT("Compare device ID: [%s]/n"),p); 902 903 if (!_tcscmp(HardwareId,p)) 904 { 905 //_tprintf(TEXT("Found! [%s]/n"),p); 906 Found = TRUE; 907 break; 908 } 909 } 910 911 if (buffer) LocalFree(buffer); 912 if (Found) break; 913 } 914 915 if (GetLastError() != NO_ERROR) 916 { 917 printf("EnumDeviceInfo"); 918 } 919 920 // 921 // Cleanup. 922 // 923 cleanup_DeviceInfo: 924 err = GetLastError(); 925 SetupDiDestroyDeviceInfoList(DeviceInfoSet); 926 SetLastError(err); 927 928 return err == NO_ERROR; //??? 929 }
遇到的问题: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
)就能安装了。