 //           Include Ifx.h for built-in InstallScript function prototypes, for Windows 
// Installer API function prototypes and constants, and to declare code for 
// the OnBegin and OnEnd events.
#include "ifx.h"
#include "Decl.h" 
    // The keyword export identifies MyFunction() as an entry-point function.
    // The argument it accepts must be a handle to the Installer database.
    
export prototype ResChangeDriver(HWND);
export prototype SetW2K (HWND);
export prototype Init  (HWND);  
export prototype DriverNeedReboot  (HWND);        
export prototype RemoveOldInstallerFromAddRemove(HWND);  
export prototype ChangeDisplayName( HWND);   
export prototype StopVdservice(HWND) ; 
export prototype StartVdservice(HWND) ;
export prototype SetPlatformProperty(HWND) ;
//-------------------------------------------------------     
export prototype RestoreOemFile(HWND);
export prototype BackupOemFile(HWND);
export prototype CopyOemFile(HWND);
prototype string SearchOemFile(string);
                
function ResChangeDriver(hMSI)   

	number ret,nBuffer;
	string szProgram,val,szCmdLine;
begin  
  #define SM_REMOTESESSION 0x1000  
  if ( GetSystemMetrics( SM_REMOTESESSION )) then
      //MessageBox("remote",1);
      SprintfMsiLog ( "ResChangeDriver() : this is remote session(RDP) reschange.exe will not run " ); 
      return 0;  
  else 
     SprintfMsiLog ( "ResChangeDriver() : this is NOT remote session(RDP) reschange.exe WILL RUN " );     
  endif;   
	nBuffer = 256;    
	
	MsiGetProperty(hMSI,"CustomActionData",val,nBuffer); 
	

	szProgram  = val ^ "reschange.exe";                                   
	                                 
	MsiGetProperty(hMSI,"IS_MAJOR_UPGRADE",val,nBuffer);   
	
	if (val = "Yes") then
	  return 0;
	endif;  
	                                 
	szCmdLine = "-install \" -devid=PCI\\VEN_1b36&DEV_0100\""; //WXP
	//  szCmdLine = "-install \" -devid=PCI\\VEN_1AF4\""; //W2K
	
	ret =  LaunchAppAndWait (szProgram,szCmdLine, LAAW_OPTION_WAIT |LAAW_OPTION_HIDDEN );
	SprintfMsiLog ( "%d =  LaunchAppAndWait (%s,%s, LAAW_OPTION_WAIT |LAAW_OPTION_HIDDEN );",ret,szProgram,szCmdLine );     
end; 
  
 
function SetW2K(hMSI)
      BOOL   gbIsOSWin2000 ;
begin 
	if (SYSINFO.nISOSL = ISOSL_WIN2000) then
	    gbIsOSWin2000 = TRUE;  
	    MsiSetProperty( ISMSI_HANDLE, "W2K", "1" );           
	  
	else 
	    MsiSetProperty( ISMSI_HANDLE, "W2K", "0" ); 
	  
	endif;
      
end;

function CopyOemFile(hMSI)
begin
	if(!Is(FILE_EXISTS,WINDIR^"inf\\oem1.inf") && Is(FILE_EXISTS,WINDIR^"inf\\oem1.pnf")) then
		CopyFile(INSTALLDIR^"qxl"^"qxl.inf",WINDIR^"inf\\oem1.inf");
	endif;
	if(!Is(FILE_EXISTS,WINDIR^"inf\\oem2.inf") && Is(FILE_EXISTS,WINDIR^"inf\\oem2.pnf")) then
		CopyFile(INSTALLDIR^"qxl"^"qxl.inf",WINDIR^"inf\\oem2.inf");
	endif;
	if(!Is(FILE_EXISTS,WINDIR^"inf\\oem3.inf") && Is(FILE_EXISTS,WINDIR^"inf\\oem3.pnf")) then
		CopyFile(INSTALLDIR^"qxl"^"qxl.inf",WINDIR^"inf\\oem3.inf");
	endif;
end;     

function RestoreOemFile(hMSI)
    string szStringB,svFileSpec,svDir,svMatchingFileName; 
    string svString,svReturnString,svReturnLine,svLine,svSubStr; 
    LIST listID;
    NUMBER ret , nvLineNumber, nResult,nvFileHandle,nNumFiles,nLength;    
    NUMBER nBuffer;
