' ########################################################################################
' Microsoft Windows
' File: advpub.inc
' Contents: Interfaces implemented by advpack.dll.
' Copyright (c) 2011 Jos? Roca
' Portions Copyright (c) Microsoft Corporation.
' All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#IF NOT %DEF(PBX_advpub_PBI)
#DEFINE PBX_advpub_PBI
%EQUATE `ADVPUB_INC = 1
#INCLUDE ONCE "Core/Windows.inc"
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: RunSetupCommand
'//
'// SYNOPSIS: Execute an install section in an INF file, or execute a
'// program. Advanced INF files are supported.
'//
'// RETURN CODES:
'//
'// S_OK Everything OK, no reboot needed.
'// No EXE to wait for.
'// S_ASYNCHRONOUS Please wait on phEXE.
'// ERROR_SUCCESS_REBOOT_REQUIRED Reboot required.
'// E_INVALIDARG NULL specified in szCmdName or szDir
'// HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION) INF's not supported on this OS version
'// E_UNEXPECTED Catastrophic failure(should never happen).
'// HRESULT_FROM_WIN32(GetLastError()) Anything else
'/////////////////////////////////////////////////////////////////////////////
'#ifndef S_ASYNCHRONOUS
'#define S_ASYNCHRONOUS _HRESULT_TYPEDEF_(0x401e8L)
'#endif
#IF NOT %DEF(%S_ASYNCHRONOUS)
%EQUATE `S_ASYNCHRONOUS = &H401E8&
#ENDIF
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as RunSetupCommand.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION RunSetupCommandA LIB "advpack.dll" ALIAS "RunSetupCommandA" ( BYVAL hWnd AS QUAD , BYREF szCmdName AS ASCIIZ , BYREF szInfSection AS ASCIIZ , BYREF szDir AS STRINGZ , BYREF lpszTitle AS ASCIIZ , BYREF phEXE AS QUAD , BYVAL dwFlags AS QUAD , BYVAL pvReserved AS QUAD ) AS LONG
DECLARE FUNCTION RunSetupCommandW LIB "advpack.dll" ALIAS "RunSetupCommandW" ( BYVAL hWnd AS QUAD
 , BYREF szCmdName AS WSTRINGZ
 , BYREF szInfSection AS WSTRINGZ
 , BYREF szDir AS WSTRINGZ
 , BYREF lpszTitle AS WSTRINGZ
 , BYREF phEXE AS DWORD
 , BYVAL dwFlags AS DWORD
 , BYVAL pvReserved AS DWORD
 ) AS LONG
