LyoKICogUlBDIG1lc3NhZ2VzCiAqCiAqIENvcHlyaWdodCAyMDAxLTIwMDIgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKgogKiBUT0RPOgogKiAgLSBmaWd1cmUgb3V0IHdoZXRoZXIgd2UgKnJlYWxseSogZ290IHRoaXMgcmlnaHQKICogIC0gY2hlY2sgZm9yIGVycm9ycyBhbmQgdGhyb3cgZXhjZXB0aW9ucwogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgInJwY25kci5oIgojaW5jbHVkZSAicnBjZGNlcC5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlICJycGNfYmluZGluZy5oIgojaW5jbHVkZSAicnBjX21pc2MuaCIKI2luY2x1ZGUgInJwY19kZWZzLmgiCiNpbmNsdWRlICJycGNfbWVzc2FnZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocnBjKTsKCnN0YXRpYyBEV09SRCBSUENSVDRfR2V0SGVhZGVyU2l6ZShScGNQa3RIZHIgKkhlYWRlcikKewogIHN0YXRpYyBjb25zdCBEV09SRCBoZWFkZXJfc2l6ZXNbXSA9IHsKICAgIHNpemVvZihIZWFkZXItPnJlcXVlc3QpLCAwLCBzaXplb2YoSGVhZGVyLT5yZXNwb25zZSksCiAgICBzaXplb2YoSGVhZGVyLT5mYXVsdCksIDAsIDAsIDAsIDAsIDAsIDAsIDAsIHNpemVvZihIZWFkZXItPmJpbmQpLAogICAgc2l6ZW9mKEhlYWRlci0+YmluZF9hY2spLCBzaXplb2YoSGVhZGVyLT5iaW5kX25hY2spLAogICAgMCwgMCwgMCwgMCwgMAogIH07CiAgVUxPTkcgcmV0ID0gMDsKICAKICBpZiAoSGVhZGVyLT5jb21tb24ucHR5cGUgPCBzaXplb2YoaGVhZGVyX3NpemVzKSAvIHNpemVvZihoZWFkZXJfc2l6ZXNbMF0pKSB7CiAgICByZXQgPSBoZWFkZXJfc2l6ZXNbSGVhZGVyLT5jb21tb24ucHR5cGVdOwogICAgaWYgKHJldCA9PSAwKQogICAgICBGSVhNRSgidW5oYW5kbGVkIHBhY2tldCB0eXBlXG4iKTsKICAgIGlmIChIZWFkZXItPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfT0JKRUNUX1VVSUQpCiAgICAgIHJldCArPSBzaXplb2YoVVVJRCk7CiAgfSBlbHNlIHsKICAgIFRSQUNFKCJpbnZhbGlkIHBhY2tldCB0eXBlXG4iKTsKICB9CgogIHJldHVybiByZXQ7Cn0KCnN0YXRpYyBWT0lEIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihScGNQa3RIZHIgKkhlYWRlciwgdW5zaWduZWQgY2hhciBQYWNrZXRUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIERhdGFSZXByZXNlbnRhdGlvbikKewogIEhlYWRlci0+Y29tbW9uLnJwY192ZXIgPSBSUENfVkVSX01BSk9SOwogIEhlYWRlci0+Y29tbW9uLnJwY192ZXJfbWlub3IgPSBSUENfVkVSX01JTk9SOwogIEhlYWRlci0+Y29tbW9uLnB0eXBlID0gUGFja2V0VHlwZTsKICBIZWFkZXItPmNvbW1vbi5kcmVwWzBdID0gTE9CWVRFKExPV09SRChEYXRhUmVwcmVzZW50YXRpb24pKTsKICBIZWFkZXItPmNvbW1vbi5kcmVwWzFdID0gSElCWVRFKExPV09SRChEYXRhUmVwcmVzZW50YXRpb24pKTsKICBIZWFkZXItPmNvbW1vbi5kcmVwWzJdID0gTE9CWVRFKEhJV09SRChEYXRhUmVwcmVzZW50YXRpb24pKTsKICBIZWFkZXItPmNvbW1vbi5kcmVwWzNdID0gSElCWVRFKEhJV09SRChEYXRhUmVwcmVzZW50YXRpb24pKTsKICBIZWFkZXItPmNvbW1vbi5hdXRoX2xlbiA9IDA7CiAgSGVhZGVyLT5jb21tb24uY2FsbF9pZCA9IDE7CiAgSGVhZGVyLT5jb21tb24uZmxhZ3MgPSAwOwogIC8qIEZsYWdzIGFuZCBmcmFnbWVudCBsZW5ndGggYXJlIGNvbXB1dGVkIGluIFJQQ1JUNF9TZW5kLiAqLwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgpzdGF0aWMgUnBjUGt0SGRyICpSUENSVDRfQnVpbGRSZXF1ZXN0SGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBCdWZmZXJMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBQcm9jTnVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVVVJRCAqT2JqZWN0VXVpZCkKewogIFJwY1BrdEhkciAqaGVhZGVyOwogIEJPT0wgaGFzX29iamVjdDsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgaGFzX29iamVjdCA9IChPYmplY3RVdWlkICE9IE5VTEwgJiYgIVV1aWRJc05pbChPYmplY3RVdWlkLCAmc3RhdHVzKSk7CiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksCiAgICAgICAgICAgICAgICAgICAgIHNpemVvZihoZWFkZXItPnJlcXVlc3QpICsgKGhhc19vYmplY3QgPyBzaXplb2YoVVVJRCkgOiAwKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9SRVFVRVNULCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+cmVxdWVzdCk7CiAgaGVhZGVyLT5yZXF1ZXN0LmFsbG9jX2hpbnQgPSBCdWZmZXJMZW5ndGg7CiAgaGVhZGVyLT5yZXF1ZXN0LmNvbnRleHRfaWQgPSAwOwogIGhlYWRlci0+cmVxdWVzdC5vcG51bSA9IFByb2NOdW07CiAgaWYgKGhhc19vYmplY3QpIHsKICAgIGhlYWRlci0+Y29tbW9uLmZsYWdzIHw9IFJQQ19GTEdfT0JKRUNUX1VVSUQ7CiAgICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiArPSBzaXplb2YoVVVJRCk7CiAgICBtZW1jcHkoJmhlYWRlci0+cmVxdWVzdCArIDEsIE9iamVjdFV1aWQsIHNpemVvZihVVUlEKSk7CiAgfQoKICByZXR1cm4gaGVhZGVyOwp9CgpzdGF0aWMgUnBjUGt0SGRyICpSUENSVDRfQnVpbGRSZXNwb25zZUhlYWRlcih1bnNpZ25lZCBsb25nIERhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIEJ1ZmZlckxlbmd0aCkKewogIFJwY1BrdEhkciAqaGVhZGVyOwoKICBoZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKGhlYWRlci0+cmVzcG9uc2UpKTsKICBpZiAoaGVhZGVyID09IE5VTEwpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgUlBDUlQ0X0J1aWxkQ29tbW9uSGVhZGVyKGhlYWRlciwgUEtUX1JFU1BPTlNFLCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+cmVzcG9uc2UpOwogIGhlYWRlci0+cmVzcG9uc2UuYWxsb2NfaGludCA9IEJ1ZmZlckxlbmd0aDsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRGYXVsdEhlYWRlcih1bnNpZ25lZCBsb25nIERhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfU1RBVFVTIFN0YXR1cykKewogIFJwY1BrdEhkciAqaGVhZGVyOwoKICBoZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKGhlYWRlci0+ZmF1bHQpKTsKICBpZiAoaGVhZGVyID09IE5VTEwpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgUlBDUlQ0X0J1aWxkQ29tbW9uSGVhZGVyKGhlYWRlciwgUEtUX0ZBVUxULCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+ZmF1bHQpOwogIGhlYWRlci0+ZmF1bHQuc3RhdHVzID0gU3RhdHVzOwoKICByZXR1cm4gaGVhZGVyOwp9CgpScGNQa3RIZHIgKlJQQ1JUNF9CdWlsZEJpbmRIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBNYXhUcmFuc21pc3Npb25TaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgTWF4UmVjZWl2ZVNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfU1lOVEFYX0lERU5USUZJRVIgKkFic3RyYWN0SWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfU1lOVEFYX0lERU5USUZJRVIgKlRyYW5zZmVySWQpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPmJpbmQpKTsKICBpZiAoaGVhZGVyID09IE5VTEwpIHsKICAgIHJldHVybiBOVUxMOwogIH0KCiAgUlBDUlQ0X0J1aWxkQ29tbW9uSGVhZGVyKGhlYWRlciwgUEtUX0JJTkQsIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBzaXplb2YoaGVhZGVyLT5iaW5kKTsKICBoZWFkZXItPmJpbmQubWF4X3RzaXplID0gTWF4VHJhbnNtaXNzaW9uU2l6ZTsKICBoZWFkZXItPmJpbmQubWF4X3JzaXplID0gTWF4UmVjZWl2ZVNpemU7CiAgaGVhZGVyLT5iaW5kLm51bV9lbGVtZW50cyA9IDE7CiAgaGVhZGVyLT5iaW5kLm51bV9zeW50YXhlcyA9IDE7CiAgbWVtY3B5KCZoZWFkZXItPmJpbmQuYWJzdHJhY3QsIEFic3RyYWN0SWQsIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKTsKICBtZW1jcHkoJmhlYWRlci0+YmluZC50cmFuc2ZlciwgVHJhbnNmZXJJZCwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpOwoKICByZXR1cm4gaGVhZGVyOwp9CgpScGNQa3RIZHIgKlJQQ1JUNF9CdWlsZEJpbmROYWNrSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGNoYXIgUnBjVmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFJwY1ZlcnNpb25NaW5vcikKewogIFJwY1BrdEhkciAqaGVhZGVyOwoKICBoZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKGhlYWRlci0+YmluZF9uYWNrKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9CSU5EX05BQ0ssIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBzaXplb2YoaGVhZGVyLT5iaW5kX25hY2spOwogIGhlYWRlci0+YmluZF9uYWNrLnByb3RvY29sc19jb3VudCA9IDE7CiAgaGVhZGVyLT5iaW5kX25hY2sucHJvdG9jb2xzWzBdLnJwY192ZXIgPSBScGNWZXJzaW9uOwogIGhlYWRlci0+YmluZF9uYWNrLnByb3RvY29sc1swXS5ycGNfdmVyX21pbm9yID0gUnBjVmVyc2lvbk1pbm9yOwoKICByZXR1cm4gaGVhZGVyOwp9CgpScGNQa3RIZHIgKlJQQ1JUNF9CdWlsZEJpbmRBY2tIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBNYXhUcmFuc21pc3Npb25TaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgTWF4UmVjZWl2ZVNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFNUUiBTZXJ2ZXJBZGRyZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBSZXN1bHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBsb25nIFJlYXNvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJQQ19TWU5UQVhfSURFTlRJRklFUiAqVHJhbnNmZXJJZCkKewogIFJwY1BrdEhkciAqaGVhZGVyOwogIHVuc2lnbmVkIGxvbmcgaGVhZGVyX3NpemU7CiAgUnBjQWRkcmVzc1N0cmluZyAqc2VydmVyX2FkZHJlc3M7CiAgUnBjUmVzdWx0cyAqcmVzdWx0czsKICBSUENfU1lOVEFYX0lERU5USUZJRVIgKnRyYW5zZmVyX2lkOwoKICBoZWFkZXJfc2l6ZSA9IHNpemVvZihoZWFkZXItPmJpbmRfYWNrKSArIHNpemVvZihScGNSZXN1bHRzKSArCiAgICAgICAgICAgICAgICBzaXplb2YoUlBDX1NZTlRBWF9JREVOVElGSUVSKSArIHNpemVvZihScGNBZGRyZXNzU3RyaW5nKSArCiAgICAgICAgICAgICAgICBzdHJsZW4oU2VydmVyQWRkcmVzcyk7CgogIGhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBoZWFkZXJfc2l6ZSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9CSU5EX0FDSywgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IGhlYWRlcl9zaXplOwogIGhlYWRlci0+YmluZF9hY2subWF4X3RzaXplID0gTWF4VHJhbnNtaXNzaW9uU2l6ZTsKICBoZWFkZXItPmJpbmRfYWNrLm1heF9yc2l6ZSA9IE1heFJlY2VpdmVTaXplOwogIHNlcnZlcl9hZGRyZXNzID0gKFJwY0FkZHJlc3NTdHJpbmcqKSgmaGVhZGVyLT5iaW5kX2FjayArIDEpOwogIHNlcnZlcl9hZGRyZXNzLT5sZW5ndGggPSBzdHJsZW4oU2VydmVyQWRkcmVzcykgKyAxOwogIHN0cmNweShzZXJ2ZXJfYWRkcmVzcy0+c3RyaW5nLCBTZXJ2ZXJBZGRyZXNzKTsKICByZXN1bHRzID0gKFJwY1Jlc3VsdHMqKSgoVUxPTkdfUFRSKXNlcnZlcl9hZGRyZXNzICsgc2l6ZW9mKFJwY0FkZHJlc3NTdHJpbmcpICsgc2VydmVyX2FkZHJlc3MtPmxlbmd0aCAtIDEpOwogIHJlc3VsdHMtPm51bV9yZXN1bHRzID0gMTsKICByZXN1bHRzLT5yZXN1bHRzWzBdLnJlc3VsdCA9IFJlc3VsdDsKICByZXN1bHRzLT5yZXN1bHRzWzBdLnJlYXNvbiA9IFJlYXNvbjsKICB0cmFuc2Zlcl9pZCA9IChSUENfU1lOVEFYX0lERU5USUZJRVIqKShyZXN1bHRzICsgMSk7CiAgbWVtY3B5KHRyYW5zZmVyX2lkLCBUcmFuc2ZlcklkLCBzaXplb2YoUlBDX1NZTlRBWF9JREVOVElGSUVSKSk7CgogIHJldHVybiBoZWFkZXI7Cn0KClZPSUQgUlBDUlQ0X0ZyZWVIZWFkZXIoUnBjUGt0SGRyICpIZWFkZXIpCnsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBIZWFkZXIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJQQ1JUNF9TZW5kIChpbnRlcm5hbCkKICogCiAqIFRyYW5zbWl0IGEgcGFja2V0IG92ZXIgY29ubmVjdGlvbiBpbiBhY2NlcHRhYmxlIGZyYWdtZW50cy4KICovClJQQ19TVEFUVVMgUlBDUlQ0X1NlbmQoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwgUnBjUGt0SGRyICpIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQnVmZmVyLCB1bnNpZ25lZCBpbnQgQnVmZmVyTGVuZ3RoKQp7CiAgUFVDSEFSIGJ1ZmZlcl9wb3M7CiAgRFdPUkQgaGRyX3NpemU7CiAgTE9ORyBjb3VudDsKCiAgYnVmZmVyX3BvcyA9IEJ1ZmZlcjsKICAvKiBUaGUgcGFja2V0IGJ1aWxkaW5nIGZ1bmN0aW9ucyBzYXZlIHRoZSBwYWNrZXQgaGVhZGVyIHNpemUsIHNvIHdlIGNhbiB1c2UgaXQuICovCiAgaGRyX3NpemUgPSBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbjsKICBIZWFkZXItPmNvbW1vbi5mbGFncyB8PSBSUENfRkxHX0ZJUlNUOwogIEhlYWRlci0+Y29tbW9uLmZsYWdzICY9IH5SUENfRkxHX0xBU1Q7CiAgd2hpbGUgKCEoSGVhZGVyLT5jb21tb24uZmxhZ3MgJiBSUENfRkxHX0xBU1QpKSB7CiAgICAvKiBkZWNpZGUgaWYgd2UgbmVlZCB0byBzcGxpdCB0aGUgcGFja2V0IGludG8gZnJhZ21lbnRzICovCiAgICBpZiAoKEJ1ZmZlckxlbmd0aCArIGhkcl9zaXplKSA8PSBDb25uZWN0aW9uLT5NYXhUcmFuc21pc3Npb25TaXplKSB7CiAgICAgIEhlYWRlci0+Y29tbW9uLmZsYWdzIHw9IFJQQ19GTEdfTEFTVDsKICAgICAgSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBCdWZmZXJMZW5ndGggKyBoZHJfc2l6ZTsKICAgIH0gZWxzZSB7CiAgICAgIEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gQ29ubmVjdGlvbi0+TWF4VHJhbnNtaXNzaW9uU2l6ZTsKICAgIH0KCiAgICAvKiB0cmFuc21pdCBwYWNrZXQgaGVhZGVyICovCiAgICBjb3VudCA9IHJwY3J0NF9jb25uX3dyaXRlKENvbm5lY3Rpb24sIEhlYWRlciwgaGRyX3NpemUpOwogICAgaWYgKGNvdW50PDApIHsKICAgICAgV0FSTigicnBjcnQ0X2Nvbm5fd3JpdGUgZmFpbGVkXG4iKTsKICAgICAgcmV0dXJuIFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgfQoKICAgIC8qIGZyYWdtZW50IGNvbnNpc3RlZCBvZiBoZWFkZXIgb25seSBhbmQgaXMgdGhlIGxhc3Qgb25lICovCiAgICBpZiAoaGRyX3NpemUgPT0gSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gJiYKICAgICAgICBIZWFkZXItPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfTEFTVCkgewogICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICB9CgogICAgLyogc2VuZCB0aGUgZnJhZ21lbnQgZGF0YSAqLwogICAgY291bnQgPSBycGNydDRfY29ubl93cml0ZShDb25uZWN0aW9uLCBidWZmZXJfcG9zLCBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbiAtIGhkcl9zaXplKTsKICAgIGlmIChjb3VudDwwKSB7CiAgICAgIFdBUk4oInJwY3J0NF9jb25uX3dyaXRlIGZhaWxlZFxuIik7CiAgICAgIHJldHVybiBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIH0KCiAgICBidWZmZXJfcG9zICs9IEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuIC0gaGRyX3NpemU7CiAgICBCdWZmZXJMZW5ndGggLT0gSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gLSBoZHJfc2l6ZTsKICAgIEhlYWRlci0+Y29tbW9uLmZsYWdzICY9IH5SUENfRkxHX0ZJUlNUOwogIH0KCiAgcmV0dXJuIFJQQ19TX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJQQ1JUNF9SZWNlaXZlIChpbnRlcm5hbCkKICogCiAqIFJlY2VpdmUgYSBwYWNrZXQgZnJvbSBjb25uZWN0aW9uIGFuZCBtZXJnZSB0aGUgZnJhZ21lbnRzLgogKi8KUlBDX1NUQVRVUyBSUENSVDRfUmVjZWl2ZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLCBScGNQa3RIZHIgKipIZWFkZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICBEV09SRCBoZHJfbGVuZ3RoOwogIExPTkcgZHdSZWFkOwogIHVuc2lnbmVkIHNob3J0IGZpcnN0X2ZsYWc7CiAgdW5zaWduZWQgbG9uZyBkYXRhX2xlbmd0aDsKICB1bnNpZ25lZCBsb25nIGJ1ZmZlcl9sZW5ndGg7CiAgdW5zaWduZWQgY2hhciAqYnVmZmVyX3B0cjsKICBScGNQa3RDb21tb25IZHIgY29tbW9uX2hkcjsKCiAgKkhlYWRlciA9IE5VTEw7CgogIFRSQUNFKCIoJXAsICVwLCAlcClcbiIsIENvbm5lY3Rpb24sIEhlYWRlciwgcE1zZyk7CgogIC8qIHJlYWQgcGFja2V0IGNvbW1vbiBoZWFkZXIgKi8KICBkd1JlYWQgPSBycGNydDRfY29ubl9yZWFkKENvbm5lY3Rpb24sICZjb21tb25faGRyLCBzaXplb2YoY29tbW9uX2hkcikpOwogIGlmIChkd1JlYWQgIT0gc2l6ZW9mKGNvbW1vbl9oZHIpKSB7CiAgICBXQVJOKCJTaG9ydCByZWFkIG9mIGhlYWRlciwgJWxkLyVkIGJ5dGVzXG4iLCBkd1JlYWQsIHNpemVvZihjb21tb25faGRyKSk7CiAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIGdvdG8gZmFpbDsKICB9CgogIC8qIHZlcmlmeSBpZiB0aGUgaGVhZGVyIHJlYWxseSBtYWtlcyBzZW5zZSAqLwogIGlmIChjb21tb25faGRyLnJwY192ZXIgIT0gUlBDX1ZFUl9NQUpPUiB8fAogICAgICBjb21tb25faGRyLnJwY192ZXJfbWlub3IgIT0gUlBDX1ZFUl9NSU5PUikgewogICAgV0FSTigidW5oYW5kbGVkIHBhY2tldCB2ZXJzaW9uXG4iKTsKICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgZ290byBmYWlsOwogIH0KCiAgaGRyX2xlbmd0aCA9IFJQQ1JUNF9HZXRIZWFkZXJTaXplKChScGNQa3RIZHIqKSZjb21tb25faGRyKTsKICBpZiAoaGRyX2xlbmd0aCA9PSAwKSB7CiAgICBXQVJOKCJoZWFkZXIgbGVuZ3RoID09IDBcbiIpOwogICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICBnb3RvIGZhaWw7CiAgfQoKICAqSGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGhkcl9sZW5ndGgpOwogIG1lbWNweSgqSGVhZGVyLCAmY29tbW9uX2hkciwgc2l6ZW9mKGNvbW1vbl9oZHIpKTsKCiAgLyogcmVhZCB0aGUgcmVzdCBvZiBwYWNrZXQgaGVhZGVyICovCiAgZHdSZWFkID0gcnBjcnQ0X2Nvbm5fcmVhZChDb25uZWN0aW9uLCAmKCpIZWFkZXIpLT5jb21tb24gKyAxLCBoZHJfbGVuZ3RoIC0gc2l6ZW9mKGNvbW1vbl9oZHIpKTsKICBpZiAoZHdSZWFkICE9IGhkcl9sZW5ndGggLSBzaXplb2YoY29tbW9uX2hkcikpIHsKICAgIFdBUk4oImJhZCBoZWFkZXIgbGVuZ3RoLCAlbGQvJWxkIGJ5dGVzXG4iLCBkd1JlYWQsIGhkcl9sZW5ndGggLSBzaXplb2YoY29tbW9uX2hkcikpOwogICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICBnb3RvIGZhaWw7CiAgfQoKICAvKiByZWFkIHBhY2tldCBib2R5ICovCiAgc3dpdGNoIChjb21tb25faGRyLnB0eXBlKSB7CiAgY2FzZSBQS1RfUkVTUE9OU0U6CiAgICBwTXNnLT5CdWZmZXJMZW5ndGggPSAoKkhlYWRlciktPnJlc3BvbnNlLmFsbG9jX2hpbnQ7CiAgICBicmVhazsKICBjYXNlIFBLVF9SRVFVRVNUOgogICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gKCpIZWFkZXIpLT5yZXF1ZXN0LmFsbG9jX2hpbnQ7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gY29tbW9uX2hkci5mcmFnX2xlbiAtIGhkcl9sZW5ndGg7CiAgfQoKICBUUkFDRSgiYnVmZmVyIGxlbmd0aCA9ICV1XG4iLCBwTXNnLT5CdWZmZXJMZW5ndGgpOwoKICBzdGF0dXMgPSBJX1JwY0dldEJ1ZmZlcihwTXNnKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSBnb3RvIGZhaWw7CgogIGZpcnN0X2ZsYWcgPSBSUENfRkxHX0ZJUlNUOwogIGJ1ZmZlcl9sZW5ndGggPSAwOwogIGJ1ZmZlcl9wdHIgPSBwTXNnLT5CdWZmZXI7CiAgd2hpbGUgKGJ1ZmZlcl9sZW5ndGggPCBwTXNnLT5CdWZmZXJMZW5ndGgpCiAgewogICAgZGF0YV9sZW5ndGggPSAoKkhlYWRlciktPmNvbW1vbi5mcmFnX2xlbiAtIGhkcl9sZW5ndGg7CiAgICBpZiAoKCgqSGVhZGVyKS0+Y29tbW9uLmZsYWdzICYgUlBDX0ZMR19GSVJTVCkgIT0gZmlyc3RfZmxhZyB8fAogICAgICAgIGRhdGFfbGVuZ3RoICsgYnVmZmVyX2xlbmd0aCA+IHBNc2ctPkJ1ZmZlckxlbmd0aCkgewogICAgICBUUkFDRSgiaW52YWxpZCBwYWNrZXQgZmxhZ3Mgb3IgYnVmZmVyIGxlbmd0aFxuIik7CiAgICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgICBnb3RvIGZhaWw7CiAgICB9CgogICAgaWYgKGRhdGFfbGVuZ3RoID09IDApIGR3UmVhZCA9IDA7IGVsc2UKICAgIGR3UmVhZCA9IHJwY3J0NF9jb25uX3JlYWQoQ29ubmVjdGlvbiwgYnVmZmVyX3B0ciwgZGF0YV9sZW5ndGgpOwogICAgaWYgKGR3UmVhZCAhPSBkYXRhX2xlbmd0aCkgewogICAgICBXQVJOKCJiYWQgZGF0YSBsZW5ndGgsICVsZC8lbGRcbiIsIGR3UmVhZCwgZGF0YV9sZW5ndGgpOwogICAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgICAgZ290byBmYWlsOwogICAgfQoKICAgIC8qIHdoZW4gdGhlcmUgaXMgbm8gbW9yZSBkYXRhIGxlZnQsIGl0IHNob3VsZCBiZSB0aGUgbGFzdCBwYWNrZXQgKi8KICAgIGlmIChidWZmZXJfbGVuZ3RoID09IHBNc2ctPkJ1ZmZlckxlbmd0aCAmJgogICAgICAgICgoKkhlYWRlciktPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfTEFTVCkgPT0gMCkgewogICAgICBXQVJOKCJubyBtb3JlIGRhdGEgbGVmdCwgYnV0IG5vdCBsYXN0IHBhY2tldFxuIik7CiAgICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgICBnb3RvIGZhaWw7CiAgICB9CgogICAgYnVmZmVyX2xlbmd0aCArPSBkYXRhX2xlbmd0aDsKICAgIGlmIChidWZmZXJfbGVuZ3RoIDwgcE1zZy0+QnVmZmVyTGVuZ3RoKSB7CiAgICAgIFRSQUNFKCJuZXh0IGhlYWRlclxuIik7CgogICAgICAvKiByZWFkIHRoZSBoZWFkZXIgb2YgbmV4dCBwYWNrZXQgKi8KICAgICAgZHdSZWFkID0gcnBjcnQ0X2Nvbm5fcmVhZChDb25uZWN0aW9uLCAqSGVhZGVyLCBoZHJfbGVuZ3RoKTsKICAgICAgaWYgKGR3UmVhZCAhPSBoZHJfbGVuZ3RoKSB7CiAgICAgICAgV0FSTigiaW52YWxpZCBwYWNrZXQgaGVhZGVyIHNpemUgKCVsZClcbiIsIGR3UmVhZCk7CiAgICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgICAgZ290byBmYWlsOwogICAgICB9CgogICAgICBidWZmZXJfcHRyICs9IGRhdGFfbGVuZ3RoOwogICAgICBmaXJzdF9mbGFnID0gMDsKICAgIH0KICB9CgogIC8qIHN1Y2Nlc3MgKi8KICBzdGF0dXMgPSBSUENfU19PSzsKCmZhaWw6CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSyAmJiAqSGVhZGVyKSB7CiAgICBSUENSVDRfRnJlZUhlYWRlcigqSGVhZGVyKTsKICAgICpIZWFkZXIgPSBOVUxMOwogIH0KICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElfUnBjR2V0QnVmZmVyIFtSUENSVDQuQF0KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjR2V0QnVmZmVyKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgVFJBQ0UoIiglcCk6IEJ1ZmZlckxlbmd0aD0lZFxuIiwgcE1zZywgcE1zZy0+QnVmZmVyTGVuZ3RoKTsKICAvKiBGSVhNRTogcGZuQWxsb2NhdGU/ICovCiAgcE1zZy0+QnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHBNc2ctPkJ1ZmZlckxlbmd0aCk7CgogIFRSQUNFKCJCdWZmZXI9JXBcbiIsIHBNc2ctPkJ1ZmZlcik7CiAgLyogRklYTUU6IHdoaWNoIGVycm9ycyB0byByZXR1cm4/ICovCiAgcmV0dXJuIHBNc2ctPkJ1ZmZlciA/IFNfT0sgOiBFX09VVE9GTUVNT1JZOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElfUnBjRnJlZUJ1ZmZlciBbUlBDUlQ0LkBdCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY0ZyZWVCdWZmZXIoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBUUkFDRSgiKCVwKSBCdWZmZXI9JXBcbiIsIHBNc2csIHBNc2ctPkJ1ZmZlcik7CiAgLyogRklYTUU6IHBmbkZyZWU/ICovCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcE1zZy0+QnVmZmVyKTsKICBwTXNnLT5CdWZmZXIgPSBOVUxMOwogIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElfUnBjU2VuZCBbUlBDUlQ0LkBdCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY1NlbmQoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKXBNc2ctPkhhbmRsZTsKICBScGNDb25uZWN0aW9uKiBjb25uOwogIFJQQ19DTElFTlRfSU5URVJGQUNFKiBjaWYgPSBOVUxMOwogIFJQQ19TRVJWRVJfSU5URVJGQUNFKiBzaWYgPSBOVUxMOwogIFJQQ19TVEFUVVMgc3RhdHVzOwogIFJwY1BrdEhkciAqaGRyOwoKICBUUkFDRSgiKCVwKVxuIiwgcE1zZyk7CiAgaWYgKCFiaW5kKSByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwoKICBpZiAoYmluZC0+c2VydmVyKSB7CiAgICBzaWYgPSBwTXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbjsKICAgIGlmICghc2lmKSByZXR1cm4gUlBDX1NfSU5URVJGQUNFX05PVF9GT1VORDsgLyogPyAqLwogICAgc3RhdHVzID0gUlBDUlQ0X09wZW5CaW5kaW5nKGJpbmQsICZjb25uLCAmc2lmLT5UcmFuc2ZlclN5bnRheCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2lmLT5JbnRlcmZhY2VJZCk7CiAgfSBlbHNlIHsKICAgIGNpZiA9IHBNc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uOwogICAgaWYgKCFjaWYpIHJldHVybiBSUENfU19JTlRFUkZBQ0VfTk9UX0ZPVU5EOyAvKiA/ICovCgogICAgaWYgKCFiaW5kLT5FbmRwb2ludCB8fCAhYmluZC0+RW5kcG9pbnRbMF0pCiAgICB7CiAgICAgIFRSQUNFKCJhdXRvbWF0aWNhbGx5IHJlc29sdmluZyBwYXJ0aWFsbHkgYm91bmQgYmluZGluZ1xuIik7CiAgICAgIHN0YXR1cyA9IFJwY0VwUmVzb2x2ZUJpbmRpbmcoYmluZCwgY2lmKTsKICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgcmV0dXJuIHN0YXR1czsKICAgIH0KCiAgICBzdGF0dXMgPSBSUENSVDRfT3BlbkJpbmRpbmcoYmluZCwgJmNvbm4sICZjaWYtPlRyYW5zZmVyU3ludGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaWYtPkludGVyZmFjZUlkKTsKICB9CgogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHJldHVybiBzdGF0dXM7CgogIGlmIChiaW5kLT5zZXJ2ZXIpIHsKICAgIGlmIChwTXNnLT5ScGNGbGFncyAmIFdJTkVfUlBDRkxBR19FWENFUFRJT04pIHsKICAgICAgaGRyID0gUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIocE1zZy0+RGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfU19DQUxMX0ZBSUxFRCk7CiAgICB9IGVsc2UgewogICAgICBoZHIgPSBSUENSVDRfQnVpbGRSZXNwb25zZUhlYWRlcihwTXNnLT5EYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNc2ctPkJ1ZmZlckxlbmd0aCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGhkciA9IFJQQ1JUNF9CdWlsZFJlcXVlc3RIZWFkZXIocE1zZy0+RGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTXNnLT5CdWZmZXJMZW5ndGgsIHBNc2ctPlByb2NOdW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZiaW5kLT5PYmplY3RVdWlkKTsKICB9CgogIHN0YXR1cyA9IFJQQ1JUNF9TZW5kKGNvbm4sIGhkciwgcE1zZy0+QnVmZmVyLCBwTXNnLT5CdWZmZXJMZW5ndGgpOwoKICBSUENSVDRfRnJlZUhlYWRlcihoZHIpOwoKICAvKiBzdWNjZXNzICovCiAgaWYgKCFiaW5kLT5zZXJ2ZXIpIHsKICAgIC8qIHNhdmUgdGhlIGNvbm5lY3Rpb24sIHNvIHRoZSByZXNwb25zZSBjYW4gYmUgcmVhZCBmcm9tIGl0ICovCiAgICBwTXNnLT5SZXNlcnZlZEZvclJ1bnRpbWUgPSBjb25uOwogICAgcmV0dXJuIFJQQ19TX09LOwogIH0KICBSUENSVDRfQ2xvc2VCaW5kaW5nKGJpbmQsIGNvbm4pOwogIHN0YXR1cyA9IFJQQ19TX09LOwoKICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElfUnBjUmVjZWl2ZSBbUlBDUlQ0LkBdCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY1JlY2VpdmUoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKXBNc2ctPkhhbmRsZTsKICBScGNDb25uZWN0aW9uKiBjb25uOwogIFJQQ19DTElFTlRfSU5URVJGQUNFKiBjaWYgPSBOVUxMOwogIFJQQ19TRVJWRVJfSU5URVJGQUNFKiBzaWYgPSBOVUxMOwogIFJQQ19TVEFUVVMgc3RhdHVzOwogIFJwY1BrdEhkciAqaGRyID0gTlVMTDsKCiAgVFJBQ0UoIiglcClcbiIsIHBNc2cpOwogIGlmICghYmluZCkgcmV0dXJuIFJQQ19TX0lOVkFMSURfQklORElORzsKCiAgaWYgKHBNc2ctPlJlc2VydmVkRm9yUnVudGltZSkgewogICAgY29ubiA9IHBNc2ctPlJlc2VydmVkRm9yUnVudGltZTsKICAgIHBNc2ctPlJlc2VydmVkRm9yUnVudGltZSA9IE5VTEw7CiAgfSBlbHNlIHsKICAgIGlmIChiaW5kLT5zZXJ2ZXIpIHsKICAgICAgc2lmID0gcE1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb247CiAgICAgIGlmICghc2lmKSByZXR1cm4gUlBDX1NfSU5URVJGQUNFX05PVF9GT1VORDsgLyogPyAqLwogICAgICBzdGF0dXMgPSBSUENSVDRfT3BlbkJpbmRpbmcoYmluZCwgJmNvbm4sICZzaWYtPlRyYW5zZmVyU3ludGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnNpZi0+SW50ZXJmYWNlSWQpOwogICAgfSBlbHNlIHsKICAgICAgY2lmID0gcE1zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb247CiAgICAgIGlmICghY2lmKSByZXR1cm4gUlBDX1NfSU5URVJGQUNFX05PVF9GT1VORDsgLyogPyAqLwoKICAgICAgaWYgKCFiaW5kLT5FbmRwb2ludCB8fCAhYmluZC0+RW5kcG9pbnRbMF0pCiAgICAgIHsKICAgICAgICBUUkFDRSgiYXV0b21hdGljYWxseSByZXNvbHZpbmcgcGFydGlhbGx5IGJvdW5kIGJpbmRpbmdcbiIpOwogICAgICAgIHN0YXR1cyA9IFJwY0VwUmVzb2x2ZUJpbmRpbmcoYmluZCwgY2lmKTsKICAgICAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSByZXR1cm4gc3RhdHVzOwogICAgICB9CgogICAgICBzdGF0dXMgPSBSUENSVDRfT3BlbkJpbmRpbmcoYmluZCwgJmNvbm4sICZjaWYtPlRyYW5zZmVyU3ludGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmNpZi0+SW50ZXJmYWNlSWQpOwogICAgfQogICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgcmV0dXJuIHN0YXR1czsKICB9CgogIHN0YXR1cyA9IFJQQ1JUNF9SZWNlaXZlKGNvbm4sICZoZHIsIHBNc2cpOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHsKICAgIFdBUk4oInJlY2VpdmUgZmFpbGVkIHdpdGggZXJyb3IgJWx4XG4iLCBzdGF0dXMpOwogICAgZ290byBmYWlsOwogIH0KCiAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CgogIHN3aXRjaCAoaGRyLT5jb21tb24ucHR5cGUpIHsKICBjYXNlIFBLVF9SRVNQT05TRToKICAgIGlmIChiaW5kLT5zZXJ2ZXIpIGdvdG8gZmFpbDsKICAgIGJyZWFrOwogIGNhc2UgUEtUX1JFUVVFU1Q6CiAgICBpZiAoIWJpbmQtPnNlcnZlcikgZ290byBmYWlsOwogICAgYnJlYWs7CiAgY2FzZSBQS1RfRkFVTFQ6CiAgICBwTXNnLT5ScGNGbGFncyB8PSBXSU5FX1JQQ0ZMQUdfRVhDRVBUSU9OOwogICAgRVJSICgid2UgZ290IGZhdWx0IHBhY2tldCB3aXRoIHN0YXR1cyAlbHhcbiIsIGhkci0+ZmF1bHQuc3RhdHVzKTsKICAgIHN0YXR1cyA9IFJQQ19TX0NBTExfRkFJTEVEOyAvKiA/ICovCiAgICBnb3RvIGZhaWw7CiAgZGVmYXVsdDoKICAgIFdBUk4oImJhZCBwYWNrZXQgdHlwZSAlZFxuIiwgaGRyLT5jb21tb24ucHR5cGUpOwogICAgZ290byBmYWlsOwogIH0KCiAgLyogc3VjY2VzcyAqLwogIHN0YXR1cyA9IFJQQ19TX09LOwoKZmFpbDoKICBpZiAoaGRyKSB7CiAgICBSUENSVDRfRnJlZUhlYWRlcihoZHIpOwogIH0KICBSUENSVDRfQ2xvc2VCaW5kaW5nKGJpbmQsIGNvbm4pOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNTZW5kUmVjZWl2ZSBbUlBDUlQ0LkBdCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY1NlbmRSZWNlaXZlKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCIoJXApXG4iLCBwTXNnKTsKICBzdGF0dXMgPSBJX1JwY1NlbmQocE1zZyk7CiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgIHN0YXR1cyA9IElfUnBjUmVjZWl2ZShwTXNnKTsKICByZXR1cm4gc3RhdHVzOwp9Cg==