begin             
     SprintfMsiLog ( "RestoreOemFile() : start" ); 
     nBuffer = 256;
      
     svSubStr = SearchOemFile(WINDIR^"inf");
     if(svSubStr = "") then 
     	MsiGetProperty(hMSI, "FILENAME", svSubStr, nBuffer);
     	if(svSubStr != "0") then
          	CopyFile(INSTALLDIR^"qxl"^"qxl.inf",WINDIR^"inf"^svSubStr+".inf");
          	SprintfMsiLog ( "ISCRIPT RestoreOemFile() : CopyFile(%s,%s)", INSTALLDIR^"qxl"^"qxl.inf",WINDIR^"inf"^svSubStr+".inf");
        else
            SprintfMsiLog ( "ISCRIPT RestoreOemFile() : INF file name not found in store." );
        endif;
	 endif;
	 
    SprintfMsiLog ( "ISCRIPT RestoreOemFile() : End"); 
end;

function string SearchOemFile(svDir)
    string szStringB,svFileSpec,svMatchingFileName; 
    string svString,svReturnString,svReturnLine,svLine,svSubStr; 
    LIST listID;
    NUMBER ret , nvLineNumber, nResult,nvFileHandle,nNumFiles,nLength;    
    NUMBER nBuffer;
begin             
     szStringB="Installation inf for qxl driver";
     svFileSpec ="oem*.inf" ;
     
     // To Do:  Write script that will be executed when MyFunction is called.
	 nResult = FindAllFiles (svDir, svFileSpec, svMatchingFileName, RESET);
	 SprintfMsiLog ( "ISCRIPT %d = FindAllFiles (%s, %s, %s, RESET);",nResult,svDir, svFileSpec, svMatchingFileName ); 
	 OpenFileMode (FILE_MODE_NORMAL); 
	 while(nResult = 0)     
			 SprintfMsiLog ( "ISCRIPT loop to find all files while(%d = 0)",nResult ); 
		     ret = FileGrep ( svMatchingFileName, szStringB, svReturnLine, nvLineNumber, RESTART ); 
		
		     if (ret = 0) then
		        ParsePath ( svReturnString, svMatchingFileName, FILENAME_ONLY );
		        SprintfMsiLog ( "ISCRIPT ParsePath (%s,%s);", svReturnString, svMatchingFileName );
                return svReturnString;
	         endif;
		      nResult = FindAllFiles(svDir, svFileSpec, svMatchingFileName, CONTINUE); 
		      SprintfMsiLog ( "ISCRIPT %d = FindAllFiles (%s, %s, %s, CONTINUE);",nResult,svDir, svFileSpec, svMatchingFileName ); 
    endwhile;
    
    return "";
end;

function BackupOemFile(hMSI)   
    // To Do:  Declare local variables.  .
    string szStringB,svFileSpec,svDir,svMatchingFileName; 
    string svString,svReturnString,svReturnLine,svLine,svSubStr; 
    LIST listID;
    NUMBER ret , nvLineNumber, nResult,nvFileHandle,nNumFiles,nLength;    
    NUMBER nBuffer;
begin             
     //WriteToLogFile("FindOemFile() : start"  ,0,1);
     SprintfMsiLog ( "ISCRIPT FindOemFile() : start" ); 
     
     svSubStr = SearchOemFile(WINDIR^"inf");
     if(svSubStr != "") then 
     	MsiSetProperty(hMSI, "FILENAME", svSubStr);
	 endif;
     
     SprintfMsiLog ( "ISCRIPT FindOemFile() : End"); 
end; 

    
    
    
 function Init(hMSI)    
		  number  nvFileHandle;  
		  string  LogFileName; 
		  number ret;
  begin    
         FuncName =  "Init()"; 
       
		     LogFileName =   LOG_FILE_NAME;  
		     LOG_FILE_GLOBAL_VAR = FOLDER_TEMP^LogFileName;  
		     ret = OpenFileMode (FILE_MODE_APPEND);
		     ret = CreateFile ( nvFileHandle, FOLDER_TEMP, LogFileName); 
		     CloseFile( nvFileHandle);  
		     LOG_FILE_LINE_NUMBER_GLOBAL_VAR = 0;
	    
  end;
    
