LyoKICogQ29weXJpZ2h0IDIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVRtcEZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSogaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJVG1wRmlsZV9mbkFkZFJlZihJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVRtcEZpbGVfZm5SZWxlYXNlKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJVG1wRmlsZV9mbkluZm8oSUFWSUZpbGUqaWZhY2UsQVZJRklMRUlORk9XKmFmaSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVRtcEZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVRtcEZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLEFWSVNUUkVBTUlORk9XKmFzaSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJVG1wRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElUbXBGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgKnNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVRtcEZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVRtcEZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CgpzdHJ1Y3QgSUNPTV9WVEFCTEUoSUFWSUZpbGUpIGl0bXBmdCA9IHsKICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogIElUbXBGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSVRtcEZpbGVfZm5BZGRSZWYsCiAgSVRtcEZpbGVfZm5SZWxlYXNlLAogIElUbXBGaWxlX2ZuSW5mbywKICBJVG1wRmlsZV9mbkdldFN0cmVhbSwKICBJVG1wRmlsZV9mbkNyZWF0ZVN0cmVhbSwKICBJVG1wRmlsZV9mbldyaXRlRGF0YSwKICBJVG1wRmlsZV9mblJlYWREYXRhLAogIElUbXBGaWxlX2ZuRW5kUmVjb3JkLAogIElUbXBGaWxlX2ZuRGVsZXRlU3RyZWFtCn07Cgp0eXBlZGVmIHN0cnVjdCBfSVRtcEZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElDT01fVkZJRUxEKElBVklGaWxlKTsKICBEV09SRCAgICAgICAgIHJlZjsKCiAgLyogSUFWSUZpbGUgc3R1ZmYgKi8KICBBVklGSUxFSU5GT1cgIGZJbmZvOwogIFBBVklTVFJFQU0gICAqcHBTdHJlYW1zOwp9IElUbXBGaWxlSW1wbDsKClBBVklGSUxFIEFWSUZJTEVfQ3JlYXRlQVZJVGVtcEZpbGUoaW50IG5TdHJlYW1zLCBQQVZJU1RSRUFNICpwcFN0cmVhbXMpIHsKICBJVG1wRmlsZUltcGwgKnRtcEZpbGU7CiAgaW50ICAgICAgICAgICBpOwoKICB0bXBGaWxlID0gTG9jYWxBbGxvYyhMUFRSLCBzaXplb2YoSVRtcEZpbGVJbXBsKSk7CiAgaWYgKHRtcEZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICB0bXBGaWxlLT5scFZ0YmwgPSAmaXRtcGZ0OwogIHRtcEZpbGUtPnJlZiAgICA9IDE7CiAgbWVtc2V0KCZ0bXBGaWxlLT5mSW5mbywgMCwgc2l6ZW9mKHRtcEZpbGUtPmZJbmZvKSk7CgogIHRtcEZpbGUtPmZJbmZvLmR3U3RyZWFtcyA9IG5TdHJlYW1zOwogIHRtcEZpbGUtPnBwU3RyZWFtcyA9IExvY2FsQWxsb2MoTFBUUiwgblN0cmVhbXMgKiBzaXplb2YoUEFWSVNUUkVBTSkpOwogIGlmICh0bXBGaWxlLT5wcFN0cmVhbXMgPT0gTlVMTCkgewogICAgTG9jYWxGcmVlKChITE9DQUwpdG1wRmlsZSk7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIGZvciAoaSA9IDA7IGkgPCBuU3RyZWFtczsgaSsrKSB7CiAgICBBVklTVFJFQU1JTkZPVyBzSW5mbzsKCiAgICB0bXBGaWxlLT5wcFN0cmVhbXNbaV0gPSBwcFN0cmVhbXNbaV07CgogICAgQVZJU3RyZWFtQWRkUmVmKHBwU3RyZWFtc1tpXSk7CiAgICBBVklTdHJlYW1JbmZvVyhwcFN0cmVhbXNbaV0sICZzSW5mbywgc2l6ZW9mKHNJbmZvKSk7CiAgICBpZiAoaSA9PSAwKSB7CiAgICAgIHRtcEZpbGUtPmZJbmZvLmR3U2NhbGUgPSBzSW5mby5kd1NjYWxlOwogICAgICB0bXBGaWxlLT5mSW5mby5kd1JhdGUgID0gc0luZm8uZHdSYXRlOwogICAgICBpZiAoIXNJbmZvLmR3U2NhbGUgfHwgIXNJbmZvLmR3UmF0ZSkgewoJdG1wRmlsZS0+ZkluZm8uZHdTY2FsZSA9IDE7Cgl0bXBGaWxlLT5mSW5mby5kd1JhdGUgID0gMTAwOwogICAgICB9CiAgICB9CgogICAgaWYgKHRtcEZpbGUtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA8IHNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSkKICAgICAgdG1wRmlsZS0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gc0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwoKICAgIHsKICAgICAgcmVnaXN0ZXIgRFdPUkQgdG1wOwoKICAgICAgdG1wID0gTXVsRGl2KEFWSVN0cmVhbVNhbXBsZVRvVGltZShwcFN0cmVhbXNbaV0sIHNJbmZvLmR3TGVuZ3RoKSwgXAoJCSAgIHRtcEZpbGUtPmZJbmZvLmR3U2NhbGUsIHRtcEZpbGUtPmZJbmZvLmR3UmF0ZSAqIDEwMDApOwogICAgICBpZiAodG1wRmlsZS0+ZkluZm8uZHdMZW5ndGggPCB0bXApCgl0bXBGaWxlLT5mSW5mby5kd0xlbmd0aCA9IHRtcDsKCiAgICAgIHRtcCA9IHNJbmZvLnJjRnJhbWUucmlnaHQgLSBzSW5mby5yY0ZyYW1lLmxlZnQ7CiAgICAgIGlmICh0bXBGaWxlLT5mSW5mby5kd1dpZHRoIDwgdG1wKQoJdG1wRmlsZS0+ZkluZm8uZHdXaWR0aCA9IHRtcDsKICAgICAgdG1wID0gc0luZm8ucmNGcmFtZS5ib3R0b20gLSBzSW5mby5yY0ZyYW1lLnRvcDsKICAgICAgaWYgKHRtcEZpbGUtPmZJbmZvLmR3SGVpZ2h0IDwgdG1wKQoJdG1wRmlsZS0+ZkluZm8uZHdIZWlnaHQgPSB0bXA7CiAgICB9CiAgfQoKICByZXR1cm4gKFBBVklGSUxFKXRtcEZpbGU7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJVG1wRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlICppZmFjZSwgUkVGSUlEIHJlZmlpZCwKCQkJCQkJTFBWT0lEICpvYmopCnsKICBJQ09NX1RISVMoSVRtcEZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElUbXBGaWxlX2ZuQWRkUmVmKElBVklGaWxlICppZmFjZSkKewogIElDT01fVEhJUyhJVG1wRmlsZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCBUaGlzLT5yZWYgKyAxKTsKICByZXR1cm4gKysoVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElUbXBGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSAqaWZhY2UpCnsKICBJQ09NX1RISVMoSVRtcEZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgVGhpcy0+cmVmIC0gMSk7CgogIGlmICghLS0oVGhpcy0+cmVmKSkgewogICAgaW50IGk7CgogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbaV0gIT0gTlVMTCkgewoJQVZJU3RyZWFtUmVsZWFzZShUaGlzLT5wcFN0cmVhbXNbaV0pOwoKCVRoaXMtPnBwU3RyZWFtc1tpXSA9IE5VTEw7CiAgICAgIH0KICAgIH0KCiAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzKTsKICAgIHJldHVybiAwOwogIH0KCiAgcmV0dXJuIFRoaXMtPnJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElUbXBGaWxlX2ZuSW5mbyhJQVZJRmlsZSAqaWZhY2UsCgkJCQkgICAgICBBVklGSUxFSU5GT1cgKmFmaSwgTE9ORyBzaXplKQp7CiAgSUNPTV9USElTKElUbXBGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxhZmksc2l6ZSk7CgogIGlmIChhZmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkoYWZpLCAmVGhpcy0+ZkluZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPmZJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+ZkluZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVRtcEZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgSUNPTV9USElTKElUbXBGaWxlSW1wbCxpZmFjZSk7CgogIFVMT05HIG5TdHJlYW0gPSAoVUxPTkcpLTE7CgogIFRSQUNFKCIoJXAsJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBsUGFyYW0gPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgaWYgKGZjY1R5cGUgIT0gc3RyZWFtdHlwZUFOWSkgewogICAgLyogc2VhcmNoIHRoZSBudW1iZXIgb2YgdGhlIHNwZWNpZmllZCBzdHJlYW0gKi8KICAgIFVMT05HIGk7CgogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICAgIEFWSVNUUkVBTUlORk9XIHNJbmZvOwogICAgICBIUkVTVUxUICAgICAgICBocjsKCiAgICAgIGhyID0gQVZJU3RyZWFtSW5mb1coVGhpcy0+cHBTdHJlYW1zW2ldLCAmc0luZm8sIHNpemVvZihzSW5mbykpOwogICAgICBpZiAoRkFJTEVEKGhyKSkKCXJldHVybiBocjsKCiAgICAgIGlmIChzSW5mby5mY2NUeXBlID09IGZjY1R5cGUpIHsKCWlmIChsUGFyYW0gPT0gMCkgewoJICBuU3RyZWFtID0gaTsKCSAgYnJlYWs7Cgl9IGVsc2UKCSAgbFBhcmFtLS07CiAgICAgIH0KICAgIH0KICB9IGVsc2UKICAgIG5TdHJlYW0gPSBsUGFyYW07CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3QgPyAqLwogIGlmIChuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICYmIFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSAhPSBOVUxMKSB7CiAgICAqYXZpcyA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKICAgIEFWSVN0cmVhbUFkZFJlZigqYXZpcyk7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIFNvcnJ5LCBidXQgdGhlIHNwZWNpZmllZCBzdHJlYW0gZG9lc24ndCBleGlzdCAqLwogIHJldHVybiBBVklFUlJfTk9EQVRBOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVRtcEZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgICAgQVZJU1RSRUFNSU5GT1cgKmFzaSkKewogIFRSQUNFKCIoJXAsJXAsJXApXG4iLGlmYWNlLGF2aXMsYXNpKTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElUbXBGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgICBMUFZPSUQgbHBEYXRhLCBMT05HIHNpemUpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJWxkKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJVG1wRmlsZV9mblJlYWREYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgIExQVk9JRCBscERhdGEsIExPTkcgKnNpemUpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElUbXBGaWxlX2ZuRW5kUmVjb3JkKElBVklGaWxlICppZmFjZSkKewogIFRSQUNFKCIoJXApXG4iLGlmYWNlKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElUbXBGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlICppZmFjZSwgRFdPUkQgZmNjVHlwZSwKCQkJCQkgICAgICBMT05HIGxQYXJhbSkKewogIFRSQUNFKCIoJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgZmNjVHlwZSwgbFBhcmFtKTsKCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQo=