LyoKICogUlBDIGVuZHBvaW50IG1hcHBlcgogKgogKiBDb3B5cmlnaHQgMjAwMiBHcmVnIFR1cm5lcgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICoKICogVE9ETzoKICogIC0gYWN0dWFsbHkgZG8gdGhpbmdzIHJpZ2h0CiAqLwoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgInJwYy5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlICJycGNfYmluZGluZy5oIgojaW5jbHVkZSAiZXBtX3Rvd2Vycy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwob2xlKTsKCi8qIFRoZSAicmVhbCIgUlBDIHBvcnRtYXBwZXIgZW5kcG9pbnRzIHRoYXQgSSBrbm93IG9mIGFyZToKICoKICogIG5jYWRnX2lwX3VkcDogMTM1CiAqICBuY2Fjbl9pcF90Y3A6IDEzNQogKiAgbmNhY25fbnA6IFxccGlwZVxlcG1hcHBlciAoPykKICogIG5jYWxycGM6IGVwbWFwcGVyCiAqCiAqIElmIHRoZSB1c2VyJ3MgbWFjaGluZSByYW4gYSBEQ0UgUlBDIGRhZW1vbiwgaXQgd291bGQKICogcHJvYmFibHkgYmUgcG9zc2libGUgdG8gY29ubmVjdCB0byBpdCwgYnV0IHRoZXJlIGFyZSBtYW55CiAqIHJlYXNvbnMgbm90IHRvLCBsaWtlOgogKiAgLSB0aGUgdXNlciBwcm9iYWJseSBkb2VzICpub3QqIHJ1biBvbmUsIGFuZCBwcm9iYWJseQogKiAgICBzaG91bGRuJ3QgYmUgZm9yY2VkIHRvIHJ1biBvbmUganVzdCBmb3IgbG9jYWwgQ09NCiAqICAtIHZlcnkgZmV3IFVuaXggc3lzdGVtcyB1c2UgRENFIFJQQy4uLiBpZiB0aGV5IHJ1biBhIFJQQwogKiAgICBkYWVtb24gYXQgYWxsLCBpdCdzIHVzdWFsbHkgU3VuIFJQQwogKiAgLSBEQ0UgUlBDIHJlZ2lzdHJhdGlvbnMgYXJlIHBlcnNpc3RlbnQgYW5kIHNhdmVkIG9uIGRpc2ssCiAqICAgIHdoaWxlIE1TLVJQQyByZWdpc3RyYXRpb25zIGFyZSBkb2N1bWVudGVkIGFzIG5vbi1wZXJzaXN0ZW50CiAqICAgIGFuZCBzdG9yZWQgb25seSBpbiBSQU0sIGFuZCBhdXRvLWRlc3Ryb3llZCB3aGVuIHRoZSBwcm9jZXNzCiAqICAgIGRpZXMgKHNvbWV0aGluZyBEQ0UgUlBDIGNhbid0IGRvKQogKgogKiBPZiBjb3Vyc2UsIGlmIHRoZSB1c2VyICpkaWQqIHdhbnQgdG8gcnVuIGEgRENFIFJQQyBkYWVtb24gYW55d2F5LAogKiB0aGVyZSB3b3VsZCBiZSBpbnRlcm9wZXJhYmlsaXR5IGFkdmFudGFnZXMsIGxpa2UgdGhlIHBvc3NpYmlsaXR5CiAqIG9mIHJ1bm5pbmcgYSBmdWxseSBmdW5jdGlvbmFsIERDT00gc2VydmVyIHVzaW5nIFdpbmUuLi4KICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjRXBSZWdpc3RlckEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjRXBSZWdpc3RlckEoIFJQQ19JRl9IQU5ETEUgSWZTcGVjLCBSUENfQklORElOR19WRUNUT1IgKkJpbmRpbmdWZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVUlEX1ZFQ1RPUiAqVXVpZFZlY3RvciwgUlBDX0NTVFIgQW5ub3RhdGlvbiApCnsKICBSUENTU19OUF9NRVNTQUdFIG1zZzsKICBSUENTU19OUF9SRVBMWSByZXBseTsKICBjaGFyICp2YXJkYXRhX3BheWxvYWQsICp2cDsKICBQUlBDX1NFUlZFUl9JTlRFUkZBQ0UgSWYgPSAoUFJQQ19TRVJWRVJfSU5URVJGQUNFKUlmU3BlYzsKICB1bnNpZ25lZCBsb25nIGM7CiAgUlBDX1NUQVRVUyByc2x0ID0gUlBDX1NfT0s7CgogIFRSQUNFKCIoJXAsJXAsJXAsJXMpXG4iLCBJZlNwZWMsIEJpbmRpbmdWZWN0b3IsIFV1aWRWZWN0b3IsIGRlYnVnc3RyX2EoKGNoYXIqKUFubm90YXRpb24pKTsKICBUUkFDRSgiIGlmaWQ9JXNcbiIsIGRlYnVnc3RyX2d1aWQoJklmLT5JbnRlcmZhY2VJZC5TeW50YXhHVUlEKSk7CiAgZm9yIChjPTA7IGM8QmluZGluZ1ZlY3Rvci0+Q291bnQ7IGMrKykgewogICAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKikoQmluZGluZ1ZlY3Rvci0+QmluZGluZ0hbY10pOwogICAgVFJBQ0UoIiBwcm90c2VxWyVsZF09JXNcbiIsIGMsIGRlYnVnc3RyX2EoYmluZC0+UHJvdHNlcSkpOwogICAgVFJBQ0UoIiBlbmRwb2ludFslbGRdPSVzXG4iLCBjLCBkZWJ1Z3N0cl9hKGJpbmQtPkVuZHBvaW50KSk7CiAgfQogIGlmIChVdWlkVmVjdG9yKSB7CiAgICBmb3IgKGM9MDsgYzxVdWlkVmVjdG9yLT5Db3VudDsgYysrKQogICAgICBUUkFDRSgiIG9ialslbGRdPSVzXG4iLCBjLCBkZWJ1Z3N0cl9ndWlkKFV1aWRWZWN0b3ItPlV1aWRbY10pKTsKICB9CgogIC8qIEZJWE1FOiBEbyBzb21ldGhpbmcgd2l0aCBhbm5vdGF0aW9uLiAqLwoKICAvKiBjb25zdHJ1Y3QgdGhlIG1lc3NhZ2UgdG8gcnBjc3MgKi8KICBtc2cubWVzc2FnZV90eXBlID0gUlBDU1NfTlBfTUVTU0FHRV9UWVBFSURfUkVHSVNURVJFUE1TRzsKICBtc2cubWVzc2FnZS5yZWdpc3RlcmVwbXNnLmlmYWNlID0gSWYtPkludGVyZmFjZUlkOwogIG1zZy5tZXNzYWdlLnJlZ2lzdGVyZXBtc2cubm9fcmVwbGFjZSA9IDA7CgogIG1zZy5tZXNzYWdlLnJlZ2lzdGVyZXBtc2cub2JqZWN0X2NvdW50ID0gKFV1aWRWZWN0b3IpID8gVXVpZFZlY3Rvci0+Q291bnQgOiAwOwogIG1zZy5tZXNzYWdlLnJlZ2lzdGVyZXBtc2cuYmluZGluZ19jb3VudCA9IEJpbmRpbmdWZWN0b3ItPkNvdW50OwoKICAvKiBjYWxjdWxhdGUgdmFyZGF0YSBwYXlsb2FkIHNpemUgKi8KICBtc2cudmFyZGF0YV9wYXlsb2FkX3NpemUgPSBtc2cubWVzc2FnZS5yZWdpc3RlcmVwbXNnLm9iamVjdF9jb3VudCAqIHNpemVvZihVVUlEKTsKICBmb3IgKGM9MDsgYyA8IG1zZy5tZXNzYWdlLnJlZ2lzdGVyZXBtc2cuYmluZGluZ19jb3VudDsgYysrKSB7CiAgICBScGNCaW5kaW5nICpiaW5kID0gKFJwY0JpbmRpbmcgKikoQmluZGluZ1ZlY3Rvci0+QmluZGluZ0hbY10pOwogICAgbXNnLnZhcmRhdGFfcGF5bG9hZF9zaXplICs9IHN0cmxlbihiaW5kLT5Qcm90c2VxKSArIDE7CiAgICBtc2cudmFyZGF0YV9wYXlsb2FkX3NpemUgKz0gc3RybGVuKGJpbmQtPkVuZHBvaW50KSArIDE7CiAgfQoKICAvKiBhbGxvY2F0ZSB0aGUgcGF5bG9hZCBidWZmZXIgKi8KICB2cCA9IHZhcmRhdGFfcGF5bG9hZCA9IExvY2FsQWxsb2MoTFBUUiwgbXNnLnZhcmRhdGFfcGF5bG9hZF9zaXplKTsKICBpZiAoIXZhcmRhdGFfcGF5bG9hZCkKICAgIHJldHVybiBSUENfU19PVVRfT0ZfTUVNT1JZOwoKICAvKiBwb3B1bGF0ZSB0aGUgcGF5bG9hZCBkYXRhICovCiAgZm9yIChjPTA7IGMgPCBtc2cubWVzc2FnZS5yZWdpc3RlcmVwbXNnLm9iamVjdF9jb3VudDsgYysrKSB7CiAgICBDb3B5TWVtb3J5KHZwLCBVdWlkVmVjdG9yLT5VdWlkW2NdLCBzaXplb2YoVVVJRCkpOwogICAgdnAgKz0gc2l6ZW9mKFVVSUQpOwogIH0KCiAgZm9yIChjPTA7IGMgPCBtc2cubWVzc2FnZS5yZWdpc3RlcmVwbXNnLmJpbmRpbmdfY291bnQ7IGMrKykgewogICAgUnBjQmluZGluZyAqYmluZCA9IChScGNCaW5kaW5nKikoQmluZGluZ1ZlY3Rvci0+QmluZGluZ0hbY10pOwogICAgdW5zaWduZWQgbG9uZyBwc2xlbiA9IHN0cmxlbihiaW5kLT5Qcm90c2VxKSArIDEsIGVwbGVuID0gc3RybGVuKGJpbmQtPkVuZHBvaW50KSArIDE7CiAgICBDb3B5TWVtb3J5KHZwLCBiaW5kLT5Qcm90c2VxLCBwc2xlbik7CiAgICB2cCArPSBwc2xlbjsKICAgIENvcHlNZW1vcnkodnAsIGJpbmQtPkVuZHBvaW50LCBlcGxlbik7CiAgICB2cCArPSBlcGxlbjsKICB9CgogIC8qIHNlbmQgb3VyIHJlcXVlc3QgKi8KICBpZiAoIVJQQ1JUNF9SUENTU09uRGVtYW5kQ2FsbCgmbXNnLCB2YXJkYXRhX3BheWxvYWQsICZyZXBseSkpCiAgICByc2x0ID0gUlBDX1NfT1VUX09GX01FTU9SWTsKCiAgLyogZnJlZSB0aGUgcGF5bG9hZCBidWZmZXIgKi8KICBMb2NhbEZyZWUodmFyZGF0YV9wYXlsb2FkKTsKCiAgcmV0dXJuIHJzbHQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBScGNFcFVucmVnaXN0ZXIgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjRXBVbnJlZ2lzdGVyKCBSUENfSUZfSEFORExFIElmU3BlYywgUlBDX0JJTkRJTkdfVkVDVE9SICpCaW5kaW5nVmVjdG9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVVSURfVkVDVE9SICpVdWlkVmVjdG9yICkKewogIFJQQ1NTX05QX01FU1NBR0UgbXNnOwogIFJQQ1NTX05QX1JFUExZIHJlcGx5OwogIGNoYXIgKnZhcmRhdGFfcGF5bG9hZCwgKnZwOwogIFBSUENfU0VSVkVSX0lOVEVSRkFDRSBJZiA9IChQUlBDX1NFUlZFUl9JTlRFUkZBQ0UpSWZTcGVjOwogIHVuc2lnbmVkIGxvbmcgYzsKICBSUENfU1RBVFVTIHJzbHQgPSBSUENfU19PSzsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIElmU3BlYywgQmluZGluZ1ZlY3RvciwgVXVpZFZlY3Rvcik7CiAgVFJBQ0UoIiBpZmlkPSVzXG4iLCBkZWJ1Z3N0cl9ndWlkKCZJZi0+SW50ZXJmYWNlSWQuU3ludGF4R1VJRCkpOwogIGZvciAoYz0wOyBjPEJpbmRpbmdWZWN0b3ItPkNvdW50OyBjKyspIHsKICAgIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopKEJpbmRpbmdWZWN0b3ItPkJpbmRpbmdIW2NdKTsKICAgIFRSQUNFKCIgcHJvdHNlcVslbGRdPSVzXG4iLCBjLCBkZWJ1Z3N0cl9hKGJpbmQtPlByb3RzZXEpKTsKICAgIFRSQUNFKCIgZW5kcG9pbnRbJWxkXT0lc1xuIiwgYywgZGVidWdzdHJfYShiaW5kLT5FbmRwb2ludCkpOwogIH0KICBpZiAoVXVpZFZlY3RvcikgewogICAgZm9yIChjPTA7IGM8VXVpZFZlY3Rvci0+Q291bnQ7IGMrKykKICAgICAgVFJBQ0UoIiBvYmpbJWxkXT0lc1xuIiwgYywgZGVidWdzdHJfZ3VpZChVdWlkVmVjdG9yLT5VdWlkW2NdKSk7CiAgfQoKICAvKiBjb25zdHJ1Y3QgdGhlIG1lc3NhZ2UgdG8gcnBjc3MgKi8KICBtc2cubWVzc2FnZV90eXBlID0gUlBDU1NfTlBfTUVTU0FHRV9UWVBFSURfVU5SRUdJU1RFUkVQTVNHOwogIG1zZy5tZXNzYWdlLnVucmVnaXN0ZXJlcG1zZy5pZmFjZSA9IElmLT5JbnRlcmZhY2VJZDsKCiAgbXNnLm1lc3NhZ2UudW5yZWdpc3RlcmVwbXNnLm9iamVjdF9jb3VudCA9IChVdWlkVmVjdG9yKSA/IFV1aWRWZWN0b3ItPkNvdW50IDogMDsKICBtc2cubWVzc2FnZS51bnJlZ2lzdGVyZXBtc2cuYmluZGluZ19jb3VudCA9IEJpbmRpbmdWZWN0b3ItPkNvdW50OwoKICAvKiBjYWxjdWxhdGUgdmFyZGF0YSBwYXlsb2FkIHNpemUgKi8KICBtc2cudmFyZGF0YV9wYXlsb2FkX3NpemUgPSBtc2cubWVzc2FnZS51bnJlZ2lzdGVyZXBtc2cub2JqZWN0X2NvdW50ICogc2l6ZW9mKFVVSUQpOwogIGZvciAoYz0wOyBjIDwgbXNnLm1lc3NhZ2UudW5yZWdpc3RlcmVwbXNnLmJpbmRpbmdfY291bnQ7IGMrKykgewogICAgUnBjQmluZGluZyAqYmluZCA9IChScGNCaW5kaW5nICopKEJpbmRpbmdWZWN0b3ItPkJpbmRpbmdIW2NdKTsKICAgIG1zZy52YXJkYXRhX3BheWxvYWRfc2l6ZSArPSBzdHJsZW4oYmluZC0+UHJvdHNlcSkgKyAxOwogICAgbXNnLnZhcmRhdGFfcGF5bG9hZF9zaXplICs9IHN0cmxlbihiaW5kLT5FbmRwb2ludCkgKyAxOwogIH0KCiAgLyogYWxsb2NhdGUgdGhlIHBheWxvYWQgYnVmZmVyICovCiAgdnAgPSB2YXJkYXRhX3BheWxvYWQgPSBMb2NhbEFsbG9jKExQVFIsIG1zZy52YXJkYXRhX3BheWxvYWRfc2l6ZSk7CiAgaWYgKCF2YXJkYXRhX3BheWxvYWQpCiAgICByZXR1cm4gUlBDX1NfT1VUX09GX01FTU9SWTsKCiAgLyogcG9wdWxhdGUgdGhlIHBheWxvYWQgZGF0YSAqLwogIGZvciAoYz0wOyBjIDwgbXNnLm1lc3NhZ2UudW5yZWdpc3RlcmVwbXNnLm9iamVjdF9jb3VudDsgYysrKSB7CiAgICBDb3B5TWVtb3J5KHZwLCBVdWlkVmVjdG9yLT5VdWlkW2NdLCBzaXplb2YoVVVJRCkpOwogICAgdnAgKz0gc2l6ZW9mKFVVSUQpOwogIH0KCiAgZm9yIChjPTA7IGMgPCBtc2cubWVzc2FnZS51bnJlZ2lzdGVyZXBtc2cuYmluZGluZ19jb3VudDsgYysrKSB7CiAgICBScGNCaW5kaW5nICpiaW5kID0gKFJwY0JpbmRpbmcqKShCaW5kaW5nVmVjdG9yLT5CaW5kaW5nSFtjXSk7CiAgICB1bnNpZ25lZCBsb25nIHBzbGVuID0gc3RybGVuKGJpbmQtPlByb3RzZXEpICsgMSwgZXBsZW4gPSBzdHJsZW4oYmluZC0+RW5kcG9pbnQpICsgMTsKICAgIENvcHlNZW1vcnkodnAsIGJpbmQtPlByb3RzZXEsIHBzbGVuKTsKICAgIHZwICs9IHBzbGVuOwogICAgQ29weU1lbW9yeSh2cCwgYmluZC0+RW5kcG9pbnQsIGVwbGVuKTsKICAgIHZwICs9IGVwbGVuOwogIH0KCiAgLyogc2VuZCBvdXIgcmVxdWVzdCAqLwogIGlmICghUlBDUlQ0X1JQQ1NTT25EZW1hbmRDYWxsKCZtc2csIHZhcmRhdGFfcGF5bG9hZCwgJnJlcGx5KSkKICAgIHJzbHQgPSBSUENfU19PVVRfT0ZfTUVNT1JZOwoKICAvKiBmcmVlIHRoZSBwYXlsb2FkIGJ1ZmZlciAqLwogIExvY2FsRnJlZSh2YXJkYXRhX3BheWxvYWQpOwoKICByZXR1cm4gcnNsdDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY0VwUmVzb2x2ZUJpbmRpbmcgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjRXBSZXNvbHZlQmluZGluZyggUlBDX0JJTkRJTkdfSEFORExFIEJpbmRpbmcsIFJQQ19JRl9IQU5ETEUgSWZTcGVjICkKewogIFJQQ1NTX05QX01FU1NBR0UgbXNnOwogIFJQQ1NTX05QX1JFUExZIHJlcGx5OwogIFBSUENfQ0xJRU5UX0lOVEVSRkFDRSBJZiA9IChQUlBDX0NMSUVOVF9JTlRFUkZBQ0UpSWZTcGVjOwogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopQmluZGluZzsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIEJpbmRpbmcsIElmU3BlYyk7CiAgVFJBQ0UoIiBwcm90c2VxPSVzXG4iLCBkZWJ1Z3N0cl9hKGJpbmQtPlByb3RzZXEpKTsKICBUUkFDRSgiIG9iaj0lc1xuIiwgZGVidWdzdHJfZ3VpZCgmYmluZC0+T2JqZWN0VXVpZCkpOwogIFRSQUNFKCIgaWZpZD0lc1xuIiwgZGVidWdzdHJfZ3VpZCgmSWYtPkludGVyZmFjZUlkLlN5bnRheEdVSUQpKTsKCiAgLyogRklYTUU6IHRvdGFsbHkgdW50ZXN0ZWQgKi8KCiAgLyoganVzdCByZXR1cm4gZm9yIGZ1bGx5IGJvdW5kIGhhbmRsZXMgKi8KICBpZiAoYmluZC0+RW5kcG9pbnQgJiYgKGJpbmQtPkVuZHBvaW50WzBdICE9ICdcMCcpKQogICAgcmV0dXJuIFJQQ19TX09LOwoKICAvKiBjb25zdHJ1Y3QgdGhlIG1lc3NhZ2UgdG8gcnBjc3MgKi8KICBtc2cubWVzc2FnZV90eXBlID0gUlBDU1NfTlBfTUVTU0FHRV9UWVBFSURfUkVTT0xWRUVQTVNHOwogIG1zZy5tZXNzYWdlLnJlc29sdmVlcG1zZy5pZmFjZSA9IElmLT5JbnRlcmZhY2VJZDsKICBtc2cubWVzc2FnZS5yZXNvbHZlZXBtc2cub2JqZWN0ID0gYmluZC0+T2JqZWN0VXVpZDsKIAogIG1zZy52YXJkYXRhX3BheWxvYWRfc2l6ZSA9IHN0cmxlbihiaW5kLT5Qcm90c2VxKSArIDE7CgogIC8qIHNlbmQgdGhlIG1lc3NhZ2UgKi8KICBpZiAoIVJQQ1JUNF9SUENTU09uRGVtYW5kQ2FsbCgmbXNnLCBiaW5kLT5Qcm90c2VxLCAmcmVwbHkpKQogICAgcmV0dXJuIFJQQ19TX09VVF9PRl9NRU1PUlk7CgogIC8qIGVtcHR5LXN0cmluZyByZXN1bHQgbWVhbnMgbm90IHJlZ2lzdGVyZWQgKi8KICBpZiAocmVwbHkuYXNfc3RyaW5nWzBdID09ICdcMCcpCiAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CiAgCiAgLyogb3RoZXJ3aXNlIHdlIGZ1bGx5IGJpbmQgdGhlIGhhbmRsZSAmIHJldHVybiBSUENfU19PSyAqLwogIHJldHVybiBSUENSVDRfUmVzb2x2ZUJpbmRpbmcoQmluZGluZywgcmVwbHkuYXNfc3RyaW5nKTsKfQoKdHlwZWRlZiB1bnNpZ25lZCBpbnQgdW5zaWduZWQzMjsKdHlwZWRlZiBzdHJ1Y3QgdHdyX3QKICAgIHsKICAgIHVuc2lnbmVkMzIgdG93ZXJfbGVuZ3RoOwogICAgLyogW3NpemVfaXNdICovIEJZVEUgdG93ZXJfb2N0ZXRfc3RyaW5nWyAxIF07CiAgICB9IAl0d3JfdDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBUb3dlckV4cGxvZGUgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgVG93ZXJFeHBsb2RlKAogICAgY29uc3QgdHdyX3QgKnRvd2VyLCBQUlBDX1NZTlRBWF9JREVOVElGSUVSIG9iamVjdCwgUFJQQ19TWU5UQVhfSURFTlRJRklFUiBzeW50YXgsCiAgICBjaGFyICoqcHJvdHNlcSwgY2hhciAqKmVuZHBvaW50LCBjaGFyICoqYWRkcmVzcykKewogICAgc2l6ZV90IHRvd2VyX3NpemU7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnA7CiAgICB1X2ludDE2IGZsb29yX2NvdW50OwogICAgY29uc3QgdHdyX3V1aWRfZmxvb3JfdCAqb2JqZWN0X2Zsb29yOwogICAgY29uc3QgdHdyX3V1aWRfZmxvb3JfdCAqc3ludGF4X2Zsb29yOwoKICAgIGlmIChwcm90c2VxKQogICAgICAgICpwcm90c2VxID0gTlVMTDsKICAgIGlmIChlbmRwb2ludCkKICAgICAgICAqZW5kcG9pbnQgPSBOVUxMOwogICAgaWYgKGFkZHJlc3MpCiAgICAgICAgKmFkZHJlc3MgPSBOVUxMOwoKICAgIHRvd2VyX3NpemUgPSB0b3dlci0+dG93ZXJfbGVuZ3RoOwoKICAgIGlmICh0b3dlcl9zaXplIDwgc2l6ZW9mKHVfaW50MTYpKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICBwID0gJnRvd2VyLT50b3dlcl9vY3RldF9zdHJpbmdbMF07CgogICAgZmxvb3JfY291bnQgPSAqKGNvbnN0IHVfaW50MTYgKilwOwogICAgcCArPSBzaXplb2YodV9pbnQxNik7CiAgICB0b3dlcl9zaXplIC09IHNpemVvZih1X2ludDE2KTsKICAgIFRSQUNFKCJmbG9vcl9jb3VudDogJWRcbiIsIGZsb29yX2NvdW50KTsKICAgIC8qIEZJWE1FOiBzaG91bGQgd2UgZG8gc29tZXRoaW5nIHdpdGggdGhlIGZsb29yIGNvdW50PyBhdCB0aGUgbW9tZW50IHdlIGRvbid0ICovCgogICAgaWYgKHRvd2VyX3NpemUgPCBzaXplb2YoKm9iamVjdF9mbG9vcikgKyBzaXplb2YoKnN5bnRheF9mbG9vcikpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIG9iamVjdF9mbG9vciA9IChjb25zdCB0d3JfdXVpZF9mbG9vcl90ICopcDsKICAgIHAgKz0gc2l6ZW9mKCpvYmplY3RfZmxvb3IpOwogICAgdG93ZXJfc2l6ZSAtPSBzaXplb2YoKm9iamVjdF9mbG9vcik7CiAgICBzeW50YXhfZmxvb3IgPSAoY29uc3QgdHdyX3V1aWRfZmxvb3JfdCAqKXA7CiAgICBwICs9IHNpemVvZigqc3ludGF4X2Zsb29yKTsKICAgIHRvd2VyX3NpemUgLT0gc2l6ZW9mKCpzeW50YXhfZmxvb3IpOwoKICAgIGlmICgob2JqZWN0X2Zsb29yLT5jb3VudF9saHMgIT0gc2l6ZW9mKG9iamVjdF9mbG9vci0+cHJvdGlkKSArCiAgICAgICAgc2l6ZW9mKG9iamVjdF9mbG9vci0+dXVpZCkgKyBzaXplb2Yob2JqZWN0X2Zsb29yLT5tYWpvcl92ZXJzaW9uKSkgfHwKICAgICAgICAob2JqZWN0X2Zsb29yLT5wcm90aWQgIT0gRVBNX1BST1RPQ09MX1VVSUQpIHx8CiAgICAgICAgKG9iamVjdF9mbG9vci0+Y291bnRfcmhzICE9IHNpemVvZihvYmplY3RfZmxvb3ItPm1pbm9yX3ZlcnNpb24pKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgaWYgKChzeW50YXhfZmxvb3ItPmNvdW50X2xocyAhPSBzaXplb2Yoc3ludGF4X2Zsb29yLT5wcm90aWQpICsKICAgICAgICBzaXplb2Yoc3ludGF4X2Zsb29yLT51dWlkKSArIHNpemVvZihzeW50YXhfZmxvb3ItPm1ham9yX3ZlcnNpb24pKSB8fAogICAgICAgIChzeW50YXhfZmxvb3ItPnByb3RpZCAhPSBFUE1fUFJPVE9DT0xfVVVJRCkgfHwKICAgICAgICAoc3ludGF4X2Zsb29yLT5jb3VudF9yaHMgIT0gc2l6ZW9mKHN5bnRheF9mbG9vci0+bWlub3JfdmVyc2lvbikpKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICBzdGF0dXMgPSBScGNUcmFuc3BvcnRfUGFyc2VUb3BPZlRvd2VyKHAsIHRvd2VyX3NpemUsIHByb3RzZXEsIGFkZHJlc3MsIGVuZHBvaW50KTsKICAgIGlmICgoc3RhdHVzID09IFJQQ19TX09LKSAmJiBzeW50YXggJiYgb2JqZWN0KQogICAgewogICAgICAgIHN5bnRheC0+U3ludGF4R1VJRCA9IHN5bnRheF9mbG9vci0+dXVpZDsKICAgICAgICBzeW50YXgtPlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uID0gc3ludGF4X2Zsb29yLT5tYWpvcl92ZXJzaW9uOwogICAgICAgIHN5bnRheC0+U3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24gPSBzeW50YXhfZmxvb3ItPm1pbm9yX3ZlcnNpb247CiAgICAgICAgb2JqZWN0LT5TeW50YXhHVUlEID0gb2JqZWN0X2Zsb29yLT51dWlkOwogICAgICAgIG9iamVjdC0+U3ludGF4VmVyc2lvbi5NYWpvclZlcnNpb24gPSBvYmplY3RfZmxvb3ItPm1ham9yX3ZlcnNpb247CiAgICAgICAgb2JqZWN0LT5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbiA9IG9iamVjdF9mbG9vci0+bWlub3JfdmVyc2lvbjsKICAgIH0KICAgIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICBUb3dlckNvbnN0cnVjdCAoUlBDUlQ0LkApCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBUb3dlckNvbnN0cnVjdCgKICAgIGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqb2JqZWN0LCBjb25zdCBSUENfU1lOVEFYX0lERU5USUZJRVIgKnN5bnRheCwKICAgIGNvbnN0IGNoYXIgKnByb3RzZXEsIGNvbnN0IGNoYXIgKmVuZHBvaW50LCBjb25zdCBjaGFyICphZGRyZXNzLAogICAgdHdyX3QgKip0b3dlcikKewogICAgc2l6ZV90IHRvd2VyX3NpemU7CiAgICBSUENfU1RBVFVTIHN0YXR1czsKICAgIHVuc2lnbmVkIGNoYXIgKnA7CiAgICB0d3JfdXVpZF9mbG9vcl90ICpvYmplY3RfZmxvb3I7CiAgICB0d3JfdXVpZF9mbG9vcl90ICpzeW50YXhfZmxvb3I7CgogICAgKnRvd2VyID0gTlVMTDsKCiAgICBzdGF0dXMgPSBScGNUcmFuc3BvcnRfR2V0VG9wT2ZUb3dlcihOVUxMLCAmdG93ZXJfc2l6ZSwgcHJvdHNlcSwgYWRkcmVzcywgZW5kcG9pbnQpOwoKICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICAgICAgcmV0dXJuIHN0YXR1czsKCiAgICB0b3dlcl9zaXplICs9IHNpemVvZih1X2ludDE2KSArIHNpemVvZigqb2JqZWN0X2Zsb29yKSArIHNpemVvZigqc3ludGF4X2Zsb29yKTsKICAgICp0b3dlciA9IElfUnBjQWxsb2NhdGUoRklFTERfT0ZGU0VUKHR3cl90LCB0b3dlcl9vY3RldF9zdHJpbmdbdG93ZXJfc2l6ZV0pKTsKICAgIGlmICghKnRvd2VyKQogICAgICAgIHJldHVybiBSUENfU19PVVRfT0ZfUkVTT1VSQ0VTOwoKICAgICgqdG93ZXIpLT50b3dlcl9sZW5ndGggPSB0b3dlcl9zaXplOwogICAgcCA9ICYoKnRvd2VyKS0+dG93ZXJfb2N0ZXRfc3RyaW5nWzBdOwogICAgKih1X2ludDE2ICopcCA9IDU7IC8qIG51bWJlciBvZiBmbG9vcnMgKi8KICAgIHAgKz0gc2l6ZW9mKHVfaW50MTYpOwogICAgb2JqZWN0X2Zsb29yID0gKHR3cl91dWlkX2Zsb29yX3QgKilwOwogICAgcCArPSBzaXplb2YoKm9iamVjdF9mbG9vcik7CiAgICBzeW50YXhfZmxvb3IgPSAodHdyX3V1aWRfZmxvb3JfdCAqKXA7CiAgICBwICs9IHNpemVvZigqc3ludGF4X2Zsb29yKTsKCiAgICBvYmplY3RfZmxvb3ItPmNvdW50X2xocyA9IHNpemVvZihvYmplY3RfZmxvb3ItPnByb3RpZCkgKyBzaXplb2Yob2JqZWN0X2Zsb29yLT51dWlkKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihvYmplY3RfZmxvb3ItPm1ham9yX3ZlcnNpb24pOwogICAgb2JqZWN0X2Zsb29yLT5wcm90aWQgPSBFUE1fUFJPVE9DT0xfVVVJRDsKICAgIG9iamVjdF9mbG9vci0+Y291bnRfcmhzID0gc2l6ZW9mKG9iamVjdF9mbG9vci0+bWlub3JfdmVyc2lvbik7CiAgICBvYmplY3RfZmxvb3ItPnV1aWQgPSBvYmplY3QtPlN5bnRheEdVSUQ7CiAgICBvYmplY3RfZmxvb3ItPm1ham9yX3ZlcnNpb24gPSBvYmplY3QtPlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uOwogICAgb2JqZWN0X2Zsb29yLT5taW5vcl92ZXJzaW9uID0gb2JqZWN0LT5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbjsKCiAgICBzeW50YXhfZmxvb3ItPmNvdW50X2xocyA9IHNpemVvZihzeW50YXhfZmxvb3ItPnByb3RpZCkgKyBzaXplb2Yoc3ludGF4X2Zsb29yLT51dWlkKSArCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihzeW50YXhfZmxvb3ItPm1ham9yX3ZlcnNpb24pOwogICAgc3ludGF4X2Zsb29yLT5wcm90aWQgPSBFUE1fUFJPVE9DT0xfVVVJRDsKICAgIHN5bnRheF9mbG9vci0+Y291bnRfcmhzID0gc2l6ZW9mKHN5bnRheF9mbG9vci0+bWlub3JfdmVyc2lvbik7CiAgICBzeW50YXhfZmxvb3ItPnV1aWQgPSBzeW50YXgtPlN5bnRheEdVSUQ7CiAgICBzeW50YXhfZmxvb3ItPm1ham9yX3ZlcnNpb24gPSBzeW50YXgtPlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uOwogICAgc3ludGF4X2Zsb29yLT5taW5vcl92ZXJzaW9uID0gc3ludGF4LT5TeW50YXhWZXJzaW9uLk1pbm9yVmVyc2lvbjsKCiAgICBzdGF0dXMgPSBScGNUcmFuc3BvcnRfR2V0VG9wT2ZUb3dlcihwLCAmdG93ZXJfc2l6ZSwgcHJvdHNlcSwgYWRkcmVzcywgZW5kcG9pbnQpOwogICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgIHsKICAgICAgICBJX1JwY0ZyZWUoKnRvd2VyKTsKICAgICAgICAqdG93ZXIgPSBOVUxMOwogICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9CiAgICByZXR1cm4gUlBDX1NfT0s7Cn0K