'#endif // (_WIN32_IE >= 0x0605)
#IF %DEF(%UNICODE)
MACRO RunSetupCommand = RunSetupCommandW
#ELSE
MACRO RunSetupCommand = RunSetupCommandA
#ENDIF
'// FLAGS:
%EQUATE `RSC_FLAG_INF = 1 ' // exxcute INF install
%EQUATE `RSC_FLAG_SKIPDISKSPACECHECK = 2 ' // Currently does nothing
%EQUATE `RSC_FLAG_QUIET = 4 ' // quiet mode, no UI
%EQUATE `RSC_FLAG_NGCONV = 8 ' // don't run groupConv
%EQUATE `RSC_FLAG_UPDHLPDLLS = 16 ' // force to self-updating on user's system
%EQUATE `RSC_FLAG_DELAYREGISTEROCX = 512 ' // force delay of ocx registration
%EQUATE `RSC_FLAG_SETUPAPI = 1024 ' // use setupapi.dll
'// please not adding flag after this. See LaunchINFSectionEx() flags.
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: NeedRebootInit
'//
'// SYNOPSIS: Initializes state for reboot checking. Call this function
'// before calling RunSetupCommand.
'// RETURNS: value required to be passed to NeedReboot()
'/////////////////////////////////////////////////////////////////////////////
DECLARE FUNCTION NeedRebootInit LIB "advpack.dll" ALIAS "NeedRebootInit" ( ) AS QUAD
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: NeedReboot
'//
'// SYNOPSIS: Compares stored state with current state to determine if a
'// reboot is required.
'// dwRebootCheck the return value from NeedRebootInit
'//
'// RETURNS:
'// TRUE if a reboot is required;
'// FALSE otherwise.
'/////////////////////////////////////////////////////////////////////////////
DECLARE FUNCTION NeedReboot LIB "advpack.dll" ALIAS "NeedReboot" ( BYVAL dwRebootCheck AS QUAD ) AS LONG
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: RebootCheckOnInstall
'//
'// SYNOPSIS: Check reboot condition if the given INF section is installed.
'// hwnd windows handle
'// pszINF INF filename with fully qualified path
'// pszSec INF section. NULL is translated as DefaultInstall or DefaultInstall.NT.
'// dwReserved Not used.
'// RETURN:
'// S_OK Reboot needed if INF section is installed.
'// S_FALSE Reboot is not needed if INF section is installed.
'// HRESULT of Win 32 errors
'//
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as RebootCheckOnInstall.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION RebootCheckOnInstallA LIB "advpack.dll" ALIAS "RebootCheckOnInstallA" ( BYVAL hwnd AS QUAD , BYREF pszINF AS ASCIIZ , BYREF pszSec AS ASCIIZ , BYVAL dwReserved AS QUAD ) AS LONG
DECLARE FUNCTION RebootCheckOnInstallW LIB "advpack.dll" ALIAS "RebootCheckOnInstallW" ( BYVAL hwnd AS QUAD
 , BYREF pszINF AS WSTRINGZ
 , BYREF pszSec AS WSTRINGZ
 , BYVAL dwReserved As DWORD
 ) AS LONG
'#endif // (_WIN32_IE >= 0x0605)
#IF %DEF(%UNICODE)
MACRO RebootCheckOnInstall = RebootCheckOnInstallW
#ELSE
MACRO RebootCheckOnInstall = RebootCheckOnInstallA
#ENDIF
'//////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: TranslateInfString
'//
'// SYNOPSIS: Translates a key value in an INF file, using advanced INF
'// syntax.
'// RETURN CODES:
'// S_OK Everything OK.
'// HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER)
'// The buffer size is too small to hold the
'// translated string. Required size is in *pdwRequiredSize.
'// E_INVALIDARG NULL specified in pszInfFilename, pszTranslateSection,
'// pszTranslateKey, pdwRequiredSize.
'// HRESULT_FROM_WIN32(ERROR_OLD_WIN_VERSION)
'// OS not supported.
'// E_UNEXPECTED Catastrophic failure -- should never happen.
'// HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER)
'// The section or key specified does not exist.
'// HRESULT_FROM_WIN32(GetLastError()) Anything else
'//
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as RebootCheckOnInstall.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION TranslateInfStringA LIB "advpack.dll" ALIAS "TranslateInfStringA" ( BYREF pszInfFilename AS ASCIIZ , BYREF pszInstallSection AS ASCIIZ , BYREF pszTranslateSection AS ASCIIZ , BYREF pszTranslateKey AS ASCIIZ , BYREF pszBuffer AS ASCIIZ , BYVAL cchBuffer AS QUAD , BYREF pdwRequiredSize AS QUAD , BYVAL pvReserved AS QUAD ) AS LONG
DECLARE FUNCTION TranslateInfStringW LIB "advpack.dll" ALIAS "TranslateInfStringW" ( BYREF pszInfFilename AS WSTRINGZ
 , BYREF pszInstallSection AS WSTRINGZ
 , BYREF pszTranslateSection AS WSTRINGZ
 , BYREF pszTranslateKey AS WSTRINGZ
 , BYREF pszBuffer AS WSTRINGZ
 , BYVAL cchBuffer AS DWORD
 , BYREF pdwRequiredSize AS DWORD
 , BYVAL pvReserved AS DWORD
 ) AS LONG
'#endif // (_WIN32_IE >= 0x0605)
#IF %DEF(%UNICODE)
MACRO TranslateInfString = TranslateInfStringW
#ELSE
MACRO TranslateInfString = TranslateInfStringA
#ENDIF
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: RegInstall
'//
'// SYNOPSIS: Loads an INF from a string resource, adds some entries to the
'// INF string substitution table, and executes the INF.
'// RETURNS:
'// S_OK success.
'// E_FAIL failure,
'/////////////////////////////////////////////////////////////////////////////
' // Size = 8 bytes
TYPE STRENTRY DWORD
 pszName AS ASCIIZ PTR ' LPSTR // String to substitute
 pszValue AS ASCIIZ PTR ' LPSTR // Replacement string or string resource
END TYPE
' // Size = 8 bytes
TYPE STRENTRYW DWORD
 pszName AS WSTRINGZ PTR ' LPWSTR // String to substitute
 pszValue AS WSTRINGZ PTR ' LPWSTR // Replacement string or string resource
END TYPE
MACRO STRENTRYA = STRENTRY
' // Size = 8 bytes
TYPE STRTABLEA DWORD
 cEntries AS DWORD ' DWORD // Number of entries in the table
 pse AS STRENTRY PTR ' LPSTRENTRY // Array of entries
END TYPE
' // Size = 8 bytes
TYPE STRTABLEW DWORD
 cEntries AS DWORD ' DWORD // Number of entries in the table
 pse AS STRENTRYW PTR ' LPSTRENTRYW // Array of entries
END TYPE
#IF %DEF(%UNICODE)
MACRO STRTABLE = STRTABLEW
#ELSE
MACRO STRTABLE = STRTABLEA
#ENDIF
MACRO CSTRTABLE = STRTABLE
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as RegInstall.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION RegInstallA LIB "advpack.dll" ALIAS "RegInstallA" ( BYVAL hm AS QUAD , BYREF pszSection AS ASCIIZ , BYREF pstTable AS STRTABLEA ) AS LONG
DECLARE FUNCTION RegInstallW LIB "advpack.dll" ALIAS "RegInstallW" ( BYVAL hm AS QUAD
 , BYREF pszSection AS WSTRINGZ
 , BYREF pstTable AS STRTABLEW
 ) AS LONG
'#endif // (_WIN32_IE >= 0x0605)
#IF %DEF(%UNICODE)
MACRO RegInstall = RegInstallW
#ELSE
MACRO RegInstall = RegInstallA
#ENDIF
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: LaunchINFSectionEx
'//
'// SYNOPSIS: Install INF section with BACKUP/ROLLBACK capabilities.
'//
'// RETURNS: E_FAIL on failure, S_OK on success.
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as LaunchINFSectionEx.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION LaunchINFSectionExA LIB "advpack.dll" ALIAS "LaunchINFSectionExA" ( BYVAL hwnd AS QUAD , BYVAL hInstance AS QUAD , BYREF pszParms AS ASCIIZ , BYVAL nShow AS LONG ) AS LONG
DECLARE FUNCTION LaunchINFSectionExW LIB "advpack.dll" ALIAS "LaunchINFSectionExW" ( BYVAL hwnd AS QUAD
 , BYVAL hInstance AS DWORD
 , BYREF pszParms AS WSTRINGZ
 , BYVAL nShow AS LONG
 ) AS LONG
'#endif // (_WIN32_IE >= 0x0605)
#IF %DEF(%UNICODE)
MACRO LaunchINFSectionEx = LaunchINFSectionExW
#ELSE
MACRO LaunchINFSectionEx = LaunchINFSectionExA
#ENDIF
'// FLAGS:
'// FLAGS value this way is for compatibility. Don't change them.
'//
%EQUATE `ALINF_QUIET = 4 ' // quiet mode, no UI
%EQUATE `ALINF_NGCONV = 8 ' // don't run groupConv
%EQUATE `ALINF_UPDHLPDLLS = 16 ' // force to self-updating on user's system
%EQUATE `ALINF_BKINSTALL = 32 ' // backup data before install
%EQUATE `ALINF_ROLLBACK = 64 ' // rollback to previous state
%EQUATE `ALINF_CHECKBKDATA = 128 ' // validate the backup data
%EQUATE `ALINF_ROLLBKDOALL = 256 ' // bypass building file list
%EQUATE `ALINF_DELAYREGISTEROCX = 512 ' // force delay of ocx registration
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: ExecuteCab
'//
'// SYNOPSIS: Extract the an INF from the CAB file, and do INF install on it.
'/////////////////////////////////////////////////////////////////////////////
'// RETURNS: E_FAIL on failure, S_OK on success.
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as ExecuteCab.
'#if (_WIN32_IE >= 0x0605)
' // Size = 276 bytes
TYPE CABINFOA DWORD
 pszCab AS ASCIIZ PTR
 pszInf AS ASCIIZ PTR
 pszSection AS ASCIIZ PTR
 szSrcPath AS ASCIIZ * %MAX_PATH ' CHAR
 dwFlags AS DWORD
END TYPE
' // Size = 536 bytes
TYPE CABINFOW DWORD
 pszCab AS WSTRINGZ PTR
 pszInf AS WSTRINGZ PTR
 pszSection AS WSTRINGZ PTR
 szSrcPath AS WSTRINGZ * %MAX_PATH ' WCHAR
 dwFlags AS DWORD
END TYPE
#IF %DEF(%UNICODE)
MACRO CABINFO = CABINFOW
#ELSE
MACRO CABINFO = CABINFOA
#ENDIF
DECLARE FUNCTION ExecuteCabA LIB "advpack.dll" ALIAS "ExecuteCabA" ( BYVAL hwnd AS QUAD , BYREF pCab AS CABINFOA , BYVAL pReserved AS QUAD ) AS LONG
DECLARE FUNCTION ExecuteCabW LIB "advpack.dll" ALIAS "ExecuteCabW" ( BYVAL hwnd AS QUAD
 , BYREF pCab AS CABINFOW
 , BYVAL pReserved AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO ExecuteCab = ExecuteCabW
#ELSE
MACRO ExecuteCab = ExecuteCabA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'// flag as LaunchINFSectionEx's flag defines
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: AdvInstallFile
'//
'// SYNOPSIS: To copy a file from the source to a destination
'// Basicly a wrapper around the setupapi file copy engine
'/////////////////////////////////////////////////////////////////////////////
'// Flags which can be passed to AdvInstallFile
'// Here is a copy of the flags defined in setupapi.h for reference below.
'//#define COPYFLG_WARN_IF_SKIP 0x00000001 // warn if user tries to skip file
'//#define COPYFLG_NOSKIP 0x00000002 // disallow skipping this file
'//#define COPYFLG_NOVERSIONCHECK 0x00000004 // ignore versions and overwrite target
'//#define COPYFLG_FORCE_FILE_IN_USE 0x00000008 // force file-in-use behavior
'//#define COPYFLG_NO_OVERWRITE 0x00000010 // do not copy if file exists on target
'//#define COPYFLG_NO_VERSION_DIALOG 0x00000020 // do not copy if target is newer
'//#define COPYFLG_REPLACEONLY 0x00000400 // copy only if file exists on target
%EQUATE `AIF_WARNIFSKIP = &H00000001 ' // system critical file: warn if user tries to skip
%EQUATE `AIF_NOSKIP = &H00000002 ' // Skip is disallowed for this file
%EQUATE `AIF_NOVERSIONCHECK = &H00000004 ' // don't check the version number of the file overwrite
%EQUATE `AIF_FORCE_FILE_IN_USE = &H00000008 ' // force file-in-use behavior
%EQUATE `AIF_NOOVERWRITE = &H00000010 ' // copy only if target doesn't exist
 ' // if AIF_QUIET, the file is not copied and
 ' // the user is not notified
