/*********************************************************************** * SetupCopyOEMInfA (SETUPAPI.@) */ BOOL WINAPI SetupCopyOEMInfA( PCSTR source, PCSTR location, DWORD media_type, DWORD style, PSTR dest, DWORD buffer_size, PDWORD required_size, PSTR *component ) { BOOL ret = FALSE; LPWSTR destW = NULL, sourceW = NULL, locationW = NULL; DWORD size; TRACE("%s, %s, %d, %d, %p, %d, %p, %p\n", debugstr_a(source), debugstr_a(location), media_type, style, dest, buffer_size, required_size, component); if (dest && !(destW = MyMalloc( buffer_size * sizeof(WCHAR) ))) return FALSE; if (source && !(sourceW = strdupAtoW( source ))) goto done; if (location && !(locationW = strdupAtoW( location ))) goto done; if (!(ret = SetupCopyOEMInfW( sourceW, locationW, media_type, style, destW, buffer_size, &size, NULL ))) { if (required_size) *required_size = size; goto done; } if (dest) { if (buffer_size >= size) { WideCharToMultiByte( CP_ACP, 0, destW, -1, dest, buffer_size, NULL, NULL ); if (component) *component = strrchr( dest, '\\' ) + 1; } else { SetLastError( ERROR_INSUFFICIENT_BUFFER ); goto done; } } done: MyFree( destW ); HeapFree( GetProcessHeap(), 0, sourceW ); HeapFree( GetProcessHeap(), 0, locationW ); if (ret) SetLastError(ERROR_SUCCESS); return ret; }
static HRESULT vboxDrvCfgInfCopyEx(IN LPCWSTR lpszInfPath, IN DWORD fCopyStyle, OUT LPWSTR lpszDstName, IN DWORD cbDstName, OUT PDWORD pcbDstNameSize, OUT LPWSTR* lpszDstNameComponent) { WCHAR aMediaLocation[_MAX_DIR]; WCHAR aDir[_MAX_DIR]; _wsplitpath(lpszInfPath, aMediaLocation, aDir, NULL, NULL); wcscat(aMediaLocation, aDir); if (!SetupCopyOEMInfW(lpszInfPath, aMediaLocation, SPOST_PATH, fCopyStyle, lpszDstName, cbDstName, pcbDstNameSize, lpszDstNameComponent)) { DWORD dwErr = GetLastError(); HRESULT hr = HRESULT_FROM_WIN32(dwErr); if (fCopyStyle != SP_COPY_REPLACEONLY || hr != VBOXDRVCFG_S_INFEXISTS) { NonStandardLogRelCrap((__FUNCTION__ ": SetupCopyOEMInf fail dwErr=%ld\n", dwErr)); } return hr; } return S_OK; }
UINT pxDiMsiInstallPnpDeviceInf( __in MSIHANDLE hInstall, __in const XDIMSI_PROCESS_RECORD* ProcessRecord) { WCHAR oemInfPath[MAX_PATH]; DWORD oemInfPathLength = 0; LPWSTR oemInfName = NULL; HRESULT hr; while (TRUE) { XDIMSI_DIALOG_ACTIVATOR_CONTEXT daContext; pxDiMsiDialogActivatorStart(&daContext); BOOL success = SetupCopyOEMInfW( ProcessRecord->InfPath, NULL, SPOST_PATH, 0, oemInfPath, RTL_NUMBER_OF(oemInfPath), &oemInfPathLength, &oemInfName); pxDiMsiDialogActivatorStop(&daContext); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); pxMsiTraceW(hInstall, L"SetupCopyOEMInf(%s) failed, hr=0x%x\n", ProcessRecord->InfPath, hr); // 0, IDABORT, IDRETRY, IDIGNORE UINT response = pxMsiErrorMessageBox(hInstall, ProcessRecord->ErrorNumber, hr); switch (response) { case IDRETRY: continue; case IDIGNORE: break; case 0: case IDABORT: default: return ERROR_INSTALL_FAILURE; } } else { pxMsiTraceW(hInstall, L"Copied %s to %s\n", ProcessRecord->InfPath, oemInfPath); hr = pxDiMsiSetInfPathInRegistry( hInstall, oemInfPath, ProcessRecord->RegRoot, ProcessRecord->RegKey, ProcessRecord->RegName); if (FAILED(hr)) { pxMsiTraceW(hInstall, L"pxMsiSetInfPathInRegistry failed, hr=0x%x\n", hr); } } break; } return ERROR_SUCCESS; }
UINT pxDiMsiInstallNetworkComponent( __in MSIHANDLE hInstall, __in const XDIMSI_PROCESS_RECORD* ProcessRecord) { // // InfPath: <inf-path> e.g. c:\program files\ndas\drivers\netlpx.inf // Param: <component-id> e.g. nkc_lpx // HRESULT hr; GUID classGuid; WCHAR className[MAX_CLASS_NAME_LEN]; BOOL success = SetupDiGetINFClassW( ProcessRecord->InfPath, &classGuid, className, MAX_CLASS_NAME_LEN, NULL); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); // // Invalid Class GUID in the inf file // pxMsiTraceW(hInstall, L"SetupDiGetINFClass failed, hr=0x%x\n", hr); return ERROR_INSTALL_FAILURE; } // // Pre-install the OEM INF file to trigger the installation of // the component by the component id later (xDiInstallNetComponent) // WCHAR oemInfPath[MAX_PATH]; DWORD oemInfPathLength; LPWSTR oemInfName; XDIMSI_DIALOG_ACTIVATOR_CONTEXT daContext; pxDiMsiDialogActivatorStart(&daContext); success = SetupCopyOEMInfW( ProcessRecord->InfPath, NULL, SPOST_PATH, 0, oemInfPath, RTL_NUMBER_OF(oemInfPath), NULL, NULL); pxDiMsiDialogActivatorStop(&daContext); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); pxMsiTraceW(hInstall, L"SetupCopyOEMInf failed, hr=0x%x\n", hr); return ERROR_INSTALL_FAILURE; } hr = pxDiMsiSetInfPathInRegistry( hInstall, oemInfPath, ProcessRecord->RegRoot, ProcessRecord->RegKey, ProcessRecord->RegName); if (FAILED(hr)) { pxMsiTraceW(hInstall, L"pxMsiSetInfPathInRegistry failed, hr=0x%x\n", hr); } while (TRUE) { pxDiMsiDialogActivatorStart(&daContext); hr = xDiInstallNetComponent( &classGuid, ProcessRecord->HardwareId, 15*1000, L"Windows Installer", NULL); pxDiMsiDialogActivatorStop(&daContext); if (FAILED(hr)) { pxMsiTraceW(hInstall, L"InstallNetComponent failed, hr=0x%x\n", hr); // 0, IDABORT, IDRETRY, IDIGNORE UINT response = pxMsiErrorMessageBox(hInstall, ProcessRecord->ErrorNumber, hr); switch (response) { case IDRETRY: continue; case IDIGNORE: break; case 0: case IDABORT: default: return ERROR_INSTALL_FAILURE; } } break; } // // The followings actions are not critical ones // Just log errors if any and return ERROR_SUCCESS // if (XDI_S_REBOOT == hr) { pxMsiQueueScheduleReboot(hInstall); } return ERROR_SUCCESS; }
UINT pxDiMsiInstallLegacyPnpDevice( __in MSIHANDLE hInstall, __in const XDIMSI_PROCESS_RECORD* ProcessRecord) { BOOL success = FALSE; BOOL reboot = FALSE; HRESULT hr; while (TRUE) { WCHAR oemInfPath[MAX_PATH]; DWORD oemInfPathLength = 0; LPWSTR oemInfName = NULL; XDIMSI_DIALOG_ACTIVATOR_CONTEXT daContext; pxDiMsiDialogActivatorStart(&daContext); success = SetupCopyOEMInfW( ProcessRecord->InfPath, NULL, SPOST_PATH, 0, oemInfPath, RTL_NUMBER_OF(oemInfPath), &oemInfPathLength, &oemInfName); pxDiMsiDialogActivatorStop(&daContext); if (!success) { hr = HRESULT_FROM_SETUPAPI(GetLastError()); pxMsiTraceW(hInstall, L"SetupCopyOEMInf(%s) failed, hr=0x%x\n", hr); } else { pxMsiTraceW(hInstall, L"hardwareId=%ls, oemInfPath=%ls\n", ProcessRecord->HardwareId, oemInfPath); hr = pxDiMsiSetInfPathInRegistry( hInstall, oemInfPath, ProcessRecord->RegRoot, ProcessRecord->RegKey, ProcessRecord->RegName); if (FAILED(hr)) { pxMsiTraceW(hInstall, L"pxMsiSetInfPathInRegistry failed, hr=0x%x\n", hr); } // // Specifying INSTALLFLAG_FORCE will overwrite the // existing device driver with the current one // irrespective of existence of higher version // pxDiMsiDialogActivatorStart(&daContext); hr = xDiInstallLegacyPnpDevice( NULL, ProcessRecord->HardwareId, ProcessRecord->InfPath, NULL, INSTALLFLAG_FORCE); pxDiMsiDialogActivatorStop(&daContext); if (FAILED(hr)) { pxMsiTraceW(hInstall, L"xDiInstallLegacyPnpDevice failed, hr=0x%x\n", hr); } } if (FAILED(hr)) { UINT response = pxMsiErrorMessageBox(hInstall, ProcessRecord->ErrorNumber, hr); switch (response) { case IDRETRY: continue; case IDIGNORE: break; case 0: case IDABORT: default: return ERROR_INSTALL_FAILURE; } } break; } return ERROR_SUCCESS; }
//+--------------------------------------------------------------------------- // // Function: HrInstallNetComponent // // Purpose: Install the specified net component // // Arguments: // szComponentId [in] component to install // nc [in] class of the component // szInfFullPath [in] full path to primary INF file // required if the primary INF and other // associated files are not pre-copied to // the right destination dirs. // Not required when installing MS components // since the files are pre-copied by // Windows NT Setup. // // Returns: S_OK or NETCFG_S_REBOOT on success, otherwise an error code // // Notes: // HRESULT HrInstallNetComponent(IN PCWSTR szComponentId, IN enum NetClass nc, IN PCWSTR szInfFullPath) { HRESULT hr=S_OK; INetCfg* pnc; // cannot install net adapters this way. they have to be // enumerated/detected and installed by PnP if ((nc == NC_NetProtocol) || (nc == NC_NetService) || (nc == NC_NetClient)) { // if full path to INF has been specified, the INF // needs to be copied using Setup API to ensure that any other files // that the primary INF copies will be correctly found by Setup API // if (szInfFullPath && wcslen(szInfFullPath)) { WCHAR szInfNameAfterCopy[MAX_PATH+1]; if (!SetupCopyOEMInfW( szInfFullPath, NULL, // other files are in the // same dir. as primary INF SPOST_PATH, // first param. contains path to INF 0, // default copy style szInfNameAfterCopy, // receives the name of the INF // after it is copied to %windir%\inf MAX_PATH, // max buf. size for the above NULL, // receives required size if non-null NULL)) // optionally retrieves filename // component of szInfNameAfterCopy { DWORD dwError = GetLastError(); hr = HRESULT_FROM_WIN32(dwError); } } if (S_OK == hr) { // get INetCfg interface hr = HrGetINetCfg(TRUE, &pnc); if (SUCCEEDED(hr)) { // install szComponentId hr = HrInstallNetComponent(pnc, szComponentId, c_aguidClass[nc]); if (SUCCEEDED(hr)) { // Apply the changes hr = pnc->Apply(); } // release INetCfg (void) HrReleaseINetCfg(TRUE, pnc); } } // show success/failure message ShowHrMessage(hr); } return hr; }
HRESULT HrInstallNetComponent (IN INetCfg *pnc, IN LPCWSTR lpszComponentId, IN const GUID *pguidClass, IN LPCWSTR lpszInfFullPath) { DWORD dwError; HRESULT hr = S_OK; WCHAR* Drive = NULL; WCHAR* Dir = NULL; WCHAR* DirWithDrive = NULL; do { // // If full path to INF has been specified, the INF // needs to be copied using Setup API to ensure that any other files // that the primary INF copies will be correctly found by Setup API // if ( lpszInfFullPath ) { // // Allocate memory to hold the strings // Drive = (WCHAR*)CoTaskMemAlloc(_MAX_DRIVE * sizeof(WCHAR)); if (NULL == Drive) { hr = E_OUTOFMEMORY; break; } ZeroMemory(Drive, _MAX_DRIVE * sizeof(WCHAR)); Dir = (WCHAR*)CoTaskMemAlloc(_MAX_DIR * sizeof(WCHAR)); if (NULL == Dir) { hr = E_OUTOFMEMORY; break; } ZeroMemory(Dir, _MAX_DRIVE * sizeof(WCHAR)); DirWithDrive = (WCHAR*)CoTaskMemAlloc((_MAX_DRIVE + _MAX_DIR) * sizeof(WCHAR)); if (NULL == DirWithDrive) { hr = E_OUTOFMEMORY; break; } ZeroMemory(DirWithDrive, (_MAX_DRIVE + _MAX_DIR) * sizeof(WCHAR)); // // Get the path where the INF file is. // _wsplitpath_s ( lpszInfFullPath, Drive, _MAX_DRIVE, Dir, _MAX_DIR, NULL, 0, NULL, 0); StringCchCopyW ( DirWithDrive, _MAX_DRIVE + _MAX_DIR, Drive ); StringCchCatW ( DirWithDrive, _MAX_DRIVE + _MAX_DIR, Dir ); // // Copy the INF file and other files referenced in the INF file. // if ( !SetupCopyOEMInfW(lpszInfFullPath, DirWithDrive, // Other files are in the // same dir. as primary INF SPOST_PATH, // First param is path to INF 0, // Default copy style NULL, // Name of the INF after // it's copied to %windir%\inf 0, // Max buf. size for the above NULL, // Required size if non-null NULL) ) { // Optionally get the filename // part of Inf name after it is copied. dwError = GetLastError(); hr = HRESULT_FROM_WIN32( dwError ); } } if ( S_OK == hr ) { // // Install the network component. // hr = HrInstallComponent( pnc, lpszComponentId, pguidClass ); if ( hr == S_OK ) { // // On success, apply the changes // hr = pnc->Apply(); } } #pragma warning(disable:4127) /* Conditional expression is constant */ } while (false); if (Drive != NULL) { CoTaskMemFree(Drive); Drive = NULL; } if (Dir != NULL) { CoTaskMemFree(Dir); Dir = NULL; } if (DirWithDrive != NULL) { CoTaskMemFree(DirWithDrive); DirWithDrive = NULL; } return hr; }