VOID EnumerateDrivers(PVOID Context, HDEVINFO hList, PSP_DEVINFO_DATA pInfoData) { HSPFILEQ hQueue; SP_DEVINSTALL_PARAMS DeviceInstallParams = {0}; SP_DRVINFO_DATA DriverInfoData; DWORD Result; DeviceInstallParams.cbSize = sizeof(DeviceInstallParams); if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams)) return; DeviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS); if (!SetupDiSetDeviceInstallParams(hList, pInfoData, &DeviceInstallParams)) return; if (!SetupDiBuildDriverInfoList(hList, pInfoData, SPDIT_CLASSDRIVER)) return; DriverInfoData.cbSize = sizeof(DriverInfoData); if (!SetupDiEnumDriverInfoW(hList, pInfoData, SPDIT_CLASSDRIVER, 0, &DriverInfoData)) return; DriverInfoData.cbSize = sizeof(DriverInfoData); if (!SetupDiSetSelectedDriverW(hList, pInfoData, &DriverInfoData)) return; hQueue = SetupOpenFileQueue(); if (hQueue == (HSPFILEQ)INVALID_HANDLE_VALUE) return; DeviceInstallParams.cbSize = sizeof(DeviceInstallParams); if (!SetupDiGetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams)) { SetupCloseFileQueue(hQueue); return; } DeviceInstallParams.FileQueue = hQueue; DeviceInstallParams.Flags |= DI_NOVCP; if (!SetupDiSetDeviceInstallParamsW(hList, pInfoData, &DeviceInstallParams)) { SetupCloseFileQueue(hQueue); return; } if(!SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, hList, pInfoData)) { SetupCloseFileQueue(hQueue); return; } /* enumerate the driver files */ SetupScanFileQueueW(hQueue, SPQ_SCAN_USE_CALLBACK, NULL, DriverFilesCallback, Context, &Result); SetupCloseFileQueue(hQueue); }
BOOL InfFile::UninstallFiles(const char *pFilesSection) const { if (!pPath) return FALSE; int res; HINF hInf; do { res = IDCONTINUE; UINT errLine; hInf = SetupOpenInfFile(pPath, NULL, INF_STYLE_WIN4, &errLine); if (hInf == INVALID_HANDLE_VALUE) res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupOpenInfFile(%s) on line %u", pPath, errLine); } while (res == IDTRYAGAIN); if (res != IDCONTINUE) return FALSE; do { res = IDCONTINUE; HSPFILEQ hFileQueue = SetupOpenFileQueue(); if (hFileQueue != INVALID_HANDLE_VALUE) { if (SetupQueueDeleteSection(hFileQueue, hInf, NULL, pFilesSection)) { PVOID pContext = SetupInitDefaultQueueCallback(NULL); if (pContext) { if(!SetupCommitFileQueue(NULL, hFileQueue, FileCallback, pContext)) res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupCommitFileQueue()"); SetupTermDefaultQueueCallback(pContext); } else { res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupInitDefaultQueueCallback()"); } } else { res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupQueueDeleteSection(%s)", pFilesSection); } SetupCloseFileQueue(hFileQueue); } else { res = ShowLastError(MB_CANCELTRYCONTINUE, "SetupOpenFileQueue()"); } } while (res == IDTRYAGAIN); SetupCloseInfFile(hInf); if (res != IDCONTINUE) return FALSE; return TRUE; }
/*********************************************************************** * AdvInstallFileW (ADVPACK.@) * * Copies a file from the source to a destination. * * PARAMS * hwnd [I] Handle to the window used for messages. * lpszSourceDir [I] Source directory. * lpszSourceFile [I] Source filename. * lpszDestDir [I] Destination directory. * lpszDestFile [I] Optional destination filename. * dwFlags [I] See advpub.h. * dwReserved [I] Reserved. Must be 0. * * RETURNS * Success: S_OK. * Failure: E_FAIL. * * NOTES * If lpszDestFile is NULL, the destination filename is the same as * lpszSourceFIle. */ HRESULT WINAPI AdvInstallFileW(HWND hwnd, LPCWSTR lpszSourceDir, LPCWSTR lpszSourceFile, LPCWSTR lpszDestDir, LPCWSTR lpszDestFile, DWORD dwFlags, DWORD dwReserved) { PSP_FILE_CALLBACK_W pFileCallback; LPWSTR szDestFilename; LPCWSTR szPath; WCHAR szRootPath[ROOT_LENGTH]; DWORD dwLen, dwLastError; HSPFILEQ fileQueue; PVOID pContext; TRACE("(%p, %s, %s, %s, %s, %d, %d)\n", hwnd, debugstr_w(lpszSourceDir), debugstr_w(lpszSourceFile), debugstr_w(lpszDestDir), debugstr_w(lpszDestFile), dwFlags, dwReserved); if (!lpszSourceDir || !lpszSourceFile || !lpszDestDir) return E_INVALIDARG; fileQueue = SetupOpenFileQueue(); if (fileQueue == INVALID_HANDLE_VALUE) return HRESULT_FROM_WIN32(GetLastError()); pContext = NULL; dwLastError = ERROR_SUCCESS; lstrcpynW(szRootPath, lpszSourceDir, ROOT_LENGTH); szPath = lpszSourceDir + ROOT_LENGTH; /* use lpszSourceFile as destination filename if lpszDestFile is NULL */ if (lpszDestFile) { dwLen = lstrlenW(lpszDestFile); szDestFilename = HeapAlloc(GetProcessHeap(), 0, (dwLen+1) * sizeof(WCHAR)); lstrcpyW(szDestFilename, lpszDestFile); } else { dwLen = lstrlenW(lpszSourceFile); szDestFilename = HeapAlloc(GetProcessHeap(), 0, (dwLen+1) * sizeof(WCHAR)); lstrcpyW(szDestFilename, lpszSourceFile); } /* add the file copy operation to the setup queue */ if (!SetupQueueCopyW(fileQueue, szRootPath, szPath, lpszSourceFile, NULL, NULL, lpszDestDir, szDestFilename, dwFlags)) { dwLastError = GetLastError(); goto done; } pContext = SetupInitDefaultQueueCallbackEx(hwnd, INVALID_HANDLE_VALUE, 0, 0, NULL); if (!pContext) { dwLastError = GetLastError(); goto done; } /* don't output anything for AIF_QUIET */ if (dwFlags & AIF_QUIET) pFileCallback = pQuietQueueCallback; else pFileCallback = pQueueCallback; /* perform the file copy */ if (!SetupCommitFileQueueW(hwnd, fileQueue, pFileCallback, pContext)) { dwLastError = GetLastError(); goto done; } done: SetupTermDefaultQueueCallback(pContext); SetupCloseFileQueue(fileQueue); HeapFree(GetProcessHeap(), 0, szDestFilename); return HRESULT_FROM_WIN32(dwLastError); }
HRESULT xDiEnumDriverFiles( __in_opt HWND Owner, __in LPCWSTR OemInfFullPath, __in DWORD Flags, __in XDI_ENUM_DRIVER_FILE_CALLBACK EnumCallback, __in LPVOID EnumContext) { HRESULT hr; BOOL success; WCHAR infFullPath[MAX_PATH]; DWORD n = GetFullPathNameW(OemInfFullPath, MAX_PATH, infFullPath, NULL); if (0 == n) { hr = HRESULT_FROM_WIN32(GetLastError()); hr = (SUCCEEDED(hr)) ? E_FAIL : hr; goto error0; } HDEVINFO devInfoSet = SetupDiCreateDeviceInfoList(NULL, Owner); if (INVALID_HANDLE_VALUE == devInfoSet) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error0; } SP_DEVINFO_DATA devInfoData = { sizeof(SP_DEVINFO_DATA) }; success = SetupDiCreateDeviceInfoW( devInfoSet, L"XDI_Temporary_Enumerator", &GUID_NULL, NULL, NULL, DICD_GENERATE_ID, &devInfoData); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error1; } HSPFILEQ fileQueueHandle = SetupOpenFileQueue(); if (INVALID_HANDLE_VALUE == fileQueueHandle) { // Error from SetupOpenFileQueue is only from out-of-memory situation // without the last error set hr = E_OUTOFMEMORY; goto error2; } SP_DEVINSTALL_PARAMS devInstallParams = {sizeof(SP_DEVINSTALL_PARAMS)}; success = SetupDiGetDeviceInstallParamsW( devInfoSet, &devInfoData, &devInstallParams); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error3; } // // Specify the search path // hr = StringCchCopyW( devInstallParams.DriverPath, MAX_PATH, infFullPath); if (FAILED(hr)) { goto error3; } devInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS; devInstallParams.FileQueue = fileQueueHandle; devInstallParams.Flags |= DI_NOVCP; devInstallParams.Flags |= DI_ENUMSINGLEINF; success = SetupDiSetDeviceInstallParamsW( devInfoSet, &devInfoData, &devInstallParams); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error3; } // // use DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE if possible // to ensure we look at duplicate nodes (which is broken in itself) // #ifndef DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE #define DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE 0x08000000L // Don't remove identical driver nodes from the class list #endif if (xDipWindowsXPOrLater()) { devInstallParams.FlagsEx |= DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE; success = SetupDiSetDeviceInstallParamsW( devInfoSet, &devInfoData, &devInstallParams); if (!success) { devInstallParams.FlagsEx &= ~DI_FLAGSEX_NO_CLASSLIST_NODE_MERGE; } } // // Build a class driver list with every driver // success = SetupDiBuildDriverInfoList( devInfoSet, &devInfoData, SPDIT_CLASSDRIVER); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error3; } SP_DRVINFO_DATA drvInfoData = { sizeof(SP_DRVINFO_DATA) }; for (DWORD index = 0; ; ++index) { success = SetupDiEnumDriverInfoW( devInfoSet, &devInfoData, SPDIT_CLASSDRIVER, index, &drvInfoData); if (!success) { break; } SP_DRVINFO_DETAIL_DATA drvInfoDetail = { sizeof(SP_DRVINFO_DETAIL_DATA) }; success = SetupDiGetDriverInfoDetailW( devInfoSet, &devInfoData, &drvInfoData, &drvInfoDetail, sizeof(SP_DRVINFO_DETAIL_DATA), NULL); if (!success && ERROR_INSUFFICIENT_BUFFER != GetLastError()) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } success = SetupDiSetSelectedDriverW( devInfoSet, &devInfoData, &drvInfoData); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } if (Flags & XDI_EDF_NO_CLASS_INSTALLER) { success = SetupDiInstallDriverFiles( devInfoSet, &devInfoData); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } } else { success = SetupDiCallClassInstaller( DIF_INSTALLDEVICEFILES, devInfoSet, &devInfoData); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } } } // // SPQ_SCAN_USE_CALLBACK_EX checks the digital signature of the file // We do not want to check the signature here. // // SPQ_SCAN_FILE_PRESENCE avoids checking the digital signature of the file // in Windows XP or later. (Not in Windows 2000) when used // with SPQ_SCAN_USE_CALLBACK_EX // XDI_ENUM_FQS_CONTEXT fqsContext = {0}; fqsContext.Callback = EnumCallback; fqsContext.CallbackContext = EnumContext; DWORD scanResult; success = SetupScanFileQueueW( fileQueueHandle, SPQ_SCAN_USE_CALLBACK, // SPQ_SCAN_USE_CALLBACKEX | SPQ_SCAN_FILE_PRESENCE, Owner, xDipEnumFileQueueScanCallback, &fqsContext, &scanResult); if (!success) { // // SetupScanFileQueue may fail using SPQ_SCAN_FILE_PRESENSE flag // Try again without SPQ_SCAN_FILE_PRESENSE // (when using SPQ_SCAN_USE_CALLBACKEX) // hr = HRESULT_FROM_SETUPAPI(GetLastError()); goto error4; } hr = S_OK; #pragma warning(disable: 4533) // to use goto in cpp error4: SetupDiDestroyDriverInfoList( devInfoSet, &devInfoData, SPDIT_CLASSDRIVER); error3: SetupCloseFileQueue(fileQueueHandle); error2: SetupDiDeleteDeviceInfo(devInfoSet, &devInfoData); error1: SetupDiDestroyDeviceInfoList(devInfoSet); error0: #pragma warning(default: 4533) return hr; }
int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow) { if (!InitializeOptions(lpCmdLine)) { if (!OptionSilent) { MessageBox(NULL, "Please specify the correct parameters:\r\n" \ "/path <Full path to the INF>\r\n" \ "/path:relative <Relative path to the INF from the current directory>\r\n" \ "/ddinstall <DDInstall section name to be processed>\r\n" \ "/os <Expected OS version in the form of x.y where x is MajorVersion, y is Minor version, ie 5.0 for Windows 2000>\r\n" \ "/buildnumber <Expected OS build number, ie 2195 for Windows 2000>\r\n" \ "/sp <Expected OS service pack number>\r\n", "Pre-Installer", MB_OK); } return ERR_FAIL; } if ((OptionOsVersionCheck) || (OptionOsBuildNumberCheck) || (OptionOsServicePackCheck)) { OSVERSIONINFO OsVersionInfo; OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (GetVersionEx(&OsVersionInfo)) { if (OptionOsVersionCheck) { CHAR Version[32]; sprintf(Version, "%d.%d", OsVersionInfo.dwMajorVersion, OsVersionInfo.dwMinorVersion); if (_stricmp(Version, ExpectedOsVersion)) { if (!OptionSilent) { CHAR ErrorMsg[256]; sprintf(ErrorMsg, "OS version %s doesn't match the expected %s", Version, ExpectedOsVersion); MessageBox(NULL, ErrorMsg, "Pre-Installer", MB_OK); } return ERR_FAIL; } } if (OptionOsBuildNumberCheck) { if (OsVersionInfo.dwBuildNumber != ExpectedOsBuildNumber) { if (!OptionSilent) { CHAR ErrorMsg[256]; sprintf(ErrorMsg, "OS build number %d doesn't match the expected %d", OsVersionInfo.dwBuildNumber, ExpectedOsBuildNumber); MessageBox(NULL, ErrorMsg, "Pre-Installer", MB_OK); } return ERR_FAIL; } } if (OptionOsServicePackCheck) { CHAR ServicePack[32]; sprintf(ServicePack, "Service Pack %d", ExpectedOsServicePack); if (_stricmp(OsVersionInfo.szCSDVersion, ServicePack)) { if (!OptionSilent) { CHAR ErrorMsg[256]; sprintf(ErrorMsg, "OS %s doesn't match the expected %s", OsVersionInfo.szCSDVersion, ServicePack); MessageBox(NULL, ErrorMsg, "Pre-Installer", MB_OK); } return ERR_FAIL; } } } else { return ERR_FAIL; } } HINF InfHandle = SetupOpenInfFile(InfPath, NULL, INF_STYLE_WIN4 , NULL); // Get INF Handle if (InfHandle != INVALID_HANDLE_VALUE) { HSPFILEQ QueueHandle = SetupOpenFileQueue(); if (QueueHandle != INVALID_HANDLE_VALUE) { SetupInstallFilesFromInfSection(InfHandle, NULL, QueueHandle, DDInstallSection, NULL, SP_COPY_FORCE_NEWER); //Copies the files PVOID Context = SetupInitDefaultQueueCallback(NULL); if (Context) { SetupCommitFileQueue(NULL, QueueHandle, FileCallback, Context); SetupTermDefaultQueueCallback(Context); } SetupCloseFileQueue(QueueHandle); } // Do not do the following as we do not want to install the drivers yet. When the device is turned on, // Windows PnP will take care of the rest of the installation process. #if 0 CHAR DDInstallServicesSection[MAX_PATH]; strcpy(DDInstallServicesSection, DDInstallSection); strcat(DDInstallServicesSection, ".Services"); SetupInstallServicesFromInfSection(InfHandle, DDInstallServicesSection, SPSVCINST_TAGTOFRONT); HKEY RegKey = SetupDiOpenClassRegKey((LPGUID)&CLSID_MEDIA, KEY_ALL_ACCESS); if (RegKey != INVALID_HANDLE_VALUE) { SetupInstallFromInfSection(NULL, InfHandle, DDInstallSection, SPINST_REGISTRY, RegKey, NULL, NULL, NULL, NULL, NULL, NULL); // Does the AddReg, Del Reg Stuff RegCloseKey(RegKey); } #endif // 0 SetupCloseInfFile(InfHandle); } if (SetupCopyOEMInf(InfPath, NULL, SPOST_PATH, NULL, NULL ,0, NULL, NULL)) { return SUCCESS; } else { DWORD err = GetLastError(); return ERR_FAIL; } }