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

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

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

[]
type Anonymous_654d2e53_a177_4231_98a2_dbbc4dcf1d8a =

    /// LPCVOID->void*
    []
    val lpcStart : System.IntPtr 

    /// LPVOID->void*
    []
    val lpStart : IntPtr


[]
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
    []
    val Editable : bool


[]
type DELTA_OUTPUT =

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

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


[]
type DELTA_HASH = 
    /// DWORD->unsigned int
    val HashSize : UInt32
    /// UCHAR[]
    []
    val HashValue : string


[]
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[]
extern bool GetDeltaInfo(
    string              lpDeltaName,
    DELTA_HEADER_INFO&  lpHeaderInfo
    )
[]
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

你可能感兴趣的:(系统维护,F#,函数编程)