%EQUATE `AIF_NO_VERSION_DIALOG = &H00000020 ' // do not copy if target is newer
%EQUATE `AIF_REPLACEONLY = &H00000400 ' // copy only if target file already present
'// Flags only known to AdvInstallFile
%EQUATE `AIF_NOLANGUAGECHECK = &H10000000 ' // don't check the language of the file
 ' // if the flags is NOT specified and AIF_QUIET
 ' // the file is not copied and the user is not notified
%EQUATE `AIF_QUIET = &H20000000 ' // No UI to the user
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as AdvInstallFile.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION AdvInstallFileA LIB "advpack.dll" ALIAS "AdvInstallFileA" ( BYVAL hwnd AS QUAD , BYREF lpszSourceDir AS ASCIIZ , BYREF lpszSourceFile AS ASCIIZ , BYREF lpszDestDir AS ASCIIZ , BYREF lpszDestFile AS ASCIIZ , BYVAL dwFlags AS QUAD , BYVAL dwReserved AS QUAD ) AS LONG
DECLARE FUNCTION AdvInstallFileW LIB "advpack.dll" ALIAS "AdvInstallFileW" ( BYVAL hwnd AS QUAD
 , BYREF lpszSourceDir AS WSTRINGZ
 , BYREF lpszSourceFile AS WSTRINGZ
 , BYREF lpszDestDir AS WSTRINGZ
 , BYREF lpszDestFile AS WSTRINGZ
 , BYVAL dwFlags AS DWORD
 , BYVAL dwReserved AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO AdvInstallFile = AdvInstallFileW
#ELSE
MACRO AdvInstallFile = AdvInstallFileA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'//////////////////////////////////////////////////////////////////
'//
'//////////////////////////////////////////////////////////////////
'// the following flags are for backwards compatiable. No API user
'// should reference them directly now.
'//
%EQUATE `IE4_RESTORE = &H00000001 ' // if this bit is off, save the registries.
%EQUATE `IE4_BACKNEW = &H00000002 ' // backup all files which are not backed up before
%EQUATE `IE4_NODELETENEW = &H00000004 ' // don't delete files we don't backed up before
%EQUATE `IE4_NOMESSAGES = &H00000008 ' // No message display in any events.
%EQUATE `IE4_NOPROGRESS = &H00000010 ' // this bit on: No file backup progressbar
%EQUATE `IE4_NOENUMKEY = &H00000020 ' // this bit on: Don't Enum sub key even there is no given valuename
%EQUATE `IE4_NO_CRC_MAPPING = &H00000040 ' // Normally you should not turn on this bit, advpack creates
 ' // internal mapping for all the entries backed up.
%EQUATE `IE4_REGSECTION = &H00000080 ' // INF AddReg/DelReg section
%EQUATE `IE4_FRDOALL = &H00000100 ' // FileRestore DoAll
%EQUATE `IE4_UPDREFCNT = &H00000200 ' // Update the ref count in .ini backup file list
%EQUATE `IE4_USEREFCNT = &H00000400 ' // use ref count to determin if the backup file should be put back
%EQUATE `IE4_EXTRAINCREFCNT = &H00000800 ' // if increase the ref cnt if it has been updated before
%EQUATE `IE4_REMOVREGBKDATA = &H00001000 ' // This bit should be used with restore bit
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: RegSaveRestore
'//
'// SYNOPSIS: Save or Restore the given register value or given INF reg section.
'//
'// RETURNS: E_FAIL on failure, S_OK on success.
'/////////////////////////////////////////////////////////////////////////////
'// Save or Restore the given register value
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as RegSaveRestore.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION RegSaveRestoreA LIB "advpack.dll" ALIAS "RegSaveRestoreA" ( BYVAL hwnd AS QUAD , BYREF pszTitleString AS ASCIIZ , BYVAL hkBckupKey AS QUAD , BYREF pcszRootKey AS ASCIIZ , BYREF pcszSubKey AS ASCIIZ , BYREF pcszValueName AS ASCIIZ , BYVAL dwFlags AS QUAD ) AS LONG
DECLARE FUNCTION RegSaveRestoreW LIB "advpack.dll" ALIAS "RegSaveRestoreW" ( BYVAL hwnd AS QUAD
 , BYREF pszTitleString AS WSTRINGZ
 , BYVAL hkBckupKey AS DWORD
 , BYREF pcszRootKey AS WSTRINGZ
 , BYREF pcszSubKey AS WSTRINGZ
 , BYREF pcszValueName AS WSTRINGZ
 , BYVAL dwFlags AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO RegSaveRestore = RegSaveRestoreW
#ELSE
MACRO RegSaveRestore = RegSaveRestoreA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'// Save or Restore the given INF Reg Section. At restore, if INF and Section pointers are NULL,
'// Restore all from the given backup key handle.
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as RegSaveRestoreOnINFA.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION RegSaveRestoreOnINFA LIB "advpack.dll" ALIAS "RegSaveRestoreOnINFA" ( BYVAL hwnd AS QUAD , BYREF pszTitle AS ASCIIZ , BYREF pszINF AS ASCIIZ , BYREF pszSection AS ASCIIZ , BYVAL hHKLMBackKey AS QUAD , BYVAL hHKCUBackKey AS QUAD , BYVAL dwFlags AS QUAD ) AS LONG
DECLARE FUNCTION RegSaveRestoreOnINFW LIB "advpack.dll" ALIAS "RegSaveRestoreOnINFW" ( BYVAL hwnd AS QUAD
 , BYREF pszTitle AS WSTRINGZ
 , BYREF pszINF AS WSTRINGZ
 , BYREF pszSection AS WSTRINGZ
 , BYVAL hHKLMBackKey AS DWORD
 , BYVAL hHKCUBackKey AS DWORD
 , BYVAL dwFlags AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO RegSaveRestoreOnINF = RegSaveRestoreOnINFW
#ELSE
MACRO RegSaveRestoreOnINF = RegSaveRestoreOnINFA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'// FLAG:
%EQUATE `RSR_RESTORE = %IE4_RESTORE ' // if this bit is off, means Save. Otherwise, restore.
%EQUATE `ARSR_NOMESSAGES = %IE4_NOMESSAGES ' // Quiet no messages in any event.
%EQUATE `ARSR_REGSECTION = %IE4_REGSECTION ' // if this bit is off, the given section is GenInstall Section
%EQUATE `ARSR_REMOVREGBKDATA = %IE4_REMOVREGBKDATA ' // if both this bit and restore bit on, remove the backup reg data without restore it
'// Turn on the logging by add these RegVale in HKLM\software\microsoft\IE4
$REG_SAVE_LOG_KEY = "RegSaveLogFile"
$REG_RESTORE_LOG_KEY = "RegRestoreLogFile"
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as RegRestoreAll.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION RegRestoreAllA LIB "advpack.dll" ALIAS "RegRestoreAllA" ( BYVAL hWnd AS QUAD , BYREF pszTitleString AS ASCIIZ , BYVAL hkBckupKey AS QUAD ) AS LONG
DECLARE FUNCTION RegRestoreAllW LIB "advpack.dll" ALIAS "RegRestoreAllW" ( BYVAL hWnd AS QUAD
 , BYREF pszTitleString AS WSTRINGZ
 , BYVAL hkBckupKey AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO RegRestoreAll = RegRestoreAllW
#ELSE
MACRO RegRestoreAll = RegRestoreAllA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: FileSaveRestore
'//
'// SYNOPSIS: Save or Restore the files on the list lpFileList.
'// If lpFileList is NULL at restore time, the function will restore
'// all based on INI index file.
'//
'// RETURNS: E_FAIL on failure, S_OK on success.
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as FileSaveRestore.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION FileSaveRestoreA LIB "advpack.dll" ALIAS "FileSaveRestoreA" ( BYVAL hDlg AS QUAD , BYREF lpFileList AS ASCIIZ , BYREF lpDir AS ASCIIZ , BYREF lpBaseName AS ASCIIZ , BYVAL dwFlags AS QUAD ) AS LONG
DECLARE FUNCTION FileSaveRestoreW LIB "advpack.dll" ALIAS "FileSaveRestoreW" ( BYVAL hDlg AS QUAD
 , BYREF lpFileList AS WSTRINGZ
 , BYREF lpDir AS WSTRINGZ
 , BYREF lpBaseName AS WSTRINGZ
 , BYVAL dwFlags AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO FileSaveRestore = FileSaveRestoreW
#ELSE
MACRO FileSaveRestore = FileSaveRestoreA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: FileSaveRestoreOnINF
'//
'// SYNOPSIS:
'//
'// RETURNS: E_FAIL on failure, S_OK on success.
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as FileSaveRestoreOnINF.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION FileSaveRestoreOnINFA LIB "advpack.dll" ALIAS "FileSaveRestoreOnINFA" ( BYVAL hWnd AS QUAD , BYREF pszTitle AS ASCIIZ , BYREF pszINF AS ASCIIZ , BYREF pszSection AS ASCIIZ , BYREF pszBackupDir AS ASCIIZ , BYREF pszBaseBackupFile AS ASCIIZ , BYVAL dwFlags AS QUAD ) AS LONG
DECLARE FUNCTION FileSaveRestoreOnINFW LIB "advpack.dll" ALIAS "FileSaveRestoreOnINFW" ( BYVAL hWnd AS QUAD
 , BYREF pszTitle AS WSTRINGZ
 , BYREF pszINF AS WSTRINGZ
 , BYREF pszSection AS WSTRINGZ
 , BYREF pszBackupDir AS WSTRINGZ
 , BYREF pszBaseBackupFile AS WSTRINGZ
 , BYVAL dwFlags AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO FileSaveRestoreOnINF = FileSaveRestoreOnINFW
#ELSE
MACRO FileSaveRestoreOnINF = FileSaveRestoreOnINFA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'// FLAGS:
%EQUATE `AFSR_RESTORE = %IE4_RESTORE ' // if this bit is off, save the file.
%EQUATE `AFSR_BACKNEW = %IE4_BACKNEW ' // backup all files which are not backed up before
%EQUATE `AFSR_NODELETENEW = %IE4_NODELETENEW ' // don't delete files we don't backed up before
%EQUATE `AFSR_NOMESSAGES = %IE4_NOMESSAGES ' // No message display in any events.
%EQUATE `AFSR_NOPROGRESS = %IE4_NOPROGRESS ' // this bit on: No file backup progressbar
%EQUATE `AFSR_UPDREFCNT = %IE4_UPDREFCNT ' // update the reference count for the files
%EQUATE `AFSR_USEREFCNT = %IE4_USEREFCNT ' // use the ref count to guide the restore file
%EQUATE `AFSR_EXTRAINCREFCNT = %IE4_EXTRAINCREFCNT
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: AddDelBackupEntry
'//
'// SYNOPSIS: If AADBE_ADD_ENTRY is specified, mark the file in the File list as not existing
'// during file save in the INI file. This can be used to mark additional files that
'// they did not exist during backup to avoid having them backup the next time the
'// FileSaveRestore is called to save files.
'// If AADBE_DEL_ENTRY is specified, delete the entry from the INI. This mechanism can
'// be used to leave files permanently on the system.
'//
'// RETURNS:
'// S_OK success
'// E_FAIL failure
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as AddDelBackupEntry.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION AddDelBackupEntryA LIB "advpack.dll" ALIAS "AddDelBackupEntryA" ( BYREF lpcszFileList AS ASCIIZ , BYREF lpcszBackupDir AS ASCIIZ , BYREF lpcszBaseName AS ASCIIZ , BYVAL dwFlags AS QUAD ) AS LONG
DECLARE FUNCTION AddDelBackupEntryW LIB "advpack.dll" ALIAS "AddDelBackupEntryW" ( BYREF lpcszFileList AS WSTRINGZ
 , BYREF lpcszBackupDir AS WSTRINGZ
 , BYREF lpcszBaseName AS WSTRINGZ
 , BYVAL dwFlags AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO AddDelBackupEntry = AddDelBackupEntryW
#ELSE
MACRO AddDelBackupEntry = AddDelBackupEntryA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
%EQUATE `AADBE_ADD_ENTRY = &H01 ' // add entries to the INI file
%EQUATE `AADBE_DEL_ENTRY = &H02 ' // delete entries from the INI file
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: FileSaveMarkNotExist
'//
'// SYNOPSIS: Mark the file in the File list as not existing during file save in the INI file
'// This can be used to mark additional files that they did not exist during backup
'// to avoid having them backup the next time the FileSaveRestore is called to save
'// files
'//
'// RETURNS:
'// S_OK success
'// E_FAIL failure
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as FileSaveMarkNotExist.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION FileSaveMarkNotExistA LIB "advpack.dll" ALIAS "FileSaveMarkNotExistA" ( BYREF lpFileList AS ASCIIZ , BYREF lpDir AS ASCIIZ , BYREF lpBaseName AS ASCIIZ ) AS LONG
DECLARE FUNCTION FileSaveMarkNotExistW LIB "advpack.dll" ALIAS "FileSaveMarkNotExistW" ( BYREF lpFileList AS WSTRINGZ
 , BYREF lpDir AS WSTRINGZ
 , BYREF lpBaseName AS WSTRINGZ
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO FileSaveMarkNotExist = FileSaveMarkNotExistW
#ELSE
MACRO FileSaveMarkNotExist = FileSaveMarkNotExistA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: GetVersionFromFile
'//
'// SYNOPSIS: Get the given file's version and lang information.
'//
'// RETURNS: E_FAIL on failure, S_OK on success.
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as GetVersionFromFile.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION GetVersionFromFileA LIB "advpack.dll" ALIAS "GetVersionFromFileA" ( BYREF lpszFilename AS ASCIIZ , BYREF pdwMSVer AS QUAD , BYREF pdwLSVer AS QUAD , BYVAL bVersion AS LONG ) AS LONG
DECLARE FUNCTION GetVersionFromFileW LIB "advpack.dll" ALIAS "GetVersionFromFileW" ( BYREF lpszFilename AS WSTRINGZ
 , BYREF pdwMSVer AS DWORD
 , BYREF pdwLSVer AS DWORD
 , BYVAL bVersion AS LONG
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO GetVersionFromFile = GetVersionFromFileW
#ELSE
MACRO GetVersionFromFile = GetVersionFromFileA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: GetVersionFromFileEx
'//
'// SYNOPSIS: Get the given disk file's version and lang information.
'//
'// RETURNS: E_FAIL on failure, S_OK on success.
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as GetVersionFromFileEx.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION GetVersionFromFileExA LIB "advpack.dll" ALIAS "GetVersionFromFileExA" ( BYREF lpszFilename AS ASCIIZ , BYREF pdwMSVer AS QUAD , BYREF pdwLSVer AS QUAD , BYVAL bVersion AS LONG ) AS LONG
DECLARE FUNCTION GetVersionFromFileExW LIB "advpack.dll" ALIAS "GetVersionFromFileExW" ( BYREF lpszFilename AS WSTRINGZ
 , BYREF pdwMSVer AS DWORD
 , BYREF pdwLSVer AS DWORD
 , BYVAL bVersion AS LONG
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO GetVersionFromFileEx = GetVersionFromFileExW
#ELSE
MACRO GetVersionFromFileEx = GetVersionFromFileExA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: IsNTAdmin
'//
'// SYNOPSIS: On NT, check if user has admin right.
'//
'// RETURNS: TURE has admin right; FLSE no admin right.
'/////////////////////////////////////////////////////////////////////////////
DECLARE FUNCTION IsNTAdmin LIB "advpack.dll" ALIAS "IsNTAdmin" ( BYVAL dwReserved AS QUAD , BYREF lpdwReserved AS QUAD ) AS LONG
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: DelNode
'//
'// SYNOPSIS: Deletes a file or directory
'//
'// RETURNS:
'// S_OK success
'// E_FAIL failure
'/////////////////////////////////////////////////////////////////////////////
'// FLAGS:
%EQUATE `ADN_DEL_IF_EMPTY = &H00000001 ' // delete the directory only if it's empty
%EQUATE `ADN_DONT_DEL_SUBDIRS = &H00000002 ' // don't delete any sub-dirs; delete only the files
%EQUATE `ADN_DONT_DEL_DIR = &H00000004 ' // don't delete the dir itself
%EQUATE `ADN_DEL_UNC_PATHS = &H00000008 ' // delete UNC paths
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as DelNode.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION DelNodeA LIB "advpack.dll" ALIAS "DelNodeA" ( BYREF pszFileOrDirName AS ASCIIZ , BYVAL dwFlags AS QUAD ) AS LONG
DECLARE FUNCTION DelNodeW LIB "advpack.dll" ALIAS "DelNodeW" ( BYREF pszFileOrDirName AS WSTRINGZ
 , BYVAL dwFlags AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO DelNode = DelNodeW
#ELSE
MACRO DelNode = DelNodeA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: DelNodeRunDLL32
'//
'// SYNOPSIS: Deletes a file or directory; the parameters to this API are of
'// WinMain type
'//
'// RETURNS:
'// S_OK success
'// E_FAIL failure
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as DelNodeRunDLL32.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION DelNodeRunDLL32A LIB "advpack.dll" ALIAS "DelNodeRunDLL32A" ( BYVAL hwnd AS QUAD , BYVAL hInstance AS QUAD , BYREF pszParms AS ASCIIZ , BYVAL nShow AS LONG ) AS LONG
DECLARE FUNCTION DelNodeRunDLL32W LIB "advpack.dll" ALIAS "DelNodeRunDLL32W" ( BYVAL hwnd AS QUAD
 , BYVAL hInstance AS DWORD
 , BYREF pszParms AS WSTRINGZ
 , BYVAL nShow AS LONG
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO DelNodeRunDLL32 = DelNodeRunDLL32W
#ELSE
MACRO DelNodeRunDLL32 = DelNodeRunDLL32A
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: OpenINFEngine, TranslateINFStringEx, CloseINFEngine
'//
'// SYNOPSIS: Three APIs give the caller the option to be more efficient when need
'// Advpack to translate INF file in a continue fashion.
'//
'// RETURNS:
'// S_OK success
'// E_FAIL failure
'/////////////////////////////////////////////////////////////////////////////
'#if !defined(UNIX) || !defined(_INC_SETUPAPI) // IEUNIX: Prevent re-def.
'//
'// Define type for reference to loaded inf file
'// (from setupapi.h)
'//
'typedef PVOID HINF;
'#endif
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as OpenINFEngine.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION OpenINFEngineA LIB "advpack.dll" ALIAS "OpenINFEngineA" ( BYREF pszInfFilename AS ASCIIZ , BYREF pszInstallSection AS ASCIIZ , BYVAL dwFlags AS QUAD , BYREF phInf AS QUAD , BYVAL pvReserved AS QUAD ) AS LONG
DECLARE FUNCTION OpenINFEngineW LIB "advpack.dll" ALIAS "OpenINFEngineW" ( BYREF pszInfFilename AS WSTRINGZ
 , BYREF pszInstallSection AS WSTRINGZ
 , BYVAL dwFlags AS DWORD
 , BYREF phInf AS DWORD
 , BYVAL pvReserved AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO OpenINFEngine = OpenINFEngineW
#ELSE
MACRO OpenINFEngine = OpenINFEngineA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as TranslateInfStringEx.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION TranslateInfStringExA LIB "advpack.dll" ALIAS "TranslateInfStringExA" ( BYVAL hInf AS QUAD , BYREF pszInfFilename AS ASCIIZ , BYREF pszTranslateSection AS ASCIIZ , BYREF pszTranslateKey AS ASCIIZ , BYREF pszBuffer AS STRINGZ , BYVAL dwBufferSize AS QUAD , BYREF pdwRequiredSize AS QUAD , BYVAL pvReserved AS QUAD ) AS LONG
DECLARE FUNCTION TranslateInfStringExW LIB "advpack.dll" ALIAS "TranslateInfStringExW" ( BYVAL hInf AS QUAD
 , BYREF pszInfFilename AS WSTRINGZ
 , BYREF pszTranslateSection AS WSTRINGZ
 , BYREF pszTranslateKey AS WSTRINGZ
 , BYREF pszBuffer AS WSTRINGZ
 , BYVAL dwBufferSize AS DWORD
 , BYREF pdwRequiredSize AS DWORD
 , BYVAL pvReserved AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO TranslateInfStringEx = TranslateInfStringExW
#ELSE
MACRO TranslateInfStringEx = TranslateInfStringExA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
DECLARE FUNCTION CloseINFEngine LIB "advpack.dll" ALIAS "CloseINFEngine" ( BYVAL hInf AS QUAD ) AS LONG
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as ExtractFiles.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION ExtractFilesA LIB "advpack.dll" ALIAS "ExtractFilesA" ( BYREF pszCabName AS ASCIIZ , BYREF pszExpandDir AS ASCIIZ , BYVAL dwFlags AS QUAD , BYREF pszFileList AS ASCIIZ , BYVAL lpReserved AS QUAD , BYVAL dwReserved AS QUAD ) AS LONG
DECLARE FUNCTION ExtractFilesW LIB "advpack.dll" ALIAS "ExtractFilesW" ( BYREF pszCabName AS WSTRINGZ
 , BYREF pszExpandDir AS WSTRINGZ
 , BYVAL dwFlags AS DWORD
 , BYREF pszFileList AS WSTRINGZ
 , BYVAL lpReserved AS DWORD
 , BYVAL dwReserved AS DWORD
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO ExtractFiles = ExtractFilesW
#ELSE
MACRO ExtractFiles = ExtractFilesA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: LaunchINFSection
'//
'// SYNOPSIS: Install INF section WITHOUT BACKUP/ROLLBACK capabilities.
'//
'// RETURNS: E_FAIL on failure, S_OK on success.
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as LaunchINFSection.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION LaunchINFSectionA LIB "advpack.dll" ALIAS "LaunchINFSectionA" ( BYVAL hwnd AS QUAD , BYVAL hInst AS QUAD , BYREF pszParams AS ASCIIZ , BYVAL nShow AS LONG ) AS LONG ' INT
DECLARE FUNCTION LaunchINFSectionW LIB "advpack.dll" ALIAS "LaunchINFSectionW" ( BYVAL hwnd AS QUAD , BYVAL hInst AS QUAD , BYREF pszParams AS WSTRINGZ , BYVAL nShow AS LONG ) AS LONG ' INT
#IF %DEF(%UNICODE)
MACRO LaunchINFSection = LaunchINFSectionW
#ELSE
MACRO LaunchINFSection = LaunchINFSectionA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'// LaunchINFSection flags
%EQUATE `LIS_QUIET = &H0001 ' // Bit 0
%EQUATE `LIS_NOGRPCONV = &H0002 ' // Bit 1
'// Flags in Advanced INF RunPreSetupCommands and RunPostSetupCommands of the Install section
'// Those flags can tell advpack how to run those commands, quiet or not quiet, wait or not wait.
'// The Default for runing those commands are: Not Quiet and Wait for finish before return the caller.
'// I.E> RunPostSetupCommands = MyCmdsSecA:1, MyCmdsSecB:2, MyCmdsSecC
'//
%EQUATE `RUNCMDS_QUIET = &H00000001
%EQUATE `RUNCMDS_NOWAIT = &H00000002
%EQUATE `RUNCMDS_DELAYPOSTCMD = &H00000004
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: UserStubWrapper
'//
'// SYNOPSIS: The function wrapper around the real per-user restore stub to
'// do some generic/intelligent function on behalf of every component.
'//
'// RETURNS: E_FAIL on failure, S_OK on success.
'/////////////////////////////////////////////////////////////////////////////
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as UserInstStubWrapper.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION UserInstStubWrapperA LIB "advpack.dll" ALIAS "UserInstStubWrapperA" ( BYVAL hwnd AS QUAD , BYVAL hInst AS QUAD , BYREF pszParams AS ASCIIZ , BYVAL nShow AS LONG ) AS LONG
DECLARE FUNCTION UserInstStubWrapperW LIB "advpack.dll" ALIAS "UserInstStubWrapperW" ( BYVAL hwnd AS QUAD
 , BYVAL hInst AS DWORD
 , BYREF pszParams AS WSTRINGZ
 , BYVAL nShow AS LONG
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO UserInstStubWrapper = UserInstStubWrapperW
#ELSE
MACRO UserInstStubWrapper = UserInstStubWrapperA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as UserUnInstStubWrapper.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION UserUnInstStubWrapperA LIB "advpack.dll" ALIAS "UserUnInstStubWrapperA" ( BYVAL hwnd AS QUAD , BYVAL hInst AS QUAD , BYREF pszParams AS ASCIIZ , BYVAL nShow AS LONG ) AS LONG
DECLARE FUNCTION UserUnInstStubWrapperW LIB "advpack.dll" ALIAS "UserUnInstStubWrapperW" ( BYVAL hwnd AS QUAD
 , BYVAL hInst AS DWORD
 , BYREF pszParams AS WSTRINGZ
 , BYVAL nShow AS LONG
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO UserUnInstStubWrapper = UserUnInstStubWrapperW
#ELSE
MACRO UserUnInstStubWrapper = UserUnInstStubWrapperA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
'/////////////////////////////////////////////////////////////////////////////
'// ENTRY POINT: SetPerUserInstValues
'//
'// SYNOPSIS: The function set the per-user stub reg values under IsInstalled\{GUID}
'// related key to ensure the later per-user process correctly.
'//
'// RETURNS: E_FAIL on failure, S_OK on success.
'/////////////////////////////////////////////////////////////////////////////
'// Args passed to the following API
'// MAX_GUID_STRING_LEN is 39 defined in cfgmgr32.h, here we just use it.
'//
' // Size = 1408 bytes
TYPE PERUSERSECTIONA DWORD
 szGUID AS ASCIIZ * 39 + 20 ' CHAR
 szDispName AS ASCIIZ * 128 ' CHAR
 szLocale AS ASCIIZ * 10 ' CHAR
 szStub AS ASCIIZ * %MAX_PATH * 4 ' CHAR
 szVersion AS ASCIIZ * 32 ' CHAR
 szCompID AS ASCIIZ * 128 ' CHAR
 dwIsInstalled AS DWORD
 bRollback AS LONG
END TYPE
' // Size = 2804 bytes
TYPE PERUSERSECTIONW DWORD
 szGUID AS WSTRINGZ * 39 + 20 ' WCHAR
 szDispName AS WSTRINGZ * 128 ' WCHAR
 szLocale AS WSTRINGZ * 10 ' WCHAR
 szStub AS WSTRINGZ * %MAX_PATH * 4 ' WCHAR
 szVersion AS WSTRINGZ * 32 ' WCHAR
 szCompID AS WSTRINGZ * 128 ' WCHAR
 dwIsInstalled AS DWORD
 bRollback AS LONG
END TYPE
#IF %DEF(%UNICODE)
MACRO PERUSERSECTION = PERUSERSECTIONW
#ELSE
MACRO PERUSERSECTION = PERUSERSECTIONA
#ENDIF
' // Note: In versions of Internet Explorer prior to 6.05, this function is exported
' // as SetPerUserSecValues.
'#if (_WIN32_IE >= 0x0605)
DECLARE FUNCTION SetPerUserSecValuesA LIB "advpack.dll" ALIAS "SetPerUserSecValuesA" ( BYREF pPerUser AS PERUSERSECTIONA ) AS LONG
DECLARE FUNCTION SetPerUserSecValuesW LIB "advpack.dll" ALIAS "SetPerUserSecValuesW" ( BYREF pPerUser AS PERUSERSECTIONW
 ) AS LONG
#IF %DEF(%UNICODE)
MACRO SetPerUserSecValues = SetPerUserSecValuesW
#ELSE
MACRO SetPerUserSecValues = SetPerUserSecValuesA
#ENDIF
'#endif // (_WIN32_IE >= 0x0605)
#ENDIF
