/* performs a setupapi-level install of the INF file */ static HRESULT spapi_install(const ADVInfo *info) { BOOL ret; HRESULT res; PVOID context; context = SetupInitDefaultQueueCallbackEx(NULL, INVALID_HANDLE_VALUE, 0, 0, NULL); if (!context) return ADV_HRESULT(GetLastError()); ret = SetupInstallFromInfSectionW(NULL, info->hinf, info->install_sec, SPINST_FILES, NULL, info->working_dir, SP_COPY_NEWER, SetupDefaultQueueCallbackW, context, NULL, NULL); if (!ret) { res = ADV_HRESULT(GetLastError()); SetupTermDefaultQueueCallback(context); return res; } SetupTermDefaultQueueCallback(context); ret = SetupInstallFromInfSectionW(NULL, info->hinf, info->install_sec, SPINST_INIFILES | SPINST_REGISTRY | SPINST_REGSVR, HKEY_LOCAL_MACHINE, NULL, 0, NULL, NULL, NULL, NULL); if (!ret) return ADV_HRESULT(GetLastError()); return S_OK; }
static void test_defaultcallback(void) { struct default_callback_context *ctxt; static const DWORD magic = 0x43515053; /* "SPQC" */ HWND owner, progress; owner = (HWND)0x123; progress = (HWND)0x456; ctxt = SetupInitDefaultQueueCallbackEx(owner, progress, WM_USER, 0, NULL); ok(ctxt != NULL, "got %p\n", ctxt); ok(ctxt->magic == magic || broken(ctxt->magic != magic) /* win2000 */, "got magic 0x%08x\n", ctxt->magic); if (ctxt->magic == magic) { ok(ctxt->owner == owner, "got %p, expected %p\n", ctxt->owner, owner); ok(ctxt->progress == progress, "got %p, expected %p\n", ctxt->progress, progress); ok(ctxt->message == WM_USER, "got %d, expected %d\n", ctxt->message, WM_USER); SetupTermDefaultQueueCallback(ctxt); } else { win_skip("Skipping tests on old systems.\n"); SetupTermDefaultQueueCallback(ctxt); return; } ctxt = SetupInitDefaultQueueCallback(owner); ok(ctxt->magic == magic, "got magic 0x%08x\n", ctxt->magic); ok(ctxt->owner == owner, "got %p, expected %p\n", ctxt->owner, owner); ok(ctxt->progress == NULL, "got %p, expected %p\n", ctxt->progress, progress); ok(ctxt->message == 0, "got %d\n", ctxt->message); SetupTermDefaultQueueCallback(ctxt); }
/* Install a section of a .inf file * Returns TRUE if success, FALSE if failure. Error code can * be retrieved with GetLastError() */ static BOOL InstallInfSection( IN HWND hWnd, IN LPCWSTR InfFile, IN LPCWSTR InfSection OPTIONAL, IN LPCWSTR InfService OPTIONAL) { WCHAR Buffer[MAX_PATH]; HINF hInf = INVALID_HANDLE_VALUE; UINT BufferSize; PVOID Context = NULL; BOOL ret = FALSE; /* Get Windows directory */ BufferSize = MAX_PATH - 5 - wcslen(InfFile); if (GetWindowsDirectoryW(Buffer, BufferSize) > BufferSize) { /* Function failed */ SetLastError(ERROR_GEN_FAILURE); goto cleanup; } /* We have enough space to add some information in the buffer */ if (Buffer[wcslen(Buffer) - 1] != '\\') wcscat(Buffer, L"\\"); wcscat(Buffer, L"Inf\\"); wcscat(Buffer, InfFile); /* Install specified section */ hInf = SetupOpenInfFileW(Buffer, NULL, INF_STYLE_WIN4, NULL); if (hInf == INVALID_HANDLE_VALUE) goto cleanup; Context = SetupInitDefaultQueueCallback(hWnd); if (Context == NULL) goto cleanup; ret = TRUE; if (ret && InfSection) { ret = SetupInstallFromInfSectionW( hWnd, hInf, InfSection, SPINST_ALL, NULL, NULL, SP_COPY_NEWER, SetupDefaultQueueCallbackW, Context, NULL, NULL); } if (ret && InfService) { ret = SetupInstallServicesFromInfSectionW( hInf, InfService, 0); } cleanup: if (Context) SetupTermDefaultQueueCallback(Context); if (hInf != INVALID_HANDLE_VALUE) SetupCloseInfFile(hInf); return ret; }
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; }
/*********************************************************************** * DoInfInstall (ADVPACK.@) */ BOOL WINAPI DoInfInstall(const SETUPCOMMAND_PARAMS *setup) { BOOL ret; HINF hinf; void *callback_context; TRACE("%p %s %s %s %s\n", setup->hwnd, debugstr_a(setup->title), debugstr_a(setup->inf_name), debugstr_a(setup->dir), debugstr_a(setup->section_name)); hinf = SetupOpenInfFileA(setup->inf_name, NULL, INF_STYLE_WIN4, NULL); if (hinf == (HINF)INVALID_HANDLE_VALUE) return FALSE; callback_context = SetupInitDefaultQueueCallback(setup->hwnd); ret = SetupInstallFromInfSectionA(0, hinf, setup->section_name, SPINST_ALL, 0, NULL, 0, SetupDefaultQueueCallbackA, callback_context, NULL, NULL); SetupTermDefaultQueueCallback(callback_context); SetupCloseInfFile(hinf); return ret; }
int PreInstallFromInf( IN HWND hWnd, IN LPTSTR Inf, IN LPTSTR InstallSection, IN LPTSTR ServiceSection ) { DWORD Err = NO_ERROR; HINF hInf = INVALID_HANDLE_VALUE; UINT ErrorLine; PVOID Context = NULL; hInf = SetupOpenInfFile(Inf, NULL, INF_STYLE_WIN4, &ErrorLine); if (hInf == INVALID_HANDLE_VALUE) { Err = GetLastError(); goto clean; } // // Install the service section // if (!SetupInstallServicesFromInfSection(hInf, ServiceSection, 0)) { Err = GetLastError(); goto clean; } Context = SetupInitDefaultQueueCallback(hWnd); if (!SetupInstallFromInfSection(hWnd, hInf, InstallSection, SPINST_REGISTRY | SPINST_FILES, NULL, NULL, 0, SetupDefaultQueueCallback, Context, NULL, NULL)) { Err = GetLastError(); goto clean; } clean: if (Context != NULL) { SetupTermDefaultQueueCallback(Context); } if (hInf != INVALID_HANDLE_VALUE) { SetupCloseInfFile(hInf); } if (Err == NO_ERROR) { return 0; } else { return 1; } }
/*********************************************************************** * 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); }
/** * Executes a sepcified .INF section to install/uninstall drivers and/or services. * * @return Exit code (EXIT_OK, EXIT_FAIL) * @param pszSection Section to execute; usually it's "DefaultInstall". * @param iMode Execution mode to use (see MSDN). * @param pszInf Full qualified path of the .INF file to use. */ int ExecuteInfFile(const _TCHAR *pszSection, int iMode, const _TCHAR *pszInf) { _tprintf(_T("Installing from INF-File: %ws (Section: %ws) ...\n"), pszInf, pszSection); UINT uErrorLine = 0; HINF hINF = SetupOpenInfFile(pszInf, NULL, INF_STYLE_WIN4, &uErrorLine); if (hINF != INVALID_HANDLE_VALUE) { PVOID pvQueue = SetupInitDefaultQueueCallback(NULL); BOOL fSuccess = SetupInstallFromInfSection(NULL, hINF, pszSection, SPINST_ALL, HKEY_LOCAL_MACHINE, NULL, SP_COPY_NEWER_OR_SAME | SP_COPY_NOSKIP, vboxDrvInstExecuteInfFileCallback, pvQueue, NULL, NULL ); if (fSuccess) { _tprintf (_T( "File installation stage successful\n")); fSuccess = SetupInstallServicesFromInfSection(hINF, L"DefaultInstall.Services", 0 /* Flags */); if (fSuccess) { _tprintf (_T( "Service installation stage successful. Installation completed\n")); } else { DWORD dwErr = GetLastError(); switch (dwErr) { case ERROR_SUCCESS_REBOOT_REQUIRED: _tprintf (_T( "A reboot is required to complete the installation\n")); break; case ERROR_SECTION_NOT_FOUND: break; default: _tprintf (_T( "Error %ld while installing service\n"), dwErr); break; } } } else _tprintf (_T( "Error %ld while installing files\n"), GetLastError()); if (pvQueue) SetupTermDefaultQueueCallback(pvQueue); SetupCloseInfFile(hINF); } else _tprintf (_T( "Unable to open %ws: %ld (error line %u)\n"), pszInf, GetLastError(), uErrorLine); return EXIT_OK; }
DWORD MMSYS_InstallDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pspDevInfoData) { UINT Length; LPWSTR pBuffer; WCHAR szBuffer[MAX_PATH]; HINF hInf; PVOID Context; BOOL Result; SC_HANDLE hSCManager, hService; WCHAR WaveName[20]; HKEY hKey; DWORD BufferSize; ULONG Index; if (!IsEqualIID(&pspDevInfoData->ClassGuid, &GUID_DEVCLASS_SOUND) && !IsEqualIID(&pspDevInfoData->ClassGuid, &GUID_DEVCLASS_MEDIA)) return ERROR_DI_DO_DEFAULT; Length = GetWindowsDirectoryW(szBuffer, MAX_PATH); if (!Length || Length >= MAX_PATH - 14) { return ERROR_GEN_FAILURE; } pBuffer = PathAddBackslashW(szBuffer); if (!pBuffer) { return ERROR_GEN_FAILURE; } wcscpy(pBuffer, L"inf\\audio.inf"); hInf = SetupOpenInfFileW(szBuffer, NULL, INF_STYLE_WIN4, NULL); if (hInf == INVALID_HANDLE_VALUE) { return ERROR_GEN_FAILURE; } Context = SetupInitDefaultQueueCallback(NULL); if (Context == NULL) { SetupCloseInfFile(hInf); return ERROR_GEN_FAILURE; } Result = SetupInstallFromInfSectionW(NULL, hInf, L"AUDIO_Inst.NT", SPINST_ALL, NULL, NULL, SP_COPY_NEWER, SetupDefaultQueueCallbackW, Context, NULL, NULL); if (Result) { Result = SetupInstallServicesFromInfSectionW(hInf, L"Audio_Inst.NT.Services", 0); } SetupTermDefaultQueueCallback(Context); SetupCloseInfFile(hInf); hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (!hSCManager) { return ERROR_DI_DO_DEFAULT; } hService = OpenService(hSCManager, L"RosAudioSrv", SERVICE_ALL_ACCESS); if (hService) { /* Make RosAudioSrv start automatically */ ChangeServiceConfig(hService, SERVICE_NO_CHANGE, SERVICE_AUTO_START, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL); StartService(hService, 0, NULL); CloseServiceHandle(hService); } CloseServiceHandle(hSCManager); if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32", 0, GENERIC_READ | GENERIC_WRITE, &hKey) == ERROR_SUCCESS) { szBuffer[Length] = '\0'; pBuffer = PathAddBackslashW(szBuffer); wcscpy(pBuffer, L"system32\\wdmaud.drv"); for(Index = 1; Index <= 4; Index++) { swprintf(WaveName, L"wave%u", Index); if (RegQueryValueExW(hKey, WaveName, 0, NULL, NULL, &BufferSize) != ERROR_MORE_DATA) { /* Store new audio driver entry */ RegSetValueExW(hKey, WaveName, 0, REG_SZ, (LPBYTE)szBuffer, (wcslen(szBuffer)+1) * sizeof(WCHAR)); break; } else { WCHAR Buffer[MAX_PATH]; BufferSize = sizeof(Buffer); if (RegQueryValueExW(hKey, WaveName, 0, NULL, (LPBYTE)Buffer, &BufferSize) == ERROR_SUCCESS) { /* Make sure the buffer is zero terminated */ Buffer[MAX_PATH-1] = L'\0'; if (!wcsicmp(Buffer, szBuffer)) { /* An entry already exists */ break; } } } } RegCloseKey(hKey); } InstallSystemSoundScheme(); return ERROR_DI_DO_DEFAULT; }
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; } }