function WriteToLogFile(LogFileLine,returnValue,Trans)   
   string sSucsess;
  begin                  
  		 switch (Trans)
             case 1:  sSucsess =  FormatMessage ( returnValue );
             case 2:  sSucsess = "Information"; 
             case 3:  sSucsess =  "dialog"; 
             case 4:  if (returnValue) then
                        sSucsess = "TRUE";
                      else
                        sSucsess = "FALSE";  
                      endif;
         endswitch ;
      
	     FileInsertLine (LOG_FILE_GLOBAL_VAR, LogFileLine + " Status: " + sSucsess, LOG_FILE_LINE_NUMBER_GLOBAL_VAR, AFTER);  
	     LOG_FILE_LINE_NUMBER_GLOBAL_VAR++;  
	  
  end;    
  
   function DriverNeedReboot(hMSI)   
   NUMBER  ret ,nBuffer ;
    string szKey ,DoINeedReboot;
  
  begin 

  		nBuffer = 256;
  		
 		RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE ) ;          
  		szKey  = "SOFTWARE\\Redhat";

      //  MsiGetProperty (ISMSI_HANDLE, "ISSCHEDULEREBOOT", DoINeedReboot, nBuffer);
    
      //  if !(DoINeedReboot = "") then
        
        	ret = RegDBSetKeyValueEx (szKey , "DriverNeedToReboot", REGDB_STRING, "1", -1 ); 
            
	//    endif;
	    
  
  end;
 
  
  
function RemoveOldInstallerFromAddRemove(hMSI)   
    // To Do:  Declare local variables.
    string OldKey,ProductKey;  
    
begin             

    // To Do:  Write script that will be executed when MyFunction is called. 
   ProductKey = "Installer\\Products";
   OldKey = "9BDEA0108918EF847777000000104814"; 
   RegDBSetDefaultRoot ( HKEY_CLASSES_ROOT ) ;  
   RegDBDeleteKey ( ProductKey ^ OldKey); 
   
end;   

function ChangeDisplayName( hMSI)
   string sKey,sVersionBuild,sVersionMajor,sVersionMinor,Product_name,Product_key,Product_ver,New_Display_name; 
   number  ret, nLength,nvVersionResult,nvVersionMajor, nvVersionMinor, nvVersionBuild;
begin
   
    nLength = MAX_PATH + 1; 

    MsiGetProperty(hMSI, "ProductCode", Product_key, nLength); 

    
    // reset buffer-size variable 

    nLength = MAX_PATH + 1; 

    MsiGetProperty(hMSI, "DISPAYED_VERSION", Product_ver, nLength); 

    if (Product_ver = "0") then
          MsiGetProperty(hMSI, "ProductVersion", Product_ver, nLength); 
    endif; 
    
    nLength = MAX_PATH + 1; 

   MsiGetProperty(hMSI, "ProductName", Product_name, nLength); 
  
   VerProductStrToNum ( nvVersionResult, Product_ver ); 
   VerProductVerPartsFromVer ( nvVersionResult,nvVersionMajor, nvVersionMinor, nvVersionBuild);
   // gVersionMajor, gVersionMinor, gVersionBuild ); 
   NumToStr ( sVersionMajor, nvVersionMajor ); 
   NumToStr ( sVersionMinor, nvVersionMinor );
   NumToStr ( sVersionBuild, nvVersionBuild );   
   
   New_Display_name = Product_name + " " + sVersionMajor + "." +  sVersionMinor + "." + sVersionBuild;
   RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE ); 
   sKey = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall" ^  Product_key;
   if ( RegDBKeyExist( sKey ) = 1)  then
   		ret = RegDBSetKeyValueEx(sKey, "DisplayName",REGDB_STRING , New_Display_name, -1 ); 
   		RegisterTool(Product_name,Product_ver,Product_key);
   endif;	 
end;  

function StopVdservice(hMSI)   
  string szProgram,szCmdLine;    
  number ret;
begin    
        szProgram = "NET.exe";
        szCmdLine = "stop "+DRIVER_SERVICE_NAME;
    	ret =  LaunchAppAndWait (szProgram,szCmdLine, LAAW_OPTION_WAIT |LAAW_OPTION_HIDDEN );

end;   

function RegisterTool(Product_name,Product_ver,Product_key)
   string  MsgLog,szKey, szName,szValue; 
   number ret,nType,nSize;
