LyoKICogUlBDIG1lc3NhZ2VzCiAqCiAqIENvcHlyaWdodCAyMDAxLTIwMDIgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBmaWd1cmUgb3V0IHdoZXRoZXIgd2UgKnJlYWxseSogZ290IHRoaXMgcmlnaHQKICogIC0gY2hlY2sgZm9yIGVycm9ycyBhbmQgdGhyb3cgZXhjZXB0aW9ucwogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgInJwY25kci5oIgojaW5jbHVkZSAicnBjZGNlcC5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlICJycGNfYmluZGluZy5oIgojaW5jbHVkZSAicnBjX21pc2MuaCIKI2luY2x1ZGUgInJwY19kZWZzLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChvbGUpOwoKRFdPUkQgUlBDUlQ0X0dldEhlYWRlclNpemUoUnBjUGt0SGRyICpIZWFkZXIpCnsKICBzdGF0aWMgY29uc3QgRFdPUkQgaGVhZGVyX3NpemVzW10gPSB7CiAgICBzaXplb2YoSGVhZGVyLT5yZXF1ZXN0KSwgMCwgc2l6ZW9mKEhlYWRlci0+cmVzcG9uc2UpLAogICAgc2l6ZW9mKEhlYWRlci0+ZmF1bHQpLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCBzaXplb2YoSGVhZGVyLT5iaW5kKSwKICAgIHNpemVvZihIZWFkZXItPmJpbmRfYWNrKSwgc2l6ZW9mKEhlYWRlci0+YmluZF9uYWNrKSwKICAgIDAsIDAsIDAsIDAsIDAKICB9OwogIFVMT05HIHJldCA9IDA7CiAgCiAgaWYgKEhlYWRlci0+Y29tbW9uLnB0eXBlIDwgc2l6ZW9mKGhlYWRlcl9zaXplcykgLyBzaXplb2YoaGVhZGVyX3NpemVzWzBdKSkgewogICAgcmV0ID0gaGVhZGVyX3NpemVzW0hlYWRlci0+Y29tbW9uLnB0eXBlXTsKICAgIGlmIChyZXQgPT0gMCkKICAgICAgRklYTUUoInVuaGFuZGxlZCBwYWNrZXQgdHlwZVxuIik7CiAgICBpZiAoSGVhZGVyLT5jb21tb24uZmxhZ3MgJiBSUENfRkxHX09CSkVDVF9VVUlEKQogICAgICByZXQgKz0gc2l6ZW9mKFVVSUQpOwogIH0gZWxzZSB7CiAgICBUUkFDRSgiaW52YWxpZCBwYWNrZXQgdHlwZVxuIik7CiAgfQoKICByZXR1cm4gcmV0Owp9CgpWT0lEIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihScGNQa3RIZHIgKkhlYWRlciwgdW5zaWduZWQgY2hhciBQYWNrZXRUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIERhdGFSZXByZXNlbnRhdGlvbikKewogIEhlYWRlci0+Y29tbW9uLnJwY192ZXIgPSBSUENfVkVSX01BSk9SOwogIEhlYWRlci0+Y29tbW9uLnJwY192ZXJfbWlub3IgPSBSUENfVkVSX01JTk9SOwogIEhlYWRlci0+Y29tbW9uLnB0eXBlID0gUGFja2V0VHlwZTsKICBIZWFkZXItPmNvbW1vbi5kcmVwWzBdID0gTE9CWVRFKExPV09SRChEYXRhUmVwcmVzZW50YXRpb24pKTsKICBIZWFkZXItPmNvbW1vbi5kcmVwWzFdID0gSElCWVRFKExPV09SRChEYXRhUmVwcmVzZW50YXRpb24pKTsKICBIZWFkZXItPmNvbW1vbi5kcmVwWzJdID0gTE9CWVRFKEhJV09SRChEYXRhUmVwcmVzZW50YXRpb24pKTsKICBIZWFkZXItPmNvbW1vbi5kcmVwWzNdID0gSElCWVRFKEhJV09SRChEYXRhUmVwcmVzZW50YXRpb24pKTsKICBIZWFkZXItPmNvbW1vbi5hdXRoX2xlbiA9IDA7CiAgSGVhZGVyLT5jb21tb24uY2FsbF9pZCA9IDE7CiAgSGVhZGVyLT5jb21tb24uZmxhZ3MgPSAwOwogIC8qIEZsYWdzIGFuZCBmcmFnbWVudCBsZW5ndGggYXJlIGNvbXB1dGVkIGluIFJQQ1JUNF9TZW5kLiAqLwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgpScGNQa3RIZHIgKlJQQ1JUNF9CdWlsZFJlcXVlc3RIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIEJ1ZmZlckxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IFByb2NOdW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVUlEICpPYmplY3RVdWlkKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CiAgQk9PTCBoYXNfb2JqZWN0OwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBoYXNfb2JqZWN0ID0gKE9iamVjdFV1aWQgIT0gTlVMTCAmJiAhVXVpZElzTmlsKE9iamVjdFV1aWQsICZzdGF0dXMpKTsKICBoZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGhlYWRlci0+cmVxdWVzdCkgKyAoaGFzX29iamVjdCA/IHNpemVvZihVVUlEKSA6IDApKTsKICBpZiAoaGVhZGVyID09IE5VTEwpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgUlBDUlQ0X0J1aWxkQ29tbW9uSGVhZGVyKGhlYWRlciwgUEtUX1JFUVVFU1QsIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBzaXplb2YoaGVhZGVyLT5yZXF1ZXN0KTsKICBoZWFkZXItPnJlcXVlc3QuYWxsb2NfaGludCA9IEJ1ZmZlckxlbmd0aDsKICBoZWFkZXItPnJlcXVlc3QuY29udGV4dF9pZCA9IDA7CiAgaGVhZGVyLT5yZXF1ZXN0Lm9wbnVtID0gUHJvY051bTsKICBpZiAoaGFzX29iamVjdCkgewogICAgaGVhZGVyLT5jb21tb24uZmxhZ3MgfD0gUlBDX0ZMR19PQkpFQ1RfVVVJRDsKICAgIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuICs9IHNpemVvZihVVUlEKTsKICAgIG1lbWNweSgmaGVhZGVyLT5yZXF1ZXN0ICsgMSwgT2JqZWN0VXVpZCwgc2l6ZW9mKFVVSUQpKTsKICB9CgogIHJldHVybiBoZWFkZXI7Cn0KClJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkUmVzcG9uc2VIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBCdWZmZXJMZW5ndGgpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPnJlc3BvbnNlKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9SRVNQT05TRSwgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHNpemVvZihoZWFkZXItPnJlc3BvbnNlKTsKICBoZWFkZXItPnJlc3BvbnNlLmFsbG9jX2hpbnQgPSBCdWZmZXJMZW5ndGg7CgogIHJldHVybiBoZWFkZXI7Cn0KClJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NUQVRVUyBTdGF0dXMpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPmZhdWx0KSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9GQVVMVCwgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHNpemVvZihoZWFkZXItPmZhdWx0KTsKICBoZWFkZXItPmZhdWx0LnN0YXR1cyA9IFN0YXR1czsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRCaW5kSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgTWF4VHJhbnNtaXNzaW9uU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IE1heFJlY2VpdmVTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NZTlRBWF9JREVOVElGSUVSICpBYnN0cmFjdElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NZTlRBWF9JREVOVElGSUVSICpUcmFuc2ZlcklkKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CgogIGhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoaGVhZGVyLT5iaW5kKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9CSU5ELCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+YmluZCk7CiAgaGVhZGVyLT5iaW5kLm1heF90c2l6ZSA9IE1heFRyYW5zbWlzc2lvblNpemU7CiAgaGVhZGVyLT5iaW5kLm1heF9yc2l6ZSA9IE1heFJlY2VpdmVTaXplOwogIGhlYWRlci0+YmluZC5udW1fZWxlbWVudHMgPSAxOwogIGhlYWRlci0+YmluZC5udW1fc3ludGF4ZXMgPSAxOwogIG1lbWNweSgmaGVhZGVyLT5iaW5kLmFic3RyYWN0LCBBYnN0cmFjdElkLCBzaXplb2YoUlBDX1NZTlRBWF9JREVOVElGSUVSKSk7CiAgbWVtY3B5KCZoZWFkZXItPmJpbmQudHJhbnNmZXIsIFRyYW5zZmVySWQsIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKTsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRCaW5kTmFja0hlYWRlcih1bnNpZ25lZCBsb25nIERhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFJwY1ZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBScGNWZXJzaW9uTWlub3IpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPmJpbmRfbmFjaykpOwogIGlmIChoZWFkZXIgPT0gTlVMTCkgewogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBSUENSVDRfQnVpbGRDb21tb25IZWFkZXIoaGVhZGVyLCBQS1RfQklORF9OQUNLLCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+YmluZF9uYWNrKTsKICBoZWFkZXItPmJpbmRfbmFjay5wcm90b2NvbHNfY291bnQgPSAxOwogIGhlYWRlci0+YmluZF9uYWNrLnByb3RvY29sc1swXS5ycGNfdmVyID0gUnBjVmVyc2lvbjsKICBoZWFkZXItPmJpbmRfbmFjay5wcm90b2NvbHNbMF0ucnBjX3Zlcl9taW5vciA9IFJwY1ZlcnNpb25NaW5vcjsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRCaW5kQWNrSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgTWF4VHJhbnNtaXNzaW9uU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IE1heFJlY2VpdmVTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgU2VydmVyQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgUmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBSZWFzb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfU1lOVEFYX0lERU5USUZJRVIgKlRyYW5zZmVySWQpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKICB1bnNpZ25lZCBsb25nIGhlYWRlcl9zaXplOwogIFJwY0FkZHJlc3NTdHJpbmcgKnNlcnZlcl9hZGRyZXNzOwogIFJwY1Jlc3VsdHMgKnJlc3VsdHM7CiAgUlBDX1NZTlRBWF9JREVOVElGSUVSICp0cmFuc2Zlcl9pZDsKCiAgaGVhZGVyX3NpemUgPSBzaXplb2YoaGVhZGVyLT5iaW5kX2FjaykgKyBzaXplb2YoUnBjUmVzdWx0cykgKwogICAgICAgICAgICAgICAgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikgKyBzaXplb2YoUnBjQWRkcmVzc1N0cmluZykgKwogICAgICAgICAgICAgICAgc3RybGVuKFNlcnZlckFkZHJlc3MpOwoKICBoZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgaGVhZGVyX3NpemUpOwogIGlmIChoZWFkZXIgPT0gTlVMTCkgewogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBSUENSVDRfQnVpbGRDb21tb25IZWFkZXIoaGVhZGVyLCBQS1RfQklORF9BQ0ssIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBoZWFkZXJfc2l6ZTsKICBoZWFkZXItPmJpbmRfYWNrLm1heF90c2l6ZSA9IE1heFRyYW5zbWlzc2lvblNpemU7CiAgaGVhZGVyLT5iaW5kX2Fjay5tYXhfcnNpemUgPSBNYXhSZWNlaXZlU2l6ZTsKICBzZXJ2ZXJfYWRkcmVzcyA9IChScGNBZGRyZXNzU3RyaW5nKikoJmhlYWRlci0+YmluZF9hY2sgKyAxKTsKICBzZXJ2ZXJfYWRkcmVzcy0+bGVuZ3RoID0gc3RybGVuKFNlcnZlckFkZHJlc3MpICsgMTsKICBzdHJjcHkoc2VydmVyX2FkZHJlc3MtPnN0cmluZywgU2VydmVyQWRkcmVzcyk7CiAgcmVzdWx0cyA9IChScGNSZXN1bHRzKikoKFVMT05HX1BUUilzZXJ2ZXJfYWRkcmVzcyArIHNpemVvZihScGNBZGRyZXNzU3RyaW5nKSArIHNlcnZlcl9hZGRyZXNzLT5sZW5ndGggLSAxKTsKICByZXN1bHRzLT5udW1fcmVzdWx0cyA9IDE7CiAgcmVzdWx0cy0+cmVzdWx0c1swXS5yZXN1bHQgPSBSZXN1bHQ7CiAgcmVzdWx0cy0+cmVzdWx0c1swXS5yZWFzb24gPSBSZWFzb247CiAgdHJhbnNmZXJfaWQgPSAoUlBDX1NZTlRBWF9JREVOVElGSUVSKikocmVzdWx0cyArIDEpOwogIG1lbWNweSh0cmFuc2Zlcl9pZCwgVHJhbnNmZXJJZCwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpOwoKICByZXR1cm4gaGVhZGVyOwp9CgpWT0lEIFJQQ1JUNF9GcmVlSGVhZGVyKFJwY1BrdEhkciAqSGVhZGVyKQp7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgSGVhZGVyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfU2VuZCAoaW50ZXJuYWwpCiAqIAogKiBUcmFuc21pdCBhIHBhY2tldCBvdmVyIGNvbm5lY3Rpb24gaW4gYWNjZXB0YWJsZSBmcmFnbWVudHMuCiAqLwpSUENfU1RBVFVTIFJQQ1JUNF9TZW5kKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sIFJwY1BrdEhkciAqSGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkJ1ZmZlciwgdW5zaWduZWQgaW50IEJ1ZmZlckxlbmd0aCkKewogIFBVQ0hBUiBidWZmZXJfcG9zOwogIERXT1JEIGhkcl9zaXplLCBjb3VudDsKCiAgYnVmZmVyX3BvcyA9IEJ1ZmZlcjsKICAvKiBUaGUgcGFja2V0IGJ1aWxkaW5nIGZ1bmN0aW9ucyBzYXZlIHRoZSBwYWNrZXQgaGVhZGVyIHNpemUsIHNvIHdlIGNhbiB1c2UgaXQuICovCiAgaGRyX3NpemUgPSBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbjsKICBIZWFkZXItPmNvbW1vbi5mbGFncyB8PSBSUENfRkxHX0ZJUlNUOwogIEhlYWRlci0+Y29tbW9uLmZsYWdzICY9IH5SUENfRkxHX0xBU1Q7CiAgd2hpbGUgKCEoSGVhZGVyLT5jb21tb24uZmxhZ3MgJiBSUENfRkxHX0xBU1QpKSB7ICAgIAogICAgLyogZGVjaWRlIGlmIHdlIG5lZWQgdG8gc3BsaXQgdGhlIHBhY2tldCBpbnRvIGZyYWdtZW50cyAqLwogICAgaWYgKChCdWZmZXJMZW5ndGggKyBoZHJfc2l6ZSkgPD0gQ29ubmVjdGlvbi0+TWF4VHJhbnNtaXNzaW9uU2l6ZSkgewogICAgICBIZWFkZXItPmNvbW1vbi5mbGFncyB8PSBSUENfRkxHX0xBU1Q7CiAgICAgIEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gQnVmZmVyTGVuZ3RoICsgaGRyX3NpemU7CiAgICB9IGVsc2UgewogICAgICBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IENvbm5lY3Rpb24tPk1heFRyYW5zbWlzc2lvblNpemU7CiAgICAgIGJ1ZmZlcl9wb3MgKz0gSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gLSBoZHJfc2l6ZTsKICAgICAgQnVmZmVyTGVuZ3RoIC09IEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuIC0gaGRyX3NpemU7CiAgICB9CgogICAgLyogdHJhbnNtaXQgcGFja2V0IGhlYWRlciAqLwogICAgaWYgKCFXcml0ZUZpbGUoQ29ubmVjdGlvbi0+Y29ubiwgSGVhZGVyLCBoZHJfc2l6ZSwgJmNvdW50LCBOVUxMKSkgewogICAgICBXQVJOKCJXcml0ZUZpbGUgZmFpbGVkIHdpdGggZXJyb3IgJWxkXG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgIHJldHVybiBHZXRMYXN0RXJyb3IoKTsKICAgIH0KCiAgICAvKiBmcmFnbWVudCBjb25zaXN0ZWQgb2YgaGVhZGVyIG9ubHkgYW5kIGlzIHRoZSBsYXN0IG9uZSAqLwogICAgaWYgKGhkcl9zaXplID09IEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuICYmCiAgICAgICAgSGVhZGVyLT5jb21tb24uZmxhZ3MgJiBSUENfRkxHX0xBU1QpIHsKICAgICAgcmV0dXJuIFJQQ19TX09LOwogICAgfQoKICAgIC8qIHNlbmQgdGhlIGZyYWdtZW50IGRhdGEgKi8KICAgIGlmICghV3JpdGVGaWxlKENvbm5lY3Rpb24tPmNvbm4sIGJ1ZmZlcl9wb3MsIEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuIC0gaGRyX3NpemUsICZjb3VudCwgTlVMTCkpIHsKICAgICAgV0FSTigiV3JpdGVGaWxlIGZhaWxlZCB3aXRoIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgICByZXR1cm4gR2V0TGFzdEVycm9yKCk7CiAgICB9CgogICAgSGVhZGVyLT5jb21tb24uZmxhZ3MgJj0gflJQQ19GTEdfRklSU1Q7CiAgfQoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUlBDUlQ0X1JlY2VpdmUgKGludGVybmFsKQogKiAKICogUmVjZWl2ZSBhIHBhY2tldCBmcm9tIGNvbm5lY3Rpb24gYW5kIG1lcmdlIHRoZSBmcmFnbWVudHMuCiAqLwpSUENfU1RBVFVTIFJQQ1JUNF9SZWNlaXZlKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sIFJwY1BrdEhkciAqKkhlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX01FU1NBR0UgcE1zZykKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIERXT1JEIGR3UmVhZCwgaGRyX2xlbmd0aDsKICB1bnNpZ25lZCBzaG9ydCBmaXJzdF9mbGFnOwogIHVuc2lnbmVkIGxvbmcgZGF0YV9sZW5ndGg7CiAgdW5zaWduZWQgbG9uZyBidWZmZXJfbGVuZ3RoOwogIHVuc2lnbmVkIGNoYXIgKmJ1ZmZlcl9wdHI7CiAgUnBjUGt0Q29tbW9uSGRyIGNvbW1vbl9oZHI7CgogICpIZWFkZXIgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCAlcCwgJXApXG4iLCBDb25uZWN0aW9uLCBIZWFkZXIsIHBNc2cpOwoKICAvKiByZWFkIHBhY2tldCBjb21tb24gaGVhZGVyICovCiAgaWYgKCFSZWFkRmlsZShDb25uZWN0aW9uLT5jb25uLCAmY29tbW9uX2hkciwgc2l6ZW9mKGNvbW1vbl9oZHIpLCAmZHdSZWFkLCBOVUxMKSkgewogICAgaWYgKEdldExhc3RFcnJvcigpICE9IEVSUk9SX01PUkVfREFUQSkgewogICAgICBXQVJOKCJSZWFkRmlsZSBmYWlsZWQgd2l0aCBlcnJvciAlbGRcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgIGdvdG8gZmFpbDsKICAgIH0KICB9CiAgaWYgKGR3UmVhZCAhPSBzaXplb2YoY29tbW9uX2hkcikpIHsKICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgZ290byBmYWlsOwogIH0KCiAgLyogdmVyaWZ5IGlmIHRoZSBoZWFkZXIgcmVhbGx5IG1ha2VzIHNlbnNlICovCiAgaWYgKGNvbW1vbl9oZHIucnBjX3ZlciAhPSBSUENfVkVSX01BSk9SIHx8CiAgICAgIGNvbW1vbl9oZHIucnBjX3Zlcl9taW5vciAhPSBSUENfVkVSX01JTk9SKSB7CiAgICBXQVJOKCJ1bmhhbmRsZWQgcGFja2V0IHZlcnNpb25cbiIpOwogICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICBnb3RvIGZhaWw7CiAgfQoKICBoZHJfbGVuZ3RoID0gUlBDUlQ0X0dldEhlYWRlclNpemUoKFJwY1BrdEhkciopJmNvbW1vbl9oZHIpOwogIGlmIChoZHJfbGVuZ3RoID09IDApIHsKICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgZ290byBmYWlsOwogIH0KCiAgKkhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBoZHJfbGVuZ3RoKTsKICBtZW1jcHkoKkhlYWRlciwgJmNvbW1vbl9oZHIsIHNpemVvZihjb21tb25faGRyKSk7CgogIC8qIHJlYWQgdGhlIHJlc3Qgb2YgcGFja2V0IGhlYWRlciAqLwogIGlmICghUmVhZEZpbGUoQ29ubmVjdGlvbi0+Y29ubiwgJigqSGVhZGVyKS0+Y29tbW9uICsgMSwKICAgICAgICAgICAgICAgIGhkcl9sZW5ndGggLSBzaXplb2YoY29tbW9uX2hkciksICZkd1JlYWQsIE5VTEwpKSB7CiAgICBpZiAoR2V0TGFzdEVycm9yKCkgIT0gRVJST1JfTU9SRV9EQVRBKSB7CiAgICAgIFdBUk4oIlJlYWRGaWxlIGZhaWxlZCB3aXRoIGVycm9yICVsZFxuIiwgR2V0TGFzdEVycm9yKCkpOwogICAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgICAgZ290byBmYWlsOwogICAgfQogIH0KICBpZiAoZHdSZWFkICE9IGhkcl9sZW5ndGggLSBzaXplb2YoY29tbW9uX2hkcikpIHsKICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgZ290byBmYWlsOwogIH0KCiAgLyogcmVhZCBwYWNrZXQgYm9keSAqLwogIHN3aXRjaCAoY29tbW9uX2hkci5wdHlwZSkgewogIGNhc2UgUEtUX1JFU1BPTlNFOgogICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gKCpIZWFkZXIpLT5yZXNwb25zZS5hbGxvY19oaW50OwogICAgYnJlYWs7CiAgY2FzZSBQS1RfUkVRVUVTVDoKICAgIHBNc2ctPkJ1ZmZlckxlbmd0aCA9ICgqSGVhZGVyKS0+cmVxdWVzdC5hbGxvY19oaW50OwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIHBNc2ctPkJ1ZmZlckxlbmd0aCA9IGNvbW1vbl9oZHIuZnJhZ19sZW4gLSBoZHJfbGVuZ3RoOwogIH0KICBzdGF0dXMgPSBJX1JwY0dldEJ1ZmZlcihwTXNnKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSBnb3RvIGZhaWw7CgogIGZpcnN0X2ZsYWcgPSBSUENfRkxHX0ZJUlNUOwogIGJ1ZmZlcl9sZW5ndGggPSAwOwogIGJ1ZmZlcl9wdHIgPSBwTXNnLT5CdWZmZXI7CiAgd2hpbGUgKGJ1ZmZlcl9sZW5ndGggPCBwTXNnLT5CdWZmZXJMZW5ndGgpCiAgewogICAgZGF0YV9sZW5ndGggPSAoKkhlYWRlciktPmNvbW1vbi5mcmFnX2xlbiAtIGhkcl9sZW5ndGg7CiAgICBpZiAoKCgqSGVhZGVyKS0+Y29tbW9uLmZsYWdzICYgUlBDX0ZMR19GSVJTVCkgIT0gZmlyc3RfZmxhZyB8fAogICAgICAgIGRhdGFfbGVuZ3RoICsgYnVmZmVyX2xlbmd0aCA+IHBNc2ctPkJ1ZmZlckxlbmd0aCkgewogICAgICBUUkFDRSgiaW52YWxpZCBwYWNrZXQgZmxhZ3Mgb3IgYnVmZmVyIGxlbmd0aFxuIik7CiAgICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgICBnb3RvIGZhaWw7CiAgICB9CgogICAgaWYgKGRhdGFfbGVuZ3RoID09IDApIGR3UmVhZCA9IDA7IGVsc2UKICAgIGlmICghUmVhZEZpbGUoQ29ubmVjdGlvbi0+Y29ubiwgYnVmZmVyX3B0ciwgZGF0YV9sZW5ndGgsICZkd1JlYWQsIE5VTEwpKSB7CiAgICAgIGlmIChHZXRMYXN0RXJyb3IoKSAhPSBFUlJPUl9NT1JFX0RBVEEpIHsKICAgICAgICBXQVJOKCJSZWFkRmlsZSBmYWlsZWQgd2l0aCBlcnJvciAlbGRcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgICAgICBnb3RvIGZhaWw7CiAgICAgIH0KICAgIH0KICAgIGlmIChkd1JlYWQgIT0gZGF0YV9sZW5ndGgpIHsKICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgIGdvdG8gZmFpbDsKICAgIH0KCiAgICBpZiAoYnVmZmVyX2xlbmd0aCA9PSBwTXNnLT5CdWZmZXJMZW5ndGggJiYKICAgICAgICAoKCpIZWFkZXIpLT5jb21tb24uZmxhZ3MgJiBSUENfRkxHX0xBU1QpID09IDApIHsKICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgIGdvdG8gZmFpbDsKICAgIH0KCiAgICBidWZmZXJfbGVuZ3RoICs9IGRhdGFfbGVuZ3RoOwogICAgaWYgKGJ1ZmZlcl9sZW5ndGggPCBwTXNnLT5CdWZmZXJMZW5ndGgpIHsKICAgICAgVFJBQ0UoIm5leHQgaGVhZGVyXG4iKTsKCiAgICAgIC8qIHJlYWQgdGhlIGhlYWRlciBvZiBuZXh0IHBhY2tldCAqLwogICAgICBpZiAoIVJlYWRGaWxlKENvbm5lY3Rpb24tPmNvbm4sICpIZWFkZXIsIGhkcl9sZW5ndGgsICZkd1JlYWQsIE5VTEwpKSB7CiAgICAgICAgaWYgKEdldExhc3RFcnJvcigpICE9IEVSUk9SX01PUkVfREFUQSkgewogICAgICAgICAgV0FSTigiUmVhZEZpbGUgZmFpbGVkIHdpdGggZXJyb3IgJWxkXG4iLCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgICBzdGF0dXMgPSBHZXRMYXN0RXJyb3IoKTsKICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYgKGR3UmVhZCAhPSBoZHJfbGVuZ3RoKSB7CiAgICAgICAgV0FSTigiaW52YWxpZCBwYWNrZXQgaGVhZGVyIHNpemUgKCVsZClcbiIsIGR3UmVhZCk7CiAgICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgICAgZ290byBmYWlsOwogICAgICB9CgogICAgICBidWZmZXJfcHRyICs9IGRhdGFfbGVuZ3RoOwogICAgICBmaXJzdF9mbGFnID0gMDsKICAgIH0KICB9CgogIC8qIHN1Y2Nlc3MgKi8KICBzdGF0dXMgPSBSUENfU19PSzsKCmZhaWw6CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSyAmJiAqSGVhZGVyKSB7CiAgICBSUENSVDRfRnJlZUhlYWRlcigqSGVhZGVyKTsKICAgICpIZWFkZXIgPSBOVUxMOwogIH0KICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElfUnBjR2V0QnVmZmVyIFtSUENSVDQuQF0KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjR2V0QnVmZmVyKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgUnBjQmluZGluZyogYmluZCA9IChScGNCaW5kaW5nKilwTXNnLT5IYW5kbGU7CgogIFRSQUNFKCIoJXApOiBCdWZmZXJMZW5ndGg9JWRcbiIsIHBNc2csIHBNc2ctPkJ1ZmZlckxlbmd0aCk7CiAgLyogRklYTUU6IHBmbkFsbG9jYXRlPyAqLwogIGlmIChiaW5kLT5zZXJ2ZXIpIHsKICAgIC8qIGl0IHR1cm5zIG91dCB0aGF0IHRoZSBvcmlnaW5hbCBidWZmZXIgZGF0YSBtdXN0IHN0aWxsIGJlIGF2YWlsYWJsZQogICAgICogd2hpbGUgdGhlIFJQQyBzZXJ2ZXIgaXMgbWFyc2hhbGxpbmcgYSByZXBseSwgc28gd2Ugc2hvdWxkIG5vdCBkZWFsbG9jYXRlCiAgICAgKiBpdCwgd2UnbGwgbGVhdmUgZGVhbGxvY2F0aW5nIHRoZSBvcmlnaW5hbCBidWZmZXIgdG8gdGhlIFJQQyBzZXJ2ZXIgKi8KICAgIHBNc2ctPkJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBwTXNnLT5CdWZmZXJMZW5ndGgpOwogIH0gZWxzZSB7CiAgICBpZiAocE1zZy0+QnVmZmVyKQogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBNc2ctPkJ1ZmZlcik7CiAgICBwTXNnLT5CdWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcE1zZy0+QnVmZmVyTGVuZ3RoKTsKICB9CiAgVFJBQ0UoIkJ1ZmZlcj0lcFxuIiwgcE1zZy0+QnVmZmVyKTsKICAvKiBGSVhNRTogd2hpY2ggZXJyb3JzIHRvIHJldHVybj8gKi8KICByZXR1cm4gcE1zZy0+QnVmZmVyID8gU19PSyA6IEVfT1VUT0ZNRU1PUlk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNGcmVlQnVmZmVyIFtSUENSVDQuQF0KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjRnJlZUJ1ZmZlcihQUlBDX01FU1NBR0UgcE1zZykKewogIFRSQUNFKCIoJXApIEJ1ZmZlcj0lcFxuIiwgcE1zZywgcE1zZy0+QnVmZmVyKTsKICAvKiBGSVhNRTogcGZuRnJlZT8gKi8KICBpZiAocE1zZy0+QnVmZmVyICE9IE5VTEwpIHsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBNc2ctPkJ1ZmZlcik7CiAgfQogIHBNc2ctPkJ1ZmZlciA9IE5VTEw7CiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNTZW5kIFtSUENSVDQuQF0KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjU2VuZChQUlBDX01FU1NBR0UgcE1zZykKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopcE1zZy0+SGFuZGxlOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUlBDX0NMSUVOVF9JTlRFUkZBQ0UqIGNpZiA9IE5VTEw7CiAgUlBDX1NFUlZFUl9JTlRFUkZBQ0UqIHNpZiA9IE5VTEw7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgUnBjUGt0SGRyICpoZHI7CgogIFRSQUNFKCIoJXApXG4iLCBwTXNnKTsKICBpZiAoIWJpbmQpIHJldHVybiBSUENfU19JTlZBTElEX0JJTkRJTkc7CgogIGlmIChiaW5kLT5zZXJ2ZXIpIHsKICAgIHNpZiA9IHBNc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uOwogICAgaWYgKCFzaWYpIHJldHVybiBSUENfU19JTlRFUkZBQ0VfTk9UX0ZPVU5EOyAvKiA/ICovCiAgICBzdGF0dXMgPSBSUENSVDRfT3BlbkJpbmRpbmcoYmluZCwgJmNvbm4sICZzaWYtPlRyYW5zZmVyU3ludGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzaWYtPkludGVyZmFjZUlkKTsKICB9IGVsc2UgewogICAgY2lmID0gcE1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb247CiAgICBpZiAoIWNpZikgcmV0dXJuIFJQQ19TX0lOVEVSRkFDRV9OT1RfRk9VTkQ7IC8qID8gKi8KICAgIHN0YXR1cyA9IFJQQ1JUNF9PcGVuQmluZGluZyhiaW5kLCAmY29ubiwgJmNpZi0+VHJhbnNmZXJTeW50YXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNpZi0+SW50ZXJmYWNlSWQpOwogIH0KCiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgcmV0dXJuIHN0YXR1czsKCiAgaWYgKGJpbmQtPnNlcnZlcikgewogICAgaWYgKHBNc2ctPlJwY0ZsYWdzICYgV0lORV9SUENGTEFHX0VYQ0VQVElPTikgewogICAgICBoZHIgPSBSUENSVDRfQnVpbGRGYXVsdEhlYWRlcihwTXNnLT5EYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19TX0NBTExfRkFJTEVEKTsKICAgIH0gZWxzZSB7CiAgICAgIGhkciA9IFJQQ1JUNF9CdWlsZFJlc3BvbnNlSGVhZGVyKHBNc2ctPkRhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcE1zZy0+QnVmZmVyTGVuZ3RoKTsKICAgIH0KICB9IGVsc2UgewogICAgaGRyID0gUlBDUlQ0X0J1aWxkUmVxdWVzdEhlYWRlcihwTXNnLT5EYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNc2ctPkJ1ZmZlckxlbmd0aCwgcE1zZy0+UHJvY051bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJpbmQtPk9iamVjdFV1aWQpOwogIH0KCiAgc3RhdHVzID0gUlBDUlQ0X1NlbmQoY29ubiwgaGRyLCBwTXNnLT5CdWZmZXIsIHBNc2ctPkJ1ZmZlckxlbmd0aCk7CgogIFJQQ1JUNF9GcmVlSGVhZGVyKGhkcik7CgogIC8qIHN1Y2Nlc3MgKi8KICBpZiAoIWJpbmQtPnNlcnZlcikgewogICAgLyogc2F2ZSB0aGUgY29ubmVjdGlvbiwgc28gdGhlIHJlc3BvbnNlIGNhbiBiZSByZWFkIGZyb20gaXQgKi8KICAgIHBNc2ctPlJlc2VydmVkRm9yUnVudGltZSA9IGNvbm47CiAgICByZXR1cm4gUlBDX1NfT0s7CiAgfQogIFJQQ1JUNF9DbG9zZUJpbmRpbmcoYmluZCwgY29ubik7CiAgc3RhdHVzID0gUlBDX1NfT0s7CgogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNSZWNlaXZlIFtSUENSVDQuQF0KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjUmVjZWl2ZShQUlBDX01FU1NBR0UgcE1zZykKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopcE1zZy0+SGFuZGxlOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUlBDX0NMSUVOVF9JTlRFUkZBQ0UqIGNpZiA9IE5VTEw7CiAgUlBDX1NFUlZFUl9JTlRFUkZBQ0UqIHNpZiA9IE5VTEw7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgUnBjUGt0SGRyICpoZHIgPSBOVUxMOwoKICBUUkFDRSgiKCVwKVxuIiwgcE1zZyk7CiAgaWYgKCFiaW5kKSByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwoKICBpZiAocE1zZy0+UmVzZXJ2ZWRGb3JSdW50aW1lKSB7CiAgICBjb25uID0gcE1zZy0+UmVzZXJ2ZWRGb3JSdW50aW1lOwogICAgcE1zZy0+UmVzZXJ2ZWRGb3JSdW50aW1lID0gTlVMTDsKICB9IGVsc2UgewogICAgaWYgKGJpbmQtPnNlcnZlcikgewogICAgICBzaWYgPSBwTXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbjsKICAgICAgaWYgKCFzaWYpIHJldHVybiBSUENfU19JTlRFUkZBQ0VfTk9UX0ZPVU5EOyAvKiA/ICovCiAgICAgIHN0YXR1cyA9IFJQQ1JUNF9PcGVuQmluZGluZyhiaW5kLCAmY29ubiwgJnNpZi0+VHJhbnNmZXJTeW50YXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2lmLT5JbnRlcmZhY2VJZCk7CiAgICB9IGVsc2UgewogICAgICBjaWYgPSBwTXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbjsKICAgICAgaWYgKCFjaWYpIHJldHVybiBSUENfU19JTlRFUkZBQ0VfTk9UX0ZPVU5EOyAvKiA/ICovCiAgICAgIHN0YXR1cyA9IFJQQ1JUNF9PcGVuQmluZGluZyhiaW5kLCAmY29ubiwgJmNpZi0+VHJhbnNmZXJTeW50YXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY2lmLT5JbnRlcmZhY2VJZCk7CiAgICB9CiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSByZXR1cm4gc3RhdHVzOwogIH0KCiAgc3RhdHVzID0gUlBDUlQ0X1JlY2VpdmUoY29ubiwgJmhkciwgcE1zZyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgewogICAgV0FSTigicmVjZWl2ZSBmYWlsZWQgd2l0aCBlcnJvciAlbHhcbiIsIHN0YXR1cyk7CiAgICBnb3RvIGZhaWw7CiAgfQoKICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKCiAgc3dpdGNoIChoZHItPmNvbW1vbi5wdHlwZSkgewogIGNhc2UgUEtUX1JFU1BPTlNFOgogICAgaWYgKGJpbmQtPnNlcnZlcikgZ290byBmYWlsOwogICAgYnJlYWs7CiAgY2FzZSBQS1RfUkVRVUVTVDoKICAgIGlmICghYmluZC0+c2VydmVyKSBnb3RvIGZhaWw7CiAgICBicmVhazsKICBjYXNlIFBLVF9GQVVMVDoKICAgIHBNc2ctPlJwY0ZsYWdzIHw9IFdJTkVfUlBDRkxBR19FWENFUFRJT047CiAgICBFUlIgKCJ3ZSBnb3QgZmF1bHQgcGFja2V0IHdpdGggc3RhdHVzICVseFxuIiwgaGRyLT5mYXVsdC5zdGF0dXMpOwogICAgc3RhdHVzID0gUlBDX1NfQ0FMTF9GQUlMRUQ7IC8qID8gKi8KICAgIGdvdG8gZmFpbDsKICBkZWZhdWx0OgogICAgZ290byBmYWlsOwogIH0KCiAgLyogc3VjY2VzcyAqLwogIHN0YXR1cyA9IFJQQ19TX09LOwoKZmFpbDoKICBpZiAoaGRyKSB7CiAgICBSUENSVDRfRnJlZUhlYWRlcihoZHIpOwogIH0KICBSUENSVDRfQ2xvc2VCaW5kaW5nKGJpbmQsIGNvbm4pOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNTZW5kUmVjZWl2ZSBbUlBDUlQ0LkBdCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY1NlbmRSZWNlaXZlKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCIoJXApXG4iLCBwTXNnKTsKICBzdGF0dXMgPSBJX1JwY1NlbmQocE1zZyk7CiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgIHN0YXR1cyA9IElfUnBjUmVjZWl2ZShwTXNnKTsKICByZXR1cm4gc3RhdHVzOwp9Cg==