LyoKICogUlBDIG1lc3NhZ2VzCiAqCiAqIENvcHlyaWdodCAyMDAxLTIwMDIgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqIENvcHlyaWdodCAyMDA2IENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKI2luY2x1ZGUgInJwY2RjZXAuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAicnBjX2JpbmRpbmcuaCIKI2luY2x1ZGUgInJwY19kZWZzLmgiCiNpbmNsdWRlICJycGNfbWVzc2FnZS5oIgojaW5jbHVkZSAibmNhc3RhdHVzLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKLyogbm90ZTogdGhlIERDRS9SUEMgc3BlYyBzYXlzIHRoZSBhbGlnbm1lbnQgYW1vdW50IHNob3VsZCBiZSA0LCBidXQKICogTVMvUlBDIHNlcnZlcnMgc2VlbSB0byBhbHdheXMgdXNlIDE2ICovCiNkZWZpbmUgQVVUSF9BTElHTk1FTlQgMTYKCi8qIGdldHMgdGhlIGFtb3VudCBuZWVkZWQgdG8gcm91bmQgYSB2YWx1ZSB1cCB0byB0aGUgc3BlY2lmaWVkIGFsaWdubWVudCAqLwojZGVmaW5lIFJPVU5EX1VQX0FNT1VOVCh2YWx1ZSwgYWxpZ25tZW50KSBcCiAgICAoKChhbGlnbm1lbnQpIC0gKCgodmFsdWUpICUgKGFsaWdubWVudCkpKSkgJSAoYWxpZ25tZW50KSkKI2RlZmluZSBST1VORF9VUCh2YWx1ZSwgYWxpZ25tZW50KSAoKCh2YWx1ZSkgKyAoKGFsaWdubWVudCkgLSAxKSkgJiB+KChhbGlnbm1lbnQpLTEpKQoKZW51bSBzZWN1cmVfcGFja2V0X2RpcmVjdGlvbgp7CiAgU0VDVVJFX1BBQ0tFVF9TRU5ELAogIFNFQ1VSRV9QQUNLRVRfUkVDRUlWRQp9OwoKc3RhdGljIFJQQ19TVEFUVVMgSV9ScGNSZUFsbG9jYXRlQnVmZmVyKFBSUENfTUVTU0FHRSBwTXNnKTsKCnN0YXRpYyBEV09SRCBSUENSVDRfR2V0SGVhZGVyU2l6ZShjb25zdCBScGNQa3RIZHIgKkhlYWRlcikKewogIHN0YXRpYyBjb25zdCBEV09SRCBoZWFkZXJfc2l6ZXNbXSA9IHsKICAgIHNpemVvZihIZWFkZXItPnJlcXVlc3QpLCAwLCBzaXplb2YoSGVhZGVyLT5yZXNwb25zZSksCiAgICBzaXplb2YoSGVhZGVyLT5mYXVsdCksIDAsIDAsIDAsIDAsIDAsIDAsIDAsIHNpemVvZihIZWFkZXItPmJpbmQpLAogICAgc2l6ZW9mKEhlYWRlci0+YmluZF9hY2spLCBzaXplb2YoSGVhZGVyLT5iaW5kX25hY2spLAogICAgMCwgMCwgMCwgMCwgMAogIH07CiAgVUxPTkcgcmV0ID0gMDsKICAKICBpZiAoSGVhZGVyLT5jb21tb24ucHR5cGUgPCBzaXplb2YoaGVhZGVyX3NpemVzKSAvIHNpemVvZihoZWFkZXJfc2l6ZXNbMF0pKSB7CiAgICByZXQgPSBoZWFkZXJfc2l6ZXNbSGVhZGVyLT5jb21tb24ucHR5cGVdOwogICAgaWYgKHJldCA9PSAwKQogICAgICBGSVhNRSgidW5oYW5kbGVkIHBhY2tldCB0eXBlXG4iKTsKICAgIGlmIChIZWFkZXItPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfT0JKRUNUX1VVSUQpCiAgICAgIHJldCArPSBzaXplb2YoVVVJRCk7CiAgfSBlbHNlIHsKICAgIFRSQUNFKCJpbnZhbGlkIHBhY2tldCB0eXBlXG4iKTsKICB9CgogIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgcGFja2V0X2hhc19ib2R5KGNvbnN0IFJwY1BrdEhkciAqSGVhZGVyKQp7CiAgICByZXR1cm4gKEhlYWRlci0+Y29tbW9uLnB0eXBlID09IFBLVF9GQVVMVCkgfHwKICAgICAgICAgICAoSGVhZGVyLT5jb21tb24ucHR5cGUgPT0gUEtUX1JFUVVFU1QpIHx8CiAgICAgICAgICAgKEhlYWRlci0+Y29tbW9uLnB0eXBlID09IFBLVF9SRVNQT05TRSk7Cn0KCnN0YXRpYyBpbnQgcGFja2V0X2hhc19hdXRoX3ZlcmlmaWVyKGNvbnN0IFJwY1BrdEhkciAqSGVhZGVyKQp7CiAgICByZXR1cm4gIShIZWFkZXItPmNvbW1vbi5wdHlwZSA9PSBQS1RfQklORF9OQUNLKSAmJgogICAgICAgICAgICEoSGVhZGVyLT5jb21tb24ucHR5cGUgPT0gUEtUX1NIVVRET1dOKTsKfQoKc3RhdGljIFZPSUQgUlBDUlQ0X0J1aWxkQ29tbW9uSGVhZGVyKFJwY1BrdEhkciAqSGVhZGVyLCB1bnNpZ25lZCBjaGFyIFBhY2tldFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uKQp7CiAgSGVhZGVyLT5jb21tb24ucnBjX3ZlciA9IFJQQ19WRVJfTUFKT1I7CiAgSGVhZGVyLT5jb21tb24ucnBjX3Zlcl9taW5vciA9IFJQQ19WRVJfTUlOT1I7CiAgSGVhZGVyLT5jb21tb24ucHR5cGUgPSBQYWNrZXRUeXBlOwogIEhlYWRlci0+Y29tbW9uLmRyZXBbMF0gPSBMT0JZVEUoTE9XT1JEKERhdGFSZXByZXNlbnRhdGlvbikpOwogIEhlYWRlci0+Y29tbW9uLmRyZXBbMV0gPSBISUJZVEUoTE9XT1JEKERhdGFSZXByZXNlbnRhdGlvbikpOwogIEhlYWRlci0+Y29tbW9uLmRyZXBbMl0gPSBMT0JZVEUoSElXT1JEKERhdGFSZXByZXNlbnRhdGlvbikpOwogIEhlYWRlci0+Y29tbW9uLmRyZXBbM10gPSBISUJZVEUoSElXT1JEKERhdGFSZXByZXNlbnRhdGlvbikpOwogIEhlYWRlci0+Y29tbW9uLmF1dGhfbGVuID0gMDsKICBIZWFkZXItPmNvbW1vbi5jYWxsX2lkID0gMTsKICBIZWFkZXItPmNvbW1vbi5mbGFncyA9IDA7CiAgLyogRmxhZ3MgYW5kIGZyYWdtZW50IGxlbmd0aCBhcmUgY29tcHV0ZWQgaW4gUlBDUlQ0X1NlbmQuICovCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCnN0YXRpYyBScGNQa3RIZHIgKlJQQ1JUNF9CdWlsZFJlcXVlc3RIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIEJ1ZmZlckxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IFByb2NOdW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVUlEICpPYmplY3RVdWlkKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CiAgQk9PTCBoYXNfb2JqZWN0OwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBoYXNfb2JqZWN0ID0gKE9iamVjdFV1aWQgIT0gTlVMTCAmJiAhVXVpZElzTmlsKE9iamVjdFV1aWQsICZzdGF0dXMpKTsKICBoZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGhlYWRlci0+cmVxdWVzdCkgKyAoaGFzX29iamVjdCA/IHNpemVvZihVVUlEKSA6IDApKTsKICBpZiAoaGVhZGVyID09IE5VTEwpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgUlBDUlQ0X0J1aWxkQ29tbW9uSGVhZGVyKGhlYWRlciwgUEtUX1JFUVVFU1QsIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBzaXplb2YoaGVhZGVyLT5yZXF1ZXN0KTsKICBoZWFkZXItPnJlcXVlc3QuYWxsb2NfaGludCA9IEJ1ZmZlckxlbmd0aDsKICBoZWFkZXItPnJlcXVlc3QuY29udGV4dF9pZCA9IDA7CiAgaGVhZGVyLT5yZXF1ZXN0Lm9wbnVtID0gUHJvY051bTsKICBpZiAoaGFzX29iamVjdCkgewogICAgaGVhZGVyLT5jb21tb24uZmxhZ3MgfD0gUlBDX0ZMR19PQkpFQ1RfVVVJRDsKICAgIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuICs9IHNpemVvZihVVUlEKTsKICAgIG1lbWNweSgmaGVhZGVyLT5yZXF1ZXN0ICsgMSwgT2JqZWN0VXVpZCwgc2l6ZW9mKFVVSUQpKTsKICB9CgogIHJldHVybiBoZWFkZXI7Cn0KClJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkUmVzcG9uc2VIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBCdWZmZXJMZW5ndGgpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPnJlc3BvbnNlKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9SRVNQT05TRSwgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHNpemVvZihoZWFkZXItPnJlc3BvbnNlKTsKICBoZWFkZXItPnJlc3BvbnNlLmFsbG9jX2hpbnQgPSBCdWZmZXJMZW5ndGg7CgogIHJldHVybiBoZWFkZXI7Cn0KClJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NUQVRVUyBTdGF0dXMpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPmZhdWx0KSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9GQVVMVCwgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHNpemVvZihoZWFkZXItPmZhdWx0KTsKICBoZWFkZXItPmZhdWx0LnN0YXR1cyA9IFN0YXR1czsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRCaW5kSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgTWF4VHJhbnNtaXNzaW9uU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IE1heFJlY2VpdmVTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAgQXNzb2NHcm91cElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpBYnN0cmFjdElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpUcmFuc2ZlcklkKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CgogIGhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoaGVhZGVyLT5iaW5kKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9CSU5ELCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+YmluZCk7CiAgaGVhZGVyLT5iaW5kLm1heF90c2l6ZSA9IE1heFRyYW5zbWlzc2lvblNpemU7CiAgaGVhZGVyLT5iaW5kLm1heF9yc2l6ZSA9IE1heFJlY2VpdmVTaXplOwogIGhlYWRlci0+YmluZC5hc3NvY19naWQgPSBBc3NvY0dyb3VwSWQ7CiAgaGVhZGVyLT5iaW5kLm51bV9lbGVtZW50cyA9IDE7CiAgaGVhZGVyLT5iaW5kLm51bV9zeW50YXhlcyA9IDE7CiAgbWVtY3B5KCZoZWFkZXItPmJpbmQuYWJzdHJhY3QsIEFic3RyYWN0SWQsIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKTsKICBtZW1jcHkoJmhlYWRlci0+YmluZC50cmFuc2ZlciwgVHJhbnNmZXJJZCwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpOwoKICByZXR1cm4gaGVhZGVyOwp9CgpzdGF0aWMgUnBjUGt0SGRyICpSUENSVDRfQnVpbGRBdXRoSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CgogIGhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICBzaXplb2YoaGVhZGVyLT5jb21tb24pICsgMTIpOwogIGlmIChoZWFkZXIgPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICBSUENSVDRfQnVpbGRDb21tb25IZWFkZXIoaGVhZGVyLCBQS1RfQVVUSDMsIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSAweDE0OwogIGhlYWRlci0+Y29tbW9uLmF1dGhfbGVuID0gMDsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRCaW5kTmFja0hlYWRlcih1bnNpZ25lZCBsb25nIERhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFJwY1ZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBScGNWZXJzaW9uTWlub3IpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPmJpbmRfbmFjaykpOwogIGlmIChoZWFkZXIgPT0gTlVMTCkgewogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBSUENSVDRfQnVpbGRDb21tb25IZWFkZXIoaGVhZGVyLCBQS1RfQklORF9OQUNLLCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+YmluZF9uYWNrKTsKICBoZWFkZXItPmJpbmRfbmFjay5yZWplY3RfcmVhc29uID0gUkVKRUNUX1JFQVNPTl9OT1RfU1BFQ0lGSUVEOwogIGhlYWRlci0+YmluZF9uYWNrLnByb3RvY29sc19jb3VudCA9IDE7CiAgaGVhZGVyLT5iaW5kX25hY2sucHJvdG9jb2xzWzBdLnJwY192ZXIgPSBScGNWZXJzaW9uOwogIGhlYWRlci0+YmluZF9uYWNrLnByb3RvY29sc1swXS5ycGNfdmVyX21pbm9yID0gUnBjVmVyc2lvbk1pbm9yOwoKICByZXR1cm4gaGVhZGVyOwp9CgpScGNQa3RIZHIgKlJQQ1JUNF9CdWlsZEJpbmRBY2tIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBNYXhUcmFuc21pc3Npb25TaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgTWF4UmVjZWl2ZVNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUENTVFIgU2VydmVyQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgUmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBSZWFzb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBSUENfU1lOVEFYX0lERU5USUZJRVIgKlRyYW5zZmVySWQpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKICB1bnNpZ25lZCBsb25nIGhlYWRlcl9zaXplOwogIFJwY0FkZHJlc3NTdHJpbmcgKnNlcnZlcl9hZGRyZXNzOwogIFJwY1Jlc3VsdHMgKnJlc3VsdHM7CiAgUlBDX1NZTlRBWF9JREVOVElGSUVSICp0cmFuc2Zlcl9pZDsKCiAgaGVhZGVyX3NpemUgPSBzaXplb2YoaGVhZGVyLT5iaW5kX2FjaykgKwogICAgICAgICAgICAgICAgUk9VTkRfVVAoRklFTERfT0ZGU0VUKFJwY0FkZHJlc3NTdHJpbmcsIHN0cmluZ1tzdHJsZW4oU2VydmVyQWRkcmVzcykgKyAxXSksIDQpICsKICAgICAgICAgICAgICAgIHNpemVvZihScGNSZXN1bHRzKSArCiAgICAgICAgICAgICAgICBzaXplb2YoUlBDX1NZTlRBWF9JREVOVElGSUVSKTsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGhlYWRlcl9zaXplKTsKICBpZiAoaGVhZGVyID09IE5VTEwpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgUlBDUlQ0X0J1aWxkQ29tbW9uSGVhZGVyKGhlYWRlciwgUEtUX0JJTkRfQUNLLCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gaGVhZGVyX3NpemU7CiAgaGVhZGVyLT5iaW5kX2Fjay5tYXhfdHNpemUgPSBNYXhUcmFuc21pc3Npb25TaXplOwogIGhlYWRlci0+YmluZF9hY2subWF4X3JzaXplID0gTWF4UmVjZWl2ZVNpemU7CiAgc2VydmVyX2FkZHJlc3MgPSAoUnBjQWRkcmVzc1N0cmluZyopKCZoZWFkZXItPmJpbmRfYWNrICsgMSk7CiAgc2VydmVyX2FkZHJlc3MtPmxlbmd0aCA9IHN0cmxlbihTZXJ2ZXJBZGRyZXNzKSArIDE7CiAgc3RyY3B5KHNlcnZlcl9hZGRyZXNzLT5zdHJpbmcsIFNlcnZlckFkZHJlc3MpOwogIC8qIHJlc3VsdHMgaXMgNC1ieXRlIGFsaWduZWQgKi8KICByZXN1bHRzID0gKFJwY1Jlc3VsdHMqKSgoVUxPTkdfUFRSKXNlcnZlcl9hZGRyZXNzICsgUk9VTkRfVVAoRklFTERfT0ZGU0VUKFJwY0FkZHJlc3NTdHJpbmcsIHN0cmluZ1tzZXJ2ZXJfYWRkcmVzcy0+bGVuZ3RoXSksIDQpKTsKICByZXN1bHRzLT5udW1fcmVzdWx0cyA9IDE7CiAgcmVzdWx0cy0+cmVzdWx0c1swXS5yZXN1bHQgPSBSZXN1bHQ7CiAgcmVzdWx0cy0+cmVzdWx0c1swXS5yZWFzb24gPSBSZWFzb247CiAgdHJhbnNmZXJfaWQgPSAoUlBDX1NZTlRBWF9JREVOVElGSUVSKikocmVzdWx0cyArIDEpOwogIG1lbWNweSh0cmFuc2Zlcl9pZCwgVHJhbnNmZXJJZCwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpOwoKICByZXR1cm4gaGVhZGVyOwp9CgpWT0lEIFJQQ1JUNF9GcmVlSGVhZGVyKFJwY1BrdEhkciAqSGVhZGVyKQp7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgSGVhZGVyKTsKfQoKTkNBX1NUQVRVUyBSUEMyTkNBX1NUQVRVUyhSUENfU1RBVFVTIHN0YXR1cykKewogICAgc3dpdGNoIChzdGF0dXMpCiAgICB7CiAgICBjYXNlIEVSUk9SX0lOVkFMSURfSEFORExFOiAgICAgICAgICAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX0NPTlRFWFRfTUlTTUFUQ0g7CiAgICBjYXNlIEVSUk9SX09VVE9GTUVNT1JZOiAgICAgICAgICAgICAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX1JFTU9URV9OT19NRU1PUlk7CiAgICBjYXNlIFJQQ19TX05PVF9MSVNURU5JTkc6ICAgICAgICAgICAgICAgcmV0dXJuIE5DQV9TX1NFUlZFUl9UT09fQlVTWTsKICAgIGNhc2UgUlBDX1NfVU5LTk9XTl9JRjogICAgICAgICAgICAgICAgICByZXR1cm4gTkNBX1NfVU5LX0lGOwogICAgY2FzZSBSUENfU19TRVJWRVJfVE9PX0JVU1k6ICAgICAgICAgICAgIHJldHVybiBOQ0FfU19TRVJWRVJfVE9PX0JVU1k7CiAgICBjYXNlIFJQQ19TX0NBTExfRkFJTEVEOiAgICAgICAgICAgICAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX1VOU1BFQzsKICAgIGNhc2UgUlBDX1NfQ0FMTF9GQUlMRURfRE5FOiAgICAgICAgICAgICByZXR1cm4gTkNBX1NfTUFOQUdFUl9OT1RfRU5URVJFRDsKICAgIGNhc2UgUlBDX1NfUFJPVE9DT0xfRVJST1I6ICAgICAgICAgICAgICByZXR1cm4gTkNBX1NfUFJPVE9fRVJST1I7CiAgICBjYXNlIFJQQ19TX1VOU1VQUE9SVEVEX1RZUEU6ICAgICAgICAgICAgcmV0dXJuIE5DQV9TX1VOU1VQUE9SVEVEX1RZUEU7CiAgICBjYXNlIFJQQ19TX0lOVkFMSURfVEFHOiAgICAgICAgICAgICAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX0lOVkFMSURfVEFHOwogICAgY2FzZSBSUENfU19JTlZBTElEX0JPVU5EOiAgICAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9JTlZBTElEX0JPVU5EOwogICAgY2FzZSBSUENfU19QUk9DTlVNX09VVF9PRl9SQU5HRTogICAgICAgIHJldHVybiBOQ0FfU19PUF9STkdfRVJST1I7CiAgICBjYXNlIFJQQ19YX1NTX0hBTkRMRVNfTUlTTUFUQ0g6ICAgICAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX0NPTlRFWFRfTUlTTUFUQ0g7CiAgICBjYXNlIFJQQ19TX0NBTExfQ0FOQ0VMTEVEOiAgICAgICAgICAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX0NBTkNFTDsKICAgIGNhc2UgUlBDX1NfQ09NTV9GQUlMVVJFOiAgICAgICAgICAgICAgICByZXR1cm4gTkNBX1NfQ09NTV9GQUlMVVJFOwogICAgY2FzZSBSUENfWF9XUk9OR19QSVBFX09SREVSOiAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9QSVBFX09SREVSOwogICAgY2FzZSBSUENfWF9QSVBFX0NMT1NFRDogICAgICAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9QSVBFX0NMT1NFRDsKICAgIGNhc2UgUlBDX1hfUElQRV9ESVNDSVBMSU5FX0VSUk9SOiAgICAgICByZXR1cm4gTkNBX1NfRkFVTFRfUElQRV9ESVNDSVBMSU5FOwogICAgY2FzZSBSUENfWF9QSVBFX0VNUFRZOiAgICAgICAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9QSVBFX0VNUFRZOwogICAgY2FzZSBTVEFUVVNfRkxPQVRfRElWSURFX0JZX1pFUk86ICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9GUF9ESVZfWkVSTzsKICAgIGNhc2UgU1RBVFVTX0ZMT0FUX0lOVkFMSURfT1BFUkFUSU9OOiAgICByZXR1cm4gTkNBX1NfRkFVTFRfRlBfRVJST1I7CiAgICBjYXNlIFNUQVRVU19GTE9BVF9PVkVSRkxPVzogICAgICAgICAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX0ZQX09WRVJGTE9XOwogICAgY2FzZSBTVEFUVVNfRkxPQVRfVU5ERVJGTE9XOiAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9GUF9VTkRFUkZMT1c7CiAgICBjYXNlIFNUQVRVU19JTlRFR0VSX0RJVklERV9CWV9aRVJPOiAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX0lOVF9ESVZfQllfWkVSTzsKICAgIGNhc2UgU1RBVFVTX0lOVEVHRVJfT1ZFUkZMT1c6ICAgICAgICAgICByZXR1cm4gTkNBX1NfRkFVTFRfSU5UX09WRVJGTE9XOwogICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBzdGF0dXM7CiAgICB9Cn0KClJQQ19TVEFUVVMgTkNBMlJQQ19TVEFUVVMoTkNBX1NUQVRVUyBzdGF0dXMpCnsKICAgIHN3aXRjaCAoc3RhdHVzKQogICAgewogICAgY2FzZSBOQ0FfU19DT01NX0ZBSUxVUkU6ICAgICAgICAgICAgcmV0dXJuIFJQQ19TX0NPTU1fRkFJTFVSRTsKICAgIGNhc2UgTkNBX1NfT1BfUk5HX0VSUk9SOiAgICAgICAgICAgIHJldHVybiBSUENfU19QUk9DTlVNX09VVF9PRl9SQU5HRTsKICAgIGNhc2UgTkNBX1NfVU5LX0lGOiAgICAgICAgICAgICAgICAgIHJldHVybiBSUENfU19VTktOT1dOX0lGOwogICAgY2FzZSBOQ0FfU19ZT1VfQ1JBU0hFRDogICAgICAgICAgICAgcmV0dXJuIFJQQ19TX0NBTExfRkFJTEVEOwogICAgY2FzZSBOQ0FfU19QUk9UT19FUlJPUjogICAgICAgICAgICAgcmV0dXJuIFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgY2FzZSBOQ0FfU19PVVRfQVJHU19UT09fQklHOiAgICAgICAgcmV0dXJuIEVSUk9SX05PVF9FTk9VR0hfU0VSVkVSX01FTU9SWTsKICAgIGNhc2UgTkNBX1NfU0VSVkVSX1RPT19CVVNZOiAgICAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVE9PX0JVU1k7CiAgICBjYXNlIE5DQV9TX1VOU1VQUE9SVEVEX1RZUEU6ICAgICAgICByZXR1cm4gUlBDX1NfVU5TVVBQT1JURURfVFlQRTsKICAgIGNhc2UgTkNBX1NfRkFVTFRfSU5UX0RJVl9CWV9aRVJPOiAgIHJldHVybiBSUENfU19aRVJPX0RJVklERTsKICAgIGNhc2UgTkNBX1NfRkFVTFRfQUREUl9FUlJPUjogICAgICAgIHJldHVybiBSUENfU19BRERSRVNTX0VSUk9SOwogICAgY2FzZSBOQ0FfU19GQVVMVF9GUF9ESVZfWkVSTzogICAgICAgcmV0dXJuIFJQQ19TX0ZQX0RJVl9aRVJPOwogICAgY2FzZSBOQ0FfU19GQVVMVF9GUF9VTkRFUkZMT1c6ICAgICAgcmV0dXJuIFJQQ19TX0ZQX1VOREVSRkxPVzsKICAgIGNhc2UgTkNBX1NfRkFVTFRfRlBfT1ZFUkZMT1c6ICAgICAgIHJldHVybiBSUENfU19GUF9PVkVSRkxPVzsKICAgIGNhc2UgTkNBX1NfRkFVTFRfSU5WQUxJRF9UQUc6ICAgICAgIHJldHVybiBSUENfU19JTlZBTElEX1RBRzsKICAgIGNhc2UgTkNBX1NfRkFVTFRfSU5WQUxJRF9CT1VORDogICAgIHJldHVybiBSUENfU19JTlZBTElEX0JPVU5EOwogICAgY2FzZSBOQ0FfU19SUENfVkVSU0lPTl9NSVNNQVRDSDogICAgcmV0dXJuIFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgY2FzZSBOQ0FfU19VTlNQRUNfUkVKRUNUOiAgICAgICAgICAgcmV0dXJuIFJQQ19TX0NBTExfRkFJTEVEX0RORTsKICAgIGNhc2UgTkNBX1NfQkFEX0FDVElEOiAgICAgICAgICAgICAgIHJldHVybiBSUENfU19DQUxMX0ZBSUxFRF9ETkU7CiAgICBjYXNlIE5DQV9TX1dIT19BUkVfWU9VX0ZBSUxFRDogICAgICByZXR1cm4gUlBDX1NfQ0FMTF9GQUlMRUQ7CiAgICBjYXNlIE5DQV9TX01BTkFHRVJfTk9UX0VOVEVSRUQ6ICAgICByZXR1cm4gUlBDX1NfQ0FMTF9GQUlMRURfRE5FOwogICAgY2FzZSBOQ0FfU19GQVVMVF9DQU5DRUw6ICAgICAgICAgICAgcmV0dXJuIFJQQ19TX0NBTExfQ0FOQ0VMTEVEOwogICAgY2FzZSBOQ0FfU19GQVVMVF9JTExfSU5TVDogICAgICAgICAgcmV0dXJuIFJQQ19TX0FERFJFU1NfRVJST1I7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX0ZQX0VSUk9SOiAgICAgICAgICByZXR1cm4gUlBDX1NfRlBfT1ZFUkZMT1c7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX0lOVF9PVkVSRkxPVzogICAgICByZXR1cm4gUlBDX1NfQUREUkVTU19FUlJPUjsKICAgIGNhc2UgTkNBX1NfRkFVTFRfVU5TUEVDOiAgICAgICAgICAgIHJldHVybiBSUENfU19DQUxMX0ZBSUxFRDsKICAgIGNhc2UgTkNBX1NfRkFVTFRfUElQRV9FTVBUWTogICAgICAgIHJldHVybiBSUENfWF9QSVBFX0VNUFRZOwogICAgY2FzZSBOQ0FfU19GQVVMVF9QSVBFX0NMT1NFRDogICAgICAgcmV0dXJuIFJQQ19YX1BJUEVfQ0xPU0VEOwogICAgY2FzZSBOQ0FfU19GQVVMVF9QSVBFX09SREVSOiAgICAgICAgcmV0dXJuIFJQQ19YX1dST05HX1BJUEVfT1JERVI7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX1BJUEVfRElTQ0lQTElORTogICByZXR1cm4gUlBDX1hfUElQRV9ESVNDSVBMSU5FX0VSUk9SOwogICAgY2FzZSBOQ0FfU19GQVVMVF9QSVBFX0NPTU1fRVJST1I6ICAgcmV0dXJuIFJQQ19TX0NPTU1fRkFJTFVSRTsKICAgIGNhc2UgTkNBX1NfRkFVTFRfUElQRV9NRU1PUlk6ICAgICAgIHJldHVybiBFUlJPUl9PVVRPRk1FTU9SWTsKICAgIGNhc2UgTkNBX1NfRkFVTFRfQ09OVEVYVF9NSVNNQVRDSDogIHJldHVybiBFUlJPUl9JTlZBTElEX0hBTkRMRTsKICAgIGNhc2UgTkNBX1NfRkFVTFRfUkVNT1RFX05PX01FTU9SWTogIHJldHVybiBFUlJPUl9OT1RfRU5PVUdIX1NFUlZFUl9NRU1PUlk7CiAgICBkZWZhdWx0OiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQp9CgpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfU2VjdXJlUGFja2V0KFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sCiAgICBlbnVtIHNlY3VyZV9wYWNrZXRfZGlyZWN0aW9uIGRpciwKICAgIFJwY1BrdEhkciAqaGRyLCB1bnNpZ25lZCBpbnQgaGRyX3NpemUsCiAgICB1bnNpZ25lZCBjaGFyICpzdHViX2RhdGEsIHVuc2lnbmVkIGludCBzdHViX2RhdGFfc2l6ZSwKICAgIFJwY0F1dGhWZXJpZmllciAqYXV0aF9oZHIsCiAgICB1bnNpZ25lZCBjaGFyICphdXRoX3ZhbHVlLCB1bnNpZ25lZCBpbnQgYXV0aF92YWx1ZV9zaXplKQp7CiAgICBTZWNCdWZmZXJEZXNjIG1lc3NhZ2U7CiAgICBTZWNCdWZmZXIgYnVmZmVyc1s0XTsKICAgIFNFQ1VSSVRZX1NUQVRVUyBzZWNfc3RhdHVzOwoKICAgIG1lc3NhZ2UudWxWZXJzaW9uID0gU0VDQlVGRkVSX1ZFUlNJT047CiAgICBtZXNzYWdlLmNCdWZmZXJzID0gc2l6ZW9mKGJ1ZmZlcnMpL3NpemVvZihidWZmZXJzWzBdKTsKICAgIG1lc3NhZ2UucEJ1ZmZlcnMgPSBidWZmZXJzOwoKICAgIGJ1ZmZlcnNbMF0uY2JCdWZmZXIgPSBoZHJfc2l6ZTsKICAgIGJ1ZmZlcnNbMF0uQnVmZmVyVHlwZSA9IFNFQ0JVRkZFUl9EQVRBfFNFQ0JVRkZFUl9SRUFET05MWV9XSVRIX0NIRUNLU1VNOwogICAgYnVmZmVyc1swXS5wdkJ1ZmZlciA9IGhkcjsKICAgIGJ1ZmZlcnNbMV0uY2JCdWZmZXIgPSBzdHViX2RhdGFfc2l6ZTsKICAgIGJ1ZmZlcnNbMV0uQnVmZmVyVHlwZSA9IFNFQ0JVRkZFUl9EQVRBOwogICAgYnVmZmVyc1sxXS5wdkJ1ZmZlciA9IHN0dWJfZGF0YTsKICAgIGJ1ZmZlcnNbMl0uY2JCdWZmZXIgPSBzaXplb2YoKmF1dGhfaGRyKTsKICAgIGJ1ZmZlcnNbMl0uQnVmZmVyVHlwZSA9IFNFQ0JVRkZFUl9EQVRBfFNFQ0JVRkZFUl9SRUFET05MWV9XSVRIX0NIRUNLU1VNOwogICAgYnVmZmVyc1syXS5wdkJ1ZmZlciA9IGF1dGhfaGRyOwogICAgYnVmZmVyc1szXS5jYkJ1ZmZlciA9IGF1dGhfdmFsdWVfc2l6ZTsKICAgIGJ1ZmZlcnNbM10uQnVmZmVyVHlwZSA9IFNFQ0JVRkZFUl9UT0tFTjsKICAgIGJ1ZmZlcnNbM10ucHZCdWZmZXIgPSBhdXRoX3ZhbHVlOwoKICAgIGlmIChkaXIgPT0gU0VDVVJFX1BBQ0tFVF9TRU5EKQogICAgewogICAgICAgIGlmICgoYXV0aF9oZHItPmF1dGhfbGV2ZWwgPT0gUlBDX0NfQVVUSE5fTEVWRUxfUEtUX1BSSVZBQ1kpICYmIHBhY2tldF9oYXNfYm9keShoZHIpKQogICAgICAgIHsKICAgICAgICAgICAgc2VjX3N0YXR1cyA9IEVuY3J5cHRNZXNzYWdlKCZDb25uZWN0aW9uLT5jdHgsIDAsICZtZXNzYWdlLCAwIC8qIEZJWE1FICovKTsKICAgICAgICAgICAgaWYgKHNlY19zdGF0dXMgIT0gU0VDX0VfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEVSUigiRW5jcnlwdE1lc3NhZ2UgZmFpbGVkIHdpdGggMHglMDh4XG4iLCBzZWNfc3RhdHVzKTsKICAgICAgICAgICAgICAgIHJldHVybiBSUENfU19TRUNfUEtHX0VSUk9SOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKGF1dGhfaGRyLT5hdXRoX2xldmVsICE9IFJQQ19DX0FVVEhOX0xFVkVMX05PTkUpCiAgICAgICAgewogICAgICAgICAgICBzZWNfc3RhdHVzID0gTWFrZVNpZ25hdHVyZSgmQ29ubmVjdGlvbi0+Y3R4LCAwLCAmbWVzc2FnZSwgMCAvKiBGSVhNRSAqLyk7CiAgICAgICAgICAgIGlmIChzZWNfc3RhdHVzICE9IFNFQ19FX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFUlIoIk1ha2VTaWduYXR1cmUgZmFpbGVkIHdpdGggMHglMDh4XG4iLCBzZWNfc3RhdHVzKTsKICAgICAgICAgICAgICAgIHJldHVybiBSUENfU19TRUNfUEtHX0VSUk9SOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgZWxzZSBpZiAoZGlyID09IFNFQ1VSRV9QQUNLRVRfUkVDRUlWRSkKICAgIHsKICAgICAgICBpZiAoKGF1dGhfaGRyLT5hdXRoX2xldmVsID09IFJQQ19DX0FVVEhOX0xFVkVMX1BLVF9QUklWQUNZKSAmJiBwYWNrZXRfaGFzX2JvZHkoaGRyKSkKICAgICAgICB7CiAgICAgICAgICAgIHNlY19zdGF0dXMgPSBEZWNyeXB0TWVzc2FnZSgmQ29ubmVjdGlvbi0+Y3R4LCAmbWVzc2FnZSwgMCAvKiBGSVhNRSAqLywgMCk7CiAgICAgICAgICAgIGlmIChzZWNfc3RhdHVzICE9IFNFQ19FX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFUlIoIkRlY3J5cHRNZXNzYWdlIGZhaWxlZCB3aXRoIDB4JTA4eFxuIiwgc2VjX3N0YXR1cyk7CiAgICAgICAgICAgICAgICByZXR1cm4gUlBDX1NfU0VDX1BLR19FUlJPUjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChhdXRoX2hkci0+YXV0aF9sZXZlbCAhPSBSUENfQ19BVVRITl9MRVZFTF9OT05FKQogICAgICAgIHsKICAgICAgICAgICAgc2VjX3N0YXR1cyA9IFZlcmlmeVNpZ25hdHVyZSgmQ29ubmVjdGlvbi0+Y3R4LCAmbWVzc2FnZSwgMCAvKiBGSVhNRSAqLywgTlVMTCk7CiAgICAgICAgICAgIGlmIChzZWNfc3RhdHVzICE9IFNFQ19FX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFUlIoIlZlcmlmeVNpZ25hdHVyZSBmYWlsZWQgd2l0aCAweCUwOHhcbiIsIHNlY19zdGF0dXMpOwogICAgICAgICAgICAgICAgcmV0dXJuIFJQQ19TX1NFQ19QS0dfRVJST1I7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFJQQ19TX09LOwp9CiAgICAgICAgIAovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJQQ1JUNF9TZW5kQXV0aCAoaW50ZXJuYWwpCiAqIAogKiBUcmFuc21pdCBhIHBhY2tldCB3aXRoIGF1dGhvcml6YXRpb24gZGF0YSBvdmVyIGNvbm5lY3Rpb24gaW4gYWNjZXB0YWJsZSBmcmFnbWVudHMuCiAqLwpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfU2VuZEF1dGgoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwgUnBjUGt0SGRyICpIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpCdWZmZXIsIHVuc2lnbmVkIGludCBCdWZmZXJMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpBdXRoLCB1bnNpZ25lZCBpbnQgQXV0aExlbmd0aCkKewogIFBVQ0hBUiBidWZmZXJfcG9zOwogIERXT1JEIGhkcl9zaXplOwogIExPTkcgY291bnQ7CiAgdW5zaWduZWQgY2hhciAqcGt0OwogIExPTkcgYWxlbjsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgUlBDUlQ0X1NldFRocmVhZEN1cnJlbnRDb25uZWN0aW9uKENvbm5lY3Rpb24pOwoKICBidWZmZXJfcG9zID0gQnVmZmVyOwogIC8qIFRoZSBwYWNrZXQgYnVpbGRpbmcgZnVuY3Rpb25zIHNhdmUgdGhlIHBhY2tldCBoZWFkZXIgc2l6ZSwgc28gd2UgY2FuIHVzZSBpdC4gKi8KICBoZHJfc2l6ZSA9IEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuOwogIGlmIChBdXRoTGVuZ3RoKQogICAgSGVhZGVyLT5jb21tb24uYXV0aF9sZW4gPSBBdXRoTGVuZ3RoOwogIGVsc2UgaWYgKENvbm5lY3Rpb24tPkF1dGhJbmZvICYmIHBhY2tldF9oYXNfYXV0aF92ZXJpZmllcihIZWFkZXIpKQogIHsKICAgIGlmICgoQ29ubmVjdGlvbi0+QXV0aEluZm8tPkF1dGhuTGV2ZWwgPT0gUlBDX0NfQVVUSE5fTEVWRUxfUEtUX1BSSVZBQ1kpICYmIHBhY2tldF9oYXNfYm9keShIZWFkZXIpKQogICAgICBIZWFkZXItPmNvbW1vbi5hdXRoX2xlbiA9IENvbm5lY3Rpb24tPmVuY3J5cHRpb25fYXV0aF9sZW47CiAgICBlbHNlCiAgICAgIEhlYWRlci0+Y29tbW9uLmF1dGhfbGVuID0gQ29ubmVjdGlvbi0+c2lnbmF0dXJlX2F1dGhfbGVuOwogIH0KICBlbHNlCiAgICBIZWFkZXItPmNvbW1vbi5hdXRoX2xlbiA9IDA7CiAgSGVhZGVyLT5jb21tb24uZmxhZ3MgfD0gUlBDX0ZMR19GSVJTVDsKICBIZWFkZXItPmNvbW1vbi5mbGFncyAmPSB+UlBDX0ZMR19MQVNUOwoKICBhbGVuID0gUlBDX0FVVEhfVkVSSUZJRVJfTEVOKCZIZWFkZXItPmNvbW1vbik7CgogIHdoaWxlICghKEhlYWRlci0+Y29tbW9uLmZsYWdzICYgUlBDX0ZMR19MQVNUKSkgewogICAgdW5zaWduZWQgY2hhciBhdXRoX3BhZF9sZW4gPSBIZWFkZXItPmNvbW1vbi5hdXRoX2xlbiA/IFJPVU5EX1VQX0FNT1VOVChCdWZmZXJMZW5ndGgsIEFVVEhfQUxJR05NRU5UKSA6IDA7CiAgICB1bnNpZ25lZCBpbnQgcGt0X3NpemUgPSBCdWZmZXJMZW5ndGggKyBoZHJfc2l6ZSArIGFsZW4gKyBhdXRoX3BhZF9sZW47CgogICAgLyogZGVjaWRlIGlmIHdlIG5lZWQgdG8gc3BsaXQgdGhlIHBhY2tldCBpbnRvIGZyYWdtZW50cyAqLwogICBpZiAocGt0X3NpemUgPD0gQ29ubmVjdGlvbi0+TWF4VHJhbnNtaXNzaW9uU2l6ZSkgewogICAgIEhlYWRlci0+Y29tbW9uLmZsYWdzIHw9IFJQQ19GTEdfTEFTVDsKICAgICBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHBrdF9zaXplOwogICAgfSBlbHNlIHsKICAgICAgYXV0aF9wYWRfbGVuID0gMDsKICAgICAgLyogbWFrZSBzdXJlIHBhY2tldCBwYXlsb2FkIHdpbGwgYmUgYSBtdWx0aXBsZSBvZiAxNiAqLwogICAgICBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9CiAgICAgICAgKChDb25uZWN0aW9uLT5NYXhUcmFuc21pc3Npb25TaXplIC0gaGRyX3NpemUgLSBhbGVuKSAmIH4oQVVUSF9BTElHTk1FTlQtMSkpICsKICAgICAgICBoZHJfc2l6ZSArIGFsZW47CiAgICB9CgogICAgcGt0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuKTsKCiAgICBtZW1jcHkocGt0LCBIZWFkZXIsIGhkcl9zaXplKTsKCiAgICAvKiBmcmFnbWVudCBjb25zaXN0ZWQgb2YgaGVhZGVyIG9ubHkgYW5kIGlzIHRoZSBsYXN0IG9uZSAqLwogICAgaWYgKGhkcl9zaXplID09IEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuKQogICAgICBnb3RvIHdyaXRlOwoKICAgIG1lbWNweShwa3QgKyBoZHJfc2l6ZSwgYnVmZmVyX3BvcywgSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gLSBoZHJfc2l6ZSAtIGF1dGhfcGFkX2xlbiAtIGFsZW4pOwoKICAgIC8qIGFkZCB0aGUgYXV0aG9yaXphdGlvbiBpbmZvICovCiAgICBpZiAoQ29ubmVjdGlvbi0+QXV0aEluZm8gJiYgcGFja2V0X2hhc19hdXRoX3ZlcmlmaWVyKEhlYWRlcikpCiAgICB7CiAgICAgIFJwY0F1dGhWZXJpZmllciAqYXV0aF9oZHIgPSAoUnBjQXV0aFZlcmlmaWVyICopJnBrdFtIZWFkZXItPmNvbW1vbi5mcmFnX2xlbiAtIGFsZW5dOwoKICAgICAgYXV0aF9oZHItPmF1dGhfdHlwZSA9IENvbm5lY3Rpb24tPkF1dGhJbmZvLT5BdXRoblN2YzsKICAgICAgYXV0aF9oZHItPmF1dGhfbGV2ZWwgPSBDb25uZWN0aW9uLT5BdXRoSW5mby0+QXV0aG5MZXZlbDsKICAgICAgYXV0aF9oZHItPmF1dGhfcGFkX2xlbmd0aCA9IGF1dGhfcGFkX2xlbjsKICAgICAgYXV0aF9oZHItPmF1dGhfcmVzZXJ2ZWQgPSAwOwogICAgICAvKiBhIHVuaXF1ZSBudW1iZXIuLi4gKi8KICAgICAgYXV0aF9oZHItPmF1dGhfY29udGV4dF9pZCA9ICh1bnNpZ25lZCBsb25nKUNvbm5lY3Rpb247CgogICAgICBpZiAoQXV0aExlbmd0aCkKICAgICAgICBtZW1jcHkoYXV0aF9oZHIgKyAxLCBBdXRoLCBBdXRoTGVuZ3RoKTsKICAgICAgZWxzZQogICAgICB7CiAgICAgICAgc3RhdHVzID0gUlBDUlQ0X1NlY3VyZVBhY2tldChDb25uZWN0aW9uLCBTRUNVUkVfUEFDS0VUX1NFTkQsCiAgICAgICAgICAgIChScGNQa3RIZHIgKilwa3QsIGhkcl9zaXplLAogICAgICAgICAgICBwa3QgKyBoZHJfc2l6ZSwgSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gLSBoZHJfc2l6ZSAtIGFsZW4sCiAgICAgICAgICAgIGF1dGhfaGRyLAogICAgICAgICAgICAodW5zaWduZWQgY2hhciAqKShhdXRoX2hkciArIDEpLCBIZWFkZXItPmNvbW1vbi5hdXRoX2xlbik7CiAgICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICAgICAgICB7CiAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwa3QpOwogICAgICAgICAgUlBDUlQ0X1NldFRocmVhZEN1cnJlbnRDb25uZWN0aW9uKE5VTEwpOwogICAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgICAgICB9CiAgICAgIH0KICAgIH0KCndyaXRlOgogICAgY291bnQgPSBycGNydDRfY29ubl93cml0ZShDb25uZWN0aW9uLCBwa3QsIEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBrdCk7CiAgICBpZiAoY291bnQ8MCkgewogICAgICBXQVJOKCJycGNydDRfY29ubl93cml0ZSBmYWlsZWQgKGF1dGgpXG4iKTsKICAgICAgUlBDUlQ0X1NldFRocmVhZEN1cnJlbnRDb25uZWN0aW9uKE5VTEwpOwogICAgICByZXR1cm4gUlBDX1NfQ0FMTF9GQUlMRUQ7CiAgICB9CgogICAgYnVmZmVyX3BvcyArPSBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbiAtIGhkcl9zaXplIC0gYWxlbiAtIGF1dGhfcGFkX2xlbjsKICAgIEJ1ZmZlckxlbmd0aCAtPSBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbiAtIGhkcl9zaXplIC0gYWxlbiAtIGF1dGhfcGFkX2xlbjsKICAgIEhlYWRlci0+Y29tbW9uLmZsYWdzICY9IH5SUENfRkxHX0ZJUlNUOwogIH0KCiAgUlBDUlQ0X1NldFRocmVhZEN1cnJlbnRDb25uZWN0aW9uKE5VTEwpOwogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfQ2xpZW50QXV0aG9yaXplIChpbnRlcm5hbCkKICoKICogQXV0aG9yaXplIGEgY2xpZW50IGNvbm5lY3Rpb24uIEEgTlVMTCBpbiBwYXJhbSBzaWduaWZpZXMgYSBuZXcgY29ubmVjdGlvbi4KICovCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUNF9DbGllbnRBdXRob3JpemUoUnBjQ29ubmVjdGlvbiAqY29ubiwgU2VjQnVmZmVyICppbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTZWNCdWZmZXIgKm91dCkKewogIFNFQ1VSSVRZX1NUQVRVUyByOwogIFNlY0J1ZmZlckRlc2Mgb3V0X2Rlc2M7CiAgU2VjQnVmZmVyRGVzYyBpbnBfZGVzYzsKICBTZWNQa2dDb250ZXh0X1NpemVzIHNlY2N0eF9zaXplczsKICBCT09MIGNvbnRpbnVlX25lZWRlZDsKICBVTE9ORyBjb250ZXh0X3JlcSA9IElTQ19SRVFfQ09OTkVDVElPTiB8IElTQ19SRVFfVVNFX0RDRV9TVFlMRSB8CiAgICAgICAgICAgICAgICAgICAgICBJU0NfUkVRX01VVFVBTF9BVVRIIHwgSVNDX1JFUV9ERUxFR0FURTsKCiAgaWYgKGNvbm4tPkF1dGhJbmZvLT5BdXRobkxldmVsID09IFJQQ19DX0FVVEhOX0xFVkVMX1BLVF9JTlRFR1JJVFkpCiAgICBjb250ZXh0X3JlcSB8PSBJU0NfUkVRX0lOVEVHUklUWTsKICBlbHNlIGlmIChjb25uLT5BdXRoSW5mby0+QXV0aG5MZXZlbCA9PSBSUENfQ19BVVRITl9MRVZFTF9QS1RfUFJJVkFDWSkKICAgIGNvbnRleHRfcmVxIHw9IElTQ19SRVFfQ09ORklERU5USUFMSVRZIHwgSVNDX1JFUV9JTlRFR1JJVFk7CgogIG91dC0+QnVmZmVyVHlwZSA9IFNFQ0JVRkZFUl9UT0tFTjsKICBvdXQtPmNiQnVmZmVyID0gY29ubi0+QXV0aEluZm8tPmNiTWF4VG9rZW47CiAgb3V0LT5wdkJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBvdXQtPmNiQnVmZmVyKTsKICBpZiAoIW91dC0+cHZCdWZmZXIpIHJldHVybiBFUlJPUl9PVVRPRk1FTU9SWTsKCiAgb3V0X2Rlc2MudWxWZXJzaW9uID0gMDsKICBvdXRfZGVzYy5jQnVmZmVycyA9IDE7CiAgb3V0X2Rlc2MucEJ1ZmZlcnMgPSBvdXQ7CgogIGlucF9kZXNjLmNCdWZmZXJzID0gMTsKICBpbnBfZGVzYy5wQnVmZmVycyA9IGluOwogIGlucF9kZXNjLnVsVmVyc2lvbiA9IDA7CgogIHIgPSBJbml0aWFsaXplU2VjdXJpdHlDb250ZXh0QSgmY29ubi0+QXV0aEluZm8tPmNyZWQsIGluID8gJmNvbm4tPmN0eCA6IE5VTEwsCiAgICAgICAgTlVMTCwgY29udGV4dF9yZXEsIDAsIFNFQ1VSSVRZX05FVFdPUktfRFJFUCwKICAgICAgICBpbiA/ICZpbnBfZGVzYyA6IE5VTEwsIDAsICZjb25uLT5jdHgsICZvdXRfZGVzYywgJmNvbm4tPmF0dHIsCiAgICAgICAgJmNvbm4tPmV4cCk7CiAgaWYgKEZBSUxFRChyKSkKICB7CiAgICAgIFdBUk4oIkluaXRpYWxpemVTZWN1cml0eUNvbnRleHQgZmFpbGVkIHdpdGggZXJyb3IgMHglMDh4XG4iLCByKTsKICAgICAgZ290byBmYWlsZWQ7CiAgfQoKICBUUkFDRSgiciA9IDB4JTA4eCwgYXR0ciA9IDB4JTA4eFxuIiwgciwgY29ubi0+YXR0cik7CiAgY29udGludWVfbmVlZGVkID0gKChyID09IFNFQ19JX0NPTlRJTlVFX05FRURFRCkgfHwKICAgICAgICAgICAgICAgICAgICAgKHIgPT0gU0VDX0lfQ09NUExFVEVfQU5EX0NPTlRJTlVFKSk7CgogIGlmICgociA9PSBTRUNfSV9DT01QTEVURV9ORUVERUQpIHx8IChyID09IFNFQ19JX0NPTVBMRVRFX0FORF9DT05USU5VRSkpCiAgewogICAgICBUUkFDRSgiY29tcGxldGUgbmVlZGVkXG4iKTsKICAgICAgciA9IENvbXBsZXRlQXV0aFRva2VuKCZjb25uLT5jdHgsICZvdXRfZGVzYyk7CiAgICAgIGlmIChGQUlMRUQocikpCiAgICAgIHsKICAgICAgICAgIFdBUk4oIkNvbXBsZXRlQXV0aFRva2VuIGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4eFxuIiwgcik7CiAgICAgICAgICBnb3RvIGZhaWxlZDsKICAgICAgfQogIH0KCiAgVFJBQ0UoImNiQnVmZmVyID0gJWxkXG4iLCBvdXQtPmNiQnVmZmVyKTsKCiAgaWYgKCFjb250aW51ZV9uZWVkZWQpCiAgewogICAgICByID0gUXVlcnlDb250ZXh0QXR0cmlidXRlc0EoJmNvbm4tPmN0eCwgU0VDUEtHX0FUVFJfU0laRVMsICZzZWNjdHhfc2l6ZXMpOwogICAgICBpZiAoRkFJTEVEKHIpKQogICAgICB7CiAgICAgICAgICBXQVJOKCJRdWVyeUNvbnRleHRBdHRyaWJ1dGVzIGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4eFxuIiwgcik7CiAgICAgICAgICBnb3RvIGZhaWxlZDsKICAgICAgfQogICAgICBjb25uLT5zaWduYXR1cmVfYXV0aF9sZW4gPSBzZWNjdHhfc2l6ZXMuY2JNYXhTaWduYXR1cmU7CiAgICAgIGNvbm4tPmVuY3J5cHRpb25fYXV0aF9sZW4gPSBzZWNjdHhfc2l6ZXMuY2JTZWN1cml0eVRyYWlsZXI7CiAgfQoKICByZXR1cm4gUlBDX1NfT0s7CgpmYWlsZWQ6CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3V0LT5wdkJ1ZmZlcik7CiAgb3V0LT5wdkJ1ZmZlciA9IE5VTEw7CiAgcmV0dXJuIEVSUk9SX0FDQ0VTU19ERU5JRUQ7IC8qIEZJWE1FOiBpcyB0aGlzIGNvcnJlY3Q/ICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUlBDUlQ0X0F1dGhvcml6ZUJpbmRpbmcgKGludGVybmFsKQogKi8Kc3RhdGljIFJQQ19TVEFUVVMgUlBDUlRfQXV0aG9yaXplQ29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBjb25uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJZVEUgKmNoYWxsZW5nZSwgVUxPTkcgY291bnQpCnsKICBTZWNCdWZmZXIgaW5wLCBvdXQ7CiAgUnBjUGt0SGRyICpyZXNwX2hkcjsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgVFJBQ0UoImNoYWxsZW5nZSAlcywgJWQgYnl0ZXNcbiIsIGNoYWxsZW5nZSwgY291bnQpOwoKICBpbnAuQnVmZmVyVHlwZSA9IFNFQ0JVRkZFUl9UT0tFTjsKICBpbnAucHZCdWZmZXIgPSBjaGFsbGVuZ2U7CiAgaW5wLmNiQnVmZmVyID0gY291bnQ7CgogIHN0YXR1cyA9IFJQQ1JUNF9DbGllbnRBdXRob3JpemUoY29ubiwgJmlucCwgJm91dCk7CiAgaWYgKHN0YXR1cykgcmV0dXJuIHN0YXR1czsKCiAgcmVzcF9oZHIgPSBSUENSVDRfQnVpbGRBdXRoSGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OKTsKICBpZiAoIXJlc3BfaGRyKQogICAgcmV0dXJuIEVfT1VUT0ZNRU1PUlk7CgogIHN0YXR1cyA9IFJQQ1JUNF9TZW5kQXV0aChjb25uLCByZXNwX2hkciwgTlVMTCwgMCwgb3V0LnB2QnVmZmVyLCBvdXQuY2JCdWZmZXIpOwoKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvdXQucHZCdWZmZXIpOwogIFJQQ1JUNF9GcmVlSGVhZGVyKHJlc3BfaGRyKTsKCiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfU2VuZCAoaW50ZXJuYWwpCiAqIAogKiBUcmFuc21pdCBhIHBhY2tldCBvdmVyIGNvbm5lY3Rpb24gaW4gYWNjZXB0YWJsZSBmcmFnbWVudHMuCiAqLwpSUENfU1RBVFVTIFJQQ1JUNF9TZW5kKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sIFJwY1BrdEhkciAqSGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkJ1ZmZlciwgdW5zaWduZWQgaW50IEJ1ZmZlckxlbmd0aCkKewogIFJQQ19TVEFUVVMgcjsKICBTZWNCdWZmZXIgb3V0OwoKICBpZiAoIUNvbm5lY3Rpb24tPkF1dGhJbmZvIHx8IFNlY0lzVmFsaWRIYW5kbGUoJkNvbm5lY3Rpb24tPmN0eCkpCiAgewogICAgcmV0dXJuIFJQQ1JUNF9TZW5kQXV0aChDb25uZWN0aW9uLCBIZWFkZXIsIEJ1ZmZlciwgQnVmZmVyTGVuZ3RoLCBOVUxMLCAwKTsKICB9CgogIC8qIHRhY2sgb24gYSBuZWdvdGlhdGUgcGFja2V0ICovCiAgUlBDUlQ0X0NsaWVudEF1dGhvcml6ZShDb25uZWN0aW9uLCBOVUxMLCAmb3V0KTsKICByID0gUlBDUlQ0X1NlbmRBdXRoKENvbm5lY3Rpb24sIEhlYWRlciwgQnVmZmVyLCBCdWZmZXJMZW5ndGgsIG91dC5wdkJ1ZmZlciwgb3V0LmNiQnVmZmVyKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBvdXQucHZCdWZmZXIpOwoKICByZXR1cm4gcjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfUmVjZWl2ZSAoaW50ZXJuYWwpCiAqIAogKiBSZWNlaXZlIGEgcGFja2V0IGZyb20gY29ubmVjdGlvbiBhbmQgbWVyZ2UgdGhlIGZyYWdtZW50cy4KICovClJQQ19TVEFUVVMgUlBDUlQ0X1JlY2VpdmUoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwgUnBjUGt0SGRyICoqSGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgIFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgRFdPUkQgaGRyX2xlbmd0aDsKICBMT05HIGR3UmVhZDsKICB1bnNpZ25lZCBzaG9ydCBmaXJzdF9mbGFnOwogIHVuc2lnbmVkIGxvbmcgZGF0YV9sZW5ndGg7CiAgdW5zaWduZWQgbG9uZyBidWZmZXJfbGVuZ3RoOwogIHVuc2lnbmVkIGxvbmcgYXV0aF9sZW5ndGg7CiAgdW5zaWduZWQgY2hhciAqYXV0aF9kYXRhID0gTlVMTDsKICBScGNQa3RDb21tb25IZHIgY29tbW9uX2hkcjsKCiAgKkhlYWRlciA9IE5VTEw7CgogIFRSQUNFKCIoJXAsICVwLCAlcClcbiIsIENvbm5lY3Rpb24sIEhlYWRlciwgcE1zZyk7CgogIFJQQ1JUNF9TZXRUaHJlYWRDdXJyZW50Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKCiAgLyogcmVhZCBwYWNrZXQgY29tbW9uIGhlYWRlciAqLwogIGR3UmVhZCA9IHJwY3J0NF9jb25uX3JlYWQoQ29ubmVjdGlvbiwgJmNvbW1vbl9oZHIsIHNpemVvZihjb21tb25faGRyKSk7CiAgaWYgKGR3UmVhZCAhPSBzaXplb2YoY29tbW9uX2hkcikpIHsKICAgIFdBUk4oIlNob3J0IHJlYWQgb2YgaGVhZGVyLCAlZCBieXRlc1xuIiwgZHdSZWFkKTsKICAgIHN0YXR1cyA9IFJQQ19TX0NBTExfRkFJTEVEOwogICAgZ290byBmYWlsOwogIH0KCiAgLyogdmVyaWZ5IGlmIHRoZSBoZWFkZXIgcmVhbGx5IG1ha2VzIHNlbnNlICovCiAgaWYgKGNvbW1vbl9oZHIucnBjX3ZlciAhPSBSUENfVkVSX01BSk9SIHx8CiAgICAgIGNvbW1vbl9oZHIucnBjX3Zlcl9taW5vciAhPSBSUENfVkVSX01JTk9SKSB7CiAgICBXQVJOKCJ1bmhhbmRsZWQgcGFja2V0IHZlcnNpb25cbiIpOwogICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICBnb3RvIGZhaWw7CiAgfQoKICBoZHJfbGVuZ3RoID0gUlBDUlQ0X0dldEhlYWRlclNpemUoKFJwY1BrdEhkciopJmNvbW1vbl9oZHIpOwogIGlmIChoZHJfbGVuZ3RoID09IDApIHsKICAgIFdBUk4oImhlYWRlciBsZW5ndGggPT0gMFxuIik7CiAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIGdvdG8gZmFpbDsKICB9CgogICpIZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaGRyX2xlbmd0aCk7CiAgbWVtY3B5KCpIZWFkZXIsICZjb21tb25faGRyLCBzaXplb2YoY29tbW9uX2hkcikpOwoKICAvKiByZWFkIHRoZSByZXN0IG9mIHBhY2tldCBoZWFkZXIgKi8KICBkd1JlYWQgPSBycGNydDRfY29ubl9yZWFkKENvbm5lY3Rpb24sICYoKkhlYWRlciktPmNvbW1vbiArIDEsIGhkcl9sZW5ndGggLSBzaXplb2YoY29tbW9uX2hkcikpOwogIGlmIChkd1JlYWQgIT0gaGRyX2xlbmd0aCAtIHNpemVvZihjb21tb25faGRyKSkgewogICAgV0FSTigiYmFkIGhlYWRlciBsZW5ndGgsICVkIGJ5dGVzLCBoZHJfbGVuZ3RoICVkXG4iLCBkd1JlYWQsIGhkcl9sZW5ndGgpOwogICAgc3RhdHVzID0gUlBDX1NfQ0FMTF9GQUlMRUQ7CiAgICBnb3RvIGZhaWw7CiAgfQoKICAvKiByZWFkIHBhY2tldCBib2R5ICovCiAgc3dpdGNoIChjb21tb25faGRyLnB0eXBlKSB7CiAgY2FzZSBQS1RfUkVTUE9OU0U6CiAgICBwTXNnLT5CdWZmZXJMZW5ndGggPSAoKkhlYWRlciktPnJlc3BvbnNlLmFsbG9jX2hpbnQ7CiAgICBicmVhazsKICBjYXNlIFBLVF9SRVFVRVNUOgogICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gKCpIZWFkZXIpLT5yZXF1ZXN0LmFsbG9jX2hpbnQ7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gY29tbW9uX2hkci5mcmFnX2xlbiAtIGhkcl9sZW5ndGggLSBSUENfQVVUSF9WRVJJRklFUl9MRU4oJmNvbW1vbl9oZHIpOwogIH0KCiAgVFJBQ0UoImJ1ZmZlciBsZW5ndGggPSAldVxuIiwgcE1zZy0+QnVmZmVyTGVuZ3RoKTsKCiAgc3RhdHVzID0gSV9ScGNHZXRCdWZmZXIocE1zZyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgZ290byBmYWlsOwoKICBmaXJzdF9mbGFnID0gUlBDX0ZMR19GSVJTVDsKICBhdXRoX2xlbmd0aCA9IGNvbW1vbl9oZHIuYXV0aF9sZW47CiAgaWYgKGF1dGhfbGVuZ3RoKSB7CiAgICBhdXRoX2RhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgUlBDX0FVVEhfVkVSSUZJRVJfTEVOKCZjb21tb25faGRyKSk7CiAgICBpZiAoIWF1dGhfZGF0YSkgewogICAgICBzdGF0dXMgPSBSUENfU19PVVRfT0ZfUkVTT1VSQ0VTOwogICAgICBnb3RvIGZhaWw7CiAgICB9CiAgfQogIGJ1ZmZlcl9sZW5ndGggPSAwOwogIHdoaWxlIChUUlVFKQogIHsKICAgIHVuc2lnbmVkIGludCBoZWFkZXJfYXV0aF9sZW4gPSBSUENfQVVUSF9WRVJJRklFUl9MRU4oJigqSGVhZGVyKS0+Y29tbW9uKTsKCiAgICAvKiB2ZXJpZnkgaGVhZGVyIGZpZWxkcyAqLwoKICAgIGlmICgoKCpIZWFkZXIpLT5jb21tb24uZnJhZ19sZW4gPCBoZHJfbGVuZ3RoKSB8fAogICAgICAgICgoKkhlYWRlciktPmNvbW1vbi5mcmFnX2xlbiAtIGhkcl9sZW5ndGggPCBoZWFkZXJfYXV0aF9sZW4pKSB7CiAgICAgIFdBUk4oImZyYWdfbGVuICVkIHRvbyBzbWFsbCBmb3IgaGRyX2xlbmd0aCAlZCBhbmQgYXV0aF9sZW4gJWRcbiIsCiAgICAgICAgKCpIZWFkZXIpLT5jb21tb24uZnJhZ19sZW4sIGhkcl9sZW5ndGgsIGhlYWRlcl9hdXRoX2xlbik7CiAgICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgICBnb3RvIGZhaWw7CiAgICB9CgogICAgaWYgKCgqSGVhZGVyKS0+Y29tbW9uLmF1dGhfbGVuICE9IGF1dGhfbGVuZ3RoKSB7CiAgICAgIFdBUk4oImF1dGhfbGVuIGhlYWRlciBmaWVsZCBjaGFuZ2VkIGZyb20gJWxkIHRvICVkXG4iLAogICAgICAgIGF1dGhfbGVuZ3RoLCAoKkhlYWRlciktPmNvbW1vbi5hdXRoX2xlbik7CiAgICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgICBnb3RvIGZhaWw7CiAgICB9CgogICAgaWYgKCgoKkhlYWRlciktPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfRklSU1QpICE9IGZpcnN0X2ZsYWcpIHsKICAgICAgVFJBQ0UoImludmFsaWQgcGFja2V0IGZsYWdzXG4iKTsKICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgIGdvdG8gZmFpbDsKICAgIH0KCiAgICBkYXRhX2xlbmd0aCA9ICgqSGVhZGVyKS0+Y29tbW9uLmZyYWdfbGVuIC0gaGRyX2xlbmd0aCAtIGhlYWRlcl9hdXRoX2xlbjsKICAgIGlmIChkYXRhX2xlbmd0aCArIGJ1ZmZlcl9sZW5ndGggPiBwTXNnLT5CdWZmZXJMZW5ndGgpIHsKICAgICAgVFJBQ0UoImFsbG9jYXRpb24gaGludCBleGNlZWRlZCwgbmV3IGJ1ZmZlciBsZW5ndGggPSAlbGRcbiIsCiAgICAgICAgZGF0YV9sZW5ndGggKyBidWZmZXJfbGVuZ3RoKTsKICAgICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gZGF0YV9sZW5ndGggKyBidWZmZXJfbGVuZ3RoOwogICAgICBzdGF0dXMgPSBJX1JwY1JlQWxsb2NhdGVCdWZmZXIocE1zZyk7CiAgICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIGdvdG8gZmFpbDsKICAgIH0KCiAgICBpZiAoZGF0YV9sZW5ndGggPT0gMCkgZHdSZWFkID0gMDsgZWxzZQogICAgZHdSZWFkID0gcnBjcnQ0X2Nvbm5fcmVhZChDb25uZWN0aW9uLAogICAgICAgICh1bnNpZ25lZCBjaGFyICopcE1zZy0+QnVmZmVyICsgYnVmZmVyX2xlbmd0aCwgZGF0YV9sZW5ndGgpOwogICAgaWYgKGR3UmVhZCAhPSBkYXRhX2xlbmd0aCkgewogICAgICBXQVJOKCJiYWQgZGF0YSBsZW5ndGgsICVkLyVsZFxuIiwgZHdSZWFkLCBkYXRhX2xlbmd0aCk7CiAgICAgIHN0YXR1cyA9IFJQQ19TX0NBTExfRkFJTEVEOwogICAgICBnb3RvIGZhaWw7CiAgICB9CgogICAgaWYgKGhlYWRlcl9hdXRoX2xlbikgewogICAgICBpZiAoaGVhZGVyX2F1dGhfbGVuIDwgc2l6ZW9mKFJwY0F1dGhWZXJpZmllcikpIHsKICAgICAgICBXQVJOKCJiYWQgYXV0aCB2ZXJpZmllciBsZW5ndGggJWRcbiIsIGhlYWRlcl9hdXRoX2xlbik7CiAgICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgICAgZ290byBmYWlsOwogICAgICB9CgogICAgICAvKiBGSVhNRTogd2Ugc2hvdWxkIGFjY3VtdWxhdGUgYXV0aGVudGljYXRpb24gZGF0YSBmb3IgdGhlIGJpbmQsCiAgICAgICAqIGJpbmRfYWNrLCBhbHRlcl9jb250ZXh0IGFuZCBhbHRlcl9jb250ZXh0X3Jlc3BvbnNlIGlmIG5lY2Vzc2FyeS4KICAgICAgICogaG93ZXZlciwgdGhlIGRldGFpbHMgb2YgaG93IHRoaXMgaXMgZG9uZSBpcyB2ZXJ5IHNrZXRjaHkgaW4gdGhlCiAgICAgICAqIERDRS9SUEMgc3BlYy4gZm9yIGFsbCBvdGhlciBwYWNrZXQgdHlwZXMgdGhhdCBoYXZlIGF1dGhlbnRpY2F0aW9uCiAgICAgICAqIHZlcmlmaWVyIGRhdGEgdGhlbiBpdCBpcyBqdXN0IGR1cGxpY2F0ZWQgaW4gYWxsIHRoZSBmcmFnbWVudHMgKi8KICAgICAgZHdSZWFkID0gcnBjcnQ0X2Nvbm5fcmVhZChDb25uZWN0aW9uLCBhdXRoX2RhdGEsIGhlYWRlcl9hdXRoX2xlbik7CiAgICAgIGlmIChkd1JlYWQgIT0gaGVhZGVyX2F1dGhfbGVuKSB7CiAgICAgICAgV0FSTigiYmFkIGF1dGhlbnRpY2F0aW9uIGRhdGEgbGVuZ3RoLCAlZC8lZFxuIiwgZHdSZWFkLAogICAgICAgICAgaGVhZGVyX2F1dGhfbGVuKTsKICAgICAgICBzdGF0dXMgPSBSUENfU19DQUxMX0ZBSUxFRDsKICAgICAgICBnb3RvIGZhaWw7CiAgICAgIH0KCiAgICAgIC8qIHRoZXNlIHBhY2tldHMgYXJlIGhhbmRsZWQgc3BlY2lhbGx5LCBub3QgYnkgdGhlIGdlbmVyaWMgU2VjdXJlUGFja2V0CiAgICAgICAqIGZ1bmN0aW9uICovCiAgICAgIGlmICgoY29tbW9uX2hkci5wdHlwZSAhPSBQS1RfQklORCkgJiYKICAgICAgICAgIChjb21tb25faGRyLnB0eXBlICE9IFBLVF9CSU5EX0FDSykgJiYKICAgICAgICAgIChjb21tb25faGRyLnB0eXBlICE9IFBLVF9BVVRIMykpCiAgICAgIHsKICAgICAgICBzdGF0dXMgPSBSUENSVDRfU2VjdXJlUGFja2V0KENvbm5lY3Rpb24sIFNFQ1VSRV9QQUNLRVRfUkVDRUlWRSwKICAgICAgICAgICAgKkhlYWRlciwgaGRyX2xlbmd0aCwKICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIgKilwTXNnLT5CdWZmZXIgKyBidWZmZXJfbGVuZ3RoLCBkYXRhX2xlbmd0aCwKICAgICAgICAgICAgKFJwY0F1dGhWZXJpZmllciAqKWF1dGhfZGF0YSwKICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIgKilhdXRoX2RhdGEgKyBzaXplb2YoUnBjQXV0aFZlcmlmaWVyKSwKICAgICAgICAgICAgaGVhZGVyX2F1dGhfbGVuIC0gc2l6ZW9mKFJwY0F1dGhWZXJpZmllcikpOwogICAgICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIGdvdG8gZmFpbDsKICAgICAgfQogICAgfQoKICAgIGJ1ZmZlcl9sZW5ndGggKz0gZGF0YV9sZW5ndGg7CiAgICBpZiAoISgoKkhlYWRlciktPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfTEFTVCkpIHsKICAgICAgVFJBQ0UoIm5leHQgaGVhZGVyXG4iKTsKCiAgICAgIC8qIHJlYWQgdGhlIGhlYWRlciBvZiBuZXh0IHBhY2tldCAqLwogICAgICBkd1JlYWQgPSBycGNydDRfY29ubl9yZWFkKENvbm5lY3Rpb24sICpIZWFkZXIsIGhkcl9sZW5ndGgpOwogICAgICBpZiAoZHdSZWFkICE9IGhkcl9sZW5ndGgpIHsKICAgICAgICBXQVJOKCJpbnZhbGlkIHBhY2tldCBoZWFkZXIgc2l6ZSAoJWQpXG4iLCBkd1JlYWQpOwogICAgICAgIHN0YXR1cyA9IFJQQ19TX0NBTExfRkFJTEVEOwogICAgICAgIGdvdG8gZmFpbDsKICAgICAgfQoKICAgICAgZmlyc3RfZmxhZyA9IDA7CiAgICB9IGVsc2UgewogICAgICBicmVhazsKICAgIH0KICB9CiAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gYnVmZmVyX2xlbmd0aDsKCiAgLyogcmVzcG9uZCB0byBhdXRob3JpemF0aW9uIHJlcXVlc3QgKi8KICBpZiAoY29tbW9uX2hkci5wdHlwZSA9PSBQS1RfQklORF9BQ0sgJiYgYXV0aF9sZW5ndGggPiBzaXplb2YoUnBjQXV0aFZlcmlmaWVyKSkKICB7CiAgICBzdGF0dXMgPSBSUENSVF9BdXRob3JpemVDb25uZWN0aW9uKENvbm5lY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhfZGF0YSArIHNpemVvZihScGNBdXRoVmVyaWZpZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRoX2xlbmd0aCk7CiAgICBpZiAoc3RhdHVzKQogICAgICAgIGdvdG8gZmFpbDsKICB9CgogIC8qIHN1Y2Nlc3MgKi8KICBzdGF0dXMgPSBSUENfU19PSzsKCmZhaWw6CiAgUlBDUlQ0X1NldFRocmVhZEN1cnJlbnRDb25uZWN0aW9uKE5VTEwpOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHsKICAgIFJQQ1JUNF9GcmVlSGVhZGVyKCpIZWFkZXIpOwogICAgKkhlYWRlciA9IE5VTEw7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGF1dGhfZGF0YSk7CiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJX1JwY0dldEJ1ZmZlciBbUlBDUlQ0LkBdCiAqCiAqIEFsbG9jYXRlcyBhIGJ1ZmZlciBmb3IgdXNlIGJ5IElfUnBjU2VuZCBvciBJX1JwY1NlbmRSZWNlaXZlIGFuZCBiaW5kcyB0byB0aGUKICogc2VydmVyIGludGVyZmFjZS4KICoKICogUEFSQU1TCiAqICBwTXNnIFtJL09dIFJQQyBtZXNzYWdlIGluZm9ybWF0aW9uLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBSUENfU19PSy4KICogIEZhaWx1cmU6IFJQQ19TX0lOVkFMSURfQklORElORyBpZiBwTXNnLT5IYW5kbGUgaXMgaW52YWxpZC4KICogICAgICAgICAgIFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRSBpZiB1bmFibGUgdG8gY29ubmVjdCB0byBzZXJ2ZXIuCiAqICAgICAgICAgICBFUlJPUl9PVVRPRk1FTU9SWSBpZiBidWZmZXIgYWxsb2NhdGlvbiBmYWlsZWQuCiAqCiAqIE5PVEVTCiAqICBUaGUgcE1zZy0+QnVmZmVyTGVuZ3RoIGZpZWxkIGRldGVybWluZXMgdGhlIHNpemUgb2YgdGhlIGJ1ZmZlciB0byBhbGxvY2F0ZSwKICogIGluIGJ5dGVzLgogKgogKiAgVXNlIElfUnBjRnJlZUJ1ZmZlcigpIHRvIHVuYmluZCBmcm9tIHRoZSBzZXJ2ZXIgYW5kIGZyZWUgdGhlIG1lc3NhZ2UgYnVmZmVyLgogKgogKiBTRUUgQUxTTwogKiAgSV9ScGNGcmVlQnVmZmVyKCksIElfUnBjU2VuZCgpLCBJX1JwY1JlY2VpdmUoKSwgSV9ScGNTZW5kUmVjZWl2ZSgpLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNHZXRCdWZmZXIoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBUUkFDRSgiKCVwKTogQnVmZmVyTGVuZ3RoPSVkXG4iLCBwTXNnLCBwTXNnLT5CdWZmZXJMZW5ndGgpOwogIC8qIEZJWE1FOiBwZm5BbGxvY2F0ZT8gKi8KICBwTXNnLT5CdWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcE1zZy0+QnVmZmVyTGVuZ3RoKTsKCiAgVFJBQ0UoIkJ1ZmZlcj0lcFxuIiwgcE1zZy0+QnVmZmVyKTsKICAvKiBGSVhNRTogd2hpY2ggZXJyb3JzIHRvIHJldHVybj8gKi8KICByZXR1cm4gcE1zZy0+QnVmZmVyID8gU19PSyA6IEVfT1VUT0ZNRU1PUlk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNSZUFsbG9jYXRlQnVmZmVyIChpbnRlcm5hbCkKICovCnN0YXRpYyBSUENfU1RBVFVTIElfUnBjUmVBbGxvY2F0ZUJ1ZmZlcihQUlBDX01FU1NBR0UgcE1zZykKewogIFRSQUNFKCIoJXApOiBCdWZmZXJMZW5ndGg9JWRcbiIsIHBNc2csIHBNc2ctPkJ1ZmZlckxlbmd0aCk7CiAgcE1zZy0+QnVmZmVyID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcE1zZy0+QnVmZmVyLCBwTXNnLT5CdWZmZXJMZW5ndGgpOwoKICBUUkFDRSgiQnVmZmVyPSVwXG4iLCBwTXNnLT5CdWZmZXIpOwogIHJldHVybiBwTXNnLT5CdWZmZXIgPyBSUENfU19PSyA6IFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNGcmVlQnVmZmVyIFtSUENSVDQuQF0KICoKICogRnJlZXMgYSBidWZmZXIgYWxsb2NhdGVkIGJ5IElfUnBjR2V0QnVmZmVyIG9yIElfUnBjUmVjZWl2ZSBhbmQgdW5iaW5kcyBmcm9tCiAqIHRoZSBzZXJ2ZXIgaW50ZXJmYWNlLgogKgogKiBQQVJBTVMKICogIHBNc2cgW0kvT10gUlBDIG1lc3NhZ2UgaW5mb3JtYXRpb24uCiAqCiAqIFJFVFVSTlMKICogIFJQQ19TX09LLgogKgogKiBTRUUgQUxTTwogKiAgSV9ScGNHZXRCdWZmZXIoKSwgSV9ScGNSZWNlaXZlKCkuCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY0ZyZWVCdWZmZXIoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBUUkFDRSgiKCVwKSBCdWZmZXI9JXBcbiIsIHBNc2csIHBNc2ctPkJ1ZmZlcik7CiAgLyogRklYTUU6IHBmbkZyZWU/ICovCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcE1zZy0+QnVmZmVyKTsKICBwTXNnLT5CdWZmZXIgPSBOVUxMOwogIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElfUnBjU2VuZCBbUlBDUlQ0LkBdCiAqCiAqIFNlbmRzIGEgbWVzc2FnZSB0byB0aGUgc2VydmVyLgogKgogKiBQQVJBTVMKICogIHBNc2cgW0kvT10gUlBDIG1lc3NhZ2UgaW5mb3JtYXRpb24uCiAqCiAqIFJFVFVSTlMKICogIFVua25vd24uCiAqCiAqIE5PVEVTCiAqICBUaGUgYnVmZmVyIG11c3QgaGF2ZSBiZWVuIGFsbG9jYXRlZCB3aXRoIElfUnBjR2V0QnVmZmVyKCkuCiAqCiAqIFNFRSBBTFNPCiAqICBJX1JwY0dldEJ1ZmZlcigpLCBJX1JwY1JlY2VpdmUoKSwgSV9ScGNTZW5kUmVjZWl2ZSgpLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNTZW5kKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilwTXNnLT5IYW5kbGU7CiAgUnBjQ29ubmVjdGlvbiogY29ubjsKICBSUENfQ0xJRU5UX0lOVEVSRkFDRSogY2lmID0gTlVMTDsKICBSUENfU1RBVFVTIHN0YXR1czsKICBScGNQa3RIZHIgKmhkcjsKCiAgVFJBQ0UoIiglcClcbiIsIHBNc2cpOwogIGlmICghYmluZCB8fCBiaW5kLT5zZXJ2ZXIpIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7CgogIGNpZiA9IHBNc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uOwogIGlmICghY2lmKSByZXR1cm4gUlBDX1NfSU5URVJGQUNFX05PVF9GT1VORDsgLyogPyAqLwoKICBpZiAoIWJpbmQtPkVuZHBvaW50IHx8ICFiaW5kLT5FbmRwb2ludFswXSkKICB7CiAgICBUUkFDRSgiYXV0b21hdGljYWxseSByZXNvbHZpbmcgcGFydGlhbGx5IGJvdW5kIGJpbmRpbmdcbiIpOwogICAgc3RhdHVzID0gUnBjRXBSZXNvbHZlQmluZGluZyhiaW5kLCBjaWYpOwogICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgcmV0dXJuIHN0YXR1czsKICB9CgogIHN0YXR1cyA9IFJQQ1JUNF9PcGVuQmluZGluZyhiaW5kLCAmY29ubiwgJmNpZi0+VHJhbnNmZXJTeW50YXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaWYtPkludGVyZmFjZUlkKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSByZXR1cm4gc3RhdHVzOwoKICBoZHIgPSBSUENSVDRfQnVpbGRSZXF1ZXN0SGVhZGVyKHBNc2ctPkRhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNc2ctPkJ1ZmZlckxlbmd0aCwgcE1zZy0+UHJvY051bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZiaW5kLT5PYmplY3RVdWlkKTsKICBpZiAoIWhkcikKICB7CiAgICBSUENSVDRfQ2xvc2VCaW5kaW5nKGJpbmQsIGNvbm4pOwogICAgcmV0dXJuIEVSUk9SX09VVE9GTUVNT1JZOwogIH0KICBoZHItPmNvbW1vbi5jYWxsX2lkID0gY29ubi0+TmV4dENhbGxJZCsrOwoKICBzdGF0dXMgPSBSUENSVDRfU2VuZChjb25uLCBoZHIsIHBNc2ctPkJ1ZmZlciwgcE1zZy0+QnVmZmVyTGVuZ3RoKTsKCiAgUlBDUlQ0X0ZyZWVIZWFkZXIoaGRyKTsKCiAgLyogc2F2ZSB0aGUgY29ubmVjdGlvbiwgc28gdGhlIHJlc3BvbnNlIGNhbiBiZSByZWFkIGZyb20gaXQgKi8KICBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUgPSBjb25uOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qIGlzIHRoaXMgc3RhdHVzIHNvbWV0aGluZyB0aGF0IHRoZSBzZXJ2ZXIgY2FuJ3QgcmVjb3ZlciBmcm9tPyAqLwpzdGF0aWMgaW5saW5lIEJPT0wgaXNfaGFyZF9lcnJvcihSUENfU1RBVFVTIHN0YXR1cykKewogICAgc3dpdGNoIChzdGF0dXMpCiAgICB7CiAgICBjYXNlIDA6IC8qIHVzZXItZGVmaW5lZCBmYXVsdCAqLwogICAgY2FzZSBFUlJPUl9BQ0NFU1NfREVOSUVEOgogICAgY2FzZSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjoKICAgIGNhc2UgUlBDX1NfUFJPVE9DT0xfRVJST1I6CiAgICBjYXNlIFJQQ19TX0NBTExfRkFJTEVEOgogICAgY2FzZSBSUENfU19DQUxMX0ZBSUxFRF9ETkU6CiAgICBjYXNlIFJQQ19TX1NFQ19QS0dfRVJST1I6CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJX1JwY1JlY2VpdmUgW1JQQ1JUNC5AXQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNSZWNlaXZlKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilwTXNnLT5IYW5kbGU7CiAgUnBjQ29ubmVjdGlvbiogY29ubjsKICBSUENfQ0xJRU5UX0lOVEVSRkFDRSogY2lmID0gTlVMTDsKICBSUENfU0VSVkVSX0lOVEVSRkFDRSogc2lmID0gTlVMTDsKICBSUENfU1RBVFVTIHN0YXR1czsKICBScGNQa3RIZHIgKmhkciA9IE5VTEw7CgogIFRSQUNFKCIoJXApXG4iLCBwTXNnKTsKICBpZiAoIWJpbmQpIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7CgogIGlmIChwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUpIHsKICAgIGNvbm4gPSBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWU7CiAgICBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUgPSBOVUxMOwogIH0gZWxzZSB7CiAgICBpZiAoYmluZC0+c2VydmVyKSB7CiAgICAgIHNpZiA9IHBNc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uOwogICAgICBpZiAoIXNpZikgcmV0dXJuIFJQQ19TX0lOVEVSRkFDRV9OT1RfRk9VTkQ7IC8qID8gKi8KICAgICAgc3RhdHVzID0gUlBDUlQ0X09wZW5CaW5kaW5nKGJpbmQsICZjb25uLCAmc2lmLT5UcmFuc2ZlclN5bnRheCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzaWYtPkludGVyZmFjZUlkKTsKICAgIH0gZWxzZSB7CiAgICAgIGNpZiA9IHBNc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uOwogICAgICBpZiAoIWNpZikgcmV0dXJuIFJQQ19TX0lOVEVSRkFDRV9OT1RfRk9VTkQ7IC8qID8gKi8KCiAgICAgIGlmICghYmluZC0+RW5kcG9pbnQgfHwgIWJpbmQtPkVuZHBvaW50WzBdKQogICAgICB7CiAgICAgICAgVFJBQ0UoImF1dG9tYXRpY2FsbHkgcmVzb2x2aW5nIHBhcnRpYWxseSBib3VuZCBiaW5kaW5nXG4iKTsKICAgICAgICBzdGF0dXMgPSBScGNFcFJlc29sdmVCaW5kaW5nKGJpbmQsIGNpZik7CiAgICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgcmV0dXJuIHN0YXR1czsKICAgICAgfQoKICAgICAgc3RhdHVzID0gUlBDUlQ0X09wZW5CaW5kaW5nKGJpbmQsICZjb25uLCAmY2lmLT5UcmFuc2ZlclN5bnRheCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaWYtPkludGVyZmFjZUlkKTsKICAgIH0KICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHJldHVybiBzdGF0dXM7CiAgfQoKICBzdGF0dXMgPSBSUENSVDRfUmVjZWl2ZShjb25uLCAmaGRyLCBwTXNnKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSB7CiAgICBXQVJOKCJyZWNlaXZlIGZhaWxlZCB3aXRoIGVycm9yICVseFxuIiwgc3RhdHVzKTsKICAgIGdvdG8gZmFpbDsKICB9CgogIHN3aXRjaCAoaGRyLT5jb21tb24ucHR5cGUpIHsKICBjYXNlIFBLVF9SRVNQT05TRToKICAgIGlmIChiaW5kLT5zZXJ2ZXIpIHsKICAgICAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgICAgICBnb3RvIGZhaWw7CiAgICB9CiAgICBicmVhazsKICBjYXNlIFBLVF9SRVFVRVNUOgogICAgaWYgKCFiaW5kLT5zZXJ2ZXIpIHsKICAgICAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgICAgICBnb3RvIGZhaWw7CiAgICB9CiAgICBicmVhazsKICBjYXNlIFBLVF9GQVVMVDoKICAgIEVSUiAoIndlIGdvdCBmYXVsdCBwYWNrZXQgd2l0aCBzdGF0dXMgMHglbHhcbiIsIGhkci0+ZmF1bHQuc3RhdHVzKTsKICAgIHN0YXR1cyA9IE5DQTJSUENfU1RBVFVTKGhkci0+ZmF1bHQuc3RhdHVzKTsKICAgIGlmIChpc19oYXJkX2Vycm9yKHN0YXR1cykpCiAgICAgICAgZ290byBmYWlsOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIFdBUk4oImJhZCBwYWNrZXQgdHlwZSAlZFxuIiwgaGRyLT5jb21tb24ucHR5cGUpOwogICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICBnb3RvIGZhaWw7CiAgfQoKICAvKiBzdWNjZXNzICovCiAgUlBDUlQ0X0Nsb3NlQmluZGluZyhiaW5kLCBjb25uKTsKICBSUENSVDRfRnJlZUhlYWRlcihoZHIpOwogIHJldHVybiBzdGF0dXM7CgpmYWlsOgogIFJQQ1JUNF9GcmVlSGVhZGVyKGhkcik7CiAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKGNvbm4pOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNTZW5kUmVjZWl2ZSBbUlBDUlQ0LkBdCiAqCiAqIFNlbmRzIGEgbWVzc2FnZSB0byB0aGUgc2VydmVyIGFuZCByZWNlaXZlcyB0aGUgcmVzcG9uc2UuCiAqCiAqIFBBUkFNUwogKiAgcE1zZyBbSS9PXSBSUEMgbWVzc2FnZSBpbmZvcm1hdGlvbi4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogUlBDX1NfT0suCiAqICBGYWlsdXJlOiBBbnkgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogIFRoZSBidWZmZXIgbXVzdCBoYXZlIGJlZW4gYWxsb2NhdGVkIHdpdGggSV9ScGNHZXRCdWZmZXIoKS4KICoKICogU0VFIEFMU08KICogIElfUnBjR2V0QnVmZmVyKCksIElfUnBjU2VuZCgpLCBJX1JwY1JlY2VpdmUoKS4KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VuZFJlY2VpdmUoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICBSUENfTUVTU0FHRSBvcmlnaW5hbF9tZXNzYWdlOwoKICBUUkFDRSgiKCVwKVxuIiwgcE1zZyk7CgogIG9yaWdpbmFsX21lc3NhZ2UgPSAqcE1zZzsKICBzdGF0dXMgPSBJX1JwY1NlbmQocE1zZyk7CiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgIHN0YXR1cyA9IElfUnBjUmVjZWl2ZShwTXNnKTsKICAvKiBmcmVlIHRoZSBidWZmZXIgcmVwbGFjZWQgYnkgYSBuZXcgYnVmZmVyIGluIElfUnBjUmVjZWl2ZSAqLwogIGlmIChzdGF0dXMgPT0gUlBDX1NfT0spCiAgICBJX1JwY0ZyZWVCdWZmZXIoJm9yaWdpbmFsX21lc3NhZ2UpOwogIHJldHVybiBzdGF0dXM7Cn0K