begin
  RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE ) ; 
  
  szKey = "SOFTWARE\\RedHat\\RHEV\\Tools\\" + Product_name; 
  szName = "Version" ;
  szValue = Product_ver;       
  nSize = -1;
  nType = REGDB_STRING;
  ret = RegDBSetKeyValueEx ( szKey, szName, nType, szValue, nSize ); 
 SprintfMsiLog("ISCRIPT %d = RegDBSetKeyValueEx ( %s, %s, %d, %s, %d ); ",ret,szKey, szName, nType, szValue, nSize);
   
   
  szKey = "SOFTWARE\\RedHat\\RHEV\\Tools\\" + Product_name; 
  szName = "Key" ;
  szValue = Product_key;       
  nSize = -1;
  nType = REGDB_STRING;
  ret = RegDBSetKeyValueEx ( szKey, szName, nType, szValue, nSize ); 
 SprintfMsiLog("ISCRIPT %d = RegDBSetKeyValueEx ( %s, %s, %d, %s, %d ); ",ret,szKey, szName, nType, szValue, nSize);

end;     
export prototype UnregisterTool (HWND) ;  
function UnregisterTool (hMSI)
   number  ret, nLength;   
   string szKey,Product_name;
begin    
      nLength = MAX_PATH + 1;
      MsiGetProperty(hMSI, "ProductName", Product_name, nLength); 
      RegDBSetDefaultRoot ( HKEY_LOCAL_MACHINE ) ; 
      szKey = "SOFTWARE\\RedHat\\RHEV\\Tools\\" + Product_name;    
      ret = RegDBDeleteKey ( szKey) ;  
      SprintfMsiLog("ISCRIPT %d = RegDBDeleteKey ( %s ); ",ret,szKey);

end;  

function StartVdservice(hMSI)   
	string szProgram,szCmdLine;    
	number ret;
begin    
	ret = LaunchAppAndWait("sc.exe","config " + DRIVER_SERVICE_NAME+ "  start= auto depend= VirtioSerial" ,  LAAW_OPTION_HIDDEN |LAAW_OPTION_WAIT);	    
	SprintfMsiLog("ret = LaunchAppAndWait   (sc.exe,config   %s  start= auto depend= VirtioSerial ,  LAAW_OPTION_HIDDEN |LAAW_OPTION_WAIT);",DRIVER_SERVICE_NAME);
        
        szProgram = "NET.exe";
        szCmdLine = "start "+DRIVER_SERVICE_NAME;
    	ret =  LaunchAppAndWait (szProgram,szCmdLine, LAAW_OPTION_WAIT |LAAW_OPTION_HIDDEN );

end;   
 

function SetPlatformProperty(hMSI)   
    // To Do:  Declare local variables.
    string szMsg,val,MYOS;       
    number nBuffer;
    
begin    
   SprintfMsiLog ( "ISCRIPT SetPlatformProperty" ); 

   MYOS = "";
   nBuffer = 256; 
   MsiGetProperty(hMSI,"VersionNT",val,nBuffer); 
/*
   if (val  = "501" ) then   
       SprintfMsiLog ( "ISCRIPT Platform is XP os id %s",val ); 
       MYOS = "XP";
   endif;    
   if (val  = "502" ) then 
       SprintfMsiLog ( "ISCRIPT Platform is 2003 os id %s",val ); 
       MYOS = "2003";
   endif; 
   
   if (val  = "600" ) then 
       SprintfMsiLog ( "ISCRIPT Platform is 2008 os id %s",val ); 
       MYOS = "2008";
   endif; 
*/
   
   if (val  = "601" ) then    
      SprintfMsiLog ( "ISCRIPT Platform is W7/2008R2 os id %s" ,val );
      MsiGetProperty(hMSI,"MsiNTProductType",val,nBuffer);  
      SprintfMsiLog ( "ISCRIPT Platform is W7/2008R2 MsiNTProductType %s" ,val );  
      // MessageBox(val,1);
      if  ( val = "1") then 
        SprintfMsiLog ( "ISCRIPT Platform is W7 " );
       	MYOS = "W7";
      else  
         SprintfMsiLog ( "ISCRIPT Platform is 2008R2 " );
        MYOS = "";
      endif;   	
   endif;
   
/*
   if (val = "602") then
   		SprintfMsiLog ( "Platform is W8/2012 os id %s" ,val );
   		MYOS = "2012";
   endif;
*/
   
   if (MYOS = "") then
		SprintfMsiLog ( "Unable to detect supported OS. Terminating.");
		abort;
   endif;
   
 //  MessageBox(MYOS,1);    
     MsiSetProperty(hMSI,"MYOS",MYOS);          
     SprintfMsiLog ( "ISCRIPT End SetPlatformProperty  MYOS = %s ",MYOS ); 
     
end;  

  



