Thursday, December 2, 2021

test

 '  Project:  Extract CABinets

'  Customer: Saxion Hogescholen

'  Function: VB Script prototype for extracting embedded CABinets from MSI files


ARGS = Wscript.Arguments.Count

Set WIOBJ = CreateObject( "WindowsInstaller.Installer" )

Set IsFileSys = CreateObject("IsFileSys.File")

Const msiStreamAnsi = 2



'  Make sure we have a good command line

If ARGS > 0 Then if InStr(1, Wscript.Arguments(0), "?", vbTextcompare) > 0 Then argCount = 0

If ARGS = 0 Then

Wscript.Echo "This script will extract embedded CABinets from" &_

vbLf & "MSI files, since this is a more efficient layout." &_

vbLf & "The argument is the path to an install database"

Wscript.Quit 1

End If



'  Open command line delivered MSI and make a changed copy

WorkingDir = Left(Wscript.Arguments(0),InStrRev(Wscript.Arguments(0),"\"))

MSIBase = Wscript.Arguments(0)

MSIChanged = WorkingDir & "Changed.MSI"

Set objFS = CreateObject( "Scripting.FileSystemObject")

Set fsoBaseFile = objFS.GetFile(MSIBase)

fsoBaseFile.Copy (MSIChanged)

Set WIOBJ = CreateObject( "WindowsInstaller.Installer")

Set ODB   = WIOBJ.OpenDatabase(MSIBase,    0)

Set MSIDB = WIOBJ.OpenDatabase(MSIChanged, 1)

If( ODB Is Nothing ) Then

   MsgBox( "Error opening MSI file: " & MSIBase )

End If

If( MSIDB Is Nothing ) Then

   MsgBox( "Error creating MSI file: " & MSIChanged )

End If



'  Get a ModuleID from those listed in the Signature table,

'  then get associated components and delete all related data

Set Media_View = MSIDB.OpenView( "SELECT Cabinet FROM Media" )

Media_View.Execute

Set Media_Record = Media_View.Fetch

Do Until Media_Record Is Nothing

If (Mid(Media_Record.StringData(1), 1, 1) = "#") Then

'  Get "_Streams" table entry name from Media table entry name

OldMediaName = Right(Media_Record.StringData(1),(Len(Media_Record.StringData(1))-1))

'  Loop to write the stream out in 1024 byte blocks

'  ****  USES "IsFileSys" INSTALLSHIELD FILE SYSTEM Object  ****

Set streamview = MSIDB.OpenView("SELECT * FROM _Streams WHERE `Name`= '" & OldMediaName & "'")

streamview.Execute

Set streamrecord = streamview.Fetch

If Not (streamrecord Is Nothing) Then

sFullPath = WorkingDir &  streamrecord.StringData(1)

IsFileSys.OpenFile (sFullPath)

Dim sData

sData = streamrecord.ReadStream(2, 1024, msiStreamAnsi)

While (sData <> Empty)

IsFileSys.WriteData(sData)

sData = streamrecord.ReadStream(2, 1024, msiStreamAnsi)

Wend

IsFileSys.CloseFile()

' MsgBox( "Written " & streamrecord.DataSize(2) & " bytes to " & sFullPath )

End If



'  Rename internal references

NewMediaName = OldMediaName

Set view = MSIDB.OpenView("UPDATE `Media` SET `Cabinet`='" & NewMediaName & "' WHERE `Cabinet`='#" & OldMediaName & "'")

view.Execute

Set view = Nothing



'  Delete old stream from database

Set view = MSIDB.OpenView("SELECT `Name` FROM _Streams WHERE `Name` = ?")

Set record = WIOBJ.CreateRecord(2)

record.StringData(1) = OldMediaName

view.Execute record

Set record = view.Fetch

view.Modify 3, record

Set view = Nothing

MsgBox "Deleted the embedded CABinet from MSI file (use Orca to recover size)."

End If

'  Continue getting next media table entries, for spanning media such as floppy discs

Set Media_Record = Media_View.Fetch

Loop



'  Close out and commit

MSIDB.Commit



Set MSIDB = Nothing

Set WIOBJ = Nothing

No comments:

Post a Comment