LyoKICogUlBDIG1lc3NhZ2VzCiAqCiAqIENvcHlyaWdodCAyMDAxLTIwMDIgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqIENvcHlyaWdodCAyMDA2IENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCgojaW5jbHVkZSAicnBjLmgiCiNpbmNsdWRlICJycGNuZHIuaCIKI2luY2x1ZGUgInJwY2RjZXAuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAicnBjX2JpbmRpbmcuaCIKI2luY2x1ZGUgInJwY19kZWZzLmgiCiNpbmNsdWRlICJycGNfbWVzc2FnZS5oIgojaW5jbHVkZSAibmNhc3RhdHVzLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKLyogbm90ZTogdGhlIERDRS9SUEMgc3BlYyBzYXlzIHRoZSBhbGlnbm1lbnQgYW1vdW50IHNob3VsZCBiZSA0LCBidXQKICogTVMvUlBDIHNlcnZlcnMgc2VlbSB0byBhbHdheXMgdXNlIDE2ICovCiNkZWZpbmUgQVVUSF9BTElHTk1FTlQgMTYKCi8qIGdldHMgdGhlIGFtb3VudCBuZWVkZWQgdG8gcm91bmQgYSB2YWx1ZSB1cCB0byB0aGUgc3BlY2lmaWVkIGFsaWdubWVudCAqLwojZGVmaW5lIFJPVU5EX1VQX0FNT1VOVCh2YWx1ZSwgYWxpZ25tZW50KSBcCiAgICAoKChhbGlnbm1lbnQpIC0gKCgodmFsdWUpICUgKGFsaWdubWVudCkpKSkgJSAoYWxpZ25tZW50KSkKI2RlZmluZSBST1VORF9VUCh2YWx1ZSwgYWxpZ25tZW50KSAoKCh2YWx1ZSkgKyAoKGFsaWdubWVudCkgLSAxKSkgJiB+KChhbGlnbm1lbnQpLTEpKQoKZW51bSBzZWN1cmVfcGFja2V0X2RpcmVjdGlvbgp7CiAgU0VDVVJFX1BBQ0tFVF9TRU5ELAogIFNFQ1VSRV9QQUNLRVRfUkVDRUlWRQp9OwoKc3RhdGljIFJQQ19TVEFUVVMgSV9ScGNSZUFsbG9jYXRlQnVmZmVyKFBSUENfTUVTU0FHRSBwTXNnKTsKCnN0YXRpYyBEV09SRCBSUENSVDRfR2V0SGVhZGVyU2l6ZShjb25zdCBScGNQa3RIZHIgKkhlYWRlcikKewogIHN0YXRpYyBjb25zdCBEV09SRCBoZWFkZXJfc2l6ZXNbXSA9IHsKICAgIHNpemVvZihIZWFkZXItPnJlcXVlc3QpLCAwLCBzaXplb2YoSGVhZGVyLT5yZXNwb25zZSksCiAgICBzaXplb2YoSGVhZGVyLT5mYXVsdCksIDAsIDAsIDAsIDAsIDAsIDAsIDAsIHNpemVvZihIZWFkZXItPmJpbmQpLAogICAgc2l6ZW9mKEhlYWRlci0+YmluZF9hY2spLCBzaXplb2YoSGVhZGVyLT5iaW5kX25hY2spLAogICAgMCwgMCwgMCwgMCwgMAogIH07CiAgVUxPTkcgcmV0ID0gMDsKICAKICBpZiAoSGVhZGVyLT5jb21tb24ucHR5cGUgPCBzaXplb2YoaGVhZGVyX3NpemVzKSAvIHNpemVvZihoZWFkZXJfc2l6ZXNbMF0pKSB7CiAgICByZXQgPSBoZWFkZXJfc2l6ZXNbSGVhZGVyLT5jb21tb24ucHR5cGVdOwogICAgaWYgKHJldCA9PSAwKQogICAgICBGSVhNRSgidW5oYW5kbGVkIHBhY2tldCB0eXBlXG4iKTsKICAgIGlmIChIZWFkZXItPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfT0JKRUNUX1VVSUQpCiAgICAgIHJldCArPSBzaXplb2YoVVVJRCk7CiAgfSBlbHNlIHsKICAgIFRSQUNFKCJpbnZhbGlkIHBhY2tldCB0eXBlXG4iKTsKICB9CgogIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgcGFja2V0X2hhc19ib2R5KGNvbnN0IFJwY1BrdEhkciAqSGVhZGVyKQp7CiAgICByZXR1cm4gKEhlYWRlci0+Y29tbW9uLnB0eXBlID09IFBLVF9GQVVMVCkgfHwKICAgICAgICAgICAoSGVhZGVyLT5jb21tb24ucHR5cGUgPT0gUEtUX1JFUVVFU1QpIHx8CiAgICAgICAgICAgKEhlYWRlci0+Y29tbW9uLnB0eXBlID09IFBLVF9SRVNQT05TRSk7Cn0KCnN0YXRpYyBpbnQgcGFja2V0X2hhc19hdXRoX3ZlcmlmaWVyKGNvbnN0IFJwY1BrdEhkciAqSGVhZGVyKQp7CiAgICByZXR1cm4gIShIZWFkZXItPmNvbW1vbi5wdHlwZSA9PSBQS1RfQklORF9OQUNLKSAmJgogICAgICAgICAgICEoSGVhZGVyLT5jb21tb24ucHR5cGUgPT0gUEtUX1NIVVRET1dOKTsKfQoKc3RhdGljIFZPSUQgUlBDUlQ0X0J1aWxkQ29tbW9uSGVhZGVyKFJwY1BrdEhkciAqSGVhZGVyLCB1bnNpZ25lZCBjaGFyIFBhY2tldFR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uKQp7CiAgSGVhZGVyLT5jb21tb24ucnBjX3ZlciA9IFJQQ19WRVJfTUFKT1I7CiAgSGVhZGVyLT5jb21tb24ucnBjX3Zlcl9taW5vciA9IFJQQ19WRVJfTUlOT1I7CiAgSGVhZGVyLT5jb21tb24ucHR5cGUgPSBQYWNrZXRUeXBlOwogIEhlYWRlci0+Y29tbW9uLmRyZXBbMF0gPSBMT0JZVEUoTE9XT1JEKERhdGFSZXByZXNlbnRhdGlvbikpOwogIEhlYWRlci0+Y29tbW9uLmRyZXBbMV0gPSBISUJZVEUoTE9XT1JEKERhdGFSZXByZXNlbnRhdGlvbikpOwogIEhlYWRlci0+Y29tbW9uLmRyZXBbMl0gPSBMT0JZVEUoSElXT1JEKERhdGFSZXByZXNlbnRhdGlvbikpOwogIEhlYWRlci0+Y29tbW9uLmRyZXBbM10gPSBISUJZVEUoSElXT1JEKERhdGFSZXByZXNlbnRhdGlvbikpOwogIEhlYWRlci0+Y29tbW9uLmF1dGhfbGVuID0gMDsKICBIZWFkZXItPmNvbW1vbi5jYWxsX2lkID0gMTsKICBIZWFkZXItPmNvbW1vbi5mbGFncyA9IDA7CiAgLyogRmxhZ3MgYW5kIGZyYWdtZW50IGxlbmd0aCBhcmUgY29tcHV0ZWQgaW4gUlBDUlQ0X1NlbmQuICovCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCnN0YXRpYyBScGNQa3RIZHIgKlJQQ1JUNF9CdWlsZFJlcXVlc3RIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIEJ1ZmZlckxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IFByb2NOdW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVUlEICpPYmplY3RVdWlkKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CiAgQk9PTCBoYXNfb2JqZWN0OwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBoYXNfb2JqZWN0ID0gKE9iamVjdFV1aWQgIT0gTlVMTCAmJiAhVXVpZElzTmlsKE9iamVjdFV1aWQsICZzdGF0dXMpKTsKICBoZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGhlYWRlci0+cmVxdWVzdCkgKyAoaGFzX29iamVjdCA/IHNpemVvZihVVUlEKSA6IDApKTsKICBpZiAoaGVhZGVyID09IE5VTEwpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgUlBDUlQ0X0J1aWxkQ29tbW9uSGVhZGVyKGhlYWRlciwgUEtUX1JFUVVFU1QsIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBzaXplb2YoaGVhZGVyLT5yZXF1ZXN0KTsKICBoZWFkZXItPnJlcXVlc3QuYWxsb2NfaGludCA9IEJ1ZmZlckxlbmd0aDsKICBoZWFkZXItPnJlcXVlc3QuY29udGV4dF9pZCA9IDA7CiAgaGVhZGVyLT5yZXF1ZXN0Lm9wbnVtID0gUHJvY051bTsKICBpZiAoaGFzX29iamVjdCkgewogICAgaGVhZGVyLT5jb21tb24uZmxhZ3MgfD0gUlBDX0ZMR19PQkpFQ1RfVVVJRDsKICAgIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuICs9IHNpemVvZihVVUlEKTsKICAgIG1lbWNweSgmaGVhZGVyLT5yZXF1ZXN0ICsgMSwgT2JqZWN0VXVpZCwgc2l6ZW9mKFVVSUQpKTsKICB9CgogIHJldHVybiBoZWFkZXI7Cn0KClJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkUmVzcG9uc2VIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBCdWZmZXJMZW5ndGgpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPnJlc3BvbnNlKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9SRVNQT05TRSwgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHNpemVvZihoZWFkZXItPnJlc3BvbnNlKTsKICBoZWFkZXItPnJlc3BvbnNlLmFsbG9jX2hpbnQgPSBCdWZmZXJMZW5ndGg7CgogIHJldHVybiBoZWFkZXI7Cn0KClJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NUQVRVUyBTdGF0dXMpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPmZhdWx0KSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9GQVVMVCwgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHNpemVvZihoZWFkZXItPmZhdWx0KTsKICBoZWFkZXItPmZhdWx0LnN0YXR1cyA9IFN0YXR1czsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRCaW5kSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgTWF4VHJhbnNtaXNzaW9uU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IE1heFJlY2VpdmVTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyAgQXNzb2NHcm91cElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpBYnN0cmFjdElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpUcmFuc2ZlcklkKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CgogIGhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoaGVhZGVyLT5iaW5kKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9CSU5ELCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+YmluZCk7CiAgaGVhZGVyLT5iaW5kLm1heF90c2l6ZSA9IE1heFRyYW5zbWlzc2lvblNpemU7CiAgaGVhZGVyLT5iaW5kLm1heF9yc2l6ZSA9IE1heFJlY2VpdmVTaXplOwogIGhlYWRlci0+YmluZC5hc3NvY19naWQgPSBBc3NvY0dyb3VwSWQ7CiAgaGVhZGVyLT5iaW5kLm51bV9lbGVtZW50cyA9IDE7CiAgaGVhZGVyLT5iaW5kLm51bV9zeW50YXhlcyA9IDE7CiAgaGVhZGVyLT5iaW5kLmFic3RyYWN0ID0gKkFic3RyYWN0SWQ7CiAgaGVhZGVyLT5iaW5kLnRyYW5zZmVyID0gKlRyYW5zZmVySWQ7CgogIHJldHVybiBoZWFkZXI7Cn0KCnN0YXRpYyBScGNQa3RIZHIgKlJQQ1JUNF9CdWlsZEF1dGhIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24pCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksCiAgICAgICAgICAgICAgICAgICAgIHNpemVvZihoZWFkZXItPmNvbW1vbikgKyAxMik7CiAgaWYgKGhlYWRlciA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9BVVRIMywgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IDB4MTQ7CiAgaGVhZGVyLT5jb21tb24uYXV0aF9sZW4gPSAwOwoKICByZXR1cm4gaGVhZGVyOwp9CgpScGNQa3RIZHIgKlJQQ1JUNF9CdWlsZEJpbmROYWNrSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgUnBjVmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFJwY1ZlcnNpb25NaW5vcikKewogIFJwY1BrdEhkciAqaGVhZGVyOwoKICBoZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKGhlYWRlci0+YmluZF9uYWNrKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9CSU5EX05BQ0ssIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBzaXplb2YoaGVhZGVyLT5iaW5kX25hY2spOwogIGhlYWRlci0+YmluZF9uYWNrLnJlamVjdF9yZWFzb24gPSBSRUpFQ1RfUkVBU09OX05PVF9TUEVDSUZJRUQ7CiAgaGVhZGVyLT5iaW5kX25hY2sucHJvdG9jb2xzX2NvdW50ID0gMTsKICBoZWFkZXItPmJpbmRfbmFjay5wcm90b2NvbHNbMF0ucnBjX3ZlciA9IFJwY1ZlcnNpb247CiAgaGVhZGVyLT5iaW5kX25hY2sucHJvdG9jb2xzWzBdLnJwY192ZXJfbWlub3IgPSBScGNWZXJzaW9uTWlub3I7CgogIHJldHVybiBoZWFkZXI7Cn0KClJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkQmluZEFja0hlYWRlcih1bnNpZ25lZCBsb25nIERhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IE1heFRyYW5zbWlzc2lvblNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBNYXhSZWNlaXZlU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgQXNzb2NHcm91cElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIFNlcnZlckFkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIFJlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgUmVhc29uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpUcmFuc2ZlcklkKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CiAgdW5zaWduZWQgbG9uZyBoZWFkZXJfc2l6ZTsKICBScGNBZGRyZXNzU3RyaW5nICpzZXJ2ZXJfYWRkcmVzczsKICBScGNSZXN1bHRzICpyZXN1bHRzOwogIFJQQ19TWU5UQVhfSURFTlRJRklFUiAqdHJhbnNmZXJfaWQ7CgogIGhlYWRlcl9zaXplID0gc2l6ZW9mKGhlYWRlci0+YmluZF9hY2spICsKICAgICAgICAgICAgICAgIFJPVU5EX1VQKEZJRUxEX09GRlNFVChScGNBZGRyZXNzU3RyaW5nLCBzdHJpbmdbc3RybGVuKFNlcnZlckFkZHJlc3MpICsgMV0pLCA0KSArCiAgICAgICAgICAgICAgICBzaXplb2YoUnBjUmVzdWx0cykgKwogICAgICAgICAgICAgICAgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUik7CgogIGhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBoZWFkZXJfc2l6ZSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9CSU5EX0FDSywgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IGhlYWRlcl9zaXplOwogIGhlYWRlci0+YmluZF9hY2subWF4X3RzaXplID0gTWF4VHJhbnNtaXNzaW9uU2l6ZTsKICBoZWFkZXItPmJpbmRfYWNrLm1heF9yc2l6ZSA9IE1heFJlY2VpdmVTaXplOwogIGhlYWRlci0+YmluZF9hY2suYXNzb2NfZ2lkID0gQXNzb2NHcm91cElkOwogIHNlcnZlcl9hZGRyZXNzID0gKFJwY0FkZHJlc3NTdHJpbmcqKSgmaGVhZGVyLT5iaW5kX2FjayArIDEpOwogIHNlcnZlcl9hZGRyZXNzLT5sZW5ndGggPSBzdHJsZW4oU2VydmVyQWRkcmVzcykgKyAxOwogIHN0cmNweShzZXJ2ZXJfYWRkcmVzcy0+c3RyaW5nLCBTZXJ2ZXJBZGRyZXNzKTsKICAvKiByZXN1bHRzIGlzIDQtYnl0ZSBhbGlnbmVkICovCiAgcmVzdWx0cyA9IChScGNSZXN1bHRzKikoKFVMT05HX1BUUilzZXJ2ZXJfYWRkcmVzcyArIFJPVU5EX1VQKEZJRUxEX09GRlNFVChScGNBZGRyZXNzU3RyaW5nLCBzdHJpbmdbc2VydmVyX2FkZHJlc3MtPmxlbmd0aF0pLCA0KSk7CiAgcmVzdWx0cy0+bnVtX3Jlc3VsdHMgPSAxOwogIHJlc3VsdHMtPnJlc3VsdHNbMF0ucmVzdWx0ID0gUmVzdWx0OwogIHJlc3VsdHMtPnJlc3VsdHNbMF0ucmVhc29uID0gUmVhc29uOwogIHRyYW5zZmVyX2lkID0gKFJQQ19TWU5UQVhfSURFTlRJRklFUiopKHJlc3VsdHMgKyAxKTsKICAqdHJhbnNmZXJfaWQgPSAqVHJhbnNmZXJJZDsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKVk9JRCBSUENSVDRfRnJlZUhlYWRlcihScGNQa3RIZHIgKkhlYWRlcikKewogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIEhlYWRlcik7Cn0KCk5DQV9TVEFUVVMgUlBDMk5DQV9TVEFUVVMoUlBDX1NUQVRVUyBzdGF0dXMpCnsKICAgIHN3aXRjaCAoc3RhdHVzKQogICAgewogICAgY2FzZSBFUlJPUl9JTlZBTElEX0hBTkRMRTogICAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9DT05URVhUX01JU01BVENIOwogICAgY2FzZSBFUlJPUl9PVVRPRk1FTU9SWTogICAgICAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9SRU1PVEVfTk9fTUVNT1JZOwogICAgY2FzZSBSUENfU19OT1RfTElTVEVOSU5HOiAgICAgICAgICAgICAgIHJldHVybiBOQ0FfU19TRVJWRVJfVE9PX0JVU1k7CiAgICBjYXNlIFJQQ19TX1VOS05PV05fSUY6ICAgICAgICAgICAgICAgICAgcmV0dXJuIE5DQV9TX1VOS19JRjsKICAgIGNhc2UgUlBDX1NfU0VSVkVSX1RPT19CVVNZOiAgICAgICAgICAgICByZXR1cm4gTkNBX1NfU0VSVkVSX1RPT19CVVNZOwogICAgY2FzZSBSUENfU19DQUxMX0ZBSUxFRDogICAgICAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9VTlNQRUM7CiAgICBjYXNlIFJQQ19TX0NBTExfRkFJTEVEX0RORTogICAgICAgICAgICAgcmV0dXJuIE5DQV9TX01BTkFHRVJfTk9UX0VOVEVSRUQ7CiAgICBjYXNlIFJQQ19TX1BST1RPQ09MX0VSUk9SOiAgICAgICAgICAgICAgcmV0dXJuIE5DQV9TX1BST1RPX0VSUk9SOwogICAgY2FzZSBSUENfU19VTlNVUFBPUlRFRF9UWVBFOiAgICAgICAgICAgIHJldHVybiBOQ0FfU19VTlNVUFBPUlRFRF9UWVBFOwogICAgY2FzZSBSUENfU19JTlZBTElEX1RBRzogICAgICAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9JTlZBTElEX1RBRzsKICAgIGNhc2UgUlBDX1NfSU5WQUxJRF9CT1VORDogICAgICAgICAgICAgICByZXR1cm4gTkNBX1NfRkFVTFRfSU5WQUxJRF9CT1VORDsKICAgIGNhc2UgUlBDX1NfUFJPQ05VTV9PVVRfT0ZfUkFOR0U6ICAgICAgICByZXR1cm4gTkNBX1NfT1BfUk5HX0VSUk9SOwogICAgY2FzZSBSUENfWF9TU19IQU5ETEVTX01JU01BVENIOiAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9DT05URVhUX01JU01BVENIOwogICAgY2FzZSBSUENfU19DQUxMX0NBTkNFTExFRDogICAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9DQU5DRUw7CiAgICBjYXNlIFJQQ19TX0NPTU1fRkFJTFVSRTogICAgICAgICAgICAgICAgcmV0dXJuIE5DQV9TX0NPTU1fRkFJTFVSRTsKICAgIGNhc2UgUlBDX1hfV1JPTkdfUElQRV9PUkRFUjogICAgICAgICAgICByZXR1cm4gTkNBX1NfRkFVTFRfUElQRV9PUkRFUjsKICAgIGNhc2UgUlBDX1hfUElQRV9DTE9TRUQ6ICAgICAgICAgICAgICAgICByZXR1cm4gTkNBX1NfRkFVTFRfUElQRV9DTE9TRUQ7CiAgICBjYXNlIFJQQ19YX1BJUEVfRElTQ0lQTElORV9FUlJPUjogICAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX1BJUEVfRElTQ0lQTElORTsKICAgIGNhc2UgUlBDX1hfUElQRV9FTVBUWTogICAgICAgICAgICAgICAgICByZXR1cm4gTkNBX1NfRkFVTFRfUElQRV9FTVBUWTsKICAgIGNhc2UgU1RBVFVTX0ZMT0FUX0RJVklERV9CWV9aRVJPOiAgICAgICByZXR1cm4gTkNBX1NfRkFVTFRfRlBfRElWX1pFUk87CiAgICBjYXNlIFNUQVRVU19GTE9BVF9JTlZBTElEX09QRVJBVElPTjogICAgcmV0dXJuIE5DQV9TX0ZBVUxUX0ZQX0VSUk9SOwogICAgY2FzZSBTVEFUVVNfRkxPQVRfT1ZFUkZMT1c6ICAgICAgICAgICAgIHJldHVybiBOQ0FfU19GQVVMVF9GUF9PVkVSRkxPVzsKICAgIGNhc2UgU1RBVFVTX0ZMT0FUX1VOREVSRkxPVzogICAgICAgICAgICByZXR1cm4gTkNBX1NfRkFVTFRfRlBfVU5ERVJGTE9XOwogICAgY2FzZSBTVEFUVVNfSU5URUdFUl9ESVZJREVfQllfWkVSTzogICAgIHJldHVybiBOQ0FfU19GQVVMVF9JTlRfRElWX0JZX1pFUk87CiAgICBjYXNlIFNUQVRVU19JTlRFR0VSX09WRVJGTE9XOiAgICAgICAgICAgcmV0dXJuIE5DQV9TX0ZBVUxUX0lOVF9PVkVSRkxPVzsKICAgIGRlZmF1bHQ6ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gc3RhdHVzOwogICAgfQp9CgpSUENfU1RBVFVTIE5DQTJSUENfU1RBVFVTKE5DQV9TVEFUVVMgc3RhdHVzKQp7CiAgICBzd2l0Y2ggKHN0YXR1cykKICAgIHsKICAgIGNhc2UgTkNBX1NfQ09NTV9GQUlMVVJFOiAgICAgICAgICAgIHJldHVybiBSUENfU19DT01NX0ZBSUxVUkU7CiAgICBjYXNlIE5DQV9TX09QX1JOR19FUlJPUjogICAgICAgICAgICByZXR1cm4gUlBDX1NfUFJPQ05VTV9PVVRfT0ZfUkFOR0U7CiAgICBjYXNlIE5DQV9TX1VOS19JRjogICAgICAgICAgICAgICAgICByZXR1cm4gUlBDX1NfVU5LTk9XTl9JRjsKICAgIGNhc2UgTkNBX1NfWU9VX0NSQVNIRUQ6ICAgICAgICAgICAgIHJldHVybiBSUENfU19DQUxMX0ZBSUxFRDsKICAgIGNhc2UgTkNBX1NfUFJPVE9fRVJST1I6ICAgICAgICAgICAgIHJldHVybiBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIGNhc2UgTkNBX1NfT1VUX0FSR1NfVE9PX0JJRzogICAgICAgIHJldHVybiBFUlJPUl9OT1RfRU5PVUdIX1NFUlZFUl9NRU1PUlk7CiAgICBjYXNlIE5DQV9TX1NFUlZFUl9UT09fQlVTWTogICAgICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1RPT19CVVNZOwogICAgY2FzZSBOQ0FfU19VTlNVUFBPUlRFRF9UWVBFOiAgICAgICAgcmV0dXJuIFJQQ19TX1VOU1VQUE9SVEVEX1RZUEU7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX0lOVF9ESVZfQllfWkVSTzogICByZXR1cm4gUlBDX1NfWkVST19ESVZJREU7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX0FERFJfRVJST1I6ICAgICAgICByZXR1cm4gUlBDX1NfQUREUkVTU19FUlJPUjsKICAgIGNhc2UgTkNBX1NfRkFVTFRfRlBfRElWX1pFUk86ICAgICAgIHJldHVybiBSUENfU19GUF9ESVZfWkVSTzsKICAgIGNhc2UgTkNBX1NfRkFVTFRfRlBfVU5ERVJGTE9XOiAgICAgIHJldHVybiBSUENfU19GUF9VTkRFUkZMT1c7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX0ZQX09WRVJGTE9XOiAgICAgICByZXR1cm4gUlBDX1NfRlBfT1ZFUkZMT1c7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX0lOVkFMSURfVEFHOiAgICAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9UQUc7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX0lOVkFMSURfQk9VTkQ6ICAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9CT1VORDsKICAgIGNhc2UgTkNBX1NfUlBDX1ZFUlNJT05fTUlTTUFUQ0g6ICAgIHJldHVybiBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIGNhc2UgTkNBX1NfVU5TUEVDX1JFSkVDVDogICAgICAgICAgIHJldHVybiBSUENfU19DQUxMX0ZBSUxFRF9ETkU7CiAgICBjYXNlIE5DQV9TX0JBRF9BQ1RJRDogICAgICAgICAgICAgICByZXR1cm4gUlBDX1NfQ0FMTF9GQUlMRURfRE5FOwogICAgY2FzZSBOQ0FfU19XSE9fQVJFX1lPVV9GQUlMRUQ6ICAgICAgcmV0dXJuIFJQQ19TX0NBTExfRkFJTEVEOwogICAgY2FzZSBOQ0FfU19NQU5BR0VSX05PVF9FTlRFUkVEOiAgICAgcmV0dXJuIFJQQ19TX0NBTExfRkFJTEVEX0RORTsKICAgIGNhc2UgTkNBX1NfRkFVTFRfQ0FOQ0VMOiAgICAgICAgICAgIHJldHVybiBSUENfU19DQUxMX0NBTkNFTExFRDsKICAgIGNhc2UgTkNBX1NfRkFVTFRfSUxMX0lOU1Q6ICAgICAgICAgIHJldHVybiBSUENfU19BRERSRVNTX0VSUk9SOwogICAgY2FzZSBOQ0FfU19GQVVMVF9GUF9FUlJPUjogICAgICAgICAgcmV0dXJuIFJQQ19TX0ZQX09WRVJGTE9XOwogICAgY2FzZSBOQ0FfU19GQVVMVF9JTlRfT1ZFUkZMT1c6ICAgICAgcmV0dXJuIFJQQ19TX0FERFJFU1NfRVJST1I7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX1VOU1BFQzogICAgICAgICAgICByZXR1cm4gUlBDX1NfQ0FMTF9GQUlMRUQ7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX1BJUEVfRU1QVFk6ICAgICAgICByZXR1cm4gUlBDX1hfUElQRV9FTVBUWTsKICAgIGNhc2UgTkNBX1NfRkFVTFRfUElQRV9DTE9TRUQ6ICAgICAgIHJldHVybiBSUENfWF9QSVBFX0NMT1NFRDsKICAgIGNhc2UgTkNBX1NfRkFVTFRfUElQRV9PUkRFUjogICAgICAgIHJldHVybiBSUENfWF9XUk9OR19QSVBFX09SREVSOwogICAgY2FzZSBOQ0FfU19GQVVMVF9QSVBFX0RJU0NJUExJTkU6ICAgcmV0dXJuIFJQQ19YX1BJUEVfRElTQ0lQTElORV9FUlJPUjsKICAgIGNhc2UgTkNBX1NfRkFVTFRfUElQRV9DT01NX0VSUk9SOiAgIHJldHVybiBSUENfU19DT01NX0ZBSUxVUkU7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX1BJUEVfTUVNT1JZOiAgICAgICByZXR1cm4gRVJST1JfT1VUT0ZNRU1PUlk7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX0NPTlRFWFRfTUlTTUFUQ0g6ICByZXR1cm4gRVJST1JfSU5WQUxJRF9IQU5ETEU7CiAgICBjYXNlIE5DQV9TX0ZBVUxUX1JFTU9URV9OT19NRU1PUlk6ICByZXR1cm4gRVJST1JfTk9UX0VOT1VHSF9TRVJWRVJfTUVNT1JZOwogICAgZGVmYXVsdDogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHN0YXR1czsKICAgIH0KfQoKc3RhdGljIFJQQ19TVEFUVVMgUlBDUlQ0X1NlY3VyZVBhY2tldChScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLAogICAgZW51bSBzZWN1cmVfcGFja2V0X2RpcmVjdGlvbiBkaXIsCiAgICBScGNQa3RIZHIgKmhkciwgdW5zaWduZWQgaW50IGhkcl9zaXplLAogICAgdW5zaWduZWQgY2hhciAqc3R1Yl9kYXRhLCB1bnNpZ25lZCBpbnQgc3R1Yl9kYXRhX3NpemUsCiAgICBScGNBdXRoVmVyaWZpZXIgKmF1dGhfaGRyLAogICAgdW5zaWduZWQgY2hhciAqYXV0aF92YWx1ZSwgdW5zaWduZWQgaW50IGF1dGhfdmFsdWVfc2l6ZSkKewogICAgU2VjQnVmZmVyRGVzYyBtZXNzYWdlOwogICAgU2VjQnVmZmVyIGJ1ZmZlcnNbNF07CiAgICBTRUNVUklUWV9TVEFUVVMgc2VjX3N0YXR1czsKCiAgICBtZXNzYWdlLnVsVmVyc2lvbiA9IFNFQ0JVRkZFUl9WRVJTSU9OOwogICAgbWVzc2FnZS5jQnVmZmVycyA9IHNpemVvZihidWZmZXJzKS9zaXplb2YoYnVmZmVyc1swXSk7CiAgICBtZXNzYWdlLnBCdWZmZXJzID0gYnVmZmVyczsKCiAgICBidWZmZXJzWzBdLmNiQnVmZmVyID0gaGRyX3NpemU7CiAgICBidWZmZXJzWzBdLkJ1ZmZlclR5cGUgPSBTRUNCVUZGRVJfREFUQXxTRUNCVUZGRVJfUkVBRE9OTFlfV0lUSF9DSEVDS1NVTTsKICAgIGJ1ZmZlcnNbMF0ucHZCdWZmZXIgPSBoZHI7CiAgICBidWZmZXJzWzFdLmNiQnVmZmVyID0gc3R1Yl9kYXRhX3NpemU7CiAgICBidWZmZXJzWzFdLkJ1ZmZlclR5cGUgPSBTRUNCVUZGRVJfREFUQTsKICAgIGJ1ZmZlcnNbMV0ucHZCdWZmZXIgPSBzdHViX2RhdGE7CiAgICBidWZmZXJzWzJdLmNiQnVmZmVyID0gc2l6ZW9mKCphdXRoX2hkcik7CiAgICBidWZmZXJzWzJdLkJ1ZmZlclR5cGUgPSBTRUNCVUZGRVJfREFUQXxTRUNCVUZGRVJfUkVBRE9OTFlfV0lUSF9DSEVDS1NVTTsKICAgIGJ1ZmZlcnNbMl0ucHZCdWZmZXIgPSBhdXRoX2hkcjsKICAgIGJ1ZmZlcnNbM10uY2JCdWZmZXIgPSBhdXRoX3ZhbHVlX3NpemU7CiAgICBidWZmZXJzWzNdLkJ1ZmZlclR5cGUgPSBTRUNCVUZGRVJfVE9LRU47CiAgICBidWZmZXJzWzNdLnB2QnVmZmVyID0gYXV0aF92YWx1ZTsKCiAgICBpZiAoZGlyID09IFNFQ1VSRV9QQUNLRVRfU0VORCkKICAgIHsKICAgICAgICBpZiAoKGF1dGhfaGRyLT5hdXRoX2xldmVsID09IFJQQ19DX0FVVEhOX0xFVkVMX1BLVF9QUklWQUNZKSAmJiBwYWNrZXRfaGFzX2JvZHkoaGRyKSkKICAgICAgICB7CiAgICAgICAgICAgIHNlY19zdGF0dXMgPSBFbmNyeXB0TWVzc2FnZSgmQ29ubmVjdGlvbi0+Y3R4LCAwLCAmbWVzc2FnZSwgMCAvKiBGSVhNRSAqLyk7CiAgICAgICAgICAgIGlmIChzZWNfc3RhdHVzICE9IFNFQ19FX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFUlIoIkVuY3J5cHRNZXNzYWdlIGZhaWxlZCB3aXRoIDB4JTA4eFxuIiwgc2VjX3N0YXR1cyk7CiAgICAgICAgICAgICAgICByZXR1cm4gUlBDX1NfU0VDX1BLR19FUlJPUjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChhdXRoX2hkci0+YXV0aF9sZXZlbCAhPSBSUENfQ19BVVRITl9MRVZFTF9OT05FKQogICAgICAgIHsKICAgICAgICAgICAgc2VjX3N0YXR1cyA9IE1ha2VTaWduYXR1cmUoJkNvbm5lY3Rpb24tPmN0eCwgMCwgJm1lc3NhZ2UsIDAgLyogRklYTUUgKi8pOwogICAgICAgICAgICBpZiAoc2VjX3N0YXR1cyAhPSBTRUNfRV9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRVJSKCJNYWtlU2lnbmF0dXJlIGZhaWxlZCB3aXRoIDB4JTA4eFxuIiwgc2VjX3N0YXR1cyk7CiAgICAgICAgICAgICAgICByZXR1cm4gUlBDX1NfU0VDX1BLR19FUlJPUjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGVsc2UgaWYgKGRpciA9PSBTRUNVUkVfUEFDS0VUX1JFQ0VJVkUpCiAgICB7CiAgICAgICAgaWYgKChhdXRoX2hkci0+YXV0aF9sZXZlbCA9PSBSUENfQ19BVVRITl9MRVZFTF9QS1RfUFJJVkFDWSkgJiYgcGFja2V0X2hhc19ib2R5KGhkcikpCiAgICAgICAgewogICAgICAgICAgICBzZWNfc3RhdHVzID0gRGVjcnlwdE1lc3NhZ2UoJkNvbm5lY3Rpb24tPmN0eCwgJm1lc3NhZ2UsIDAgLyogRklYTUUgKi8sIDApOwogICAgICAgICAgICBpZiAoc2VjX3N0YXR1cyAhPSBTRUNfRV9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRVJSKCJEZWNyeXB0TWVzc2FnZSBmYWlsZWQgd2l0aCAweCUwOHhcbiIsIHNlY19zdGF0dXMpOwogICAgICAgICAgICAgICAgcmV0dXJuIFJQQ19TX1NFQ19QS0dfRVJST1I7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoYXV0aF9oZHItPmF1dGhfbGV2ZWwgIT0gUlBDX0NfQVVUSE5fTEVWRUxfTk9ORSkKICAgICAgICB7CiAgICAgICAgICAgIHNlY19zdGF0dXMgPSBWZXJpZnlTaWduYXR1cmUoJkNvbm5lY3Rpb24tPmN0eCwgJm1lc3NhZ2UsIDAgLyogRklYTUUgKi8sIE5VTEwpOwogICAgICAgICAgICBpZiAoc2VjX3N0YXR1cyAhPSBTRUNfRV9PSykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRVJSKCJWZXJpZnlTaWduYXR1cmUgZmFpbGVkIHdpdGggMHglMDh4XG4iLCBzZWNfc3RhdHVzKTsKICAgICAgICAgICAgICAgIHJldHVybiBSUENfU19TRUNfUEtHX0VSUk9SOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBSUENfU19PSzsKfQogICAgICAgICAKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfU2VuZEF1dGggKGludGVybmFsKQogKiAKICogVHJhbnNtaXQgYSBwYWNrZXQgd2l0aCBhdXRob3JpemF0aW9uIGRhdGEgb3ZlciBjb25uZWN0aW9uIGluIGFjY2VwdGFibGUgZnJhZ21lbnRzLgogKi8Kc3RhdGljIFJQQ19TVEFUVVMgUlBDUlQ0X1NlbmRBdXRoKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sIFJwY1BrdEhkciAqSGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQnVmZmVyLCB1bnNpZ25lZCBpbnQgQnVmZmVyTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqQXV0aCwgdW5zaWduZWQgaW50IEF1dGhMZW5ndGgpCnsKICBQVUNIQVIgYnVmZmVyX3BvczsKICBEV09SRCBoZHJfc2l6ZTsKICBMT05HIGNvdW50OwogIHVuc2lnbmVkIGNoYXIgKnBrdDsKICBMT05HIGFsZW47CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFJQQ1JUNF9TZXRUaHJlYWRDdXJyZW50Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKCiAgYnVmZmVyX3BvcyA9IEJ1ZmZlcjsKICAvKiBUaGUgcGFja2V0IGJ1aWxkaW5nIGZ1bmN0aW9ucyBzYXZlIHRoZSBwYWNrZXQgaGVhZGVyIHNpemUsIHNvIHdlIGNhbiB1c2UgaXQuICovCiAgaGRyX3NpemUgPSBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbjsKICBpZiAoQXV0aExlbmd0aCkKICAgIEhlYWRlci0+Y29tbW9uLmF1dGhfbGVuID0gQXV0aExlbmd0aDsKICBlbHNlIGlmIChDb25uZWN0aW9uLT5BdXRoSW5mbyAmJiBwYWNrZXRfaGFzX2F1dGhfdmVyaWZpZXIoSGVhZGVyKSkKICB7CiAgICBpZiAoKENvbm5lY3Rpb24tPkF1dGhJbmZvLT5BdXRobkxldmVsID09IFJQQ19DX0FVVEhOX0xFVkVMX1BLVF9QUklWQUNZKSAmJiBwYWNrZXRfaGFzX2JvZHkoSGVhZGVyKSkKICAgICAgSGVhZGVyLT5jb21tb24uYXV0aF9sZW4gPSBDb25uZWN0aW9uLT5lbmNyeXB0aW9uX2F1dGhfbGVuOwogICAgZWxzZQogICAgICBIZWFkZXItPmNvbW1vbi5hdXRoX2xlbiA9IENvbm5lY3Rpb24tPnNpZ25hdHVyZV9hdXRoX2xlbjsKICB9CiAgZWxzZQogICAgSGVhZGVyLT5jb21tb24uYXV0aF9sZW4gPSAwOwogIEhlYWRlci0+Y29tbW9uLmZsYWdzIHw9IFJQQ19GTEdfRklSU1Q7CiAgSGVhZGVyLT5jb21tb24uZmxhZ3MgJj0gflJQQ19GTEdfTEFTVDsKCiAgYWxlbiA9IFJQQ19BVVRIX1ZFUklGSUVSX0xFTigmSGVhZGVyLT5jb21tb24pOwoKICB3aGlsZSAoIShIZWFkZXItPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfTEFTVCkpIHsKICAgIHVuc2lnbmVkIGNoYXIgYXV0aF9wYWRfbGVuID0gSGVhZGVyLT5jb21tb24uYXV0aF9sZW4gPyBST1VORF9VUF9BTU9VTlQoQnVmZmVyTGVuZ3RoLCBBVVRIX0FMSUdOTUVOVCkgOiAwOwogICAgdW5zaWduZWQgaW50IHBrdF9zaXplID0gQnVmZmVyTGVuZ3RoICsgaGRyX3NpemUgKyBhbGVuICsgYXV0aF9wYWRfbGVuOwoKICAgIC8qIGRlY2lkZSBpZiB3ZSBuZWVkIHRvIHNwbGl0IHRoZSBwYWNrZXQgaW50byBmcmFnbWVudHMgKi8KICAgaWYgKHBrdF9zaXplIDw9IENvbm5lY3Rpb24tPk1heFRyYW5zbWlzc2lvblNpemUpIHsKICAgICBIZWFkZXItPmNvbW1vbi5mbGFncyB8PSBSUENfRkxHX0xBU1Q7CiAgICAgSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBwa3Rfc2l6ZTsKICAgIH0gZWxzZSB7CiAgICAgIGF1dGhfcGFkX2xlbiA9IDA7CiAgICAgIC8qIG1ha2Ugc3VyZSBwYWNrZXQgcGF5bG9hZCB3aWxsIGJlIGEgbXVsdGlwbGUgb2YgMTYgKi8KICAgICAgSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPQogICAgICAgICgoQ29ubmVjdGlvbi0+TWF4VHJhbnNtaXNzaW9uU2l6ZSAtIGhkcl9zaXplIC0gYWxlbikgJiB+KEFVVEhfQUxJR05NRU5ULTEpKSArCiAgICAgICAgaGRyX3NpemUgKyBhbGVuOwogICAgfQoKICAgIHBrdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbik7CgogICAgbWVtY3B5KHBrdCwgSGVhZGVyLCBoZHJfc2l6ZSk7CgogICAgLyogZnJhZ21lbnQgY29uc2lzdGVkIG9mIGhlYWRlciBvbmx5IGFuZCBpcyB0aGUgbGFzdCBvbmUgKi8KICAgIGlmIChoZHJfc2l6ZSA9PSBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbikKICAgICAgZ290byB3cml0ZTsKCiAgICBtZW1jcHkocGt0ICsgaGRyX3NpemUsIGJ1ZmZlcl9wb3MsIEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuIC0gaGRyX3NpemUgLSBhdXRoX3BhZF9sZW4gLSBhbGVuKTsKCiAgICAvKiBhZGQgdGhlIGF1dGhvcml6YXRpb24gaW5mbyAqLwogICAgaWYgKENvbm5lY3Rpb24tPkF1dGhJbmZvICYmIHBhY2tldF9oYXNfYXV0aF92ZXJpZmllcihIZWFkZXIpKQogICAgewogICAgICBScGNBdXRoVmVyaWZpZXIgKmF1dGhfaGRyID0gKFJwY0F1dGhWZXJpZmllciAqKSZwa3RbSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gLSBhbGVuXTsKCiAgICAgIGF1dGhfaGRyLT5hdXRoX3R5cGUgPSBDb25uZWN0aW9uLT5BdXRoSW5mby0+QXV0aG5TdmM7CiAgICAgIGF1dGhfaGRyLT5hdXRoX2xldmVsID0gQ29ubmVjdGlvbi0+QXV0aEluZm8tPkF1dGhuTGV2ZWw7CiAgICAgIGF1dGhfaGRyLT5hdXRoX3BhZF9sZW5ndGggPSBhdXRoX3BhZF9sZW47CiAgICAgIGF1dGhfaGRyLT5hdXRoX3Jlc2VydmVkID0gMDsKICAgICAgLyogYSB1bmlxdWUgbnVtYmVyLi4uICovCiAgICAgIGF1dGhfaGRyLT5hdXRoX2NvbnRleHRfaWQgPSAodW5zaWduZWQgbG9uZylDb25uZWN0aW9uOwoKICAgICAgaWYgKEF1dGhMZW5ndGgpCiAgICAgICAgbWVtY3B5KGF1dGhfaGRyICsgMSwgQXV0aCwgQXV0aExlbmd0aCk7CiAgICAgIGVsc2UKICAgICAgewogICAgICAgIHN0YXR1cyA9IFJQQ1JUNF9TZWN1cmVQYWNrZXQoQ29ubmVjdGlvbiwgU0VDVVJFX1BBQ0tFVF9TRU5ELAogICAgICAgICAgICAoUnBjUGt0SGRyICopcGt0LCBoZHJfc2l6ZSwKICAgICAgICAgICAgcGt0ICsgaGRyX3NpemUsIEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuIC0gaGRyX3NpemUgLSBhbGVuLAogICAgICAgICAgICBhdXRoX2hkciwKICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIgKikoYXV0aF9oZHIgKyAxKSwgSGVhZGVyLT5jb21tb24uYXV0aF9sZW4pOwogICAgICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICAgICAgewogICAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGt0KTsKICAgICAgICAgIFJQQ1JUNF9TZXRUaHJlYWRDdXJyZW50Q29ubmVjdGlvbihOVUxMKTsKICAgICAgICAgIHJldHVybiBzdGF0dXM7CiAgICAgICAgfQogICAgICB9CiAgICB9Cgp3cml0ZToKICAgIGNvdW50ID0gcnBjcnQ0X2Nvbm5fd3JpdGUoQ29ubmVjdGlvbiwgcGt0LCBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbik7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwa3QpOwogICAgaWYgKGNvdW50PDApIHsKICAgICAgV0FSTigicnBjcnQ0X2Nvbm5fd3JpdGUgZmFpbGVkIChhdXRoKVxuIik7CiAgICAgIFJQQ1JUNF9TZXRUaHJlYWRDdXJyZW50Q29ubmVjdGlvbihOVUxMKTsKICAgICAgcmV0dXJuIFJQQ19TX0NBTExfRkFJTEVEOwogICAgfQoKICAgIGJ1ZmZlcl9wb3MgKz0gSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gLSBoZHJfc2l6ZSAtIGFsZW4gLSBhdXRoX3BhZF9sZW47CiAgICBCdWZmZXJMZW5ndGggLT0gSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gLSBoZHJfc2l6ZSAtIGFsZW4gLSBhdXRoX3BhZF9sZW47CiAgICBIZWFkZXItPmNvbW1vbi5mbGFncyAmPSB+UlBDX0ZMR19GSVJTVDsKICB9CgogIFJQQ1JUNF9TZXRUaHJlYWRDdXJyZW50Q29ubmVjdGlvbihOVUxMKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUlBDUlQ0X0NsaWVudEF1dGhvcml6ZSAoaW50ZXJuYWwpCiAqCiAqIEF1dGhvcml6ZSBhIGNsaWVudCBjb25uZWN0aW9uLiBBIE5VTEwgaW4gcGFyYW0gc2lnbmlmaWVzIGEgbmV3IGNvbm5lY3Rpb24uCiAqLwpzdGF0aWMgUlBDX1NUQVRVUyBSUENSVDRfQ2xpZW50QXV0aG9yaXplKFJwY0Nvbm5lY3Rpb24gKmNvbm4sIFNlY0J1ZmZlciAqaW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU2VjQnVmZmVyICpvdXQpCnsKICBTRUNVUklUWV9TVEFUVVMgcjsKICBTZWNCdWZmZXJEZXNjIG91dF9kZXNjOwogIFNlY0J1ZmZlckRlc2MgaW5wX2Rlc2M7CiAgU2VjUGtnQ29udGV4dF9TaXplcyBzZWNjdHhfc2l6ZXM7CiAgQk9PTCBjb250aW51ZV9uZWVkZWQ7CiAgVUxPTkcgY29udGV4dF9yZXEgPSBJU0NfUkVRX0NPTk5FQ1RJT04gfCBJU0NfUkVRX1VTRV9EQ0VfU1RZTEUgfAogICAgICAgICAgICAgICAgICAgICAgSVNDX1JFUV9NVVRVQUxfQVVUSCB8IElTQ19SRVFfREVMRUdBVEU7CgogIGlmIChjb25uLT5BdXRoSW5mby0+QXV0aG5MZXZlbCA9PSBSUENfQ19BVVRITl9MRVZFTF9QS1RfSU5URUdSSVRZKQogICAgY29udGV4dF9yZXEgfD0gSVNDX1JFUV9JTlRFR1JJVFk7CiAgZWxzZSBpZiAoY29ubi0+QXV0aEluZm8tPkF1dGhuTGV2ZWwgPT0gUlBDX0NfQVVUSE5fTEVWRUxfUEtUX1BSSVZBQ1kpCiAgICBjb250ZXh0X3JlcSB8PSBJU0NfUkVRX0NPTkZJREVOVElBTElUWSB8IElTQ19SRVFfSU5URUdSSVRZOwoKICBvdXQtPkJ1ZmZlclR5cGUgPSBTRUNCVUZGRVJfVE9LRU47CiAgb3V0LT5jYkJ1ZmZlciA9IGNvbm4tPkF1dGhJbmZvLT5jYk1heFRva2VuOwogIG91dC0+cHZCdWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3V0LT5jYkJ1ZmZlcik7CiAgaWYgKCFvdXQtPnB2QnVmZmVyKSByZXR1cm4gRVJST1JfT1VUT0ZNRU1PUlk7CgogIG91dF9kZXNjLnVsVmVyc2lvbiA9IDA7CiAgb3V0X2Rlc2MuY0J1ZmZlcnMgPSAxOwogIG91dF9kZXNjLnBCdWZmZXJzID0gb3V0OwoKICBpbnBfZGVzYy5jQnVmZmVycyA9IDE7CiAgaW5wX2Rlc2MucEJ1ZmZlcnMgPSBpbjsKICBpbnBfZGVzYy51bFZlcnNpb24gPSAwOwoKICByID0gSW5pdGlhbGl6ZVNlY3VyaXR5Q29udGV4dFcoJmNvbm4tPkF1dGhJbmZvLT5jcmVkLCBpbiA/ICZjb25uLT5jdHggOiBOVUxMLAogICAgICAgIGluID8gTlVMTCA6IGNvbm4tPkF1dGhJbmZvLT5zZXJ2ZXJfcHJpbmNpcGFsX25hbWUsIGNvbnRleHRfcmVxLCAwLAogICAgICAgIFNFQ1VSSVRZX05FVFdPUktfRFJFUCwgaW4gPyAmaW5wX2Rlc2MgOiBOVUxMLCAwLCAmY29ubi0+Y3R4LAogICAgICAgICZvdXRfZGVzYywgJmNvbm4tPmF0dHIsICZjb25uLT5leHApOwogIGlmIChGQUlMRUQocikpCiAgewogICAgICBXQVJOKCJJbml0aWFsaXplU2VjdXJpdHlDb250ZXh0IGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4eFxuIiwgcik7CiAgICAgIGdvdG8gZmFpbGVkOwogIH0KCiAgVFJBQ0UoInIgPSAweCUwOHgsIGF0dHIgPSAweCUwOHhcbiIsIHIsIGNvbm4tPmF0dHIpOwogIGNvbnRpbnVlX25lZWRlZCA9ICgociA9PSBTRUNfSV9DT05USU5VRV9ORUVERUQpIHx8CiAgICAgICAgICAgICAgICAgICAgIChyID09IFNFQ19JX0NPTVBMRVRFX0FORF9DT05USU5VRSkpOwoKICBpZiAoKHIgPT0gU0VDX0lfQ09NUExFVEVfTkVFREVEKSB8fCAociA9PSBTRUNfSV9DT01QTEVURV9BTkRfQ09OVElOVUUpKQogIHsKICAgICAgVFJBQ0UoImNvbXBsZXRlIG5lZWRlZFxuIik7CiAgICAgIHIgPSBDb21wbGV0ZUF1dGhUb2tlbigmY29ubi0+Y3R4LCAmb3V0X2Rlc2MpOwogICAgICBpZiAoRkFJTEVEKHIpKQogICAgICB7CiAgICAgICAgICBXQVJOKCJDb21wbGV0ZUF1dGhUb2tlbiBmYWlsZWQgd2l0aCBlcnJvciAweCUwOHhcbiIsIHIpOwogICAgICAgICAgZ290byBmYWlsZWQ7CiAgICAgIH0KICB9CgogIFRSQUNFKCJjYkJ1ZmZlciA9ICVsZFxuIiwgb3V0LT5jYkJ1ZmZlcik7CgogIGlmICghY29udGludWVfbmVlZGVkKQogIHsKICAgICAgciA9IFF1ZXJ5Q29udGV4dEF0dHJpYnV0ZXNBKCZjb25uLT5jdHgsIFNFQ1BLR19BVFRSX1NJWkVTLCAmc2VjY3R4X3NpemVzKTsKICAgICAgaWYgKEZBSUxFRChyKSkKICAgICAgewogICAgICAgICAgV0FSTigiUXVlcnlDb250ZXh0QXR0cmlidXRlcyBmYWlsZWQgd2l0aCBlcnJvciAweCUwOHhcbiIsIHIpOwogICAgICAgICAgZ290byBmYWlsZWQ7CiAgICAgIH0KICAgICAgY29ubi0+c2lnbmF0dXJlX2F1dGhfbGVuID0gc2VjY3R4X3NpemVzLmNiTWF4U2lnbmF0dXJlOwogICAgICBjb25uLT5lbmNyeXB0aW9uX2F1dGhfbGVuID0gc2VjY3R4X3NpemVzLmNiU2VjdXJpdHlUcmFpbGVyOwogIH0KCiAgcmV0dXJuIFJQQ19TX09LOwoKZmFpbGVkOgogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG91dC0+cHZCdWZmZXIpOwogIG91dC0+cHZCdWZmZXIgPSBOVUxMOwogIHJldHVybiBFUlJPUl9BQ0NFU1NfREVOSUVEOyAvKiBGSVhNRTogaXMgdGhpcyBjb3JyZWN0PyAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJQQ1JUNF9BdXRob3JpemVCaW5kaW5nIChpbnRlcm5hbCkKICovCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUX0F1dGhvcml6ZUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogY29ubiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCWVRFICpjaGFsbGVuZ2UsIFVMT05HIGNvdW50KQp7CiAgU2VjQnVmZmVyIGlucCwgb3V0OwogIFJwY1BrdEhkciAqcmVzcF9oZHI7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCJjaGFsbGVuZ2UgJXMsICVkIGJ5dGVzXG4iLCBjaGFsbGVuZ2UsIGNvdW50KTsKCiAgaW5wLkJ1ZmZlclR5cGUgPSBTRUNCVUZGRVJfVE9LRU47CiAgaW5wLnB2QnVmZmVyID0gY2hhbGxlbmdlOwogIGlucC5jYkJ1ZmZlciA9IGNvdW50OwoKICBzdGF0dXMgPSBSUENSVDRfQ2xpZW50QXV0aG9yaXplKGNvbm4sICZpbnAsICZvdXQpOwogIGlmIChzdGF0dXMpIHJldHVybiBzdGF0dXM7CgogIHJlc3BfaGRyID0gUlBDUlQ0X0J1aWxkQXV0aEhlYWRlcihORFJfTE9DQUxfREFUQV9SRVBSRVNFTlRBVElPTik7CiAgaWYgKCFyZXNwX2hkcikKICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICBzdGF0dXMgPSBSUENSVDRfU2VuZEF1dGgoY29ubiwgcmVzcF9oZHIsIE5VTEwsIDAsIG91dC5wdkJ1ZmZlciwgb3V0LmNiQnVmZmVyKTsKCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3V0LnB2QnVmZmVyKTsKICBSUENSVDRfRnJlZUhlYWRlcihyZXNwX2hkcik7CgogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUlBDUlQ0X1NlbmQgKGludGVybmFsKQogKiAKICogVHJhbnNtaXQgYSBwYWNrZXQgb3ZlciBjb25uZWN0aW9uIGluIGFjY2VwdGFibGUgZnJhZ21lbnRzLgogKi8KUlBDX1NUQVRVUyBSUENSVDRfU2VuZChScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLCBScGNQa3RIZHIgKkhlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICB2b2lkICpCdWZmZXIsIHVuc2lnbmVkIGludCBCdWZmZXJMZW5ndGgpCnsKICBSUENfU1RBVFVTIHI7CiAgU2VjQnVmZmVyIG91dDsKCiAgaWYgKCFDb25uZWN0aW9uLT5BdXRoSW5mbyB8fCBTZWNJc1ZhbGlkSGFuZGxlKCZDb25uZWN0aW9uLT5jdHgpKQogIHsKICAgIHJldHVybiBSUENSVDRfU2VuZEF1dGgoQ29ubmVjdGlvbiwgSGVhZGVyLCBCdWZmZXIsIEJ1ZmZlckxlbmd0aCwgTlVMTCwgMCk7CiAgfQoKICAvKiB0YWNrIG9uIGEgbmVnb3RpYXRlIHBhY2tldCAqLwogIHIgPSBSUENSVDRfQ2xpZW50QXV0aG9yaXplKENvbm5lY3Rpb24sIE5VTEwsICZvdXQpOwogIGlmIChyID09IFJQQ19TX09LKQogIHsKICAgIHIgPSBSUENSVDRfU2VuZEF1dGgoQ29ubmVjdGlvbiwgSGVhZGVyLCBCdWZmZXIsIEJ1ZmZlckxlbmd0aCwgb3V0LnB2QnVmZmVyLCBvdXQuY2JCdWZmZXIpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3V0LnB2QnVmZmVyKTsKICB9CgogIHJldHVybiByOwp9CgovKiB2YWxpZGF0ZXMgdmVyc2lvbiBhbmQgZnJhZ19sZW4gZmllbGRzICovClJQQ19TVEFUVVMgUlBDUlQ0X1ZhbGlkYXRlQ29tbW9uSGVhZGVyKGNvbnN0IFJwY1BrdENvbW1vbkhkciAqaGRyKQp7CiAgRFdPUkQgaGRyX2xlbmd0aDsKCiAgLyogdmVyaWZ5IGlmIHRoZSBoZWFkZXIgcmVhbGx5IG1ha2VzIHNlbnNlICovCiAgaWYgKGhkci0+cnBjX3ZlciAhPSBSUENfVkVSX01BSk9SIHx8CiAgICAgIGhkci0+cnBjX3Zlcl9taW5vciAhPSBSUENfVkVSX01JTk9SKQogIHsKICAgIFdBUk4oInVuaGFuZGxlZCBwYWNrZXQgdmVyc2lvblxuIik7CiAgICByZXR1cm4gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgfQoKICBoZHJfbGVuZ3RoID0gUlBDUlQ0X0dldEhlYWRlclNpemUoKGNvbnN0IFJwY1BrdEhkciopaGRyKTsKICBpZiAoaGRyX2xlbmd0aCA9PSAwKQogIHsKICAgIFdBUk4oImhlYWRlciBsZW5ndGggPT0gMFxuIik7CiAgICByZXR1cm4gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgfQoKICBpZiAoaGRyLT5mcmFnX2xlbiA8IGhkcl9sZW5ndGgpCiAgewogICAgV0FSTigiYmFkIGZyYWcgbGVuZ3RoICVkXG4iLCBoZHItPmZyYWdfbGVuKTsKICAgIHJldHVybiBSUENfU19QUk9UT0NPTF9FUlJPUjsKICB9CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfcmVjZWl2ZV9mcmFnbWVudCAoaW50ZXJuYWwpCiAqIAogKiBSZWNlaXZlIGEgZnJhZ21lbnQgZnJvbSBhIGNvbm5lY3Rpb24uCiAqLwpSUENfU1RBVFVTIFJQQ1JUNF9yZWNlaXZlX2ZyYWdtZW50KFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sIFJwY1BrdEhkciAqKkhlYWRlciwgdm9pZCAqKlBheWxvYWQpCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICBEV09SRCBoZHJfbGVuZ3RoOwogIExPTkcgZHdSZWFkOwogIFJwY1BrdENvbW1vbkhkciBjb21tb25faGRyOwoKICAqSGVhZGVyID0gTlVMTDsKICAqUGF5bG9hZCA9IE5VTEw7CgogIFRSQUNFKCIoJXAsICVwLCAlcClcbiIsIENvbm5lY3Rpb24sIEhlYWRlciwgUGF5bG9hZCk7CgogIC8qIHJlYWQgcGFja2V0IGNvbW1vbiBoZWFkZXIgKi8KICBkd1JlYWQgPSBycGNydDRfY29ubl9yZWFkKENvbm5lY3Rpb24sICZjb21tb25faGRyLCBzaXplb2YoY29tbW9uX2hkcikpOwogIGlmIChkd1JlYWQgIT0gc2l6ZW9mKGNvbW1vbl9oZHIpKSB7CiAgICBXQVJOKCJTaG9ydCByZWFkIG9mIGhlYWRlciwgJWQgYnl0ZXNcbiIsIGR3UmVhZCk7CiAgICBzdGF0dXMgPSBSUENfU19DQUxMX0ZBSUxFRDsKICAgIGdvdG8gZmFpbDsKICB9CgogIHN0YXR1cyA9IFJQQ1JUNF9WYWxpZGF0ZUNvbW1vbkhlYWRlcigmY29tbW9uX2hkcik7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgZ290byBmYWlsOwoKICBoZHJfbGVuZ3RoID0gUlBDUlQ0X0dldEhlYWRlclNpemUoKFJwY1BrdEhkciopJmNvbW1vbl9oZHIpOwogIGlmIChoZHJfbGVuZ3RoID09IDApIHsKICAgIFdBUk4oImhlYWRlciBsZW5ndGggPT0gMFxuIik7CiAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIGdvdG8gZmFpbDsKICB9CgogICpIZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgaGRyX2xlbmd0aCk7CiAgbWVtY3B5KCpIZWFkZXIsICZjb21tb25faGRyLCBzaXplb2YoY29tbW9uX2hkcikpOwoKICAvKiByZWFkIHRoZSByZXN0IG9mIHBhY2tldCBoZWFkZXIgKi8KICBkd1JlYWQgPSBycGNydDRfY29ubl9yZWFkKENvbm5lY3Rpb24sICYoKkhlYWRlciktPmNvbW1vbiArIDEsIGhkcl9sZW5ndGggLSBzaXplb2YoY29tbW9uX2hkcikpOwogIGlmIChkd1JlYWQgIT0gaGRyX2xlbmd0aCAtIHNpemVvZihjb21tb25faGRyKSkgewogICAgV0FSTigiYmFkIGhlYWRlciBsZW5ndGgsICVkIGJ5dGVzLCBoZHJfbGVuZ3RoICVkXG4iLCBkd1JlYWQsIGhkcl9sZW5ndGgpOwogICAgc3RhdHVzID0gUlBDX1NfQ0FMTF9GQUlMRUQ7CiAgICBnb3RvIGZhaWw7CiAgfQoKICBpZiAoY29tbW9uX2hkci5mcmFnX2xlbiAtIGhkcl9sZW5ndGgpCiAgewogICAgKlBheWxvYWQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY29tbW9uX2hkci5mcmFnX2xlbiAtIGhkcl9sZW5ndGgpOwogICAgaWYgKCEqUGF5bG9hZCkKICAgIHsKICAgICAgc3RhdHVzID0gUlBDX1NfT1VUX09GX1JFU09VUkNFUzsKICAgICAgZ290byBmYWlsOwogICAgfQoKICAgIGR3UmVhZCA9IHJwY3J0NF9jb25uX3JlYWQoQ29ubmVjdGlvbiwgKlBheWxvYWQsIGNvbW1vbl9oZHIuZnJhZ19sZW4gLSBoZHJfbGVuZ3RoKTsKICAgIGlmIChkd1JlYWQgIT0gY29tbW9uX2hkci5mcmFnX2xlbiAtIGhkcl9sZW5ndGgpCiAgICB7CiAgICAgIFdBUk4oImJhZCBkYXRhIGxlbmd0aCwgJWQvJWRcbiIsIGR3UmVhZCwgY29tbW9uX2hkci5mcmFnX2xlbiAtIGhkcl9sZW5ndGgpOwogICAgICBzdGF0dXMgPSBSUENfU19DQUxMX0ZBSUxFRDsKICAgICAgZ290byBmYWlsOwogICAgfQogIH0KICBlbHNlCiAgICAqUGF5bG9hZCA9IE5VTEw7CgogIC8qIHN1Y2Nlc3MgKi8KICBzdGF0dXMgPSBSUENfU19PSzsKCmZhaWw6CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgewogICAgUlBDUlQ0X0ZyZWVIZWFkZXIoKkhlYWRlcik7CiAgICAqSGVhZGVyID0gTlVMTDsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsICpQYXlsb2FkKTsKICAgICpQYXlsb2FkID0gTlVMTDsKICB9CiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfUmVjZWl2ZSAoaW50ZXJuYWwpCiAqCiAqIFJlY2VpdmUgYSBwYWNrZXQgZnJvbSBjb25uZWN0aW9uIGFuZCBtZXJnZSB0aGUgZnJhZ21lbnRzLgogKi8KUlBDX1NUQVRVUyBSUENSVDRfUmVjZWl2ZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLCBScGNQa3RIZHIgKipIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICBEV09SRCBoZHJfbGVuZ3RoOwogIHVuc2lnbmVkIHNob3J0IGZpcnN0X2ZsYWc7CiAgdW5zaWduZWQgbG9uZyBkYXRhX2xlbmd0aDsKICB1bnNpZ25lZCBsb25nIGJ1ZmZlcl9sZW5ndGg7CiAgdW5zaWduZWQgbG9uZyBhdXRoX2xlbmd0aDsKICB1bnNpZ25lZCBjaGFyICphdXRoX2RhdGEgPSBOVUxMOwogIFJwY1BrdEhkciAqQ3VycmVudEhlYWRlciA9IE5VTEw7CiAgdm9pZCAqcGF5bG9hZCA9IE5VTEw7CgogICpIZWFkZXIgPSBOVUxMOwogIHBNc2ctPkJ1ZmZlciA9IE5VTEw7CgogIFRSQUNFKCIoJXAsICVwLCAlcClcbiIsIENvbm5lY3Rpb24sIEhlYWRlciwgcE1zZyk7CgogIFJQQ1JUNF9TZXRUaHJlYWRDdXJyZW50Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKCiAgc3RhdHVzID0gUlBDUlQ0X3JlY2VpdmVfZnJhZ21lbnQoQ29ubmVjdGlvbiwgSGVhZGVyLCAmcGF5bG9hZCk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgZ290byBmYWlsOwoKICBoZHJfbGVuZ3RoID0gUlBDUlQ0X0dldEhlYWRlclNpemUoKkhlYWRlcik7CgogIC8qIHJlYWQgcGFja2V0IGJvZHkgKi8KICBzd2l0Y2ggKCgqSGVhZGVyKS0+Y29tbW9uLnB0eXBlKSB7CiAgY2FzZSBQS1RfUkVTUE9OU0U6CiAgICBwTXNnLT5CdWZmZXJMZW5ndGggPSAoKkhlYWRlciktPnJlc3BvbnNlLmFsbG9jX2hpbnQ7CiAgICBicmVhazsKICBjYXNlIFBLVF9SRVFVRVNUOgogICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gKCpIZWFkZXIpLT5yZXF1ZXN0LmFsbG9jX2hpbnQ7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gKCpIZWFkZXIpLT5jb21tb24uZnJhZ19sZW4gLSBoZHJfbGVuZ3RoIC0gUlBDX0FVVEhfVkVSSUZJRVJfTEVOKCYoKkhlYWRlciktPmNvbW1vbik7CiAgfQoKICBUUkFDRSgiYnVmZmVyIGxlbmd0aCA9ICV1XG4iLCBwTXNnLT5CdWZmZXJMZW5ndGgpOwoKICBwTXNnLT5CdWZmZXIgPSBJX1JwY0FsbG9jYXRlKHBNc2ctPkJ1ZmZlckxlbmd0aCk7CiAgaWYgKCFwTXNnLT5CdWZmZXIpCiAgewogICAgc3RhdHVzID0gRVJST1JfT1VUT0ZNRU1PUlk7CiAgICBnb3RvIGZhaWw7CiAgfQoKICBmaXJzdF9mbGFnID0gUlBDX0ZMR19GSVJTVDsKICBhdXRoX2xlbmd0aCA9ICgqSGVhZGVyKS0+Y29tbW9uLmF1dGhfbGVuOwogIGlmIChhdXRoX2xlbmd0aCkgewogICAgYXV0aF9kYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFJQQ19BVVRIX1ZFUklGSUVSX0xFTigmKCpIZWFkZXIpLT5jb21tb24pKTsKICAgIGlmICghYXV0aF9kYXRhKSB7CiAgICAgIHN0YXR1cyA9IFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgIGdvdG8gZmFpbDsKICAgIH0KICB9CiAgQ3VycmVudEhlYWRlciA9ICpIZWFkZXI7CiAgYnVmZmVyX2xlbmd0aCA9IDA7CiAgd2hpbGUgKFRSVUUpCiAgewogICAgdW5zaWduZWQgaW50IGhlYWRlcl9hdXRoX2xlbiA9IFJQQ19BVVRIX1ZFUklGSUVSX0xFTigmQ3VycmVudEhlYWRlci0+Y29tbW9uKTsKCiAgICAvKiB2ZXJpZnkgaGVhZGVyIGZpZWxkcyAqLwoKICAgIGlmICgoQ3VycmVudEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuIDwgaGRyX2xlbmd0aCkgfHwKICAgICAgICAoQ3VycmVudEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuIC0gaGRyX2xlbmd0aCA8IGhlYWRlcl9hdXRoX2xlbikpIHsKICAgICAgV0FSTigiZnJhZ19sZW4gJWQgdG9vIHNtYWxsIGZvciBoZHJfbGVuZ3RoICVkIGFuZCBhdXRoX2xlbiAlZFxuIiwKICAgICAgICBDdXJyZW50SGVhZGVyLT5jb21tb24uZnJhZ19sZW4sIGhkcl9sZW5ndGgsIEN1cnJlbnRIZWFkZXItPmNvbW1vbi5hdXRoX2xlbik7CiAgICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgICBnb3RvIGZhaWw7CiAgICB9CgogICAgaWYgKEN1cnJlbnRIZWFkZXItPmNvbW1vbi5hdXRoX2xlbiAhPSBhdXRoX2xlbmd0aCkgewogICAgICBXQVJOKCJhdXRoX2xlbiBoZWFkZXIgZmllbGQgY2hhbmdlZCBmcm9tICVsZCB0byAlZFxuIiwKICAgICAgICBhdXRoX2xlbmd0aCwgQ3VycmVudEhlYWRlci0+Y29tbW9uLmF1dGhfbGVuKTsKICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgIGdvdG8gZmFpbDsKICAgIH0KCiAgICBpZiAoKEN1cnJlbnRIZWFkZXItPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfRklSU1QpICE9IGZpcnN0X2ZsYWcpIHsKICAgICAgVFJBQ0UoImludmFsaWQgcGFja2V0IGZsYWdzXG4iKTsKICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgIGdvdG8gZmFpbDsKICAgIH0KCiAgICBkYXRhX2xlbmd0aCA9IEN1cnJlbnRIZWFkZXItPmNvbW1vbi5mcmFnX2xlbiAtIGhkcl9sZW5ndGggLSBoZWFkZXJfYXV0aF9sZW47CiAgICBpZiAoZGF0YV9sZW5ndGggKyBidWZmZXJfbGVuZ3RoID4gcE1zZy0+QnVmZmVyTGVuZ3RoKSB7CiAgICAgIFRSQUNFKCJhbGxvY2F0aW9uIGhpbnQgZXhjZWVkZWQsIG5ldyBidWZmZXIgbGVuZ3RoID0gJWxkXG4iLAogICAgICAgIGRhdGFfbGVuZ3RoICsgYnVmZmVyX2xlbmd0aCk7CiAgICAgIHBNc2ctPkJ1ZmZlckxlbmd0aCA9IGRhdGFfbGVuZ3RoICsgYnVmZmVyX2xlbmd0aDsKICAgICAgc3RhdHVzID0gSV9ScGNSZUFsbG9jYXRlQnVmZmVyKHBNc2cpOwogICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSBnb3RvIGZhaWw7CiAgICB9CgogICAgbWVtY3B5KCh1bnNpZ25lZCBjaGFyICopcE1zZy0+QnVmZmVyICsgYnVmZmVyX2xlbmd0aCwgcGF5bG9hZCwgZGF0YV9sZW5ndGgpOwoKICAgIGlmIChoZWFkZXJfYXV0aF9sZW4pIHsKICAgICAgaWYgKGhlYWRlcl9hdXRoX2xlbiA8IHNpemVvZihScGNBdXRoVmVyaWZpZXIpIHx8CiAgICAgICAgICBoZWFkZXJfYXV0aF9sZW4gPiBSUENfQVVUSF9WRVJJRklFUl9MRU4oJigqSGVhZGVyKS0+Y29tbW9uKSkgewogICAgICAgIFdBUk4oImJhZCBhdXRoIHZlcmlmaWVyIGxlbmd0aCAlZFxuIiwgaGVhZGVyX2F1dGhfbGVuKTsKICAgICAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgICAgICBnb3RvIGZhaWw7CiAgICAgIH0KCiAgICAgIC8qIEZJWE1FOiB3ZSBzaG91bGQgYWNjdW11bGF0ZSBhdXRoZW50aWNhdGlvbiBkYXRhIGZvciB0aGUgYmluZCwKICAgICAgICogYmluZF9hY2ssIGFsdGVyX2NvbnRleHQgYW5kIGFsdGVyX2NvbnRleHRfcmVzcG9uc2UgaWYgbmVjZXNzYXJ5LgogICAgICAgKiBob3dldmVyLCB0aGUgZGV0YWlscyBvZiBob3cgdGhpcyBpcyBkb25lIGlzIHZlcnkgc2tldGNoeSBpbiB0aGUKICAgICAgICogRENFL1JQQyBzcGVjLiBmb3IgYWxsIG90aGVyIHBhY2tldCB0eXBlcyB0aGF0IGhhdmUgYXV0aGVudGljYXRpb24KICAgICAgICogdmVyaWZpZXIgZGF0YSB0aGVuIGl0IGlzIGp1c3QgZHVwbGljYXRlZCBpbiBhbGwgdGhlIGZyYWdtZW50cyAqLwogICAgICBtZW1jcHkoYXV0aF9kYXRhLCAodW5zaWduZWQgY2hhciAqKXBheWxvYWQgKyBkYXRhX2xlbmd0aCwgaGVhZGVyX2F1dGhfbGVuKTsKCiAgICAgIC8qIHRoZXNlIHBhY2tldHMgYXJlIGhhbmRsZWQgc3BlY2lhbGx5LCBub3QgYnkgdGhlIGdlbmVyaWMgU2VjdXJlUGFja2V0CiAgICAgICAqIGZ1bmN0aW9uICovCiAgICAgIGlmICgoKCpIZWFkZXIpLT5jb21tb24ucHR5cGUgIT0gUEtUX0JJTkQpICYmCiAgICAgICAgICAoKCpIZWFkZXIpLT5jb21tb24ucHR5cGUgIT0gUEtUX0JJTkRfQUNLKSAmJgogICAgICAgICAgKCgqSGVhZGVyKS0+Y29tbW9uLnB0eXBlICE9IFBLVF9BVVRIMykpCiAgICAgIHsKICAgICAgICBzdGF0dXMgPSBSUENSVDRfU2VjdXJlUGFja2V0KENvbm5lY3Rpb24sIFNFQ1VSRV9QQUNLRVRfUkVDRUlWRSwKICAgICAgICAgICAgQ3VycmVudEhlYWRlciwgaGRyX2xlbmd0aCwKICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIgKilwTXNnLT5CdWZmZXIgKyBidWZmZXJfbGVuZ3RoLCBkYXRhX2xlbmd0aCwKICAgICAgICAgICAgKFJwY0F1dGhWZXJpZmllciAqKWF1dGhfZGF0YSwKICAgICAgICAgICAgYXV0aF9kYXRhICsgc2l6ZW9mKFJwY0F1dGhWZXJpZmllciksCiAgICAgICAgICAgIGhlYWRlcl9hdXRoX2xlbiAtIHNpemVvZihScGNBdXRoVmVyaWZpZXIpKTsKICAgICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSBnb3RvIGZhaWw7CiAgICAgIH0KICAgIH0KCiAgICBidWZmZXJfbGVuZ3RoICs9IGRhdGFfbGVuZ3RoOwogICAgaWYgKCEoQ3VycmVudEhlYWRlci0+Y29tbW9uLmZsYWdzICYgUlBDX0ZMR19MQVNUKSkgewogICAgICBUUkFDRSgibmV4dCBoZWFkZXJcbiIpOwoKICAgICAgaWYgKCpIZWFkZXIgIT0gQ3VycmVudEhlYWRlcikKICAgICAgewogICAgICAgICAgUlBDUlQ0X0ZyZWVIZWFkZXIoQ3VycmVudEhlYWRlcik7CiAgICAgICAgICBDdXJyZW50SGVhZGVyID0gTlVMTDsKICAgICAgfQogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwYXlsb2FkKTsKICAgICAgcGF5bG9hZCA9IE5VTEw7CgogICAgICBzdGF0dXMgPSBSUENSVDRfcmVjZWl2ZV9mcmFnbWVudChDb25uZWN0aW9uLCAmQ3VycmVudEhlYWRlciwgJnBheWxvYWQpOwogICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSBnb3RvIGZhaWw7CgogICAgICBmaXJzdF9mbGFnID0gMDsKICAgIH0gZWxzZSB7CiAgICAgIGJyZWFrOwogICAgfQogIH0KICBwTXNnLT5CdWZmZXJMZW5ndGggPSBidWZmZXJfbGVuZ3RoOwoKICAvKiByZXNwb25kIHRvIGF1dGhvcml6YXRpb24gcmVxdWVzdCAqLwogIGlmICgoKkhlYWRlciktPmNvbW1vbi5wdHlwZSA9PSBQS1RfQklORF9BQ0sgJiYgYXV0aF9sZW5ndGggPiBzaXplb2YoUnBjQXV0aFZlcmlmaWVyKSkKICB7CiAgICBzdGF0dXMgPSBSUENSVF9BdXRob3JpemVDb25uZWN0aW9uKENvbm5lY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF1dGhfZGF0YSArIHNpemVvZihScGNBdXRoVmVyaWZpZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhdXRoX2xlbmd0aCk7CiAgICBpZiAoc3RhdHVzKQogICAgICAgIGdvdG8gZmFpbDsKICB9CgogIC8qIHN1Y2Nlc3MgKi8KICBzdGF0dXMgPSBSUENfU19PSzsKCmZhaWw6CiAgUlBDUlQ0X1NldFRocmVhZEN1cnJlbnRDb25uZWN0aW9uKE5VTEwpOwogIGlmIChDdXJyZW50SGVhZGVyICE9ICpIZWFkZXIpCiAgICBSUENSVDRfRnJlZUhlYWRlcihDdXJyZW50SGVhZGVyKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSB7CiAgICBJX1JwY0ZyZWUocE1zZy0+QnVmZmVyKTsKICAgIHBNc2ctPkJ1ZmZlciA9IE5VTEw7CiAgICBSUENSVDRfRnJlZUhlYWRlcigqSGVhZGVyKTsKICAgICpIZWFkZXIgPSBOVUxMOwogIH0KICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhdXRoX2RhdGEpOwogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBheWxvYWQpOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNOZWdvdGlhdGVUcmFuc2ZlclN5bnRheCBbUlBDUlQ0LkBdCiAqCiAqIE5lZ290aWF0ZXMgdGhlIHRyYW5zZmVyIHN5bnRheCB1c2VkIGJ5IGEgY2xpZW50IGNvbm5lY3Rpb24gYnkgY29ubmVjdGluZwogKiB0byB0aGUgc2VydmVyLgogKgogKiBQQVJBTVMKICogIHBNc2cgICBbSV0gUlBDIE1lc3NhZ2Ugc3RydWN0dXJlLgogKiAgcEFzeW5jIFtJXSBBc3luY2hyb25vdXMgc3RhdGUgdG8gc2V0LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBSUENfU19PSy4KICogIEZhaWx1cmU6IEFueSBlcnJvciBjb2RlLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNOZWdvdGlhdGVUcmFuc2ZlclN5bnRheChQUlBDX01FU1NBR0UgcE1zZykKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopcE1zZy0+SGFuZGxlOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUlBDX1NUQVRVUyBzdGF0dXMgPSBSUENfU19PSzsKCiAgVFJBQ0UoIiglcClcbiIsIHBNc2cpOwoKICBpZiAoIWJpbmQgfHwgYmluZC0+c2VydmVyKQogICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKCiAgLyogaWYgd2UgYWxyZWFkeSBoYXZlIGEgY29ubmVjdGlvbiwgd2UgZG9uJ3QgbmVlZCB0byBuZWdvdGlhdGUgYWdhaW4gKi8KICBpZiAoIXBNc2ctPlJlc2VydmVkRm9yUnVudGltZSkKICB7CiAgICBSUENfQ0xJRU5UX0lOVEVSRkFDRSAqY2lmID0gcE1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb247CiAgICBpZiAoIWNpZikgcmV0dXJuIFJQQ19TX0lOVEVSRkFDRV9OT1RfRk9VTkQ7CgogICAgaWYgKCFiaW5kLT5FbmRwb2ludCB8fCAhYmluZC0+RW5kcG9pbnRbMF0pCiAgICB7CiAgICAgIFRSQUNFKCJhdXRvbWF0aWNhbGx5IHJlc29sdmluZyBwYXJ0aWFsbHkgYm91bmQgYmluZGluZ1xuIik7CiAgICAgIHN0YXR1cyA9IFJwY0VwUmVzb2x2ZUJpbmRpbmcoYmluZCwgY2lmKTsKICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgcmV0dXJuIHN0YXR1czsKICAgIH0KCiAgICBzdGF0dXMgPSBSUENSVDRfT3BlbkJpbmRpbmcoYmluZCwgJmNvbm4sICZjaWYtPlRyYW5zZmVyU3ludGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaWYtPkludGVyZmFjZUlkKTsKCiAgICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgewogICAgICBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUgPSBjb25uOwogICAgICBSUENSVDRfQWRkUmVmQmluZGluZyhiaW5kKTsKICAgIH0KICB9CgogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNHZXRCdWZmZXIgW1JQQ1JUNC5AXQogKgogKiBBbGxvY2F0ZXMgYSBidWZmZXIgZm9yIHVzZSBieSBJX1JwY1NlbmQgb3IgSV9ScGNTZW5kUmVjZWl2ZSBhbmQgYmluZHMgdG8gdGhlCiAqIHNlcnZlciBpbnRlcmZhY2UuCiAqCiAqIFBBUkFNUwogKiAgcE1zZyBbSS9PXSBSUEMgbWVzc2FnZSBpbmZvcm1hdGlvbi4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogUlBDX1NfT0suCiAqICBGYWlsdXJlOiBSUENfU19JTlZBTElEX0JJTkRJTkcgaWYgcE1zZy0+SGFuZGxlIGlzIGludmFsaWQuCiAqICAgICAgICAgICBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEUgaWYgdW5hYmxlIHRvIGNvbm5lY3QgdG8gc2VydmVyLgogKiAgICAgICAgICAgRVJST1JfT1VUT0ZNRU1PUlkgaWYgYnVmZmVyIGFsbG9jYXRpb24gZmFpbGVkLgogKgogKiBOT1RFUwogKiAgVGhlIHBNc2ctPkJ1ZmZlckxlbmd0aCBmaWVsZCBkZXRlcm1pbmVzIHRoZSBzaXplIG9mIHRoZSBidWZmZXIgdG8gYWxsb2NhdGUsCiAqICBpbiBieXRlcy4KICoKICogIFVzZSBJX1JwY0ZyZWVCdWZmZXIoKSB0byB1bmJpbmQgZnJvbSB0aGUgc2VydmVyIGFuZCBmcmVlIHRoZSBtZXNzYWdlIGJ1ZmZlci4KICoKICogU0VFIEFMU08KICogIElfUnBjRnJlZUJ1ZmZlcigpLCBJX1JwY1NlbmQoKSwgSV9ScGNSZWNlaXZlKCksIElfUnBjU2VuZFJlY2VpdmUoKS4KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjR2V0QnVmZmVyKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilwTXNnLT5IYW5kbGU7CgogIFRSQUNFKCIoJXApOiBCdWZmZXJMZW5ndGg9JWRcbiIsIHBNc2csIHBNc2ctPkJ1ZmZlckxlbmd0aCk7CgogIGlmICghYmluZCkKICAgIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7CgogIHBNc2ctPkJ1ZmZlciA9IElfUnBjQWxsb2NhdGUocE1zZy0+QnVmZmVyTGVuZ3RoKTsKICBUUkFDRSgiQnVmZmVyPSVwXG4iLCBwTXNnLT5CdWZmZXIpOwoKICBpZiAoIXBNc2ctPkJ1ZmZlcikKICAgIHJldHVybiBFUlJPUl9PVVRPRk1FTU9SWTsKCiAgaWYgKCFiaW5kLT5zZXJ2ZXIpCiAgewogICAgc3RhdHVzID0gSV9ScGNOZWdvdGlhdGVUcmFuc2ZlclN5bnRheChwTXNnKTsKICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgICAgIElfUnBjRnJlZShwTXNnLT5CdWZmZXIpOwogIH0KICBlbHNlCiAgICBzdGF0dXMgPSBSUENfU19PSzsKCiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJX1JwY1JlQWxsb2NhdGVCdWZmZXIgKGludGVybmFsKQogKi8Kc3RhdGljIFJQQ19TVEFUVVMgSV9ScGNSZUFsbG9jYXRlQnVmZmVyKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgVFJBQ0UoIiglcCk6IEJ1ZmZlckxlbmd0aD0lZFxuIiwgcE1zZywgcE1zZy0+QnVmZmVyTGVuZ3RoKTsKICBwTXNnLT5CdWZmZXIgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBwTXNnLT5CdWZmZXIsIHBNc2ctPkJ1ZmZlckxlbmd0aCk7CgogIFRSQUNFKCJCdWZmZXI9JXBcbiIsIHBNc2ctPkJ1ZmZlcik7CiAgcmV0dXJuIHBNc2ctPkJ1ZmZlciA/IFJQQ19TX09LIDogRVJST1JfT1VUT0ZNRU1PUlk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNGcmVlQnVmZmVyIFtSUENSVDQuQF0KICoKICogRnJlZXMgYSBidWZmZXIgYWxsb2NhdGVkIGJ5IElfUnBjR2V0QnVmZmVyIG9yIElfUnBjUmVjZWl2ZSBhbmQgdW5iaW5kcyBmcm9tCiAqIHRoZSBzZXJ2ZXIgaW50ZXJmYWNlLgogKgogKiBQQVJBTVMKICogIHBNc2cgW0kvT10gUlBDIG1lc3NhZ2UgaW5mb3JtYXRpb24uCiAqCiAqIFJFVFVSTlMKICogIFJQQ19TX09LLgogKgogKiBTRUUgQUxTTwogKiAgSV9ScGNHZXRCdWZmZXIoKSwgSV9ScGNSZWNlaXZlKCkuCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY0ZyZWVCdWZmZXIoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKXBNc2ctPkhhbmRsZTsKCiAgVFJBQ0UoIiglcCkgQnVmZmVyPSVwXG4iLCBwTXNnLCBwTXNnLT5CdWZmZXIpOwoKICBpZiAoIWJpbmQpIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7CgogIGlmIChwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUpCiAgewogICAgUnBjQ29ubmVjdGlvbiAqY29ubiA9IHBNc2ctPlJlc2VydmVkRm9yUnVudGltZTsKICAgIFJQQ1JUNF9DbG9zZUJpbmRpbmcoYmluZCwgY29ubik7CiAgICBSUENSVDRfUmVsZWFzZUJpbmRpbmcoYmluZCk7CiAgICBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUgPSBOVUxMOwogIH0KICBJX1JwY0ZyZWUocE1zZy0+QnVmZmVyKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KCnN0YXRpYyB2b2lkIENBTExCQUNLIGFzeW5jX2FwY19ub3RpZmllcl9wcm9jKFVMT05HX1BUUiB1bFBhcmFtKQp7CiAgICBSUENfQVNZTkNfU1RBVEUgKnN0YXRlID0gKFJQQ19BU1lOQ19TVEFURSAqKXVsUGFyYW07CiAgICBzdGF0ZS0+dS5BUEMuTm90aWZpY2F0aW9uUm91dGluZShzdGF0ZSwgTlVMTCwgc3RhdGUtPkV2ZW50KTsKfQoKc3RhdGljIERXT1JEIFdJTkFQSSBhc3luY19ub3RpZmllcl9wcm9jKExQVk9JRCBwKQp7CiAgICBScGNDb25uZWN0aW9uICpjb25uID0gcDsKICAgIFJQQ19BU1lOQ19TVEFURSAqc3RhdGUgPSBjb25uLT5hc3luY19zdGF0ZTsKCiAgICBpZiAoc3RhdGUgJiYgY29ubi0+b3BzLT53YWl0X2Zvcl9pbmNvbWluZ19kYXRhKGNvbm4pICE9IC0xKQogICAgewogICAgICAgIHN0YXRlLT5FdmVudCA9IFJwY0NhbGxDb21wbGV0ZTsKICAgICAgICBzd2l0Y2ggKHN0YXRlLT5Ob3RpZmljYXRpb25UeXBlKQogICAgICAgIHsKICAgICAgICBjYXNlIFJwY05vdGlmaWNhdGlvblR5cGVFdmVudDoKICAgICAgICAgICAgVFJBQ0UoIlJwY05vdGlmaWNhdGlvblR5cGVFdmVudCAlcFxuIiwgc3RhdGUtPnUuaEV2ZW50KTsKICAgICAgICAgICAgU2V0RXZlbnQoc3RhdGUtPnUuaEV2ZW50KTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBScGNOb3RpZmljYXRpb25UeXBlQXBjOgogICAgICAgICAgICBUUkFDRSgiUnBjTm90aWZpY2F0aW9uVHlwZUFwYyAlcFxuIiwgc3RhdGUtPnUuQVBDLmhUaHJlYWQpOwogICAgICAgICAgICBRdWV1ZVVzZXJBUEMoYXN5bmNfYXBjX25vdGlmaWVyX3Byb2MsIHN0YXRlLT51LkFQQy5oVGhyZWFkLCAoVUxPTkdfUFRSKXN0YXRlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBScGNOb3RpZmljYXRpb25UeXBlSW9jOgogICAgICAgICAgICBUUkFDRSgiUnBjTm90aWZpY2F0aW9uVHlwZUlvYyAlcCwgMHgleCwgMHglbHgsICVwXG4iLAogICAgICAgICAgICAgICAgc3RhdGUtPnUuSU9DLmhJT1BvcnQsIHN0YXRlLT51LklPQy5kd051bWJlck9mQnl0ZXNUcmFuc2ZlcnJlZCwKICAgICAgICAgICAgICAgIHN0YXRlLT51LklPQy5kd0NvbXBsZXRpb25LZXksIHN0YXRlLT51LklPQy5scE92ZXJsYXBwZWQpOwogICAgICAgICAgICBQb3N0UXVldWVkQ29tcGxldGlvblN0YXR1cyhzdGF0ZS0+dS5JT0MuaElPUG9ydCwKICAgICAgICAgICAgICAgIHN0YXRlLT51LklPQy5kd051bWJlck9mQnl0ZXNUcmFuc2ZlcnJlZCwKICAgICAgICAgICAgICAgIHN0YXRlLT51LklPQy5kd0NvbXBsZXRpb25LZXksCiAgICAgICAgICAgICAgICBzdGF0ZS0+dS5JT0MubHBPdmVybGFwcGVkKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBScGNOb3RpZmljYXRpb25UeXBlSHduZDoKICAgICAgICAgICAgVFJBQ0UoIlJwY05vdGlmaWNhdGlvblR5cGVId25kICVwIDB4JXhcbiIsIHN0YXRlLT51LkhXTkQuaFduZCwKICAgICAgICAgICAgICAgIHN0YXRlLT51LkhXTkQuTXNnKTsKICAgICAgICAgICAgUG9zdE1lc3NhZ2VXKHN0YXRlLT51LkhXTkQuaFduZCwgc3RhdGUtPnUuSFdORC5Nc2csIDAsIDApOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJwY05vdGlmaWNhdGlvblR5cGVDYWxsYmFjazoKICAgICAgICAgICAgVFJBQ0UoIlJwY05vdGlmaWNhdGlvblR5cGVDYWxsYmFjayAlcFxuIiwgc3RhdGUtPnUuTm90aWZpY2F0aW9uUm91dGluZSk7CiAgICAgICAgICAgIHN0YXRlLT51Lk5vdGlmaWNhdGlvblJvdXRpbmUoc3RhdGUsIE5VTEwsIHN0YXRlLT5FdmVudCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUnBjTm90aWZpY2F0aW9uVHlwZU5vbmU6CiAgICAgICAgICAgIFRSQUNFKCJScGNOb3RpZmljYXRpb25UeXBlTm9uZVxuIik7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEZJWE1FKCJ1bmtub3duIE5vdGlmaWNhdGlvblR5cGU6ICVkLzB4JXhcbiIsIHN0YXRlLT5Ob3RpZmljYXRpb25UeXBlLCBzdGF0ZS0+Tm90aWZpY2F0aW9uVHlwZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJX1JwY1NlbmQgW1JQQ1JUNC5AXQogKgogKiBTZW5kcyBhIG1lc3NhZ2UgdG8gdGhlIHNlcnZlci4KICoKICogUEFSQU1TCiAqICBwTXNnIFtJL09dIFJQQyBtZXNzYWdlIGluZm9ybWF0aW9uLgogKgogKiBSRVRVUk5TCiAqICBVbmtub3duLgogKgogKiBOT1RFUwogKiAgVGhlIGJ1ZmZlciBtdXN0IGhhdmUgYmVlbiBhbGxvY2F0ZWQgd2l0aCBJX1JwY0dldEJ1ZmZlcigpLgogKgogKiBTRUUgQUxTTwogKiAgSV9ScGNHZXRCdWZmZXIoKSwgSV9ScGNSZWNlaXZlKCksIElfUnBjU2VuZFJlY2VpdmUoKS4KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VuZChQUlBDX01FU1NBR0UgcE1zZykKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopcE1zZy0+SGFuZGxlOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgUnBjUGt0SGRyICpoZHI7CgogIFRSQUNFKCIoJXApXG4iLCBwTXNnKTsKICBpZiAoIWJpbmQgfHwgYmluZC0+c2VydmVyIHx8ICFwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUpIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7CgogIGNvbm4gPSBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWU7CgogIGhkciA9IFJQQ1JUNF9CdWlsZFJlcXVlc3RIZWFkZXIocE1zZy0+RGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1zZy0+QnVmZmVyTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1zZy0+UHJvY051bSAmIH5SUENfRkxBR1NfVkFMSURfQklULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJpbmQtPk9iamVjdFV1aWQpOwogIGlmICghaGRyKQogICAgcmV0dXJuIEVSUk9SX09VVE9GTUVNT1JZOwogIGhkci0+Y29tbW9uLmNhbGxfaWQgPSBjb25uLT5OZXh0Q2FsbElkKys7CgogIHN0YXR1cyA9IFJQQ1JUNF9TZW5kKGNvbm4sIGhkciwgcE1zZy0+QnVmZmVyLCBwTXNnLT5CdWZmZXJMZW5ndGgpOwoKICBSUENSVDRfRnJlZUhlYWRlcihoZHIpOwoKICBpZiAoc3RhdHVzID09IFJQQ19TX09LICYmIHBNc2ctPlJwY0ZsYWdzICYgUlBDX0JVRkZFUl9BU1lOQykKICB7CiAgICBpZiAoIVF1ZXVlVXNlcldvcmtJdGVtKGFzeW5jX25vdGlmaWVyX3Byb2MsIGNvbm4sIFdUX0VYRUNVVEVERUZBVUxUIHwgV1RfRVhFQ1VURUxPTkdGVU5DVElPTikpCiAgICAgICAgc3RhdHVzID0gUlBDX1NfT1VUX09GX1JFU09VUkNFUzsKICB9CgogIHJldHVybiBzdGF0dXM7Cn0KCi8qIGlzIHRoaXMgc3RhdHVzIHNvbWV0aGluZyB0aGF0IHRoZSBzZXJ2ZXIgY2FuJ3QgcmVjb3ZlciBmcm9tPyAqLwpzdGF0aWMgaW5saW5lIEJPT0wgaXNfaGFyZF9lcnJvcihSUENfU1RBVFVTIHN0YXR1cykKewogICAgc3dpdGNoIChzdGF0dXMpCiAgICB7CiAgICBjYXNlIDA6IC8qIHVzZXItZGVmaW5lZCBmYXVsdCAqLwogICAgY2FzZSBFUlJPUl9BQ0NFU1NfREVOSUVEOgogICAgY2FzZSBFUlJPUl9JTlZBTElEX1BBUkFNRVRFUjoKICAgIGNhc2UgUlBDX1NfUFJPVE9DT0xfRVJST1I6CiAgICBjYXNlIFJQQ19TX0NBTExfRkFJTEVEOgogICAgY2FzZSBSUENfU19DQUxMX0ZBSUxFRF9ETkU6CiAgICBjYXNlIFJQQ19TX1NFQ19QS0dfRVJST1I6CiAgICAgICAgcmV0dXJuIFRSVUU7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBJX1JwY1JlY2VpdmUgW1JQQ1JUNC5AXQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNSZWNlaXZlKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilwTXNnLT5IYW5kbGU7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgUnBjUGt0SGRyICpoZHIgPSBOVUxMOwogIFJwY0Nvbm5lY3Rpb24gKmNvbm47CgogIFRSQUNFKCIoJXApXG4iLCBwTXNnKTsKICBpZiAoIWJpbmQgfHwgYmluZC0+c2VydmVyIHx8ICFwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUpIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7CgogIGNvbm4gPSBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWU7CiAgc3RhdHVzID0gUlBDUlQ0X1JlY2VpdmUoY29ubiwgJmhkciwgcE1zZyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgewogICAgV0FSTigicmVjZWl2ZSBmYWlsZWQgd2l0aCBlcnJvciAlbHhcbiIsIHN0YXR1cyk7CiAgICBnb3RvIGZhaWw7CiAgfQoKICBzd2l0Y2ggKGhkci0+Y29tbW9uLnB0eXBlKSB7CiAgY2FzZSBQS1RfUkVTUE9OU0U6CiAgICBicmVhazsKICBjYXNlIFBLVF9GQVVMVDoKICAgIEVSUiAoIndlIGdvdCBmYXVsdCBwYWNrZXQgd2l0aCBzdGF0dXMgMHglbHhcbiIsIGhkci0+ZmF1bHQuc3RhdHVzKTsKICAgIHN0YXR1cyA9IE5DQTJSUENfU1RBVFVTKGhkci0+ZmF1bHQuc3RhdHVzKTsKICAgIGlmIChpc19oYXJkX2Vycm9yKHN0YXR1cykpCiAgICAgICAgZ290byBmYWlsOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIFdBUk4oImJhZCBwYWNrZXQgdHlwZSAlZFxuIiwgaGRyLT5jb21tb24ucHR5cGUpOwogICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICBnb3RvIGZhaWw7CiAgfQoKICAvKiBzdWNjZXNzICovCiAgUlBDUlQ0X0ZyZWVIZWFkZXIoaGRyKTsKICByZXR1cm4gc3RhdHVzOwoKZmFpbDoKICBSUENSVDRfRnJlZUhlYWRlcihoZHIpOwogIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihjb25uKTsKICBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUgPSBOVUxMOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNTZW5kUmVjZWl2ZSBbUlBDUlQ0LkBdCiAqCiAqIFNlbmRzIGEgbWVzc2FnZSB0byB0aGUgc2VydmVyIGFuZCByZWNlaXZlcyB0aGUgcmVzcG9uc2UuCiAqCiAqIFBBUkFNUwogKiAgcE1zZyBbSS9PXSBSUEMgbWVzc2FnZSBpbmZvcm1hdGlvbi4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogUlBDX1NfT0suCiAqICBGYWlsdXJlOiBBbnkgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogIFRoZSBidWZmZXIgbXVzdCBoYXZlIGJlZW4gYWxsb2NhdGVkIHdpdGggSV9ScGNHZXRCdWZmZXIoKS4KICoKICogU0VFIEFMU08KICogIElfUnBjR2V0QnVmZmVyKCksIElfUnBjU2VuZCgpLCBJX1JwY1JlY2VpdmUoKS4KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VuZFJlY2VpdmUoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICB2b2lkICpvcmlnaW5hbF9idWZmZXI7CgogIFRSQUNFKCIoJXApXG4iLCBwTXNnKTsKCiAgb3JpZ2luYWxfYnVmZmVyID0gcE1zZy0+QnVmZmVyOwogIHN0YXR1cyA9IElfUnBjU2VuZChwTXNnKTsKICBpZiAoc3RhdHVzID09IFJQQ19TX09LKQogICAgc3RhdHVzID0gSV9ScGNSZWNlaXZlKHBNc2cpOwogIC8qIGZyZWUgdGhlIGJ1ZmZlciByZXBsYWNlZCBieSBhIG5ldyBidWZmZXIgaW4gSV9ScGNSZWNlaXZlICovCiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgIElfUnBjRnJlZShvcmlnaW5hbF9idWZmZXIpOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNBc3luY1NldEhhbmRsZSBbUlBDUlQ0LkBdCiAqCiAqIFNldHMgdGhlIGFzeW5jaHJvbm91cyBzdGF0ZSBvZiB0aGUgaGFuZGxlIGNvbnRhaW5lZCBpbiB0aGUgUlBDIG1lc3NhZ2UKICogc3RydWN0dXJlLgogKgogKiBQQVJBTVMKICogIHBNc2cgICBbSV0gUlBDIE1lc3NhZ2Ugc3RydWN0dXJlLgogKiAgcEFzeW5jIFtJXSBBc3luY2hyb25vdXMgc3RhdGUgdG8gc2V0LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBSUENfU19PSy4KICogIEZhaWx1cmU6IEFueSBlcnJvciBjb2RlLgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgSV9ScGNBc3luY1NldEhhbmRsZShQUlBDX01FU1NBR0UgcE1zZywgUFJQQ19BU1lOQ19TVEFURSBwQXN5bmMpCnsKICAgIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopcE1zZy0+SGFuZGxlOwogICAgUnBjQ29ubmVjdGlvbiAqY29ubjsKCiAgICBUUkFDRSgiKCVwLCAlcClcbiIsIHBNc2csIHBBc3luYyk7CgogICAgaWYgKCFiaW5kIHx8IGJpbmQtPnNlcnZlciB8fCAhcE1zZy0+UmVzZXJ2ZWRGb3JSdW50aW1lKSByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwoKICAgIGNvbm4gPSBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWU7CiAgICBjb25uLT5hc3luY19zdGF0ZSA9IHBBc3luYzsKCiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNBc3luY0Fib3J0Q2FsbCBbUlBDUlQ0LkBdCiAqCiAqIEFib3J0cyBhbiBhc3luY2hyb25vdXMgY2FsbC4KICoKICogUEFSQU1TCiAqICBwQXN5bmMgICAgICAgIFtJXSBBc3luY2hyb25vdXMgc3RhdGUuCiAqICBFeGNlcHRpb25Db2RlIFtJXSBFeGNlcHRpb24gY29kZS4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogUlBDX1NfT0suCiAqICBGYWlsdXJlOiBBbnkgZXJyb3IgY29kZS4KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjQXN5bmNBYm9ydENhbGwoUFJQQ19BU1lOQ19TVEFURSBwQXN5bmMsIFVMT05HIEV4Y2VwdGlvbkNvZGUpCnsKICAgIEZJWE1FKCIoJXAsICVkKTogc3R1YlxuIiwgcEFzeW5jLCBFeGNlcHRpb25Db2RlKTsKICAgIHJldHVybiBSUENfU19JTlZBTElEX0FTWU5DX0hBTkRMRTsKfQo=