LyogQ29weXJpZ2h0IKkgMjAxMCAtIDIwMTMgVU5JU1lTIENPUlBPUkFUSU9OCiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdAogKiB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLCBidXQKICogV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgT1IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UsIEdPT0QgVElUTEUgb3IKICogTk9OIElORlJJTkdFTUVOVC4gIFNlZSB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUKICogZGV0YWlscy4KICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpZmRlZiBDT05GSUdfTU9EVkVSU0lPTlMKI2luY2x1ZGUgPGNvbmZpZy9tb2R2ZXJzaW9ucy5oPgojZW5kaWYKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgkJLyogZm9yIG1vZHVsZV9pbml0IGFuZCBtb2R1bGVfZXhpdCAqLwojaW5jbHVkZSA8bGludXgvc2xhYi5oPgkJLyogZm9yIG1lbWNweSAqLwojaW5jbHVkZSA8bGludXgvdHlwZXMuaD4KCi8qIEltcGxlbWVudGF0aW9uIG9mIGV4cG9ydGVkIGZ1bmN0aW9ucyBmb3IgU3VwZXJ2aXNvciBjaGFubmVscyAqLwojaW5jbHVkZSAiY2hhbm5lbC5oIgoKLyoKICogUm91dGluZSBEZXNjcmlwdGlvbjoKICogVHJpZXMgdG8gaW5zZXJ0IHRoZSBwcmVidWlsdCBzaWduYWwgcG9pbnRlZCB0byBieSBwU2lnbmFsIGludG8gdGhlIG50aAogKiBRdWV1ZSBvZiB0aGUgQ2hhbm5lbCBwb2ludGVkIHRvIGJ5IHBDaGFubmVsCiAqCiAqIFBhcmFtZXRlcnM6CiAqIHBDaGFubmVsOiAoSU4pIHBvaW50cyB0byB0aGUgSU8gQ2hhbm5lbAogKiBRdWV1ZTogKElOKSBudGggUXVldWUgb2YgdGhlIElPIENoYW5uZWwKICogcFNpZ25hbDogKElOKSBwb2ludGVyIHRvIHRoZSBzaWduYWwKICoKICogQXNzdW1wdGlvbnM6CiAqIC0gcENoYW5uZWwsIFF1ZXVlIGFuZCBwU2lnbmFsIGFyZSB2YWxpZC4KICogLSBJZiBpbnNlcnRpb24gZmFpbHMgZHVlIHRvIGEgZnVsbCBxdWV1ZSwgdGhlIGNhbGxlciB3aWxsIGRldGVybWluZSB0aGUKICogcmV0cnkgcG9saWN5IChlLmcuIHdhaXQgJiB0cnkgYWdhaW4sIHJlcG9ydCBhbiBlcnJvciwgZXRjLikuCiAqCiAqIFJldHVybiB2YWx1ZToKICogMSBpZiB0aGUgaW5zZXJ0aW9uIHN1Y2NlZWRzLCAwIGlmIHRoZSBxdWV1ZSB3YXMgZnVsbC4KICovCnVuc2lnbmVkIGNoYXIKdmlzb3Jfc2lnbmFsX2luc2VydChDSEFOTkVMX0hFQURFUiBfX2lvbWVtICpwQ2hhbm5lbCwgVTMyIFF1ZXVlLCB2b2lkICpwU2lnbmFsKQp7Cgl2b2lkIF9faW9tZW0gKnBzaWduYWw7Cgl1bnNpZ25lZCBpbnQgaGVhZCwgdGFpbCwgbm9mOwoKCVNJR05BTF9RVUVVRV9IRUFERVIgX19pb21lbSAqcHFoZHIgPQoJICAgIChTSUdOQUxfUVVFVUVfSEVBREVSIF9faW9tZW0gKikKCQkoKGNoYXIgX19pb21lbSAqKSBwQ2hhbm5lbCArIHJlYWRxKCZwQ2hhbm5lbC0+b0NoYW5uZWxTcGFjZSkpCgkJKyBRdWV1ZTsKCgkvKiBjYXB0dXJlIGN1cnJlbnQgaGVhZCBhbmQgdGFpbCAqLwoJaGVhZCA9IHJlYWRsKCZwcWhkci0+SGVhZCk7Cgl0YWlsID0gcmVhZGwoJnBxaGRyLT5UYWlsKTsKCgkvKiBxdWV1ZSBpcyBmdWxsIGlmIChoZWFkICsgMSkgJSBuIGVxdWFscyB0YWlsICovCglpZiAoKChoZWFkICsgMSkgJSByZWFkbCgmcHFoZHItPk1heFNpZ25hbFNsb3RzKSkgPT0gdGFpbCkgewoJCW5vZiA9IHJlYWRxKCZwcWhkci0+TnVtT3ZlcmZsb3dzKSArIDE7CgkJd3JpdGVxKG5vZiwgJnBxaGRyLT5OdW1PdmVyZmxvd3MpOwoJCXJldHVybiAwOwoJfQoKCS8qIGluY3JlbWVudCB0aGUgaGVhZCBpbmRleCAqLwoJaGVhZCA9IChoZWFkICsgMSkgJSByZWFkbCgmcHFoZHItPk1heFNpZ25hbFNsb3RzKTsKCgkvKiBjb3B5IHNpZ25hbCB0byB0aGUgaGVhZCBsb2NhdGlvbiBmcm9tIHRoZSBhcmVhIHBvaW50ZWQgdG8KCSAqIGJ5IHBTaWduYWwKCSAqLwoJcHNpZ25hbCA9IChjaGFyIF9faW9tZW0gKilwcWhkciArIHJlYWRxKCZwcWhkci0+b1NpZ25hbEJhc2UpICsKCQkoaGVhZCAqIHJlYWRsKCZwcWhkci0+U2lnbmFsU2l6ZSkpOwoJTUVNQ1BZX1RPSU8ocHNpZ25hbCwgcFNpZ25hbCwgcmVhZGwoJnBxaGRyLT5TaWduYWxTaXplKSk7CgoJVm9sYXRpbGVCYXJyaWVyKCk7Cgl3cml0ZWwoaGVhZCwgJnBxaGRyLT5IZWFkKTsKCgl3cml0ZXEocmVhZHEoJnBxaGRyLT5OdW1TaWduYWxzU2VudCkgKyAxLCAmcHFoZHItPk51bVNpZ25hbHNTZW50KTsKCXJldHVybiAxOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHZpc29yX3NpZ25hbF9pbnNlcnQpOwoKLyoKICogUm91dGluZSBEZXNjcmlwdGlvbjoKICogUmVtb3ZlcyBvbmUgc2lnbmFsIGZyb20gQ2hhbm5lbCBwQ2hhbm5lbCdzIG50aCBRdWV1ZSBhdCB0aGUKICogdGltZSBvZiB0aGUgY2FsbCBhbmQgY29waWVzIGl0IGludG8gdGhlIG1lbW9yeSBwb2ludGVkIHRvIGJ5CiAqIHBTaWduYWwuCiAqCiAqIFBhcmFtZXRlcnM6CiAqIHBDaGFubmVsOiAoSU4pIHBvaW50cyB0byB0aGUgSU8gQ2hhbm5lbAogKiBRdWV1ZTogKElOKSBudGggUXVldWUgb2YgdGhlIElPIENoYW5uZWwKICogcFNpZ25hbDogKElOKSBwb2ludGVyIHRvIHdoZXJlIHRoZSBzaWduYWxzIGFyZSB0byBiZSBjb3BpZWQKICoKICogQXNzdW1wdGlvbnM6CiAqIC0gcENoYW5uZWwgYW5kIFF1ZXVlIGFyZSB2YWxpZC4KICogLSBwU2lnbmFsIHBvaW50cyB0byBhIG1lbW9yeSBhcmVhIGxhcmdlIGVub3VnaCB0byBob2xkIHF1ZXVlJ3MgU2lnbmFsU2l6ZQogKgogKiBSZXR1cm4gdmFsdWU6CiAqIDEgaWYgdGhlIHJlbW92YWwgc3VjY2VlZHMsIDAgaWYgdGhlIHF1ZXVlIHdhcyBlbXB0eS4KICovCnVuc2lnbmVkIGNoYXIKdmlzb3Jfc2lnbmFsX3JlbW92ZShDSEFOTkVMX0hFQURFUiBfX2lvbWVtICpwQ2hhbm5lbCwgVTMyIFF1ZXVlLCB2b2lkICpwU2lnbmFsKQp7Cgl2b2lkIF9faW9tZW0gKnBzb3VyY2U7Cgl1bnNpZ25lZCBpbnQgaGVhZCwgdGFpbDsKCVNJR05BTF9RVUVVRV9IRUFERVIgX19pb21lbSAqcHFoZHIgPQoJICAgIChTSUdOQUxfUVVFVUVfSEVBREVSIF9faW9tZW0gKikgKChjaGFyIF9faW9tZW0gKikgcENoYW5uZWwgKwoJCQkJICAgIHJlYWRxKCZwQ2hhbm5lbC0+b0NoYW5uZWxTcGFjZSkpICsgUXVldWU7CgoJLyogY2FwdHVyZSBjdXJyZW50IGhlYWQgYW5kIHRhaWwgKi8KCWhlYWQgPSByZWFkbCgmcHFoZHItPkhlYWQpOwoJdGFpbCA9IHJlYWRsKCZwcWhkci0+VGFpbCk7CgoJLyogcXVldWUgaXMgZW1wdHkgaWYgdGhlIGhlYWQgaW5kZXggZXF1YWxzIHRoZSB0YWlsIGluZGV4ICovCglpZiAoaGVhZCA9PSB0YWlsKSB7CgkJd3JpdGVxKHJlYWRxKCZwcWhkci0+TnVtRW1wdHlDbnQpICsgMSwgJnBxaGRyLT5OdW1FbXB0eUNudCk7CgkJcmV0dXJuIDA7Cgl9CgoJLyogYWR2YW5jZSBwYXN0IHRoZSAnZW1wdHknIGZyb250IHNsb3QgKi8KCXRhaWwgPSAodGFpbCArIDEpICUgcmVhZGwoJnBxaGRyLT5NYXhTaWduYWxTbG90cyk7CgoJLyogY29weSBzaWduYWwgZnJvbSB0YWlsIGxvY2F0aW9uIHRvIHRoZSBhcmVhIHBvaW50ZWQgdG8gYnkgcFNpZ25hbCAqLwoJcHNvdXJjZSA9IChjaGFyIF9faW9tZW0gKikgcHFoZHIgKyByZWFkcSgmcHFoZHItPm9TaWduYWxCYXNlKSArCgkJKHRhaWwgKiByZWFkbCgmcHFoZHItPlNpZ25hbFNpemUpKTsKCU1FTUNQWV9GUk9NSU8ocFNpZ25hbCwgcHNvdXJjZSwgcmVhZGwoJnBxaGRyLT5TaWduYWxTaXplKSk7CgoJVm9sYXRpbGVCYXJyaWVyKCk7Cgl3cml0ZWwodGFpbCwgJnBxaGRyLT5UYWlsKTsKCgl3cml0ZXEocmVhZHEoJnBxaGRyLT5OdW1TaWduYWxzUmVjZWl2ZWQpICsgMSwKCSAgICAgICAmcHFoZHItPk51bVNpZ25hbHNSZWNlaXZlZCk7CglyZXR1cm4gMTsKfQpFWFBPUlRfU1lNQk9MX0dQTCh2aXNvcl9zaWduYWxfcmVtb3ZlKTsKCi8qCiAqIFJvdXRpbmUgRGVzY3JpcHRpb246CiAqIFJlbW92ZXMgYWxsIHNpZ25hbHMgcHJlc2VudCBpbiBDaGFubmVsIHBDaGFubmVsJ3MgbnRoIFF1ZXVlIGF0IHRoZQogKiB0aW1lIG9mIHRoZSBjYWxsIGFuZCBjb3BpZXMgdGhlbSBpbnRvIHRoZSBtZW1vcnkgcG9pbnRlZCB0byBieQogKiBwU2lnbmFsLiAgUmV0dXJucyB0aGUgIyBvZiBzaWduYWxzIGNvcGllZCBhcyB0aGUgdmFsdWUgb2YgdGhlIHJvdXRpbmUuCiAqCiAqIFBhcmFtZXRlcnM6CiAqIHBDaGFubmVsOiAoSU4pIHBvaW50cyB0byB0aGUgSU8gQ2hhbm5lbAogKiBRdWV1ZTogKElOKSBudGggUXVldWUgb2YgdGhlIElPIENoYW5uZWwKICogcFNpZ25hbDogKElOKSBwb2ludGVyIHRvIHdoZXJlIHRoZSBzaWduYWxzIGFyZSB0byBiZSBjb3BpZWQKICoKICogQXNzdW1wdGlvbnM6CiAqIC0gcENoYW5uZWwgYW5kIFF1ZXVlIGFyZSB2YWxpZC4KICogLSBwU2lnbmFsIHBvaW50cyB0byBhIG1lbW9yeSBhcmVhIGxhcmdlIGVub3VnaCB0byBob2xkIFF1ZXVlJ3MgTWF4U2lnbmFscwogKiAjIG9mIHNpZ25hbHMsIGVhY2ggb2Ygd2hpY2ggaXMgUXVldWUncyBTaWduYWxTaXplLgogKgogKiBSZXR1cm4gdmFsdWU6CiAqICMgb2Ygc2lnbmFscyBjb3BpZWQuCiAqLwp1bnNpZ25lZCBpbnQKU2lnbmFsUmVtb3ZlQWxsKHBDSEFOTkVMX0hFQURFUiBwQ2hhbm5lbCwgVTMyIFF1ZXVlLCB2b2lkICpwU2lnbmFsKQp7Cgl2b2lkICpwc291cmNlOwoJdW5zaWduZWQgaW50IGhlYWQsIHRhaWwsIHNpZ25hbENvdW50ID0gMDsKCXBTSUdOQUxfUVVFVUVfSEVBREVSIHBxaGRyID0KCSAgICAocFNJR05BTF9RVUVVRV9IRUFERVIpICgoY2hhciAqKSBwQ2hhbm5lbCArCgkJCQkgICAgcENoYW5uZWwtPm9DaGFubmVsU3BhY2UpICsgUXVldWU7CgoJLyogY2FwdHVyZSBjdXJyZW50IGhlYWQgYW5kIHRhaWwgKi8KCWhlYWQgPSBwcWhkci0+SGVhZDsKCXRhaWwgPSBwcWhkci0+VGFpbDsKCgkvKiBxdWV1ZSBpcyBlbXB0eSBpZiB0aGUgaGVhZCBpbmRleCBlcXVhbHMgdGhlIHRhaWwgaW5kZXggKi8KCWlmIChoZWFkID09IHRhaWwpCgkJcmV0dXJuIDA7CgoJd2hpbGUgKGhlYWQgIT0gdGFpbCkgewoJCS8qIGFkdmFuY2UgcGFzdCB0aGUgJ2VtcHR5JyBmcm9udCBzbG90ICovCgkJdGFpbCA9ICh0YWlsICsgMSkgJSBwcWhkci0+TWF4U2lnbmFsU2xvdHM7CgoJCS8qIGNvcHkgc2lnbmFsIGZyb20gdGFpbCBsb2NhdGlvbiB0byB0aGUgYXJlYSBwb2ludGVkCgkJICogdG8gYnkgcFNpZ25hbAoJCSAqLwoJCXBzb3VyY2UgPQoJCSAgICAoY2hhciAqKSBwcWhkciArIHBxaGRyLT5vU2lnbmFsQmFzZSArCgkJICAgICh0YWlsICogcHFoZHItPlNpZ25hbFNpemUpOwoJCU1FTUNQWSgoY2hhciAqKSBwU2lnbmFsICsgKHBxaGRyLT5TaWduYWxTaXplICogc2lnbmFsQ291bnQpLAoJCSAgICAgICBwc291cmNlLCBwcWhkci0+U2lnbmFsU2l6ZSk7CgoJCVZvbGF0aWxlQmFycmllcigpOwoJCXBxaGRyLT5UYWlsID0gdGFpbDsKCgkJc2lnbmFsQ291bnQrKzsKCQlwcWhkci0+TnVtU2lnbmFsc1JlY2VpdmVkKys7Cgl9CgoJcmV0dXJuIHNpZ25hbENvdW50Owp9CgovKgogKiBSb3V0aW5lIERlc2NyaXB0aW9uOgogKiBEZXRlcm1pbmUgd2hldGhlciBhIHNpZ25hbCBxdWV1ZSBpcyBlbXB0eS4KICoKICogUGFyYW1ldGVyczoKICogcENoYW5uZWw6IChJTikgcG9pbnRzIHRvIHRoZSBJTyBDaGFubmVsCiAqIFF1ZXVlOiAoSU4pIG50aCBRdWV1ZSBvZiB0aGUgSU8gQ2hhbm5lbAogKgogKiBSZXR1cm4gdmFsdWU6CiAqIDEgaWYgdGhlIHNpZ25hbCBxdWV1ZSBpcyBlbXB0eSwgMCBvdGhlcndpc2UuCiAqLwp1bnNpZ25lZCBjaGFyCnZpc29yX3NpZ25hbHF1ZXVlX2VtcHR5KENIQU5ORUxfSEVBREVSIF9faW9tZW0gKnBDaGFubmVsLCBVMzIgUXVldWUpCnsKCVNJR05BTF9RVUVVRV9IRUFERVIgX19pb21lbSAqcHFoZHIgPQoJICAgIChTSUdOQUxfUVVFVUVfSEVBREVSIF9faW9tZW0gKikgKChjaGFyIF9faW9tZW0gKikgcENoYW5uZWwgKwoJCQkJICAgIHJlYWRxKCZwQ2hhbm5lbC0+b0NoYW5uZWxTcGFjZSkpICsgUXVldWU7CglyZXR1cm4gcmVhZGwoJnBxaGRyLT5IZWFkKSA9PSByZWFkbCgmcHFoZHItPlRhaWwpOwp9CkVYUE9SVF9TWU1CT0xfR1BMKHZpc29yX3NpZ25hbHF1ZXVlX2VtcHR5KTsKCg==