--[[ 
============================================================================================================
Script to place the driver in a location that the OS will automatically find it (the driver store) and not show the user
the hardware wizard.  

** NOTE ** This script relies on the files being installed on disk by the Copy_Driver_Files.lua script.

GLOBAL VARIABLES USED IN THIS SCRIPT
  > UseDCGCert. Set in the Project Actions script at install startup.  Indicates that driver is signed with Datacard's certificate.

GLOBAL VARIABLES SET BY THIS SCRIPT
  > bContinueInstall is a flag used to let the calling app know if the action succeeded of failed.
  > bRestartRequired is a flag used to let the calling app know a restart will be required to complete the driver installation.
  
NOTES
 1. If the driver is signed using the Datacard Verisign certificate we cannot do a silent install.
	
 3. See USB staging script for notes about what dpinst return value means.
============================================================================================================
]]--

fDebug("[Script Start]: Stage_Driver");
bRestartRequired = false;
local strInstalledPrinterName = "XPS Card Printer"; -- Do Not Change!
local pathCommonAppDataFolder = Shell.GetFolder(SHF_APPLICATIONDATA_COMMON);
local pathDpinstExeFolder = pathCommonAppDataFolder.."\\Datacard\\XPS Card Printer";

local dpinstExe = ""; 
if (System.Is64BitOS()) then
	dpinstExe = pathDpinstExeFolder.."\\dpinst64.exe";
else
	dpinstExe = pathDpinstExeFolder.."\\dpinst32.exe";
end

local dpinstQuietParam = "";
if (UseDCGCert) then
	fDebug("  INFO: Datacard signed. Staging will ask user to trust our install.");
	dpinstQuietParam = "";
else
	dpinstQuietParam = " /q /sw /f";
end	
local dpinstParams = dpinstQuietParam.." /sa";


--[[
=============================================================
Stage the printer driver. 
Required for ALL printers, network and USB.
=============================================================
]]--
local nmbrDriversStaged = -1;
local bDriverStaged = false;
fDebug("  INFO: Calling "..dpinstExe.." with parameters: "..dpinstParams.." using files from: "..pathDpinstExeFolder.."\\network");
local nStagingStatus = File.Run(dpinstExe, dpinstParams.." /path network", pathDpinstExeFolder, SW_SHOWNORMAL, true);
--Decode the dpinst return value	
local dpinstRtnAsHexCode = string.format("%X", nStagingStatus);
fDebug("  INFO: Dpinst return code: "..dpinstRtnAsHexCode);

-- look at the four right most digits to determine if the driver was installed or staged
local strNmbrDriversStagedOrInstalled = String.Right(dpinstRtnAsHexCode, 4);
nmbrDriversStaged = String.ToNumber(strNmbrDriversStagedOrInstalled);

-- look at the two left most digits to determine of the staging failed or if is succeeded but a restart is required.
local strStagingFlag = String.Left(dpinstRtnAsHexCode,2);
local nmbrStagingFlag = String.ToNumber(strStagingFlag);

-- use decoded return value to decide if driver has been staged successfully.
if (nmbrStagingFlag == 80) then
	bDriverStaged = false;
	fDebug("  INFO: Dpinst returned staging failed flag. Will try rundll32 next.");
else
	if ((nmbrDriversStaged == 0) or (nmbrDriversStaged == 1) or (nmbrDriversStaged == 100)) then -- one driver staged or installed.
		bDriverStaged = true;
		fDebug("  INFO: Dpinst returned that driver was staged.");
		-- set the restart flag.
		if (nmbrStagingFlag == 40) then
			bRestartRequired = true;
			fDebug("  INFO: Network dpinst returned restart needed flag.");
		end
	else
		bDriverStaged = false;
		fDebug("  INFO: Driver could not be staged by dpinst.  Will try rundll32 next.");
	end	
end	
		
if (not bDriverStaged) then 
	fDebug("  INFO: Using rundll32 to stage the driver...");
	-- The driver is not staged.  Try a secondary means to stage the driver. 
	-- NOTE: This will never return an error if rundll32 fails so we won't know if the driver has been staged.
	local nRtnCode = Shell.Execute(_SystemFolder.."\\rundll32.exe", "open", _SystemFolder.."\\printui.dll,PrintUIEntry /ia /m\""..strInstalledPrinterName.."\" /f\""..pathDpinstExeFolder.."\\network\\dxp01drv.inf\"", "", SW_SHOWNORMAL, true);
	local nLastError = Application.GetLastError();
	fDebug("  INFO: rundll32 of printui dll return code: "..nRtnCode.."  GetLastError value is: "..nLastError);	
	if (nLastError ~= 0) then
		bContinueInstall = false;
		fDebug("  ERROR: Driver not staged. Call to PrintUIEntry of printui dll failed with error: "..LastError..": ".._tblErrorMessages[LastError].."\r\n");
	else
		bRestartRequired = true; -- rundll32 doesn't tell us anything so restart to be safe.
	end
end
		
fDebug("[Script Exit]: Stage_Driver \r\n");	