终于找到一点有关增量压缩的门了

728 篇文章 1 订阅
248 篇文章 0 订阅

终于找到一点有关增量压缩的门了

使用系统自带的 msdelta.dll,对系统中的增量干缩文件进行有关操作,GetDeltaInfo、Apply,总是提示参数错误。
一直就以为定义的结构、类型有错误,直到放弃了这些操作,压缩了一个新文件,才知道前面的操作都是对的,只不过微软对标准的增量压缩文件进行了一些改造,在文件的前面加上了四个字节,即, 我们提到过的 DCN、DCD、DCM等,和一个分隔符。
去掉前面的四个字节以后,再进行 GetDeltaInfo、Apply 操作就正常了。
这只解决了一个问题,DCN 的问题。
但后面的也可以不管了。
DCM 文件,可以 GetDeltaInfo,但不能 Apply,还是提示参数错误。
DCD 文件,由于过于复杂,就不想管了。因为涉及到基准文件的问题,难于确定。
这也可以解释在日志看到有关解压缩时,微软使用的是 ApplyB 了,不是针对文件进行,而是针对数组进行的操作了。
读出文件来以后,去掉了前面的四个字节。
知道问题以后,代码实际上很简单:

[<Struct; StructLayoutAttribute(LayoutKind.Explicit)>]
type Anonymous_654d2e53_a177_4231_98a2_dbbc4dcf1d8a =

    /// LPCVOID->void*
    [<FieldOffsetAttribute(0)>]
    val lpcStart : System.IntPtr 

    /// LPVOID->void*
    [<FieldOffsetAttribute(0)>]
    val lpStart : IntPtr


[<Struct; StructLayoutAttribute(LayoutKind.Sequential)>]
type DELTA_INPUT =

    /// Anonymous_654d2e53_a177_4231_98a2_dbbc4dcf1d8a
    val Union1 : Anonymous_654d2e53_a177_4231_98a2_dbbc4dcf1d8a

    /// SIZE_T->ULONG_PTR->unsigned int
    val uSize : UInt32

    /// BOOL->int
    [<MarshalAsAttribute(UnmanagedType.Bool)>]
    val Editable : bool


[<Struct; StructLayoutAttribute(LayoutKind.Sequential)>]
type DELTA_OUTPUT =

    /// LPVOID->void*
    val lpStart : System.IntPtr

    /// SIZE_T->ULONG_PTR->unsigned int
    val uSize : UInt32


[<Struct; StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi)>]
type DELTA_HASH = 
    /// DWORD->unsigned int
    val HashSize : UInt32
    /// UCHAR[]
    [<MarshalAsAttribute(UnmanagedType.ByValTStr,SizeConst=32)>]
    val HashValue : string


[<Struct; StructLayoutAttribute(LayoutKind.Sequential)>]
type DELTA_HEADER_INFO =
    /// DELTA_FILE_TYPE->__int64
    val FileTypeSet : Int64
    /// DELTA_FILE_TYPE->__int64
    val FileType : Int64
    /// DELTA_FLAG_TYPE->__int64
    val Flags : Int64
    /// SIZE_T->ULONG_PTR->unsigned int
    val TargetSize : UInt32
    /// FILETIME->_FILETIME
    val TargetFileTime : ComTypes.FILETIME
    /// ALG_ID->unsigned int
    val TargetHashAlgId : UInt32
    /// DELTA_HASH->_DELTA_HASH
//    val TargetHash : DELTA_HASH[<DllImport("msdelta.dll")>]
extern bool GetDeltaInfo(
    string              lpDeltaName,
    DELTA_HEADER_INFO&  lpHeaderInfo
    )
[<DllImportAttribute("msdelta.dll",SetLastError=true)>]
extern  bool ApplyDelta(
    int64 ApplyFlags, 
    string lpSourceName, 
    string lpDeltaName, 
    string lpTargetName) 

let (++) a b  = System.IO.Path.Combine(a, b)

let GetDeltaInfo FilePath =
    let mutable hd = new DELTA_HEADER_INFO()
    GetDeltaInfo ( FilePath, &hd  )
    hd

GetDeltaInfo @"d:\vmicshutdown-DCN.dll"
GetDeltaInfo @"d:\wnv-DCN.sys"

let ApplyDCN DCNFilePath = 
//    (IO.DirectoryInfo(noDCNFile)).Name
    let basePath = IO.Path.GetDirectoryName(DCNFilePath)
    let noDCNFile = IO.Path.GetTempFileName()
    let Target = DCNFilePath + ".Apply"
    use r = System.IO.File.OpenRead(DCNFilePath)
    let mutable fileContent = Array.init (int r.Length) ( fun i -> byte 0)

    r.Read(fileContent, 0, (int r.Length))
    r.Close()

    if ( System.Text.Encoding.ASCII.GetString( fileContent.[0..2] ) = "DCN" ) then
        use w = System.IO.File.OpenWrite(noDCNFile)
        w.Write(fileContent.[4..], 0, (fileContent.[4..]).Length)
        w.Close()
        ApplyDelta ( 0L, "", noDCNFile, Target  ) |> ignore
    IO.File.Delete(noDCNFile)
ApplyDCN @"d:\wnv.sys"

IO.Directory.GetFiles(@"S:\R\amd64_microsoft-windows-wnv_31bf3856ad364e35_6.3.9600.16384_none_a06476a92abb3455")
|>Seq.map ApplyDCN
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值