您的位置:首页 > 其它

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

2015-08-20 20:09 906 查看
终于找到一点有关增量压缩的门了

使用系统自带的 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: