|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: S E T U P D I . C P P
//
// Contents: Code to copy Net class inf file
//
// Notes:
//
//----------------------------------------------------------------------------
#include "notify.h"
// =================================================================
// Forward declarations
HRESULT HrCopyMiniportInf (VOID); HRESULT HrGetProtocolInf (LPWSTR lpszWindowsDir, LPWSTR *lppszProtocolInf); HRESULT HrGetMediaRootDir (LPWSTR lpszInfFile, LPWSTR *lppszMediaRoot); HRESULT HrGetPnpID (LPWSTR lpszInfFile, LPWSTR *lppszPnpID); HRESULT HrGetKeyValue (HINF hInf, LPCWSTR lpszSection, LPCWSTR lpszKey, DWORD dwIndex, LPWSTR *lppszValue);
const WCHAR c_szInfPath[] = L"Inf\\"; const WCHAR c_szMiniportInf[] = L"mux_mp.inf"; const WCHAR c_szInfSourcePathInfo[] = L"InfSourcePathInfo"; const WCHAR c_szOriginalInfSourcePath[] = L"OriginalInfSourcePath";
HRESULT HrCopyMiniportInf (VOID) { LPWSTR lpszWindowsDir; LPWSTR lpszProtocolInf; LPWSTR lpszMediaRoot; LPWSTR lpszMiniportInf; DWORD dwLen; HRESULT hr;
//
// Get %windir% directory.
//
dwLen = GetSystemWindowsDirectoryW( NULL, 0 );
if ( dwLen == 0 ) { return HRESULT_FROM_WIN32(GetLastError()); }
// Add 1 for NULL and 1 for "\" in case it is needed.
dwLen += wcslen(c_szInfPath) + 2;
lpszWindowsDir = (LPWSTR)CoTaskMemAlloc( dwLen * sizeof(WCHAR) );
if ( !lpszWindowsDir ) { return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); }
if ( GetSystemWindowsDirectoryW(lpszWindowsDir, dwLen) == 0 ) { hr = HRESULT_FROM_WIN32( GetLastError() ); } else { // Append "inf\" to %windir%.
dwLen = wcslen( lpszWindowsDir );
if ( lpszWindowsDir[dwLen-1] == L'\\' ) { wcscat( lpszWindowsDir, c_szInfPath ); } else { wcscat( lpszWindowsDir, L"\\" ); wcscat( lpszWindowsDir, c_szInfPath ); }
//
// Find the protocol inf name. Originally, it was netsf.inf but has
// been renamed to oem?.inf by SetupCopyOEMInf.
//
hr = HrGetProtocolInf( lpszWindowsDir, &lpszProtocolInf );
if ( hr == S_OK ) { //
// Get the directory from where protocol was installed.
hr = HrGetMediaRootDir( lpszProtocolInf, &lpszMediaRoot );
if ( hr == S_OK ) {
TraceMsg(L"Media root directory is %s.\n", lpszMediaRoot);
// Add 1 for NULL and 1 for "\" in case it is needed.
lpszMiniportInf = (LPWSTR)CoTaskMemAlloc( (wcslen(lpszMediaRoot) + wcslen(c_szMiniportInf) + 2) * sizeof(WCHAR) ); if ( lpszMiniportInf == NULL ) { hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); } else { //
// We know the full path from where the protocol is being installed. Our
// miniport inf is in the same location. Copy the miniport inf to
// %windir%\inf so that when we install the virtual miniport, Setup
// will find the miniport inf.
//
wcscpy( lpszMiniportInf, lpszMediaRoot );
dwLen = wcslen( lpszMiniportInf ); if ( lpszMiniportInf[dwLen-1] != L'\\' ) { wcscat( lpszMiniportInf, L"\\" ); }
wcscat( lpszMiniportInf, c_szMiniportInf );
TraceMsg(L"Calling SetupCopyOEMInf for %s.\n", lpszMiniportInf);
if ( !SetupCopyOEMInfW(lpszMiniportInf, lpszMediaRoot, SPOST_PATH, 0, NULL, 0, NULL, NULL) ) { hr = HRESULT_FROM_WIN32(GetLastError()); }
CoTaskMemFree( lpszMiniportInf ); }
CoTaskMemFree( lpszMediaRoot ); }
CoTaskMemFree( lpszProtocolInf ); } }
CoTaskMemFree( lpszWindowsDir );
return hr; }
//
// The function searches through all the inf files in %windir%\inf and
// returns the name of the protocol's inf.
//
HRESULT HrGetProtocolInf (LPWSTR lpszWindowsDir, LPWSTR *lppszProtocolInf) { LPWSTR lpszFileList; LPWSTR lpszFile; LPWSTR lpszFileWithPath; LPWSTR lpszPnpID; DWORD dwSizeNeeded; BOOL fTrailingSlash; DWORD dwLen; BYTE found; HRESULT hr;
*lppszProtocolInf = NULL; dwLen = wcslen( lpszWindowsDir ); fTrailingSlash = lpszWindowsDir[dwLen-1] == L'\\';
if ( SetupGetInfFileListW(lpszWindowsDir, INF_STYLE_WIN4, NULL, 0, &dwSizeNeeded) == 0 ) { return HRESULT_FROM_WIN32(GetLastError()); }
lpszFileList = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded );
if ( !lpszFileList ) { return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); }
if ( SetupGetInfFileListW( lpszWindowsDir, INF_STYLE_WIN4, lpszFileList, dwSizeNeeded, NULL) == 0 )
{ CoTaskMemFree( lpszFileList ); return HRESULT_FROM_WIN32(GetLastError()); }
lpszFile = lpszFileList; found = 0; hr = S_OK; while( (hr == S_OK) && !found && *lpszFile ) { lpszFileWithPath = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * (wcslen(lpszFile) + dwLen + 1 + ((fTrailingSlash) ? 0 : 1)) ); if ( !lpszFileWithPath ) { hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); } else { if ( fTrailingSlash ) { swprintf( lpszFileWithPath, L"%s%s", lpszWindowsDir, lpszFile ); } else { swprintf( lpszFileWithPath, L"%s\\%s", lpszWindowsDir, lpszFile ); }
hr = HrGetPnpID( lpszFileWithPath, &lpszPnpID );
// If the inf file installs a driver then, it will have a Model
// section with the hwid/PnpID of the driver that is installed.
//
// In case, there is an error getting the hwid, we simply ignore
// the inf file and continue with the next one.
if ( hr == S_OK ) { if (_wcsicmp(lpszPnpID, c_szMuxProtocol) == 0 ) { found = 1; }
CoTaskMemFree( lpszPnpID ); }
if ( !found ) { hr = S_OK; CoTaskMemFree( lpszFileWithPath ); lpszFile += wcslen(lpszFile) + 1; } } }
if ( found ) { *lppszProtocolInf = lpszFileWithPath; } else { hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); }
CoTaskMemFree( lpszFileList );
return hr; }
HRESULT HrGetPnpID (LPWSTR lpszInfFile, LPWSTR *lppszPnpID) { HINF hInf; LPWSTR lpszModelSection; HRESULT hr;
*lppszPnpID = NULL;
hInf = SetupOpenInfFileW( lpszInfFile, NULL, INF_STYLE_WIN4, NULL );
if ( hInf == INVALID_HANDLE_VALUE ) {
return HRESULT_FROM_WIN32(GetLastError()); }
hr = HrGetKeyValue( hInf, L"Manufacturer", NULL, 1, &lpszModelSection );
if ( hr == S_OK ) { hr = HrGetKeyValue( hInf, lpszModelSection, NULL, 2, lppszPnpID );
CoTaskMemFree( lpszModelSection ); }
SetupCloseInfFile( hInf );
return hr; }
HRESULT HrGetMediaRootDir (LPWSTR lpszInfFile, LPWSTR *lppszMediaRoot) { HINF hInf; HRESULT hr;
*lppszMediaRoot = NULL;
hInf = SetupOpenInfFileW( lpszInfFile, NULL, INF_STYLE_WIN4, NULL );
if ( hInf == INVALID_HANDLE_VALUE ) {
return HRESULT_FROM_WIN32(GetLastError()); }
//
// Contained within the protocol INF should be a [InfSourcePathInfo]
// section with the following entry:
//
// OriginalInfSourcePath = %1%
//
// If we retrieve the value (i.e., field 1) of this line, we'll get the
// full path where the INF originally came from.
//
hr = HrGetKeyValue( hInf, c_szInfSourcePathInfo, c_szOriginalInfSourcePath, 1, lppszMediaRoot );
SetupCloseInfFile( hInf );
return hr; }
HRESULT HrGetKeyValue (HINF hInf, LPCWSTR lpszSection, LPCWSTR lpszKey, DWORD dwIndex, LPWSTR *lppszValue) { INFCONTEXT infCtx; DWORD dwSizeNeeded; HRESULT hr;
*lppszValue = NULL;
if ( SetupFindFirstLineW(hInf, lpszSection, lpszKey, &infCtx) == FALSE ) { return HRESULT_FROM_WIN32(GetLastError()); }
SetupGetStringFieldW( &infCtx, dwIndex, NULL, 0, &dwSizeNeeded );
*lppszValue = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded );
if ( !*lppszValue ) { return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); }
if ( SetupGetStringFieldW(&infCtx, dwIndex, *lppszValue, dwSizeNeeded, NULL) == FALSE ) {
hr = HRESULT_FROM_WIN32(GetLastError());
CoTaskMemFree( *lppszValue ); *lppszValue = NULL; } else { hr = S_OK; }
return hr; }
|