home *** CD-ROM | disk | FTP | other *** search
/ PCNET 2006 September - Disc 1 / PCNET_CD_2006_09.iso / surpriz / MSRMesh-VirtualWIFI.MSI / setupdi.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2005-06-24  |  11.4 KB  |  417 lines

  1. /*
  2.  * Author   : Ranveer Chandra
  3.  * Directory: VirtualWiFi_Root\notifyob
  4.  * File Name: setupdi.cpp
  5.  * Purpose  : Code to copy Net class inf file
  6.  */
  7.  
  8. #include "notify.h"
  9.  
  10. // =================================================================
  11. // Forward declarations
  12.  
  13. HRESULT HrCopyMiniportInf (VOID);
  14. HRESULT HrGetProtocolInf (LPWSTR lpszWindowsDir,
  15.                           LPWSTR *lppszProtocolInf);
  16. HRESULT HrGetMediaRootDir (LPWSTR lpszInfFile,
  17.                            LPWSTR *lppszMediaRoot);
  18. HRESULT HrGetPnpID (LPWSTR lpszInfFile,
  19.                     LPWSTR *lppszPnpID);
  20. HRESULT HrGetKeyValue (HINF hInf,
  21.                        LPCWSTR lpszSection,
  22.                        LPCWSTR lpszKey,
  23.                        DWORD  dwIndex,
  24.                        LPWSTR *lppszValue);
  25.  
  26.  
  27.  
  28. const WCHAR c_szInfPath[]               = L"Inf\\";
  29. const WCHAR c_szMiniportInf[]           = L"vwifi_mp.inf";
  30. const WCHAR c_szInfSourcePathInfo[]     = L"InfSourcePathInfo";
  31. const WCHAR c_szOriginalInfSourcePath[] = L"OriginalInfSourcePath";
  32.  
  33. HRESULT HrCopyMiniportInf (VOID)
  34. {
  35.     LPWSTR  lpszWindowsDir;
  36.     LPWSTR  lpszProtocolInf;
  37.     LPWSTR  lpszMediaRoot;
  38.     LPWSTR  lpszMiniportInf;
  39.     DWORD   dwLen;
  40.     HRESULT hr;
  41.  
  42.     //
  43.     // Get %windir% directory.
  44.     //
  45.  
  46.     dwLen = GetSystemWindowsDirectoryW( NULL, 0 );
  47.  
  48.     if ( dwLen == 0 )
  49.     {
  50.         return HRESULT_FROM_WIN32(GetLastError());
  51.     }
  52.  
  53.     // Add 1 for NULL and 1 for "\" in case it is needed.
  54.  
  55.     dwLen += wcslen(c_szInfPath) + 2;
  56.  
  57.     lpszWindowsDir = (LPWSTR)CoTaskMemAlloc( dwLen * sizeof(WCHAR) );
  58.  
  59.     if ( !lpszWindowsDir )
  60.     {
  61.         return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  62.     }
  63.  
  64.     if ( GetSystemWindowsDirectoryW(lpszWindowsDir, dwLen) == 0 )
  65.     {
  66.         hr = HRESULT_FROM_WIN32( GetLastError() );
  67.     }
  68.     else
  69.     {
  70.         // Append "inf\" to %windir%.
  71.  
  72.         dwLen = wcslen( lpszWindowsDir );
  73.  
  74.         if ( lpszWindowsDir[dwLen-1] == L'\\' )
  75.         {
  76.             wcscat( lpszWindowsDir, c_szInfPath );
  77.         }
  78.         else
  79.         {
  80.             wcscat( lpszWindowsDir, L"\\" );
  81.             wcscat( lpszWindowsDir, c_szInfPath );
  82.         }
  83.  
  84.         //
  85.         // Find the protocol inf name. Originally, it was netsf.inf but has
  86.         // been renamed to oem?.inf by SetupCopyOEMInf.
  87.         //
  88.  
  89.         hr = HrGetProtocolInf( lpszWindowsDir, &lpszProtocolInf );
  90.  
  91.         if ( hr == S_OK )
  92.         {
  93.             //
  94.             // Get the directory from where protocol was installed.
  95.  
  96.             hr = HrGetMediaRootDir( lpszProtocolInf, &lpszMediaRoot );
  97.  
  98.             if ( hr == S_OK )
  99.             {
  100.  
  101.                 TraceMsg(L"Media root directory is %s.\n", lpszMediaRoot);
  102.  
  103.                 // Add 1 for NULL and 1 for "\" in case it is needed.
  104.  
  105.                 lpszMiniportInf = (LPWSTR)CoTaskMemAlloc( (wcslen(lpszMediaRoot) +
  106.                                                           wcslen(c_szMiniportInf) + 2) *
  107.                                                           sizeof(WCHAR) );
  108.                 if ( lpszMiniportInf == NULL )
  109.                 {
  110.                     hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  111.                 }
  112.                 else
  113.                 {
  114.                     //
  115.                     // We know the full path from where the protocol is being installed. Our
  116.                     // miniport inf is in the same location. Copy the miniport inf to
  117.                     // %windir%\inf so that when we install the virtual miniport, Setup
  118.                     // will find the miniport inf.
  119.                     //
  120.  
  121.                     wcscpy( lpszMiniportInf, lpszMediaRoot );
  122.  
  123.                     dwLen = wcslen( lpszMiniportInf );
  124.                     if ( lpszMiniportInf[dwLen-1] != L'\\' )
  125.                     {
  126.                         wcscat( lpszMiniportInf, L"\\" );
  127.                     }
  128.  
  129.                     wcscat( lpszMiniportInf, c_szMiniportInf );
  130.  
  131.                     TraceMsg(L"Calling SetupCopyOEMInf for %s.\n", lpszMiniportInf);
  132.  
  133.                     if ( !SetupCopyOEMInfW(lpszMiniportInf,
  134.                                           lpszMediaRoot,
  135.                                           SPOST_PATH,
  136.                                           0,
  137.                                           NULL,
  138.                                           0,
  139.                                           NULL,
  140.                                           NULL) )
  141.                     {
  142.                         hr = HRESULT_FROM_WIN32(GetLastError());
  143.                     }
  144.  
  145.                     CoTaskMemFree( lpszMiniportInf );
  146.                 }
  147.  
  148.                 CoTaskMemFree( lpszMediaRoot );
  149.             }
  150.  
  151.             CoTaskMemFree( lpszProtocolInf );
  152.         }
  153.     }
  154.  
  155.     CoTaskMemFree( lpszWindowsDir );
  156.  
  157.     return hr;
  158. }
  159.  
  160.  
  161. //
  162. // The function searches through all the inf files in %windir%\inf and
  163. // returns the name of the protocol's inf.
  164. //
  165.  
  166. HRESULT HrGetProtocolInf (LPWSTR lpszWindowsDir,
  167.                           LPWSTR *lppszProtocolInf)
  168. {
  169.     LPWSTR  lpszFileList;
  170.     LPWSTR  lpszFile;
  171.     LPWSTR  lpszFileWithPath;
  172.     LPWSTR  lpszPnpID;
  173.     DWORD   dwSizeNeeded;
  174.     BOOL    fTrailingSlash;
  175.     DWORD   dwLen;
  176.     BYTE    found;
  177.     HRESULT hr;
  178.  
  179.     *lppszProtocolInf = NULL;
  180.     dwLen = wcslen( lpszWindowsDir );
  181.     fTrailingSlash = lpszWindowsDir[dwLen-1] == L'\\';
  182.  
  183.     if ( SetupGetInfFileListW(lpszWindowsDir,
  184.                               INF_STYLE_WIN4,
  185.                               NULL,
  186.                               0,
  187.                               &dwSizeNeeded) == 0 )
  188.     {
  189.         return HRESULT_FROM_WIN32(GetLastError());
  190.     }
  191.  
  192.     lpszFileList = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded );
  193.  
  194.     if ( !lpszFileList )
  195.     {
  196.         return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  197.     }
  198.  
  199.     if ( SetupGetInfFileListW( lpszWindowsDir,
  200.                                INF_STYLE_WIN4,
  201.                                lpszFileList,
  202.                                dwSizeNeeded,
  203.                                NULL) == 0 )
  204.  
  205.     {
  206.         CoTaskMemFree( lpszFileList );
  207.         return HRESULT_FROM_WIN32(GetLastError());
  208.     }
  209.  
  210.     lpszFile = lpszFileList;
  211.     found = 0;
  212.     hr = S_OK;
  213.     while( (hr == S_OK) && !found && *lpszFile )
  214.     {
  215.         lpszFileWithPath = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) *
  216.                                                   (wcslen(lpszFile) +
  217.                                                   dwLen + 1 +
  218.                                                   ((fTrailingSlash) ? 0 : 1)) );
  219.         if ( !lpszFileWithPath )
  220.         {
  221.             hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  222.         }
  223.         else
  224.         {
  225.             if ( fTrailingSlash )
  226.             {
  227.              swprintf( lpszFileWithPath, L"%s%s",
  228.                        lpszWindowsDir,
  229.                        lpszFile );
  230.             }
  231.             else
  232.             {
  233.                 swprintf( lpszFileWithPath, L"%s\\%s",
  234.                           lpszWindowsDir,
  235.                           lpszFile );
  236.             }
  237.  
  238.             hr = HrGetPnpID( lpszFileWithPath, &lpszPnpID );
  239.  
  240.             // If the inf file installs a driver then, it will have a Model
  241.             // section with the hwid/PnpID of the driver that is installed.
  242.             //
  243.             // In case, there is an error getting the hwid, we simply ignore
  244.             // the inf file and continue with the next one.
  245.  
  246.             if ( hr == S_OK )
  247.             {
  248.                 if (_wcsicmp(lpszPnpID, c_szMuxProtocol) == 0 )
  249.                 {
  250.                     found = 1;
  251.                 }
  252.  
  253.                 CoTaskMemFree( lpszPnpID );
  254.             }
  255.  
  256.             if ( !found )
  257.             {
  258.                 hr = S_OK;
  259.                 CoTaskMemFree( lpszFileWithPath );
  260.                 lpszFile += wcslen(lpszFile) + 1;
  261.             }
  262.         }
  263.     }
  264.  
  265.     if ( found )
  266.     {
  267.         *lppszProtocolInf = lpszFileWithPath;
  268.     }
  269.     else
  270.     {
  271.         hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
  272.     }
  273.  
  274.     CoTaskMemFree( lpszFileList );
  275.  
  276.     return hr;
  277. }
  278.  
  279. HRESULT HrGetPnpID (LPWSTR lpszInfFile,
  280.                     LPWSTR *lppszPnpID)
  281. {
  282.     HINF    hInf;
  283.     LPWSTR  lpszModelSection;
  284.     HRESULT hr;
  285.  
  286.     *lppszPnpID = NULL;
  287.  
  288.     hInf = SetupOpenInfFileW( lpszInfFile,
  289.                               NULL,
  290.                               INF_STYLE_WIN4,
  291.                               NULL );
  292.  
  293.     if ( hInf == INVALID_HANDLE_VALUE )
  294.     {
  295.  
  296.         return HRESULT_FROM_WIN32(GetLastError());
  297.     }
  298.  
  299.     hr = HrGetKeyValue( hInf,
  300.                         L"Manufacturer",
  301.                         NULL,
  302.                         1,
  303.                         &lpszModelSection );
  304.  
  305.     if ( hr == S_OK )
  306.     {
  307.         hr = HrGetKeyValue( hInf,
  308.                             lpszModelSection,
  309.                             NULL,
  310.                             2,
  311.                             lppszPnpID );
  312.  
  313.         CoTaskMemFree( lpszModelSection );
  314.     }
  315.  
  316.     SetupCloseInfFile( hInf );
  317.  
  318.     return hr;
  319. }
  320.  
  321. HRESULT HrGetMediaRootDir (LPWSTR lpszInfFile,
  322.                            LPWSTR *lppszMediaRoot)
  323. {
  324.     HINF    hInf;
  325.     HRESULT hr;
  326.  
  327.     *lppszMediaRoot = NULL;
  328.  
  329.     hInf = SetupOpenInfFileW( lpszInfFile,
  330.                               NULL,
  331.                               INF_STYLE_WIN4,
  332.                               NULL );
  333.  
  334.     if ( hInf == INVALID_HANDLE_VALUE )
  335.     {
  336.  
  337.         return HRESULT_FROM_WIN32(GetLastError());
  338.     }
  339.  
  340.     //
  341.     // Contained within the protocol INF should be a [InfSourcePathInfo]
  342.     // section with the following entry:
  343.     //
  344.     //     OriginalInfSourcePath = %1%
  345.     //
  346.     // If we retrieve the value (i.e., field 1) of this line, we'll get the
  347.     // full path where the INF originally came from.
  348.     //
  349.  
  350.     hr = HrGetKeyValue( hInf,
  351.                         c_szInfSourcePathInfo,
  352.                         c_szOriginalInfSourcePath,
  353.                         1,
  354.                         lppszMediaRoot );
  355.  
  356.     SetupCloseInfFile( hInf );
  357.  
  358.     return hr;
  359. }
  360.  
  361. HRESULT HrGetKeyValue (HINF hInf,
  362.                        LPCWSTR lpszSection,
  363.                        LPCWSTR lpszKey,
  364.                        DWORD  dwIndex,
  365.                        LPWSTR *lppszValue)
  366. {
  367.     INFCONTEXT  infCtx;
  368.     DWORD       dwSizeNeeded;
  369.     HRESULT     hr;
  370.  
  371.     *lppszValue = NULL;
  372.  
  373.     if ( SetupFindFirstLineW(hInf,
  374.                              lpszSection,
  375.                              lpszKey,
  376.                              &infCtx) == FALSE )
  377.     {
  378.         return HRESULT_FROM_WIN32(GetLastError());
  379.     }
  380.  
  381.     SetupGetStringFieldW( &infCtx,
  382.                           dwIndex,
  383.                           NULL,
  384.                           0,
  385.                           &dwSizeNeeded );
  386.  
  387.     *lppszValue = (LPWSTR)CoTaskMemAlloc( sizeof(WCHAR) * dwSizeNeeded );
  388.  
  389.     if ( !*lppszValue  )
  390.     {
  391.        return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
  392.     }
  393.  
  394.     if ( SetupGetStringFieldW(&infCtx,
  395.                               dwIndex,
  396.                               *lppszValue,
  397.                               dwSizeNeeded,
  398.                               NULL) == FALSE )
  399.     {
  400.  
  401.         hr = HRESULT_FROM_WIN32(GetLastError());
  402.  
  403.         CoTaskMemFree( *lppszValue );
  404.         *lppszValue = NULL;
  405.     }
  406.     else
  407.     {
  408.         hr = S_OK;
  409.     }
  410.  
  411.     return hr;
  412. }
  413.  
  414.  
  415.  
  416.  
  417.