vrsreg.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 16k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //***************************************************************************
  2. //*     Copyright (c) Microsoft Corporation 1995. All rights reserved.      *
  3. //***************************************************************************
  4. //*                                                                         *
  5. //* vrsreg.cpp - stub exe to register the virus scanner engine.             *
  6. //*                                                                         *
  7. //* created 10-15-96 inateeg                                                *
  8. //*                                                                         *
  9. //***************************************************************************
  10. //***************************************************************************
  11. //* INCLUDE FILES                                                           *
  12. //***************************************************************************
  13. #include <windows.h>
  14. #include <windowsx.h>
  15. #include <olectl.h>
  16. #include <olectlid.h>
  17. #include <initguid.h>
  18. #include "vrsscan.h"
  19. #include "resource.h"
  20. #include "advpub.h"
  21. //***************************************************************************
  22. //* GLOBAL VARIABLES                                                        *
  23. //***************************************************************************
  24. BOOL    g_bRegister;
  25. DWORD   g_dwFlags;
  26. CLSID   g_clsid;
  27. HINSTANCE g_hInst;
  28. #define MAX_STRING      512
  29. #define STR_OLESTR      1
  30. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  31. // internal use as ANSI string only
  32. #define VENDOR_REG      "CLSID\%s\VirusScanner"
  33. #define SCANNER_COOKIE  "Cookie"
  34. // predefined built in INF section name,  ANSI string required
  35. #define SETUP_SECTION1  "InstallOCXs"
  36. #define SETUP_SECTION2  "InstallRegs"
  37. #define SETUP_UNINSTALL "Uninstall"
  38. #define SETUP_TITLE     "Virus Scanner Setup"
  39. // default macfee info
  40. #define MACFEE_CLSID    TEXT("{91B0C1B0-0B71-11d0-8217-00A02474294C}")
  41. #define DEFAULT_ENGINE  TEXT("McAfee")
  42. BOOL Init( HINSTANCE hInstance, LPTSTR lpszCmdLine, INT nCmdShow );
  43. BOOL ParseCmdLine( LPTSTR lpszCmdLine );
  44. LPWSTR MakeWideStrFromAnsi( LPSTR psz, BYTE  bType );
  45. LPSTR MakeAnsiStrFromWide( LPWSTR pwsz,  BYTE  bType );
  46. void SaveRestoreCookie( CLSID clsid, DWORD *pdwCookie, BOOL bSave );
  47. void ErrorMsg( HWND hWnd, UINT idErr );
  48. HRESULT RegInstall( HINSTANCE hInst );
  49. BOOL GetWideString( HINSTANCE hInstance, UINT id, LPWSTR *lplpwsStr );
  50. //***************************************************************************
  51. //*                                                                         *
  52. //* NAME:       WinMain                                                     *
  53. //*                                                                         *
  54. //* SYNOPSIS:   Main entry point for the program.                           *
  55. //*                                                                         *
  56. //* REQUIRES:   hInstance:                                                  *
  57. //*             hPrevInstance:                                              *
  58. //*             lpszCmdLine:                                                *
  59. //*             nCmdShow:                                                   *
  60. //*                                                                         *
  61. //* RETURNS:    int:                                                        *
  62. //*                                                                         *
  63. //***************************************************************************
  64. INT WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
  65.                     LPTSTR lpszCmdLine, INT nCmdShow )
  66. {
  67.     HRESULT hr = E_FAIL;
  68.     IRegisterVirusScanEngine *pIRegVirusScanner = NULL;
  69.     DWORD   dwCookie = 0;
  70.     LPWSTR  lpwsDesc = NULL;
  71.     if ( Init( hInstance, lpszCmdLine, nCmdShow ) )
  72.     {
  73.         if ( !GetWideString( hInstance, IDS_VRSENG_DESC, &lpwsDesc ) )
  74.             return hr;  //bail out
  75.         CoInitialize( NULL );
  76.         hr = CoCreateInstance( CLSID_VirusScan, NULL, CLSCTX_INPROC_SERVER, IID_IRegisterVirusScanEngine, (void**) &pIRegVirusScanner );
  77.         if( SUCCEEDED(hr) )
  78.         {
  79.             if ( g_bRegister )
  80.             {
  81.                 // Do register OCX and add Reg first
  82.                 if ( RegInstall( hInstance ) == S_OK )
  83.                 {
  84.                     hr = pIRegVirusScanner->RegisterScanEngine( g_clsid, lpwsDesc, g_dwFlags, 0, &dwCookie );
  85.                     SaveRestoreCookie( g_clsid, &dwCookie, TRUE );
  86.                 }
  87.             }
  88.             else
  89.             {
  90.                 SaveRestoreCookie( g_clsid, &dwCookie, FALSE );
  91.                 pIRegVirusScanner->UnRegisterScanEngine( g_clsid, lpwsDesc, g_dwFlags, 0, dwCookie );
  92.                 // Do Unregister OCX and del Reg
  93.                 hr = RegInstall( hInstance );
  94.             }
  95.         }
  96.         else
  97.         {
  98.              ErrorMsg( NULL, IDS_ERR_CREATINSTANCE );
  99.         }
  100.         CoUninitialize();
  101.     }
  102.     if ( lpwsDesc )
  103.         CoTaskMemFree( lpwsDesc );
  104.     return hr;
  105. }
  106. //***************************************************************************
  107. //*                                                                         *
  108. //* NAME:       Init                                                        *
  109. //*                                                                         *
  110. //* SYNOPSIS:   Initialization for the program is done here.                *
  111. //*                                                                         *
  112. //* REQUIRES:   hInstance:                                                  *
  113. //*             hPrevInstance:                                              *
  114. //*             lpszCmdLine:                                                *
  115. //*             nCmdShow:                                                   *
  116. //*                                                                         *
  117. //* RETURNS:    BOOL:                                                       *
  118. //*                                                                         *
  119. //***************************************************************************
  120. BOOL Init( HINSTANCE hInstance, LPTSTR lpszCmdLine, INT nCmdShow )
  121. {
  122.     TCHAR  szTmpBuf[MAX_PATH];
  123.     LPWSTR pwszClsid;
  124.     g_hInst = hInstance;
  125.     HRESULT hr;
  126.     g_dwFlags = 0;
  127.     if ( !ParseCmdLine(lpszCmdLine) )
  128.     {
  129.         ErrorMsg( NULL, IDS_ERR_BADCMDLINE );
  130.         return FALSE;
  131.     }
  132.     if ( LoadString( hInstance, IDS_VRSENG_CLSID, szTmpBuf, ARRAYSIZE(szTmpBuf) ) )
  133.     {
  134. #ifdef UNICODE
  135.         pwszClsid = szTmpBuf;
  136. #else
  137.         pwszClsid = MakeWideStrFromAnsi( szTmpBuf, STR_OLESTR );
  138. #endif
  139.         hr = CLSIDFromString( pwszClsid, &g_clsid );
  140. #ifndef UNICODE
  141.         CoTaskMemFree( pwszClsid );
  142. #endif
  143.         if ( FAILED( hr) )
  144.             return FALSE;
  145.     }
  146.     if ( lstrcmpi( szTmpBuf, MACFEE_CLSID ) == 0 )
  147.            g_dwFlags |= SFV_DONTDOUI;
  148.     return TRUE;
  149. }
  150. //***************************************************************************
  151. //*                                                                         *
  152. //*  ParseCmdLine()                                                     *
  153. //*                                                                         *
  154. //*  Purpose:    Parses the command line looking for switches               *
  155. //*                                                                         *
  156. //*  Parameters: LPSTR lpszCmdLineOrg - Original command line               *
  157. //*                                                                         *
  158. //*                                                                         *
  159. //*  Return:     (BOOL) TRUE if successful                                  *
  160. //*                     FALSE if an error occurs                            *
  161. //*                                                                         *
  162. //***************************************************************************
  163. BOOL ParseCmdLine( LPTSTR lpszCmdLine )
  164. {
  165.     LPTSTR pArg;
  166.     LPWSTR ;
  167.     if( (!lpszCmdLine) || (lpszCmdLine[0] == 0) )
  168.        return FALSE;
  169.     pArg = strtok( lpszCmdLine, TEXT(" ") );
  170.     while ( pArg )
  171.     {
  172.        if ( lstrcmpi( pArg, TEXT("/U") ) == 0 )
  173.        {
  174.            g_bRegister = FALSE;
  175.        }
  176.        else if ( lstrcmpi( pArg, TEXT("/R") ) == 0 )
  177.        {
  178.            g_bRegister = TRUE;
  179.        }
  180.        else
  181.        {
  182.            return FALSE;
  183.        }
  184.        pArg = strtok( NULL, TEXT(" ") );
  185.     }
  186.     return TRUE;
  187. }
  188. void SaveRestoreCookie( CLSID clsid, DWORD *pdwCookie, BOOL bSave )
  189. {
  190.     char    szBuf[MAX_PATH];
  191.     LPOLESTR  pwsClsid;
  192.     HKEY    hKey;
  193.     LPSTR   pszClsid;
  194.     DWORD   dwSize;
  195.     StringFromCLSID( clsid, &pwsClsid );
  196.     pszClsid = MakeAnsiStrFromWide( pwsClsid, STR_OLESTR );
  197.     CoTaskMemFree( pwsClsid );
  198.     wsprintf( szBuf, VENDOR_REG, pszClsid );
  199.     if ( RegOpenKeyExA( HKEY_CLASSES_ROOT, szBuf, 0, KEY_ALL_ACCESS, &hKey ) == ERROR_SUCCESS )
  200.     {
  201.         if ( bSave )
  202.         {
  203.             RegSetValueExA( hKey, SCANNER_COOKIE, 0, REG_DWORD, (LPBYTE)pdwCookie, sizeof(DWORD) );
  204.         }
  205.         else
  206.         {
  207.             dwSize = sizeof(DWORD);
  208.             *pdwCookie = 0;
  209.             RegQueryValueExA( hKey, SCANNER_COOKIE, NULL, NULL, (LPBYTE)pdwCookie, &dwSize );
  210.         }
  211.         RegCloseKey( hKey );
  212.     }
  213.     CoTaskMemFree( pszClsid );
  214. }
  215. //******************************************************************************
  216. //*  CreateInfFile - Create an INF file from an hmodule
  217. //*
  218. //*  ENTRY
  219. //*      hInst - hmodule that contains the REGINST resource
  220. //*      pszInfFileName - OUT the location to get the INF filename
  221. //*      pszDir - OUT dir directory the INF file
  222. //*
  223. //*  EXIT
  224. //*      HRESULT
  225. //******************************************************************************
  226. HRESULT CreateInfFile( HINSTANCE hInst, LPTSTR pszInfFileName, LPTSTR pszDir )
  227. {
  228.     HRESULT hr = E_FAIL;
  229.     TCHAR szInfFilePath[MAX_PATH];
  230.     LPVOID pvInfData;
  231.     HRSRC hrsrcInfData;
  232.     DWORD cbInfData, cbWritten;
  233.     HANDLE hfileInf = INVALID_HANDLE_VALUE;
  234.     if ( GetTempPath(ARRAYSIZE(szInfFilePath), szInfFilePath) > ARRAYSIZE(szInfFilePath))
  235.     {
  236.         goto Cleanup;
  237.     }
  238.     lstrcpy( pszDir, szInfFilePath );
  239.     if (GetTempFileName(szInfFilePath, TEXT("RGI"), 0, pszInfFileName) == 0)
  240.     {
  241.         goto Cleanup;
  242.     }
  243.     hrsrcInfData = FindResource(hInst, TEXT("REGINST"), TEXT("REGINST"));
  244.     if (hrsrcInfData == NULL)
  245.     {
  246.         goto Cleanup;
  247.     }
  248.     cbInfData = SizeofResource(hInst, hrsrcInfData);
  249.     pvInfData = LockResource(LoadResource(hInst, hrsrcInfData));
  250.     if (pvInfData == NULL)
  251.     {
  252.         goto Cleanup;
  253.     }
  254.     hfileInf = CreateFile(pszInfFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
  255.                           FILE_ATTRIBUTE_NORMAL, NULL);
  256.     if (hfileInf == INVALID_HANDLE_VALUE)
  257.     {
  258.         goto Cleanup;
  259.     }
  260.     if ((WriteFile(hfileInf, pvInfData, cbInfData, &cbWritten, NULL) == FALSE) ||
  261.         (cbWritten != cbInfData))
  262.     {
  263.         goto Cleanup;
  264.     }
  265.     hr = S_OK;
  266. Cleanup:
  267.     if (hfileInf != INVALID_HANDLE_VALUE)
  268.     {
  269.         CloseHandle(hfileInf);
  270.     }
  271.     return hr;
  272. }
  273. //********************************************************************************
  274. //*  RegInstall - Install a registry INF
  275. //*
  276. //*
  277. //********************************************************************************
  278. HRESULT RegInstall( HINSTANCE hInst )
  279. {
  280.     HRESULT hr = E_FAIL;
  281.     TCHAR szInfFileName[MAX_PATH];
  282.     HINSTANCE hLib;
  283.     TCHAR szPath[MAX_PATH];
  284.     LPTSTR lpTmp;
  285.     LPSTR  lpInfFile = NULL, lpDir = NULL;
  286.     RUNSETUPCOMMAND pfRunSetupCommand;
  287.     //
  288.     // Load advpack.dll.
  289.     //
  290.     szPath[0] = 0;
  291.     GetSystemDirectory( szPath, ARRAYSIZE(szPath) );
  292.     lpTmp = CharPrev(szPath, szPath+lstrlen(szPath) );
  293.     if ( (lpTmp > szPath) && (*lpTmp != TEXT('\') ) )
  294.     {
  295.        lstrcat( szPath, TEXT("\") );
  296.     }
  297.     lstrcat( szPath, TEXT("advpack.dll") );
  298.     hLib = LoadLibrary( szPath );
  299.     if ( !hLib )
  300.     {
  301.        ErrorMsg( NULL, IDS_ERR_LOADADV );
  302.        hr = S_FALSE;
  303.        goto Cleanup;
  304.     }
  305.     pfRunSetupCommand = (RUNSETUPCOMMAND)GetProcAddress( hLib, TEXT("RunSetupCommand") );
  306.     if ( !pfRunSetupCommand )
  307.     {
  308.        ErrorMsg( NULL, IDS_ERR_GETPROCADD );
  309.        hr = S_FALSE;
  310.        goto Cleanup;
  311.     }
  312.     //
  313.     // Create the INF file.
  314.     //
  315.     szInfFileName[0] = TEXT('');
  316.     szPath[0] = TEXT('');
  317.     hr = CreateInfFile(hInst, szInfFileName, szPath );
  318.     if (FAILED(hr))
  319.     {
  320.         goto Cleanup;
  321.     }
  322. #ifdef UNICODE
  323.     lpInfFile = MakeAnsiStrFromWide( szInfFileName, STR_OLESTR );
  324.     lpDir =  MakeAnsiStrFromWide( szPath, STR_OLESTR );
  325. #else
  326.     lpInfFile = szInfFileName;
  327.     lpDir = szPath;
  328. #endif
  329.     //
  330.     // Execute the INF engine on the INF.
  331.     //
  332.     if ( g_bRegister )
  333.     {
  334.         hr = pfRunSetupCommand( NULL, lpInfFile, SETUP_SECTION1, lpDir,
  335.                                 SETUP_TITLE, NULL,
  336.                                 RSC_FLAG_INF|RSC_FLAG_QUIET|RSC_FLAG_NGCONV, NULL);
  337.         if (FAILED(hr))
  338.         {
  339.             goto Cleanup;
  340.         }
  341.         hr = pfRunSetupCommand( NULL, lpInfFile, SETUP_SECTION2, lpDir,
  342.                                 SETUP_TITLE, NULL,
  343.                                 RSC_FLAG_INF|RSC_FLAG_QUIET|RSC_FLAG_NGCONV, NULL);
  344.     }
  345.     else
  346.         hr = pfRunSetupCommand( NULL, lpInfFile, SETUP_UNINSTALL, lpDir,
  347.                                 SETUP_TITLE, NULL,
  348.                                 RSC_FLAG_INF|RSC_FLAG_QUIET|RSC_FLAG_NGCONV, NULL);
  349.     if (FAILED(hr))
  350.     {
  351.         goto Cleanup;
  352.     }
  353. Cleanup:
  354.     //
  355.     // Delete the INF file, Free library.
  356.     //
  357.     if ( hLib )
  358.         FreeLibrary( hLib );
  359.     if (szInfFileName[0] )
  360.     {
  361.         DeleteFile(szInfFileName);
  362.     }
  363. #ifdef UNICODE
  364.     if ( lpInfFile )
  365.     {
  366.         CoTaskMemFree( lpInfFile );     
  367.     }
  368.     if ( lpDir )
  369.     {
  370.         CoTaskMemFree( lpDir );     
  371.     }
  372. #endif
  373.     return hr;
  374. }
  375. BOOL GetWideString( HINSTANCE hInstance, UINT id, LPWSTR *lplpwsStr )
  376. {
  377.     LPTSTR lpStr;
  378.     
  379.     lpStr = (LPTSTR)CoTaskMemAlloc( MAX_STRING );
  380.     if ( !lpStr )
  381.         return FALSE;
  382.     if ( LoadString( hInstance, id, lpStr, MAX_STRING/sizeof(TCHAR) ) )
  383.     {
  384. #ifdef UNICODE
  385.         *lplpwsStr = lpStr;
  386. #else
  387.         *lplpwsStr = MakeWideStrFromAnsi( lpStr, STR_OLESTR );
  388. #endif
  389. #ifndef UNICODE
  390.         CoTaskMemFree( lpStr );
  391. #endif
  392.         if ( *lplpwsStr == 0 )
  393.             return FALSE;
  394.     }
  395.     return TRUE;
  396. }
  397. //=--------------------------------------------------------------------------=
  398. // given a string, make a BSTR out of it.
  399. //
  400. // Parameters:
  401. //    LPSTR         - [in]
  402. //    BYTE          - [in]
  403. //
  404. // Output:
  405. //    LPWSTR        - needs to be cast to final desired result
  406. //
  407. // Notes:
  408. //
  409. LPWSTR MakeWideStrFromAnsi( LPSTR psz, BYTE  bType )
  410. {
  411.     LPWSTR pwsz;
  412.     int i;
  413.     // arg checking.
  414.     //
  415.     if (!psz)
  416.         return NULL;
  417.     // compute the length of the required BSTR
  418.     //
  419.     i =  MultiByteToWideChar(CP_ACP, 0, psz, -1, NULL, 0);
  420.     if (i <= 0) return NULL;
  421.     // allocate the widestr, +1 for terminating null
  422.     //
  423.     switch (bType) {
  424.     case STR_OLESTR:
  425.         pwsz = (LPWSTR) CoTaskMemAlloc(i * sizeof(WCHAR));
  426.         break;
  427.     default:
  428.         return(NULL);
  429.     }
  430.     if (!pwsz) return NULL;
  431.     MultiByteToWideChar(CP_ACP, 0, psz, -1, pwsz, i);
  432.     pwsz[i - 1] = 0;
  433.     return pwsz;
  434. }
  435. LPSTR MakeAnsiStrFromWide( LPWSTR pwsz,  BYTE  bType )
  436. {
  437.     LPSTR psz;
  438.     int i;
  439.     // arg checking.
  440.     //
  441.     if (!pwsz)
  442.         return NULL;
  443.     // compute the length of the required BSTR
  444.     //
  445.     i =  WideCharToMultiByte(CP_ACP, 0, pwsz, -1, NULL, 0, NULL, NULL);
  446.     if (i <= 0) return NULL;
  447.     // allocate the ansistr, +1 for terminating null
  448.     //
  449.     switch (bType) {
  450.     case STR_OLESTR:
  451.         psz = (LPSTR) CoTaskMemAlloc(i * sizeof(CHAR));
  452.         break;
  453.     default:
  454.         return(NULL);
  455.     }
  456.     if (!psz) return NULL;
  457.     WideCharToMultiByte(CP_ACP, 0, pwsz, -1, psz, i, NULL, NULL);
  458.     psz[i - 1] = 0;
  459.     return psz;
  460. }
  461. void ErrorMsg( HWND hWnd, UINT idErr )
  462. {
  463.     TCHAR szBuf[MAX_STRING];
  464.     if ( !LoadString( g_hInst, idErr, szBuf, ARRAYSIZE(szBuf) ) )
  465.     {
  466.         wsprintf( szBuf, TEXT("LoadString failed on error id: %d"), idErr );
  467.     }
  468.     MessageBox( hWnd, szBuf, TEXT(SETUP_TITLE), MB_ICONSTOP|MB_OK );
  469. }