LyoKICogZHJpdmVycy9pbnB1dC9taXNjL2FtYmFyZWxsYV9pcl9wYW5hc29uaWMuYwogKgogKiBIaXN0b3J5OgogKiAgICAgIDIwMDcvMDMvMjggLSBbRHJhZ29uIENoaWFuZ10gY3JlYXRlZCBmaWxlCiAqCTIwMDkvMDMvMTAgLSBbQW50aG9ueSBHaW5nZXJdIFBvcnQgdG8gMi42LjI4CiAqCiAqIENvcHlyaWdodCAoQykgMjAwNC0yMDA5LCBBbWJhcmVsbGEsIEluYy4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUKICogR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UKICogYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNyBVU0EKICoKICovCgojaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KCi8qKgogKiBQdWxzZS1XaWR0aC1Db2RlZCBTaWduYWxzIHZhcnkgdGhlIGxlbmd0aCBvZiBwdWxzZXMgdG8gY29kZSB0aGUgaW5mb3JtYXRpb24uCiAqIEluIHRoaXMgY2FzZSBpZiB0aGUgcHVsc2Ugd2lkdGggaXMgc2hvcnQgKGFwcHJveGltYXRlbHkgNTUwdXMpIGl0CiAqIGNvcnJlc3BvbmRzIHRvIGEgbG9naWNhbCB6ZXJvIG9yIGEgbG93LiBJZiB0aGUgcHVsc2Ugd2lkdGggaXMgbG9uZwogKiAoYXBwcm94aW1hdGVseSAyMjAwdXMpIGl0IGNvcnJlc3BvbmRzIHRvIGEgbG9naWNhbCBvbmUgb3IgYSBoaWdoLgogKgogKiAgICAgICAgICstLSsgICstLSsgICstLS0tKyAgKy0tLS0rCiAqICAgICAgICAgfCAgfCAgfCAgfCAgfCAgICB8ICB8ICAgIHwKICogICAgICAtLS0rICArLS0rICArLS0rICAgICstLSsgICAgKy0tLQogKiAgICAgICAgICAwICAgICAwICAgICAgMSAgICAgICAxCiAqLwoKI2RlZmluZSBQQU5BU09OSUNfREVGQVVMVF9GUkVRVUVOQ1kJMzgwMDAJLyogMzhLSHogKi8KCi8qIFQgPSA0MjAgo2dzIHRvIGFwcHJveCA0MjQgo2dzIGluIHRoZSBVU0EgYW5kIENhbmFkYSAqLwovKiBUID0gNDU0IKNncyB0byBhcHByb3ggNDYwIKNncyBpbiBFdXJvcGUgYW5kIG90aGVycyAgKi8KI2RlZmluZSBQQU5BU09OSUNfREVGQVVMVF9TTUFMTEVSX1RJTUUJNDU0CS8qIFQsIDQ1MCBtaWNyb3NlY29uZHMuICovCgovKiogYml0IDAKICogICAgICAgICArLS0tLSsgICAgKy0tLQogKiAgICAgICAgIHwgICAgfCAgICB8CiAqICAgICAgLS0tKyAgICArLS0tLSsKICogICAgICAgICAgIDJUICAgMlQKICovCgovKiogYml0IDEKICogICAgICAgICArLS0tLSsgICAgICAgICAgICArLS0tCiAqICAgICAgICAgfCAgICB8ICAgICAgICAgICAgfAogKiAgICAgIC0tLSsgICAgKy0tLS0tLS0tLS0tLSsKICogICAgICAgICAgIDJUICAgICAgIDZUCiAqLwoKLyoqIHN0YXJ0CiAqICAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKyAgICAgICAgICAgICAgICArLS0tCiAqICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICB8CiAqICAgICAgLS0tKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKy0tLS0tLS0tLS0tLS0tLS0rCiAqICAgICAgICAgICAgICAgICAgICAgICAgIDE2VCAgICAgICAgICAgICAgICAgICAgICA4VAogKi8KCiNkZWZpbmUgUEFOQVNPTklDX0xFQURFUl9ISUdIX1VQQk9VTkQJNTAKI2RlZmluZSBQQU5BU09OSUNfTEVBREVSX0hJR0hfTE9XQk9VTkQJNDIKI2RlZmluZSBQQU5BU09OSUNfTEVBREVSX0xPV19VUEJPVU5ECTI2CiNkZWZpbmUgUEFOQVNPTklDX0xFQURFUl9MT1dfTE9XQk9VTkQJMTgKCiNkZWZpbmUgUEFOQVNPTklDX0RBVEFfSElHSF9VUEJPVU5ECTkKI2RlZmluZSBQQU5BU09OSUNfREFUQV9ISUdIX0xPV0JPVU5ECTEKI2RlZmluZSBQQU5BU09OSUNfREFUQV8wX0xPV19VUEJPVU5ECTkKI2RlZmluZSBQQU5BU09OSUNfREFUQV8wX0xPV19MT1dCT1VORAkxCiNkZWZpbmUgUEFOQVNPTklDX0RBVEFfMV9MT1dfVVBCT1VORAkyMAojZGVmaW5lIFBBTkFTT05JQ19EQVRBXzFfTE9XX0xPV0JPVU5ECTEyCgpzdGF0aWMgaW50IGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfbGVhZGVyX2NvZGUoc3RydWN0IGFtYmFyZWxsYV9pcl9pbmZvICpwaW5mbykKewoJdTE2IHZhbCA9IGFtYmFyZWxsYV9pcl9yZWFkX2RhdGEocGluZm8sIHBpbmZvLT5pcl9wcmVhZCk7CgoJaWYgKCh2YWwgPCBQQU5BU09OSUNfTEVBREVSX0hJR0hfVVBCT1VORCkgICYmCgkgICAgKHZhbCA+IFBBTkFTT05JQ19MRUFERVJfSElHSF9MT1dCT1VORCkpIHsKCX0gZWxzZSB7CgkJcmV0dXJuIDA7Cgl9CgoJaWYgKChwaW5mby0+aXJfcHJlYWQgKyAxKSA+PSBNQVhfSVJfQlVGRkVSKSB7CgkJdmFsID0gYW1iYXJlbGxhX2lyX3JlYWRfZGF0YShwaW5mbywgMCk7Cgl9IGVsc2UgewoJCXZhbCA9IGFtYmFyZWxsYV9pcl9yZWFkX2RhdGEocGluZm8sIHBpbmZvLT5pcl9wcmVhZCArIDEpOwoJfQoKCWlmICgodmFsIDwgUEFOQVNPTklDX0xFQURFUl9MT1dfVVBCT1VORCkgJiYKCSAgICAodmFsID4gUEFOQVNPTklDX0xFQURFUl9MT1dfTE9XQk9VTkQpICkKCQlyZXR1cm4gMTsKCWVsc2UKCQlyZXR1cm4gMDsKfQoKc3RhdGljIGludCBhbWJhcmVsbGFfaXJfcGFuYXNvbmljX2ZpbmRfaGVhZChzdHJ1Y3QgYW1iYXJlbGxhX2lyX2luZm8gKnBpbmZvKQp7CglpbnQgaSwgdmFsID0gMDsKCglpID0gYW1iYXJlbGxhX2lyX2dldF90aWNrX3NpemUocGluZm8pIC0gcGluZm8tPmZyYW1lX2luZm8uZnJhbWVfaGVhZF9zaXplICsgMTsKCgl3aGlsZShpLS0pIHsKCQlpZihhbWJhcmVsbGFfaXJfcGFuYXNvbmljX3B1bHNlX2xlYWRlcl9jb2RlKHBpbmZvKSkgewoJCQlkZXZfZGJnKCZwaW5mby0+aW5wdXQtPmRldiwgImZpbmQgbGVhZGVyIGNvZGUsIGkgWyVkXVxuIiwgaSk7CgkJCXZhbCA9IDE7CgkJCWJyZWFrOwoJCX0gZWxzZSB7CgkJCWRldl9kYmcoJnBpbmZvLT5pbnB1dC0+ZGV2LCAiZGlkbid0ICBmaW5kIGxlYWRlciBjb2RlLCBpIFslZF1cbiIsIGkpOwoJCQlhbWJhcmVsbGFfaXJfbW92ZV9yZWFkX3B0cihwaW5mbywgMSk7CgkJfQoJfQoKCXJldHVybiB2YWwgOwp9CgpzdGF0aWMgaW50IGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfY29kZV8wKHN0cnVjdCBhbWJhcmVsbGFfaXJfaW5mbyAqcGluZm8pCnsKCXUxNiB2YWwgPSBhbWJhcmVsbGFfaXJfcmVhZF9kYXRhKHBpbmZvLCBwaW5mby0+aXJfcHJlYWQpOwoJaWYgKCh2YWwgPCBQQU5BU09OSUNfREFUQV9ISUdIX1VQQk9VTkQpICAmJgoJICAgICh2YWwgPiBQQU5BU09OSUNfREFUQV9ISUdIX0xPV0JPVU5EKSkgewoJfSBlbHNlIHsKCQlyZXR1cm4gMDsKCX0KCglpZiAoKHBpbmZvLT5pcl9wcmVhZCArIDEpID49IE1BWF9JUl9CVUZGRVIpIHsKCQl2YWwgPSBhbWJhcmVsbGFfaXJfcmVhZF9kYXRhKHBpbmZvLCAwKTsKCX0gZWxzZSB7CgkJdmFsID0gYW1iYXJlbGxhX2lyX3JlYWRfZGF0YShwaW5mbywgcGluZm8tPmlyX3ByZWFkICsgMSk7Cgl9CgoJaWYgKCh2YWwgPCBQQU5BU09OSUNfREFUQV8wX0xPV19VUEJPVU5EKSAmJgoJICAgICh2YWwgPiBQQU5BU09OSUNfREFUQV8wX0xPV19MT1dCT1VORCkgKQoJCXJldHVybiAxOwoJZWxzZQoJCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfY29kZV8xKHN0cnVjdCBhbWJhcmVsbGFfaXJfaW5mbyAqcGluZm8pCnsKCXUxNiB2YWwgPSBhbWJhcmVsbGFfaXJfcmVhZF9kYXRhKHBpbmZvLCBwaW5mby0+aXJfcHJlYWQpOwoKCWlmICgodmFsIDwgUEFOQVNPTklDX0RBVEFfSElHSF9VUEJPVU5EKSAgJiYKCSAgICAodmFsID4gUEFOQVNPTklDX0RBVEFfSElHSF9MT1dCT1VORCkpIHsKCX0gZWxzZSB7CgkJcmV0dXJuIDA7Cgl9CgoJaWYgKChwaW5mby0+aXJfcHJlYWQgKyAxKSA+PSBNQVhfSVJfQlVGRkVSKSB7CgkJdmFsID0gYW1iYXJlbGxhX2lyX3JlYWRfZGF0YShwaW5mbywgMCk7Cgl9IGVsc2UgewoJCXZhbCA9IGFtYmFyZWxsYV9pcl9yZWFkX2RhdGEocGluZm8sIHBpbmZvLT5pcl9wcmVhZCArIDEpOwoJfQoKCWlmICgodmFsIDwgUEFOQVNPTklDX0RBVEFfMV9MT1dfVVBCT1VORCkgJiYKCSAgICAodmFsID4gUEFOQVNPTklDX0RBVEFfMV9MT1dfTE9XQk9VTkQpICkKCQlyZXR1cm4gMTsKCWVsc2UKCQlyZXR1cm4gMDsKfQoKc3RhdGljIGludCBhbWJhcmVsbGFfaXJfcGFuYXNvbmljX3B1bHNlX2RhdGFfdHJhbnNsYXRlKHN0cnVjdCBhbWJhcmVsbGFfaXJfaW5mbyAqcGluZm8sIHU4ICogZGF0YSkKewoJaW50IGk7CgoJKmRhdGEgPSAwOwoKCWZvciAoaSA9IDc7IGkgPj0gMDsgaS0tKSB7CgkJaWYgKGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfY29kZV8wKHBpbmZvKSkgewoKCQl9IGVsc2UgaWYgKGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfY29kZV8xKHBpbmZvKSkgewoJCQkqZGF0YSB8PSAxIDw8IGk7CgkJfSBlbHNlIHsKCQkJZGV2X2RiZygmcGluZm8tPmlucHV0LT5kZXYsICIlZCBFUlJPUiwgdGhlIHdhdmVmb3JtIGNhbid0IG1hdGNoIiwKCQkJCSAgcGluZm8tPmlyX3ByZWFkKTsKCQkJcmV0dXJuIC0xOwoJCX0KCQlhbWJhcmVsbGFfaXJfbW92ZV9yZWFkX3B0cihwaW5mbywgMik7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgYW1iYXJlbGxhX2lyX3BhbmFzb25pY19wdWxzZV9kZWNvZGUoc3RydWN0IGFtYmFyZWxsYV9pcl9pbmZvICpwaW5mbywgdTMyICp1aWQpCnsKCXU4IGFkZHIwID0gMCwgYWRkcjEgPSAwLCBkYXRhMCA9IDAsIGRhdGExID0gMCwgZGF0YTIgPSAwLCBkYXRhMyA9IDA7CglpbnQgcnZhbDsKCgkvKiBUaGVuIGZvbGxvd3MgMjIgYml0cyBvZiBkYXRhLCBicm9rZW4gZG93biBpbiA0IGJ5dGVzIG9mIDggYml0cy4gKi8KCgkvKiBUaGUgZmlyc3QgOCBiaXRzIGlzIHRoZSBBZGRyZXNzIDAuICovCglydmFsID0gYW1iYXJlbGxhX2lyX3BhbmFzb25pY19wdWxzZV9kYXRhX3RyYW5zbGF0ZShwaW5mbywgJmFkZHIwKTsKCWlmIChydmFsIDwgMCkKCQlyZXR1cm4gcnZhbDsKCgkvKiBUaGUgc2Vjb25kIDggYml0cyBpcyB0aGUgQWRkcmVzcyAxLiAqLwoJcnZhbCA9IGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfZGF0YV90cmFuc2xhdGUocGluZm8sICZhZGRyMSk7CglpZiAocnZhbCA8IDApCgkJcmV0dXJuIHJ2YWw7CgoJLyogVGhlIHRoaXJkIDggYml0cyBpcyB0aGUgZGF0YSAwLiAqLwoJcnZhbCA9IGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfZGF0YV90cmFuc2xhdGUocGluZm8sICZkYXRhMCk7CglpZiAocnZhbCA8IDApCgkJcmV0dXJuIHJ2YWw7CgoJLyogVGhlIHRoaXJkIDggYml0cyBpcyB0aGUgZGF0YSAxLiAqLwoJcnZhbCA9IGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfZGF0YV90cmFuc2xhdGUocGluZm8sICZkYXRhMSk7CglpZiAocnZhbCA8IDApCgkJcmV0dXJuIHJ2YWw7CgoJLyogVGhlIHRoaXJkIDggYml0cyBpcyB0aGUgZGF0YSAyLiAqLwoJcnZhbCA9IGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfZGF0YV90cmFuc2xhdGUocGluZm8sICZkYXRhMik7CglpZiAocnZhbCA8IDApCgkJcmV0dXJuIHJ2YWw7CgoJLyogVGhlIHRoaXJkIDggYml0cyBpcyB0aGUgZGF0YSAzLiAqLwoJcnZhbCA9IGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcHVsc2VfZGF0YV90cmFuc2xhdGUocGluZm8sICZkYXRhMyk7CglpZiAocnZhbCA8IDApCgkJcmV0dXJuIHJ2YWw7CgoJZGV2X2RiZygmcGluZm8tPmlucHV0LT5kZXYsICJcdGFkZHIwXHRhZGRyMVx0ZGF0YTBcdGRhdGExXHRkYXRhMlx0ZGF0YTMiKTsKCWRldl9kYmcoJnBpbmZvLT5pbnB1dC0+ZGV2LCAiXHQweCV4XHQweCV4XHQweCV4XHQweCV4XHQweCV4XHQweCV4XG4iLAoJCQlhZGRyMCwgYWRkcjEsIGRhdGEwLCBkYXRhMSwgZGF0YTIsIGRhdGEzKTsKCgkqdWlkID0gKGRhdGEwIDw8IDI0KSB8IChkYXRhMSA8PCAxNikgfCAoZGF0YTIgPDwgOCkgfCBkYXRhMzsKCglyZXR1cm4gMDsKfQoKaW50IGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfcGFyc2Uoc3RydWN0IGFtYmFyZWxsYV9pcl9pbmZvICpwaW5mbywgdTMyICp1aWQpCnsKCWludAkJCQlydmFsOwoJaW50CQkJCWN1cl9wdHIgPSBwaW5mby0+aXJfcHJlYWQ7CgoJaWYgKGFtYmFyZWxsYV9pcl9wYW5hc29uaWNfZmluZF9oZWFkKHBpbmZvKQoJCSYmIGFtYmFyZWxsYV9pcl9nZXRfdGlja19zaXplKHBpbmZvKSA+PSBwaW5mby0+ZnJhbWVfaW5mby5mcmFtZV9kYXRhX3NpemUKCQkrIHBpbmZvLT5mcmFtZV9pbmZvLmZyYW1lX2hlYWRfc2l6ZSkgewoKCQlkZXZfZGJnKCZwaW5mby0+aW5wdXQtPmRldiwgImdvIHRvIGRlY29kZSBzdGF0Z2VcbiIpOwoJCWFtYmFyZWxsYV9pcl9tb3ZlX3JlYWRfcHRyKHBpbmZvLCBwaW5mby0+ZnJhbWVfaW5mby5mcmFtZV9oZWFkX3NpemUpOy8vbW92ZSBwdHIgdG8gZGF0YQoJCXJ2YWwgPSBhbWJhcmVsbGFfaXJfcGFuYXNvbmljX3B1bHNlX2RlY29kZShwaW5mbywgdWlkKTsKCX0gZWxzZSB7CgkJcmV0dXJuIC0xOwoJfQoKCWlmIChydmFsID49IDApIHsKCQlkZXZfZGJnKCZwaW5mby0+aW5wdXQtPmRldiwgImJ1ZmZlclslZF0tLT5tb3JuYWwga2V5XG4iLCBjdXJfcHRyKTsKCQlyZXR1cm4gMDsKCX0KCglyZXR1cm4gKC0xKTsKfQoKdm9pZCBhbWJhcmVsbGFfaXJfZ2V0X3BhbmFzb25pY19pbmZvKHN0cnVjdCBhbWJhcmVsbGFfaXJfZnJhbWVfaW5mbyAqcGZyYW1lX2luZm8pCnsKCXBmcmFtZV9pbmZvLT5mcmFtZV9oZWFkX3NpemUgCT0gMjsKCXBmcmFtZV9pbmZvLT5mcmFtZV9kYXRhX3NpemUgCT0gOTY7CglwZnJhbWVfaW5mby0+ZnJhbWVfZW5kX3NpemUJPSAxOwoJcGZyYW1lX2luZm8tPmZyYW1lX3JlcGVhdF9oZWFkX3NpemUJPSAwOwp9Cgo=