LyoKICogQ29weXJpZ2h0IDIwMDItMjAwMyBNaWNoYWVsIEf8bm5ld2lnCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNkZWZpbmUgQ09NX05PX1dJTkRPV1NfSAojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZG93c3guaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgojaWZuZGVmIERJQlBUUgojZGVmaW5lIERJQlBUUihscCkgICAgICAoKExQQllURSkobHApICsgKGxwKS0+YmlTaXplICsgXAogICAgICAgICAgICAgICAgICAgICAgICAgKGxwKS0+YmlDbHJVc2VkICogc2l6ZW9mKFJHQlFVQUQpKQojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJR2V0RnJhbWVfZm5RdWVyeUludGVyZmFjZShJR2V0RnJhbWUgKmlmYWNlLAoJCQkJCQkgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUdldEZyYW1lX2ZuQWRkUmVmKElHZXRGcmFtZSAqaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUdldEZyYW1lX2ZuUmVsZWFzZShJR2V0RnJhbWUgKmlmYWNlKTsKc3RhdGljIExQVk9JRCAgV0lOQVBJIElHZXRGcmFtZV9mbkdldEZyYW1lKElHZXRGcmFtZSAqaWZhY2UsIExPTkcgbFBvcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJR2V0RnJhbWVfZm5CZWdpbihJR2V0RnJhbWUgKmlmYWNlLCBMT05HIGxTdGFydCwKCQkJCQlMT05HIGxFbmQsIExPTkcgbFJhdGUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUdldEZyYW1lX2ZuRW5kKElHZXRGcmFtZSAqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUdldEZyYW1lX2ZuU2V0Rm9ybWF0KElHZXRGcmFtZSAqaWZhY2UsCgkJCQkJICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpLAoJCQkJCSAgICBMUFZPSUQgbHBCaXRzLCBJTlQgeCwgSU5UIHksCgkJCQkJICAgIElOVCBkeCwgSU5UIGR5KTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUdldEZyYW1lVnRibCBpZ2V0ZnJhbWVWdGJsID0gewogIElHZXRGcmFtZV9mblF1ZXJ5SW50ZXJmYWNlLAogIElHZXRGcmFtZV9mbkFkZFJlZiwKICBJR2V0RnJhbWVfZm5SZWxlYXNlLAogIElHZXRGcmFtZV9mbkdldEZyYW1lLAogIElHZXRGcmFtZV9mbkJlZ2luLAogIElHZXRGcmFtZV9mbkVuZCwKICBJR2V0RnJhbWVfZm5TZXRGb3JtYXQKfTsKCnR5cGVkZWYgc3RydWN0IF9JR2V0RnJhbWVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElHZXRGcmFtZVZ0YmwgKmxwVnRibDsKICBMT05HICAgICAgICAgICAgICAgcmVmOwoKICAvKiBJR2V0RnJhbWUgc3R1ZmYgKi8KICBCT09MICAgICAgICAgICAgICAgYkZpeGVkU3RyZWFtOwogIFBBVklTVFJFQU0gICAgICAgICBwU3RyZWFtOwoKICBMUFZPSUQgICAgICAgICAgICAgbHBJbkJ1ZmZlcjsKICBMT05HICAgICAgICAgICAgICAgY2JJbkJ1ZmZlcjsKICBMUEJJVE1BUElORk9IRUFERVIgbHBJbkZvcm1hdDsKICBMT05HICAgICAgICAgICAgICAgY2JJbkZvcm1hdDsKCiAgTE9ORyAgICAgICAgICAgICAgIGxDdXJyZW50RnJhbWU7CiAgTFBCSVRNQVBJTkZPSEVBREVSIGxwT3V0Rm9ybWF0OwogIExQVk9JRCAgICAgICAgICAgICBscE91dEJ1ZmZlcjsKCiAgSElDICAgICAgICAgICAgICAgIGhpYzsKICBCT09MICAgICAgICAgICAgICAgYlJlc2l6ZTsKICBEV09SRCAgICAgICAgICAgICAgeDsKICBEV09SRCAgICAgICAgICAgICAgeTsKICBEV09SRCAgICAgICAgICAgICAgZHg7CiAgRFdPUkQgICAgICAgICAgICAgIGR5OwoKICBCT09MICAgICAgICAgICAgICAgYkZvcm1hdENoYW5nZXM7CiAgRFdPUkQgICAgICAgICAgICAgIGR3Rm9ybWF0Q2hhbmdlQ291bnQ7CiAgRFdPUkQgICAgICAgICAgICAgIGR3RWRpdENvdW50Owp9IElHZXRGcmFtZUltcGw7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgdm9pZCBBVklGSUxFX0Nsb3NlQ29tcHJlc3NvcihJR2V0RnJhbWVJbXBsICpUaGlzKQp7CiAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ICE9IE5VTEwgJiYgVGhpcy0+bHBJbkZvcm1hdCAhPSBUaGlzLT5scE91dEZvcm1hdCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5scE91dEZvcm1hdCk7CiAgICBUaGlzLT5scE91dEZvcm1hdCA9IE5VTEw7CiAgfQogIGlmIChUaGlzLT5scEluRm9ybWF0ICE9IE5VTEwpIHsKICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+bHBJbkZvcm1hdCk7CiAgICBUaGlzLT5scEluRm9ybWF0ID0gTlVMTDsKICB9CiAgaWYgKFRoaXMtPmhpYyAhPSBOVUxMKSB7CiAgICBpZiAoVGhpcy0+YlJlc2l6ZSkKICAgICAgSUNEZWNvbXByZXNzRXhFbmQoVGhpcy0+aGljKTsKICAgIGVsc2UKICAgICAgSUNEZWNvbXByZXNzRW5kKFRoaXMtPmhpYyk7CiAgICBJQ0Nsb3NlKFRoaXMtPmhpYyk7CiAgICBUaGlzLT5oaWMgPSBOVUxMOwogIH0KfQoKUEdFVEZSQU1FIEFWSUZJTEVfQ3JlYXRlR2V0RnJhbWUoUEFWSVNUUkVBTSBwU3RyZWFtKQp7CiAgSUdldEZyYW1lSW1wbCAqcGc7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChwU3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gTlVMTDsKCiAgcGcgPSAoSUdldEZyYW1lSW1wbCopTG9jYWxBbGxvYyhMUFRSLCBzaXplb2YoSUdldEZyYW1lSW1wbCkpOwogIGlmIChwZyAhPSBOVUxMKSB7CiAgICBwZy0+bHBWdGJsICAgICAgICA9ICZpZ2V0ZnJhbWVWdGJsOwogICAgcGctPnJlZiAgICAgICAgICAgPSAxOwogICAgcGctPmxDdXJyZW50RnJhbWUgPSAtMTsKICAgIHBnLT5wU3RyZWFtICAgICAgID0gcFN0cmVhbTsKICAgIElBVklTdHJlYW1fQWRkUmVmKHBTdHJlYW0pOwogIH0KCiAgcmV0dXJuIChQR0VURlJBTUUpcGc7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJR2V0RnJhbWVfZm5RdWVyeUludGVyZmFjZShJR2V0RnJhbWUgKmlmYWNlLAoJCQkJCQkgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJR2V0RnJhbWVJbXBsICpUaGlzID0gKElHZXRGcmFtZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JR2V0RnJhbWUsIHJlZmlpZCkpIHsKICAgICpvYmogPSBpZmFjZTsKICAgIHJldHVybiBTX09LOwogIH0KCiAgcmV0dXJuIE9MRV9FX0VOVU1fTk9NT1JFOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUdldEZyYW1lX2ZuQWRkUmVmKElHZXRGcmFtZSAqaWZhY2UpCnsKICBJR2V0RnJhbWVJbXBsICpUaGlzID0gKElHZXRGcmFtZUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElHZXRGcmFtZV9mblJlbGVhc2UoSUdldEZyYW1lICppZmFjZSkKewogIElHZXRGcmFtZUltcGwgKlRoaXMgPSAoSUdldEZyYW1lSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICBpZiAoIXJlZikgewogICAgQVZJRklMRV9DbG9zZUNvbXByZXNzb3IoVGhpcyk7CiAgICBpZiAoVGhpcy0+cFN0cmVhbSAhPSBOVUxMKSB7CiAgICAgIElBVklTdHJlYW1fUmVsZWFzZShUaGlzLT5wU3RyZWFtKTsKICAgICAgVGhpcy0+cFN0cmVhbSA9IE5VTEw7CiAgICB9CgogICAgTG9jYWxGcmVlKChITE9DQUwpaWZhY2UpOwogICAgcmV0dXJuIDA7CiAgfQoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgTFBWT0lEICBXSU5BUEkgSUdldEZyYW1lX2ZuR2V0RnJhbWUoSUdldEZyYW1lICppZmFjZSwgTE9ORyBsUG9zKQp7CiAgSUdldEZyYW1lSW1wbCAqVGhpcyA9IChJR2V0RnJhbWVJbXBsICopaWZhY2U7CgogIExPTkcgcmVhZEJ5dGVzOwogIExPTkcgcmVhZFNhbXBsZXM7CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgaWZhY2UsIGxQb3MpOwoKICAvKiBXZSBkb24ndCB3YW50IG5lZ2F0aXZlIHN0YXJ0IHZhbHVlcyEgLS0gbWFya3MgaW52YWxpZCBidWZmZXIgY29udGVudCAqLwogIGlmIChsUG9zIDwgMCkKICAgIHJldHVybiBOVUxMOwoKICAvKiBjaGVjayBzdGF0ZSAqLwogIGlmIChUaGlzLT5wU3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gTlVMTDsKICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIC8qIENvdWxkIHN0cmVhbSBoYXZlIGNoYW5nZWQ/ICovCiAgaWYgKCEgVGhpcy0+YkZpeGVkU3RyZWFtKSB7CiAgICBBVklTVFJFQU1JTkZPVyBzSW5mbzsKCiAgICBJQVZJU3RyZWFtX0luZm8oVGhpcy0+cFN0cmVhbSwgJnNJbmZvLCBzaXplb2Yoc0luZm8pKTsKCiAgICBpZiAoc0luZm8uZHdFZGl0Q291bnQgIT0gVGhpcy0+ZHdFZGl0Q291bnQpIHsKICAgICAgVGhpcy0+ZHdFZGl0Q291bnQgICA9IHNJbmZvLmR3RWRpdENvdW50OwogICAgICBUaGlzLT5sQ3VycmVudEZyYW1lID0gLTE7CiAgICB9CgogICAgaWYgKHNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgIT0gVGhpcy0+ZHdGb3JtYXRDaGFuZ2VDb3VudCkgewogICAgICAvKiBzdHJlYW0gaGFzIGNoYW5nZWQgKi8KICAgICAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0ICE9IE5VTEwpIHsKCUJJVE1BUElORk9IRUFERVIgYmk7CgoJbWVtY3B5KCZiaSwgVGhpcy0+bHBPdXRGb3JtYXQsIHNpemVvZihiaSkpOwoJQVZJRklMRV9DbG9zZUNvbXByZXNzb3IoVGhpcyk7CgoJaWYgKEZBSUxFRChJR2V0RnJhbWVfU2V0Rm9ybWF0KGlmYWNlLCAmYmksIE5VTEwsIDAsIDAsIC0xLCAtMSkpKSB7CgkgIGlmIChGQUlMRUQoSUdldEZyYW1lX1NldEZvcm1hdChpZmFjZSwgTlVMTCwgTlVMTCwgMCwgMCwgLTEsIC0xKSkpCgkgICAgcmV0dXJuIE5VTEw7Cgl9CiAgICAgIH0gZWxzZSBpZiAoRkFJTEVEKElHZXRGcmFtZV9TZXRGb3JtYXQoaWZhY2UsIE5VTEwsIE5VTEwsIDAsIDAsIC0xLCAtMSkpKQoJcmV0dXJuIE5VTEw7CiAgICB9CiAgfQoKICBpZiAobFBvcyAhPSBUaGlzLT5sQ3VycmVudEZyYW1lKSB7CiAgICBMT05HIGxOZXh0ID0gSUFWSVN0cmVhbV9GaW5kU2FtcGxlKFRoaXMtPnBTdHJlYW0sbFBvcyxGSU5EX0tFWXxGSU5EX1BSRVYpOwoKICAgIGlmIChsTmV4dCA9PSAtMSkKICAgICAgcmV0dXJuIE5VTEw7IC8qIGZyYW1lIGRvZXNuJ3QgZXhpc3QgKi8KICAgIGlmIChsTmV4dCA8PSBUaGlzLT5sQ3VycmVudEZyYW1lICYmIFRoaXMtPmxDdXJyZW50RnJhbWUgPCBsUG9zKQogICAgICBsTmV4dCA9IFRoaXMtPmxDdXJyZW50RnJhbWUgKyAxOwoKICAgIGZvciAoOyBsTmV4dCA8PSBsUG9zOyBsTmV4dCsrKSB7CiAgICAgIC8qIG5ldyBmb3JtYXQgZm9yIHRoaXMgZnJhbWU/ICovCiAgICAgIGlmIChUaGlzLT5iRm9ybWF0Q2hhbmdlcykgewoJSUFWSVN0cmVhbV9SZWFkRm9ybWF0KFRoaXMtPnBTdHJlYW0sIGxOZXh0LAoJCQkgICAgICBUaGlzLT5scEluRm9ybWF0LCAmVGhpcy0+Y2JJbkZvcm1hdCk7CglpZiAoVGhpcy0+bHBPdXRGb3JtYXQgIT0gTlVMTCkgewoJICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQtPmJpQml0Q291bnQgPD0gOCkKCSAgICBJQ0RlY29tcHJlc3NHZXRQYWxldHRlKFRoaXMtPmhpYywgVGhpcy0+bHBJbkZvcm1hdCwKCQkJCSAgIFRoaXMtPmxwT3V0Rm9ybWF0KTsKCX0KICAgICAgfQoKICAgICAgLyogcmVhZCBpbnB1dCBmcmFtZSAqLwogICAgICB3aGlsZSAoRkFJTEVEKEFWSVN0cmVhbVJlYWQoVGhpcy0+cFN0cmVhbSwgbE5leHQsIDEsIFRoaXMtPmxwSW5CdWZmZXIsCgkJCQkgIFRoaXMtPmNiSW5CdWZmZXIsICZyZWFkQnl0ZXMsICZyZWFkU2FtcGxlcykpKSB7CgkvKiBub3QgZW5vdWdoIG1lbW9yeSBmb3IgaW5wdXQgYnVmZmVyPyAqLwoJcmVhZEJ5dGVzID0gMDsKCWlmIChGQUlMRUQoQVZJU3RyZWFtU2FtcGxlU2l6ZShUaGlzLT5wU3RyZWFtLCBsTmV4dCwgJnJlYWRCeXRlcykpKQoJICByZXR1cm4gTlVMTDsgLyogYmFkIHRoaW5nLCBidXQgYmFkIHRoaW5ncyB3aWxsIGhhcHBlbiAqLwoJaWYgKHJlYWRCeXRlcyA8PSAwKSB7CgkgIEVSUigiOiBJQVZJU3RyZWFtOjpSRWFkIGRvZXNuJ3QgcmV0dXJuIG5lZWRlZCBieXRlcyFcbiIpOwoJICByZXR1cm4gTlVMTDsKCX0KCgkvKiBJQVZJU3RyZWFtOjpSZWFkIGZhaWxlZCBiZWNhdXNlIG9mIG90aGVyIHJlYXNvbnMgbm90IGJ1ZmZlcnNpemU/ICovCglpZiAoVGhpcy0+Y2JJbkJ1ZmZlciA+PSByZWFkQnl0ZXMpCgkgIGJyZWFrOwoJVGhpcy0+Y2JJbkJ1ZmZlciA9IFRoaXMtPmNiSW5Gb3JtYXQgKyByZWFkQnl0ZXM7CglUaGlzLT5scEluRm9ybWF0ID0gR2xvYmFsUmVBbGxvY1B0cihUaGlzLT5scEluRm9ybWF0LCBUaGlzLT5jYkluQnVmZmVyLCAwKTsKCWlmIChUaGlzLT5scEluRm9ybWF0ID09IE5VTEwpCgkgIHJldHVybiBOVUxMOyAvKiBvdXQgb2YgbWVtb3J5ICovCglUaGlzLT5scEluQnVmZmVyID0gKEJZVEUqKVRoaXMtPmxwSW5Gb3JtYXQgKyBUaGlzLT5jYkluRm9ybWF0OwogICAgICB9CgogICAgICBpZiAocmVhZFNhbXBsZXMgIT0gMSkgewoJRVJSKCI6IG5vIGZyYW1lcyByZWFkXG4iKTsKCXJldHVybiBOVUxMOwogICAgICB9CiAgICAgIGlmIChyZWFkQnl0ZXMgIT0gMCkgewoJVGhpcy0+bHBJbkZvcm1hdC0+YmlTaXplSW1hZ2UgPSByZWFkQnl0ZXM7CgoJLyogbm90aGluZyB0byBkZWNvbXByZXNzPyAqLwoJaWYgKFRoaXMtPmhpYyA9PSBOVUxMKSB7CgkgIFRoaXMtPmxDdXJyZW50RnJhbWUgPSBsUG9zOwoJICByZXR1cm4gVGhpcy0+bHBJbkZvcm1hdDsKCX0KCglpZiAoVGhpcy0+YlJlc2l6ZSkgewoJICBJQ0RlY29tcHJlc3NFeChUaGlzLT5oaWMsMCxUaGlzLT5scEluRm9ybWF0LFRoaXMtPmxwSW5CdWZmZXIsMCwwLAoJCQkgVGhpcy0+bHBJbkZvcm1hdC0+YmlXaWR0aCxUaGlzLT5scEluRm9ybWF0LT5iaUhlaWdodCwKCQkJIFRoaXMtPmxwT3V0Rm9ybWF0LFRoaXMtPmxwT3V0QnVmZmVyLFRoaXMtPngsVGhpcy0+eSwKCQkJIFRoaXMtPmR4LFRoaXMtPmR5KTsKCX0gZWxzZSB7CgkgIElDRGVjb21wcmVzcyhUaGlzLT5oaWMsIDAsIFRoaXMtPmxwSW5Gb3JtYXQsIFRoaXMtPmxwSW5CdWZmZXIsCgkJICAgICAgIFRoaXMtPmxwT3V0Rm9ybWF0LCBUaGlzLT5scE91dEJ1ZmZlcik7Cgl9CiAgICAgIH0KICAgIH0gLyogZm9yIChsTmV4dCA8IGxQb3MpICovCiAgfSAvKiBpZiAoVGhpcy0+bEN1cnJlbnRGcmFtZSAhPSBsUG9zKSAqLwoKICByZXR1cm4gKFRoaXMtPmhpYyA9PSBOVUxMID8gVGhpcy0+bHBJbkZvcm1hdCA6IFRoaXMtPmxwT3V0Rm9ybWF0KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElHZXRGcmFtZV9mbkJlZ2luKElHZXRGcmFtZSAqaWZhY2UsIExPTkcgbFN0YXJ0LAoJCQkJCUxPTkcgbEVuZCwgTE9ORyBsUmF0ZSkKewogIElHZXRGcmFtZUltcGwgKlRoaXMgPSAoSUdldEZyYW1lSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJWxkKVxuIiwgaWZhY2UsIGxTdGFydCwgbEVuZCwgbFJhdGUpOwoKICBUaGlzLT5iRml4ZWRTdHJlYW0gPSBUUlVFOwoKICByZXR1cm4gKElHZXRGcmFtZV9HZXRGcmFtZShpZmFjZSwgbFN0YXJ0KSA/IEFWSUVSUl9PSyA6IEFWSUVSUl9FUlJPUik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJR2V0RnJhbWVfZm5FbmQoSUdldEZyYW1lICppZmFjZSkKewogIElHZXRGcmFtZUltcGwgKlRoaXMgPSAoSUdldEZyYW1lSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICBUaGlzLT5iRml4ZWRTdHJlYW0gPSBGQUxTRTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElHZXRGcmFtZV9mblNldEZvcm1hdChJR2V0RnJhbWUgKmlmYWNlLAoJCQkJCSAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaVdhbnRlZCwKCQkJCQkgICAgTFBWT0lEIGxwQml0cywgSU5UIHgsIElOVCB5LAoJCQkJCSAgICBJTlQgZHgsIElOVCBkeSkKewogIElHZXRGcmFtZUltcGwgKlRoaXMgPSAoSUdldEZyYW1lSW1wbCAqKWlmYWNlOwoKICBBVklTVFJFQU1JTkZPVyAgICAgc0luZm87CiAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmkgICAgICAgICA9IGxwYmlXYW50ZWQ7CiAgQk9PTCAgICAgICAgICAgICAgIGJCZXN0RGlzcGxheSA9IEZBTFNFOwoKICBUUkFDRSgiKCVwLCVwLCVwLCVkLCVkLCVkLCVkKVxuIiwgaWZhY2UsIGxwYmlXYW50ZWQsIGxwQml0cywKCXgsIHksIGR4LCBkeSk7CgogIGlmIChUaGlzLT5wU3RyZWFtID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOwoKICBpZiAoKExPTkcpbHBiaVdhbnRlZCA9PSBBVklHRVRGUkFNRUZfQkVTVERJU1BMQVlGTVQpIHsKICAgIGxwYmkgPSBOVUxMOwogICAgYkJlc3REaXNwbGF5ID0gVFJVRTsKICB9CgogIElBVklTdHJlYW1fSW5mbyhUaGlzLT5wU3RyZWFtLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogIGlmIChzSW5mby5mY2NUeXBlICE9IHN0cmVhbXR5cGVWSURFTykKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIFRoaXMtPmJGb3JtYXRDaGFuZ2VzID0KICAgIChzSW5mby5kd0ZsYWdzICYgQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTID8gVFJVRSA6IEZBTFNFICk7CiAgVGhpcy0+ZHdGb3JtYXRDaGFuZ2VDb3VudCA9IHNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7CiAgVGhpcy0+ZHdFZGl0Q291bnQgICAgICAgICA9IHNJbmZvLmR3RWRpdENvdW50OwogIFRoaXMtPmxDdXJyZW50RnJhbWUgICAgICAgPSAtMTsKCiAgLyogZ2V0IGlucHV0IGZvcm1hdCBmcm9tIHN0cmVhbSAqLwogIGlmIChUaGlzLT5scEluRm9ybWF0ID09IE5VTEwpIHsKICAgIEhSRVNVTFQgaHI7CgogICAgVGhpcy0+Y2JJbkJ1ZmZlciA9IChMT05HKXNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICAgIGlmIChUaGlzLT5jYkluQnVmZmVyID09IDApCiAgICAgIFRoaXMtPmNiSW5CdWZmZXIgPSAxMDI0OwoKICAgIElBVklTdHJlYW1fUmVhZEZvcm1hdChUaGlzLT5wU3RyZWFtLCBzSW5mby5kd1N0YXJ0LAoJCQkgIE5VTEwsICZUaGlzLT5jYkluRm9ybWF0KTsKCiAgICBUaGlzLT5scEluRm9ybWF0ID0KICAgICAgKExQQklUTUFQSU5GT0hFQURFUilHbG9iYWxBbGxvY1B0cihHSE5ELCBUaGlzLT5jYkluRm9ybWF0ICsgVGhpcy0+Y2JJbkJ1ZmZlcik7CiAgICBpZiAoVGhpcy0+bHBJbkZvcm1hdCA9PSBOVUxMKSB7CiAgICAgIEFWSUZJTEVfQ2xvc2VDb21wcmVzc29yKFRoaXMpOwogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIH0KCiAgICBociA9IElBVklTdHJlYW1fUmVhZEZvcm1hdChUaGlzLT5wU3RyZWFtLCBzSW5mby5kd1N0YXJ0LCBUaGlzLT5scEluRm9ybWF0LCAmVGhpcy0+Y2JJbkZvcm1hdCk7CiAgICBpZiAoRkFJTEVEKGhyKSkgewogICAgICBBVklGSUxFX0Nsb3NlQ29tcHJlc3NvcihUaGlzKTsKICAgICAgcmV0dXJuIGhyOwogICAgfQoKICAgIFRoaXMtPmxwSW5CdWZmZXIgPSAoKExQQllURSlUaGlzLT5scEluRm9ybWF0KSArIFRoaXMtPmNiSW5Gb3JtYXQ7CiAgfQoKICAvKiBjaGVjayBpbnB1dCBmb3JtYXQgKi8KICBpZiAoVGhpcy0+bHBJbkZvcm1hdC0+YmlDbHJVc2VkID09IDAgJiYgVGhpcy0+bHBJbkZvcm1hdC0+YmlCaXRDb3VudCA8PSA4KQogICAgVGhpcy0+bHBJbkZvcm1hdC0+YmlDbHJVc2VkID0gMXUgPDwgVGhpcy0+bHBJbkZvcm1hdC0+YmlCaXRDb3VudDsKICBpZiAoVGhpcy0+bHBJbkZvcm1hdC0+YmlTaXplSW1hZ2UgPT0gMCAmJgogICAgICBUaGlzLT5scEluRm9ybWF0LT5iaUNvbXByZXNzaW9uID09IEJJX1JHQikgewogICAgVGhpcy0+bHBJbkZvcm1hdC0+YmlTaXplSW1hZ2UgPQogICAgICBESUJXSURUSEJZVEVTKCpUaGlzLT5scEluRm9ybWF0KSAqIFRoaXMtPmxwSW5Gb3JtYXQtPmJpSGVpZ2h0OwogIH0KCiAgLyogb25seSB0byBwYXNzIHRocm91Z2g/ICovCiAgaWYgKFRoaXMtPmxwSW5Gb3JtYXQtPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCICYmIGxwQml0cyA9PSBOVUxMKSB7CiAgICBpZiAobHBiaSA9PSBOVUxMIHx8IAoJKGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCICYmCgkgbHBiaS0+YmlXaWR0aCA9PSBUaGlzLT5scEluRm9ybWF0LT5iaVdpZHRoICYmCgkgbHBiaS0+YmlIZWlnaHQgPT0gVGhpcy0+bHBJbkZvcm1hdC0+YmlIZWlnaHQgJiYKCSBscGJpLT5iaUJpdENvdW50ID09IFRoaXMtPmxwSW5Gb3JtYXQtPmJpQml0Q291bnQpKSB7CiAgICAgIFRoaXMtPmxwT3V0Rm9ybWF0ID0gVGhpcy0+bHBJbkZvcm1hdDsKICAgICAgVGhpcy0+bHBPdXRCdWZmZXIgPSBESUJQVFIoVGhpcy0+bHBJbkZvcm1hdCk7CiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9CiAgfQoKICAvKiBuZWVkIG1lbW9yeSBmb3Igb3V0cHV0IGZvcm1hdD8gKi8KICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkgewogICAgVGhpcy0+bHBPdXRGb3JtYXQgPQogICAgICAoTFBCSVRNQVBJTkZPSEVBREVSKUdsb2JhbEFsbG9jUHRyKEdITkQsIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKQoJCQkJCSArIDI1NiAqIHNpemVvZihSR0JRVUFEKSk7CiAgICBpZiAoVGhpcy0+bHBPdXRGb3JtYXQgPT0gTlVMTCkgewogICAgICBBVklGSUxFX0Nsb3NlQ29tcHJlc3NvcihUaGlzKTsKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICB9CiAgfQoKICAvKiBuZWVkIGhhbmRsZSB0byB2aWRlbyBjb21wcmVzc29yICovCiAgaWYgKFRoaXMtPmhpYyA9PSBOVUxMKSB7CiAgICBGT1VSQ0MgZmNjSGFuZGxlcjsKCiAgICBpZiAoVGhpcy0+bHBJbkZvcm1hdC0+YmlDb21wcmVzc2lvbiA9PSBCSV9SR0IpCiAgICAgIGZjY0hhbmRsZXIgPSBjb21wdHlwZURJQjsKICAgIGVsc2UgaWYgKFRoaXMtPmxwSW5Gb3JtYXQtPmJpQ29tcHJlc3Npb24gPT0gQklfUkxFOCkKICAgICAgZmNjSGFuZGxlciA9IG1taW9GT1VSQ0MoJ1InLCdMJywnRScsJyAnKTsKICAgIGVsc2UKICAgICAgZmNjSGFuZGxlciA9IHNJbmZvLmZjY0hhbmRsZXI7CgogICAgaWYgKGxwYmkgIT0gTlVMTCkgewogICAgICBpZiAobHBiaS0+YmlXaWR0aCA9PSAwKQoJbHBiaS0+YmlXaWR0aCA9IFRoaXMtPmxwSW5Gb3JtYXQtPmJpV2lkdGg7CiAgICAgIGlmIChscGJpLT5iaUhlaWdodCA9PSAwKQoJbHBiaS0+YmlIZWlnaHQgPSBUaGlzLT5scEluRm9ybWF0LT5iaUhlaWdodDsKICAgIH0KCiAgICBUaGlzLT5oaWMgPSBJQ0xvY2F0ZShJQ1RZUEVfVklERU8sIGZjY0hhbmRsZXIsIFRoaXMtPmxwSW5Gb3JtYXQsIGxwYmksIElDTU9ERV9ERUNPTVBSRVNTKTsKICAgIGlmIChUaGlzLT5oaWMgPT0gTlVMTCkgewogICAgICBBVklGSUxFX0Nsb3NlQ29tcHJlc3NvcihUaGlzKTsKICAgICAgcmV0dXJuIEFWSUVSUl9OT0NPTVBSRVNTT1I7CiAgICB9CiAgfQoKICAvKiBvdXRwdXQgZm9ybWF0IGdpdmVuPyAqLwogIGlmIChscGJpICE9IE5VTEwpIHsKICAgIC8qIGNoZWNrIHRoZSBnaXZlbiBvdXRwdXQgZm9ybWF0IC4uLiAqLwogICAgaWYgKGxwYmktPmJpQ2xyVXNlZCA9PSAwICYmIGxwYmktPmJpQml0Q291bnQgPD0gOCkKICAgICAgbHBiaS0+YmlDbHJVc2VkID0gMXUgPDwgbHBiaS0+YmlCaXRDb3VudDsKCiAgICAvKiAuLi4gYW5kIHJlbWVtYmVyIGl0ICovCiAgICBtZW1jcHkoVGhpcy0+bHBPdXRGb3JtYXQsIGxwYmksCgkgICBscGJpLT5iaVNpemUgKyBscGJpLT5iaUNsclVzZWQgKiBzaXplb2YoUkdCUVVBRCkpOwogICAgaWYgKGxwYmktPmJpQml0Q291bnQgPD0gOCkKICAgICAgSUNEZWNvbXByZXNzR2V0UGFsZXR0ZShUaGlzLT5oaWMsIFRoaXMtPmxwSW5Gb3JtYXQsIFRoaXMtPmxwT3V0Rm9ybWF0KTsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICBpZiAoYkJlc3REaXNwbGF5KSB7CiAgICAgIElDR2V0RGlzcGxheUZvcm1hdChUaGlzLT5oaWMsIFRoaXMtPmxwSW5Gb3JtYXQsCgkJCSBUaGlzLT5scE91dEZvcm1hdCwgMCwgZHgsIGR5KTsKICAgIH0gZWxzZSBpZiAoSUNEZWNvbXByZXNzR2V0Rm9ybWF0KFRoaXMtPmhpYywgVGhpcy0+bHBJbkZvcm1hdCwKCQkJCSAgICAgVGhpcy0+bHBPdXRGb3JtYXQpIDwgMCkgewogICAgICBBVklGSUxFX0Nsb3NlQ29tcHJlc3NvcihUaGlzKTsKICAgICAgcmV0dXJuIEFWSUVSUl9OT0NPTVBSRVNTT1I7CiAgICB9CgogICAgLyogY2hlY2sgb3V0cHV0IGZvcm1hdCAqLwogICAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0LT5iaUNsclVzZWQgPT0gMCAmJgoJVGhpcy0+bHBPdXRGb3JtYXQtPmJpQml0Q291bnQgPD0gOCkKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQtPmJpQ2xyVXNlZCA9IDF1IDw8IFRoaXMtPmxwT3V0Rm9ybWF0LT5iaUJpdENvdW50OwogICAgaWYgKFRoaXMtPmxwT3V0Rm9ybWF0LT5iaVNpemVJbWFnZSA9PSAwICYmCglUaGlzLT5scE91dEZvcm1hdC0+YmlDb21wcmVzc2lvbiA9PSBCSV9SR0IpIHsKICAgICAgVGhpcy0+bHBPdXRGb3JtYXQtPmJpU2l6ZUltYWdlID0KCURJQldJRFRIQllURVMoKlRoaXMtPmxwT3V0Rm9ybWF0KSAqIFRoaXMtPmxwT3V0Rm9ybWF0LT5iaUhlaWdodDsKICAgIH0KCiAgICBpZiAobHBCaXRzID09IE5VTEwpIHsKICAgICAgcmVnaXN0ZXIgRFdPUkQgc2l6ZSA9IFRoaXMtPmxwT3V0Rm9ybWF0LT5iaUNsclVzZWQgKiBzaXplb2YoUkdCUVVBRCk7CgogICAgICBzaXplICs9IFRoaXMtPmxwT3V0Rm9ybWF0LT5iaVNpemUgKyBUaGlzLT5scE91dEZvcm1hdC0+YmlTaXplSW1hZ2U7CiAgICAgIFRoaXMtPmxwT3V0Rm9ybWF0ID0KCShMUEJJVE1BUElORk9IRUFERVIpR2xvYmFsUmVBbGxvY1B0cihUaGlzLT5scE91dEZvcm1hdCwgc2l6ZSwgR01FTV9NT1ZFQUJMRSk7CiAgICAgIGlmIChUaGlzLT5scE91dEZvcm1hdCA9PSBOVUxMKSB7CglBVklGSUxFX0Nsb3NlQ29tcHJlc3NvcihUaGlzKTsKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICB9CiAgICAgIFRoaXMtPmxwT3V0QnVmZmVyID0gRElCUFRSKFRoaXMtPmxwT3V0Rm9ybWF0KTsKICAgIH0gZWxzZQogICAgICBUaGlzLT5scE91dEJ1ZmZlciA9IGxwQml0czsKCiAgICAvKiBmb3IgdXNlciBzaXplIHdhcyBpcnJlbGV2YW50ICovCiAgICBpZiAoZHggPT0gLTEpCiAgICAgIGR4ID0gVGhpcy0+bHBPdXRGb3JtYXQtPmJpV2lkdGg7CiAgICBpZiAoZHkgPT0gLTEpCiAgICAgIGR5ID0gVGhpcy0+bHBPdXRGb3JtYXQtPmJpSGVpZ2h0OwoKICAgIC8qIG5lZWQgdG8gcmVzaXplPyAqLwogICAgaWYgKHggIT0gMCB8fCB5ICE9IDApIHsKICAgICAgaWYgKGR5ID09IFRoaXMtPmxwT3V0Rm9ybWF0LT5iaUhlaWdodCAmJgoJICBkeCA9PSBUaGlzLT5scE91dEZvcm1hdC0+YmlXaWR0aCkKCVRoaXMtPmJSZXNpemUgPSBGQUxTRTsKICAgICAgZWxzZQoJVGhpcy0+YlJlc2l6ZSA9IFRSVUU7CiAgICB9CgogICAgaWYgKFRoaXMtPmJSZXNpemUpIHsKICAgICAgVGhpcy0+eCAgPSB4OwogICAgICBUaGlzLT55ICA9IHk7CiAgICAgIFRoaXMtPmR4ID0gZHg7CiAgICAgIFRoaXMtPmR5ID0gZHk7CgogICAgICBpZiAoSUNEZWNvbXByZXNzRXhCZWdpbihUaGlzLT5oaWMsMCxUaGlzLT5scEluRm9ybWF0LFRoaXMtPmxwSW5CdWZmZXIsMCwKCQkJICAgICAgMCxUaGlzLT5scEluRm9ybWF0LT5iaVdpZHRoLAoJCQkgICAgICBUaGlzLT5scEluRm9ybWF0LT5iaUhlaWdodCxUaGlzLT5scE91dEZvcm1hdCwKCQkJICAgICAgVGhpcy0+bHBPdXRCdWZmZXIsIHgsIHksIGR4LCBkeSkgPT0gSUNFUlJfT0spCglyZXR1cm4gQVZJRVJSX09LOwogICAgfSBlbHNlIGlmIChJQ0RlY29tcHJlc3NCZWdpbihUaGlzLT5oaWMsIFRoaXMtPmxwSW5Gb3JtYXQsCgkJCQkgVGhpcy0+bHBPdXRGb3JtYXQpID09IElDRVJSX09LKQogICAgICByZXR1cm4gQVZJRVJSX09LOwoKICAgIEFWSUZJTEVfQ2xvc2VDb21wcmVzc29yKFRoaXMpOwoKICAgIHJldHVybiBBVklFUlJfQ09NUFJFU1NPUjsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8K