DWORD GetServiceInfFilePath_Passthru( LPTSTR lpFilename, DWORD nSize ) { // Get Path to This Module DWORD nResult; TCHAR szDrive[ _MAX_DRIVE ]; TCHAR szDir[ _MAX_DIR ]; nResult = GetModuleFileName( NULL, lpFilename, nSize ); if( nResult == 0 ) { return 0; } _tsplitpath( lpFilename, szDrive, szDir, NULL, NULL ); _tmakepath( lpFilename, szDrive, szDir, _T ("netsf"), _T(".inf") ); return (DWORD )_tcslen( lpFilename ); } DWORD GetServiceInfFilePath_PassthruMP( LPTSTR lpFilename, DWORD nSize ) { // Get Path to This Module DWORD nResult; TCHAR szDrive[ _MAX_DRIVE ]; TCHAR szDir[ _MAX_DIR ]; nResult = GetModuleFileName( NULL, lpFilename, nSize ); if( nResult == 0 ) { return 0; } _tsplitpath( lpFilename, szDrive, szDir, NULL, NULL ); _tmakepath( lpFilename, szDrive, szDir, _T ("netsf_m"), _T(".inf") ); return (DWORD )_tcslen( lpFilename ); } DWORD InstallDriver_Passthru() { DWORD nResult; //_tprintf( _T("Installing %s...\n"), NDISPROT_FRIENDLY_NAME ); nResult = MessageBox(NULL, _T("你要安裝 Passthru 網絡驅動?" ), _T ("Passthru網絡過濾驅動"), MB_OKCANCEL | MB_ICONINFORMATION ); if( nResult != IDOK ) { return 0; } // Get Path to Service INF File // ---------------------------- // The INF file is assumed to be in the same folder as this application... TCHAR szFileFullPath[ _MAX_PATH ]; //----------------------------------------------------------------------- //第一次在一個系統上使用這個程序安裝Passthru時,會出現安裝失敗的狀況,或者 //安裝成功,但passthru miniport的部分沒有安裝上去,在windows 目錄下 的setupapi.log文件中能夠看到 //安裝失敗記錄,錯誤是找不到文件。在「設備管理器」選擇顯示隱藏設備後 //也不會在 網絡適配器 下面看到 passthru miniport項。但手動安裝在'本地網絡屬性"->"安裝"->」服務「選擇 //硬盤上netsf.inf進行安裝成功候,再用程序安裝就能夠了。 //在網絡上查了一下,這個問題應該是由於 Passthru這個驅動須要兩個inf文件,而netsf_m.inf並不沒有被複制到 //系統的inf 目錄(c:\windows\inf)去。雖然 netsf.inf 裏面有[CopyInf = netsf_m.inf]項要求複製netsf_m.inf //但這個不能 正常工做(The \"CopyINF\" directive, by design, is only observed if the original INF is //not yet in the INF directory. So to work around the problem, you have to //update your installation app (snetcfg) to also copy the Net class (miniport) //inf using SetupCopyOEMInf when it comes to installing IM drivers. Make sure //you specify a fully qualified path of the INF in the SetupCopyOEMInf //arguments. //) // //因此這個問題的解決就是本身把 netsf_m.inf這個文件放到c:\windows\inf目錄去。這能夠經過在 netsf.inf裏面添加 //copyfile項,像copy Passthru.sys同樣添加一項copy netsf_m.inf的項。另外一種方法就是像下面這樣添加調用 //SetupCopyOEMInfW來複制netsf_m.inf的代碼 TCHAR szDrive[ _MAX_DRIVE ]; TCHAR szDir[ _MAX_DIR ]; TCHAR szDirWithDrive[_MAX_DRIVE+_MAX_DIR]; nResult = GetServiceInfFilePath_PassthruMP( szFileFullPath, MAX_PATH ); if( nResult == 0 ) { //_tprintf( _T("Unable to get INF file path.\n") ); MessageBox(NULL, _T("獲取INF文件路徑失敗!"),_T("安裝程序錯誤提示"),MB_OK); return 0; } // // Get the path where the INF file is. // _tsplitpath( szFileFullPath, szDrive, szDir, NULL, NULL ); _tcscpy( szDirWithDrive, szDrive ); _tcscat( szDirWithDrive, szDir ); if ( !SetupCopyOEMInfW( szFileFullPath, szDirWithDrive, // 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. ) { MessageBox(NULL, _T("複製 PasstruMP 的inf安裝文件到系統目錄失敗!"),_T("安裝程序錯誤提示"),MB_OK); } //------------------------------------------------------------------------ nResult = GetServiceInfFilePath_Passthru( szFileFullPath, MAX_PATH ); if( nResult == 0 ) { // _tprintf( _T("Unable to get INF file path.\n") ); MessageBox(NULL, _T("獲取INF文件路徑失敗!"),_T("安裝程序錯誤提示"),MB_OK); return 0; } //_tprintf( _T("INF Path: %s\n"), szFileFullPath ); HRESULT hr=S_OK; //_tprintf( _T("PnpID: %s\n"), _T( "ms_passthru")); hr = InstallSpecifiedComponent( szFileFullPath, //驅動安裝的inf文件路徑 , 適當修改吧 _T ("ms_passthru"), // NDISPROT_SERVICE_PNP_DEVICE_ID, //這個也要適當修改的 &GUID_DEVCLASS_NETSERVICE //NDIS Protocal 類型 ); if( hr != S_OK ) { /*ErrMsg( hr, L"InstallSpecifiedComponent\n" );*/ MessageBox(NULL, _T("安裝驅動失敗!"),_T("安裝程序錯誤提示"),MB_OK); }else { MessageBox(NULL, _T("成功安裝驅動!"),_T("安裝程序提示"),MB_OK); } return 0; } DWORD UninstallDriver_Passthru() { //_tprintf( _T("Uninstalling %s...\n"), NDISPROT_FRIENDLY_NAME ); int nResult = MessageBox(NULL, _T("你要卸載Passthru網絡驅動?" ), _T ("Passthru網絡過濾驅動"), MB_OKCANCEL | MB_ICONINFORMATION ); if( nResult != IDOK ) { return 0; } INetCfg *pnc; INetCfgComponent *pncc; INetCfgClass *pncClass; INetCfgClassSetup *pncClassSetup; LPTSTR lpszApp; GUID guidClass; OBO_TOKEN obo; HRESULT hr; hr = HrGetINetCfg( TRUE, APP_NAME, &pnc, &lpszApp ); if ( hr == S_OK ) { // // Get a reference to the network component to uninstall. // hr = pnc->FindComponent( _T ("ms_passthru"), &pncc ); if ( hr == S_OK ) { // // Get the class GUID. // hr = pncc->GetClassGuid( &guidClass ); if ( hr == S_OK ) { // // Get a reference to component's class. // hr = pnc->QueryNetCfgClass( &guidClass, IID_INetCfgClass, (PVOID *)&pncClass ); if ( hr == S_OK ) { // // Get the setup interface. // hr = pncClass->QueryInterface( IID_INetCfgClassSetup, (LPVOID *)&pncClassSetup ); if ( hr == S_OK ) { // // Uninstall the component. // ZeroMemory( &obo, sizeof(OBO_TOKEN) ); obo.Type = OBO_USER; hr = pncClassSetup->DeInstall( pncc, &obo, NULL ); if ( (hr == S_OK) || (hr == NETCFG_S_REBOOT) ) { hr = pnc->Apply(); if ( (hr != S_OK) && (hr != NETCFG_S_REBOOT) ) { //ErrMsg( hr, // L"Couldn't apply the changes after" // L" uninstalling %s.", // _T ("ms_passthru" )); MessageBox(NULL, _T ("卸載驅動以後沒法成功應用!"),_T ("安裝程序錯誤提示"),MB_OK); }else { MessageBox(NULL, _T("成功卸載驅動!"),_T("安裝程序提示"),MB_OK); } } else { //ErrMsg( hr, // L"Failed to uninstall %s.", // _T("ms_passthru" )); MessageBox(NULL, _T("卸載網絡組件失敗!"),_T("安裝程序錯誤提示"),MB_OK); } ReleaseRef( pncClassSetup ); } else { //ErrMsg( hr, // L"Couldn't get an interface to setup class." ); MessageBox(NULL, _T("沒法獲得安裝類接口!"),_T("安裝程序錯誤提示"),MB_OK); } ReleaseRef( pncClass ); } else { //ErrMsg( hr, // L"Couldn't get a pointer to class interface " // L"of %s.", // _T ("ms_passthru") ); MessageBox(NULL, _T("沒法獲得安裝類接口!"),_T("安裝程序錯誤提示"),MB_OK); } } else { //ErrMsg( hr, // L"Couldn't get the class guid of %s.", // _T("ms_passthru") ); MessageBox(NULL, _T("沒法獲得安裝類接口的 GUID !"),_T("安裝程序錯誤提示"),MB_OK); } ReleaseRef( pncc ); } else { //ErrMsg( hr, // L"Couldn't get an interface pointer to %s.", // _T ("ms_passthru") ); MessageBox(NULL, _T("沒法獲得一個接口指針!"),_T("安裝程序錯誤提示"),MB_OK); } HrReleaseINetCfg( pnc, TRUE ); } else { if ( (hr == NETCFG_E_NO_WRITE_LOCK) && lpszApp ) { // ErrMsg( hr, // L"%s currently holds the lock, try later.", // lpszApp ); MessageBox(NULL, _T("碰到死鎖問題,稍後再試!"),_T("安裝程序錯誤提示"),MB_OK); CoTaskMemFree( lpszApp ); } else { // ErrMsg( hr, L"Couldn't get the notify object interface." ); MessageBox(NULL, _T("沒法獲得通知對象接口!"),_T("安裝程序錯誤提示"),MB_OK); } } return 0; }