LyoKICogUlBDIG1lc3NhZ2VzCiAqCiAqIENvcHlyaWdodCAyMDAxLTIwMDIgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICogQ29weXJpZ2h0IDIwMDQgRmlsaXAgTmF2YXJhCiAqIENvcHlyaWdodCAyMDA2IENvZGVXZWF2ZXJzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgInJwY25kci5oIgojaW5jbHVkZSAicnBjZGNlcC5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlICJycGNfYmluZGluZy5oIgojaW5jbHVkZSAicnBjX21pc2MuaCIKI2luY2x1ZGUgInJwY19kZWZzLmgiCiNpbmNsdWRlICJycGNfbWVzc2FnZS5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocnBjKTsKCi8qIG5vdGU6IHRoZSBEQ0UvUlBDIHNwZWMgc2F5cyB0aGUgYWxpZ25tZW50IGFtb3VudCBzaG91bGQgYmUgNCwgYnV0CiAqIE1TL1JQQyBzZXJ2ZXJzIHNlZW0gdG8gYWx3YXlzIHVzZSAxNiAqLwojZGVmaW5lIEFVVEhfQUxJR05NRU5UIDE2CgovKiBnZXRzIHRoZSBhbW91bnQgbmVlZGVkIHRvIHJvdW5kIGEgdmFsdWUgdXAgdG8gdGhlIHNwZWNpZmllZCBhbGlnbm1lbnQgKi8KI2RlZmluZSBST1VORF9VUF9BTU9VTlQodmFsdWUsIGFsaWdubWVudCkgXAogICAgKCgoYWxpZ25tZW50KSAtICgoKHZhbHVlKSAlIChhbGlnbm1lbnQpKSkpICUgKGFsaWdubWVudCkpCgpzdGF0aWMgRFdPUkQgUlBDUlQ0X0dldEhlYWRlclNpemUoUnBjUGt0SGRyICpIZWFkZXIpCnsKICBzdGF0aWMgY29uc3QgRFdPUkQgaGVhZGVyX3NpemVzW10gPSB7CiAgICBzaXplb2YoSGVhZGVyLT5yZXF1ZXN0KSwgMCwgc2l6ZW9mKEhlYWRlci0+cmVzcG9uc2UpLAogICAgc2l6ZW9mKEhlYWRlci0+ZmF1bHQpLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCBzaXplb2YoSGVhZGVyLT5iaW5kKSwKICAgIHNpemVvZihIZWFkZXItPmJpbmRfYWNrKSwgc2l6ZW9mKEhlYWRlci0+YmluZF9uYWNrKSwKICAgIDAsIDAsIDAsIDAsIDAKICB9OwogIFVMT05HIHJldCA9IDA7CiAgCiAgaWYgKEhlYWRlci0+Y29tbW9uLnB0eXBlIDwgc2l6ZW9mKGhlYWRlcl9zaXplcykgLyBzaXplb2YoaGVhZGVyX3NpemVzWzBdKSkgewogICAgcmV0ID0gaGVhZGVyX3NpemVzW0hlYWRlci0+Y29tbW9uLnB0eXBlXTsKICAgIGlmIChyZXQgPT0gMCkKICAgICAgRklYTUUoInVuaGFuZGxlZCBwYWNrZXQgdHlwZVxuIik7CiAgICBpZiAoSGVhZGVyLT5jb21tb24uZmxhZ3MgJiBSUENfRkxHX09CSkVDVF9VVUlEKQogICAgICByZXQgKz0gc2l6ZW9mKFVVSUQpOwogIH0gZWxzZSB7CiAgICBUUkFDRSgiaW52YWxpZCBwYWNrZXQgdHlwZVxuIik7CiAgfQoKICByZXR1cm4gcmV0Owp9CgpzdGF0aWMgVk9JRCBSUENSVDRfQnVpbGRDb21tb25IZWFkZXIoUnBjUGt0SGRyICpIZWFkZXIsIHVuc2lnbmVkIGNoYXIgUGFja2V0VHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24pCnsKICBIZWFkZXItPmNvbW1vbi5ycGNfdmVyID0gUlBDX1ZFUl9NQUpPUjsKICBIZWFkZXItPmNvbW1vbi5ycGNfdmVyX21pbm9yID0gUlBDX1ZFUl9NSU5PUjsKICBIZWFkZXItPmNvbW1vbi5wdHlwZSA9IFBhY2tldFR5cGU7CiAgSGVhZGVyLT5jb21tb24uZHJlcFswXSA9IExPQllURShMT1dPUkQoRGF0YVJlcHJlc2VudGF0aW9uKSk7CiAgSGVhZGVyLT5jb21tb24uZHJlcFsxXSA9IEhJQllURShMT1dPUkQoRGF0YVJlcHJlc2VudGF0aW9uKSk7CiAgSGVhZGVyLT5jb21tb24uZHJlcFsyXSA9IExPQllURShISVdPUkQoRGF0YVJlcHJlc2VudGF0aW9uKSk7CiAgSGVhZGVyLT5jb21tb24uZHJlcFszXSA9IEhJQllURShISVdPUkQoRGF0YVJlcHJlc2VudGF0aW9uKSk7CiAgSGVhZGVyLT5jb21tb24uYXV0aF9sZW4gPSAwOwogIEhlYWRlci0+Y29tbW9uLmNhbGxfaWQgPSAxOwogIEhlYWRlci0+Y29tbW9uLmZsYWdzID0gMDsKICAvKiBGbGFncyBhbmQgZnJhZ21lbnQgbGVuZ3RoIGFyZSBjb21wdXRlZCBpbiBSUENSVDRfU2VuZC4gKi8KfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoKc3RhdGljIFJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkUmVxdWVzdEhlYWRlcih1bnNpZ25lZCBsb25nIERhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgQnVmZmVyTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgUHJvY051bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVVSUQgKk9iamVjdFV1aWQpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKICBCT09MIGhhc19vYmplY3Q7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIGhhc19vYmplY3QgPSAoT2JqZWN0VXVpZCAhPSBOVUxMICYmICFVdWlkSXNOaWwoT2JqZWN0VXVpZCwgJnN0YXR1cykpOwogIGhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICBzaXplb2YoaGVhZGVyLT5yZXF1ZXN0KSArIChoYXNfb2JqZWN0ID8gc2l6ZW9mKFVVSUQpIDogMCkpOwogIGlmIChoZWFkZXIgPT0gTlVMTCkgewogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBSUENSVDRfQnVpbGRDb21tb25IZWFkZXIoaGVhZGVyLCBQS1RfUkVRVUVTVCwgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHNpemVvZihoZWFkZXItPnJlcXVlc3QpOwogIGhlYWRlci0+cmVxdWVzdC5hbGxvY19oaW50ID0gQnVmZmVyTGVuZ3RoOwogIGhlYWRlci0+cmVxdWVzdC5jb250ZXh0X2lkID0gMDsKICBoZWFkZXItPnJlcXVlc3Qub3BudW0gPSBQcm9jTnVtOwogIGlmIChoYXNfb2JqZWN0KSB7CiAgICBoZWFkZXItPmNvbW1vbi5mbGFncyB8PSBSUENfRkxHX09CSkVDVF9VVUlEOwogICAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gKz0gc2l6ZW9mKFVVSUQpOwogICAgbWVtY3B5KCZoZWFkZXItPnJlcXVlc3QgKyAxLCBPYmplY3RVdWlkLCBzaXplb2YoVVVJRCkpOwogIH0KCiAgcmV0dXJuIGhlYWRlcjsKfQoKc3RhdGljIFJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkUmVzcG9uc2VIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBCdWZmZXJMZW5ndGgpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPnJlc3BvbnNlKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9SRVNQT05TRSwgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHNpemVvZihoZWFkZXItPnJlc3BvbnNlKTsKICBoZWFkZXItPnJlc3BvbnNlLmFsbG9jX2hpbnQgPSBCdWZmZXJMZW5ndGg7CgogIHJldHVybiBoZWFkZXI7Cn0KClJwY1BrdEhkciAqUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIodW5zaWduZWQgbG9uZyBEYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NUQVRVUyBTdGF0dXMpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPmZhdWx0KSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9GQVVMVCwgRGF0YVJlcHJlc2VudGF0aW9uKTsKICBoZWFkZXItPmNvbW1vbi5mcmFnX2xlbiA9IHNpemVvZihoZWFkZXItPmZhdWx0KTsKICBoZWFkZXItPmZhdWx0LnN0YXR1cyA9IFN0YXR1czsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRCaW5kSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgTWF4VHJhbnNtaXNzaW9uU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IE1heFJlY2VpdmVTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NZTlRBWF9JREVOVElGSUVSICpBYnN0cmFjdElkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX1NZTlRBWF9JREVOVElGSUVSICpUcmFuc2ZlcklkKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CgogIGhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoaGVhZGVyLT5iaW5kKSk7CiAgaWYgKGhlYWRlciA9PSBOVUxMKSB7CiAgICByZXR1cm4gTlVMTDsKICB9CgogIFJQQ1JUNF9CdWlsZENvbW1vbkhlYWRlcihoZWFkZXIsIFBLVF9CSU5ELCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+YmluZCk7CiAgaGVhZGVyLT5iaW5kLm1heF90c2l6ZSA9IE1heFRyYW5zbWlzc2lvblNpemU7CiAgaGVhZGVyLT5iaW5kLm1heF9yc2l6ZSA9IE1heFJlY2VpdmVTaXplOwogIGhlYWRlci0+YmluZC5udW1fZWxlbWVudHMgPSAxOwogIGhlYWRlci0+YmluZC5udW1fc3ludGF4ZXMgPSAxOwogIG1lbWNweSgmaGVhZGVyLT5iaW5kLmFic3RyYWN0LCBBYnN0cmFjdElkLCBzaXplb2YoUlBDX1NZTlRBWF9JREVOVElGSUVSKSk7CiAgbWVtY3B5KCZoZWFkZXItPmJpbmQudHJhbnNmZXIsIFRyYW5zZmVySWQsIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKTsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRBdXRoSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uKQp7CiAgUnBjUGt0SGRyICpoZWFkZXI7CgogIGhlYWRlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICBzaXplb2YoaGVhZGVyLT5jb21tb24pICsgMTIpOwogIGlmIChoZWFkZXIgPT0gTlVMTCkKICAgIHJldHVybiBOVUxMOwoKICBSUENSVDRfQnVpbGRDb21tb25IZWFkZXIoaGVhZGVyLCBQS1RfQVVUSDMsIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSAweDE0OwogIGhlYWRlci0+Y29tbW9uLmF1dGhfbGVuID0gMDsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRCaW5kTmFja0hlYWRlcih1bnNpZ25lZCBsb25nIERhdGFSZXByZXNlbnRhdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyIFJwY1ZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciBScGNWZXJzaW9uTWlub3IpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKCiAgaGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihoZWFkZXItPmJpbmRfbmFjaykpOwogIGlmIChoZWFkZXIgPT0gTlVMTCkgewogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBSUENSVDRfQnVpbGRDb21tb25IZWFkZXIoaGVhZGVyLCBQS1RfQklORF9OQUNLLCBEYXRhUmVwcmVzZW50YXRpb24pOwogIGhlYWRlci0+Y29tbW9uLmZyYWdfbGVuID0gc2l6ZW9mKGhlYWRlci0+YmluZF9uYWNrKTsKICBoZWFkZXItPmJpbmRfbmFjay5wcm90b2NvbHNfY291bnQgPSAxOwogIGhlYWRlci0+YmluZF9uYWNrLnByb3RvY29sc1swXS5ycGNfdmVyID0gUnBjVmVyc2lvbjsKICBoZWFkZXItPmJpbmRfbmFjay5wcm90b2NvbHNbMF0ucnBjX3Zlcl9taW5vciA9IFJwY1ZlcnNpb25NaW5vcjsKCiAgcmV0dXJuIGhlYWRlcjsKfQoKUnBjUGt0SGRyICpSUENSVDRfQnVpbGRCaW5kQWNrSGVhZGVyKHVuc2lnbmVkIGxvbmcgRGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgTWF4VHJhbnNtaXNzaW9uU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IE1heFJlY2VpdmVTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBTVFIgU2VydmVyQWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGxvbmcgUmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgbG9uZyBSZWFzb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfU1lOVEFYX0lERU5USUZJRVIgKlRyYW5zZmVySWQpCnsKICBScGNQa3RIZHIgKmhlYWRlcjsKICB1bnNpZ25lZCBsb25nIGhlYWRlcl9zaXplOwogIFJwY0FkZHJlc3NTdHJpbmcgKnNlcnZlcl9hZGRyZXNzOwogIFJwY1Jlc3VsdHMgKnJlc3VsdHM7CiAgUlBDX1NZTlRBWF9JREVOVElGSUVSICp0cmFuc2Zlcl9pZDsKCiAgaGVhZGVyX3NpemUgPSBzaXplb2YoaGVhZGVyLT5iaW5kX2FjaykgKyBzaXplb2YoUnBjUmVzdWx0cykgKwogICAgICAgICAgICAgICAgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikgKyBzaXplb2YoUnBjQWRkcmVzc1N0cmluZykgKwogICAgICAgICAgICAgICAgc3RybGVuKFNlcnZlckFkZHJlc3MpOwoKICBoZWFkZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgaGVhZGVyX3NpemUpOwogIGlmIChoZWFkZXIgPT0gTlVMTCkgewogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBSUENSVDRfQnVpbGRDb21tb25IZWFkZXIoaGVhZGVyLCBQS1RfQklORF9BQ0ssIERhdGFSZXByZXNlbnRhdGlvbik7CiAgaGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBoZWFkZXJfc2l6ZTsKICBoZWFkZXItPmJpbmRfYWNrLm1heF90c2l6ZSA9IE1heFRyYW5zbWlzc2lvblNpemU7CiAgaGVhZGVyLT5iaW5kX2Fjay5tYXhfcnNpemUgPSBNYXhSZWNlaXZlU2l6ZTsKICBzZXJ2ZXJfYWRkcmVzcyA9IChScGNBZGRyZXNzU3RyaW5nKikoJmhlYWRlci0+YmluZF9hY2sgKyAxKTsKICBzZXJ2ZXJfYWRkcmVzcy0+bGVuZ3RoID0gc3RybGVuKFNlcnZlckFkZHJlc3MpICsgMTsKICBzdHJjcHkoc2VydmVyX2FkZHJlc3MtPnN0cmluZywgU2VydmVyQWRkcmVzcyk7CiAgcmVzdWx0cyA9IChScGNSZXN1bHRzKikoKFVMT05HX1BUUilzZXJ2ZXJfYWRkcmVzcyArIHNpemVvZihScGNBZGRyZXNzU3RyaW5nKSArIHNlcnZlcl9hZGRyZXNzLT5sZW5ndGggLSAxKTsKICByZXN1bHRzLT5udW1fcmVzdWx0cyA9IDE7CiAgcmVzdWx0cy0+cmVzdWx0c1swXS5yZXN1bHQgPSBSZXN1bHQ7CiAgcmVzdWx0cy0+cmVzdWx0c1swXS5yZWFzb24gPSBSZWFzb247CiAgdHJhbnNmZXJfaWQgPSAoUlBDX1NZTlRBWF9JREVOVElGSUVSKikocmVzdWx0cyArIDEpOwogIG1lbWNweSh0cmFuc2Zlcl9pZCwgVHJhbnNmZXJJZCwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpOwoKICByZXR1cm4gaGVhZGVyOwp9CgpWT0lEIFJQQ1JUNF9GcmVlSGVhZGVyKFJwY1BrdEhkciAqSGVhZGVyKQp7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgSGVhZGVyKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfU2VuZEF1dGggKGludGVybmFsKQogKiAKICogVHJhbnNtaXQgYSBwYWNrZXQgd2l0aCBhdXRob3JpemF0aW9uIGRhdGEgb3ZlciBjb25uZWN0aW9uIGluIGFjY2VwdGFibGUgZnJhZ21lbnRzLgogKi8Kc3RhdGljIFJQQ19TVEFUVVMgUlBDUlQ0X1NlbmRBdXRoKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sIFJwY1BrdEhkciAqSGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQnVmZmVyLCB1bnNpZ25lZCBpbnQgQnVmZmVyTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqQXV0aCwgdW5zaWduZWQgaW50IEF1dGhMZW5ndGgpCnsKICBQVUNIQVIgYnVmZmVyX3BvczsKICBEV09SRCBoZHJfc2l6ZTsKICBMT05HIGNvdW50OwogIHVuc2lnbmVkIGNoYXIgKnBrdDsKICBMT05HIGFsZW4gPSBBdXRoTGVuZ3RoID8gKEF1dGhMZW5ndGggKyBzaXplb2YoUnBjQXV0aFZlcmlmaWVyKSkgOiAwOwoKICBidWZmZXJfcG9zID0gQnVmZmVyOwogIC8qIFRoZSBwYWNrZXQgYnVpbGRpbmcgZnVuY3Rpb25zIHNhdmUgdGhlIHBhY2tldCBoZWFkZXIgc2l6ZSwgc28gd2UgY2FuIHVzZSBpdC4gKi8KICBoZHJfc2l6ZSA9IEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuOwogIEhlYWRlci0+Y29tbW9uLmF1dGhfbGVuID0gQXV0aExlbmd0aDsKICBIZWFkZXItPmNvbW1vbi5mbGFncyB8PSBSUENfRkxHX0ZJUlNUOwogIEhlYWRlci0+Y29tbW9uLmZsYWdzICY9IH5SUENfRkxHX0xBU1Q7CiAgd2hpbGUgKCEoSGVhZGVyLT5jb21tb24uZmxhZ3MgJiBSUENfRkxHX0xBU1QpKSB7CiAgICB1bnNpZ25lZCBjaGFyIGF1dGhfcGFkX2xlbiA9IEF1dGhMZW5ndGggPyBST1VORF9VUF9BTU9VTlQoQnVmZmVyTGVuZ3RoLCBBVVRIX0FMSUdOTUVOVCkgOiAwOwogICAgdW5zaWduZWQgaW50IHBrdF9zaXplID0gQnVmZmVyTGVuZ3RoICsgaGRyX3NpemUgKyBhbGVuICsgYXV0aF9wYWRfbGVuOwoKICAgIC8qIGRlY2lkZSBpZiB3ZSBuZWVkIHRvIHNwbGl0IHRoZSBwYWNrZXQgaW50byBmcmFnbWVudHMgKi8KICAgaWYgKHBrdF9zaXplIDw9IENvbm5lY3Rpb24tPk1heFRyYW5zbWlzc2lvblNpemUpIHsKICAgICBIZWFkZXItPmNvbW1vbi5mbGFncyB8PSBSUENfRkxHX0xBU1Q7CiAgICAgSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPSBwa3Rfc2l6ZTsKICAgIH0gZWxzZSB7CiAgICAgIGF1dGhfcGFkX2xlbiA9IDA7CiAgICAgIC8qIG1ha2Ugc3VyZSBwYWNrZXQgcGF5bG9hZCB3aWxsIGJlIGEgbXVsdGlwbGUgb2YgMTYgKi8KICAgICAgSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gPQogICAgICAgICgoQ29ubmVjdGlvbi0+TWF4VHJhbnNtaXNzaW9uU2l6ZSAtIGhkcl9zaXplIC0gYWxlbikgJiB+KEFVVEhfQUxJR05NRU5ULTEpKSArCiAgICAgICAgaGRyX3NpemUgKyBhbGVuOwogICAgfQoKICAgIHBrdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbik7CgogICAgbWVtY3B5KHBrdCwgSGVhZGVyLCBoZHJfc2l6ZSk7CgogICAgLyogZnJhZ21lbnQgY29uc2lzdGVkIG9mIGhlYWRlciBvbmx5IGFuZCBpcyB0aGUgbGFzdCBvbmUgKi8KICAgIGlmIChoZHJfc2l6ZSA9PSBIZWFkZXItPmNvbW1vbi5mcmFnX2xlbikKICAgICAgZ290byB3cml0ZTsKCiAgICBtZW1jcHkocGt0ICsgaGRyX3NpemUsIGJ1ZmZlcl9wb3MsIEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuIC0gaGRyX3NpemUgLSBhdXRoX3BhZF9sZW4gLSBhbGVuKTsKCiAgICAvKiBhZGQgdGhlIGF1dGhvcml6YXRpb24gaW5mbyAqLwogICAgaWYgKENvbm5lY3Rpb24tPkF1dGhJbmZvICYmIEF1dGhMZW5ndGgpCiAgICB7CiAgICAgIFJwY0F1dGhWZXJpZmllciAqYXV0aF9oZHIgPSAoUnBjQXV0aFZlcmlmaWVyICopJnBrdFtIZWFkZXItPmNvbW1vbi5mcmFnX2xlbiAtIGFsZW5dOwoKICAgICAgYXV0aF9oZHItPmF1dGhfdHlwZSA9IENvbm5lY3Rpb24tPkF1dGhJbmZvLT5BdXRoblN2YzsKICAgICAgYXV0aF9oZHItPmF1dGhfbGV2ZWwgPSBDb25uZWN0aW9uLT5BdXRoSW5mby0+QXV0aG5MZXZlbDsKICAgICAgYXV0aF9oZHItPmF1dGhfcGFkX2xlbmd0aCA9IGF1dGhfcGFkX2xlbjsKICAgICAgYXV0aF9oZHItPmF1dGhfcmVzZXJ2ZWQgPSAwOwogICAgICAvKiBhIHVuaXF1ZSBudW1iZXIuLi4gKi8KICAgICAgYXV0aF9oZHItPmF1dGhfY29udGV4dF9pZCA9ICh1bnNpZ25lZCBsb25nKUNvbm5lY3Rpb247CgogICAgICBtZW1jcHkoYXV0aF9oZHIgKyAxLCBBdXRoLCBBdXRoTGVuZ3RoKTsKICAgIH0KCndyaXRlOgogICAgY291bnQgPSBycGNydDRfY29ubl93cml0ZShDb25uZWN0aW9uLCBwa3QsIEhlYWRlci0+Y29tbW9uLmZyYWdfbGVuKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBrdCk7CiAgICBpZiAoY291bnQ8MCkgewogICAgICBXQVJOKCJycGNydDRfY29ubl93cml0ZSBmYWlsZWQgKGF1dGgpXG4iKTsKICAgICAgcmV0dXJuIFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgfQoKICAgIGJ1ZmZlcl9wb3MgKz0gSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gLSBoZHJfc2l6ZSAtIGFsZW4gLSBhdXRoX3BhZF9sZW47CiAgICBCdWZmZXJMZW5ndGggLT0gSGVhZGVyLT5jb21tb24uZnJhZ19sZW4gLSBoZHJfc2l6ZSAtIGFsZW4gLSBhdXRoX3BhZF9sZW47CiAgICBIZWFkZXItPmNvbW1vbi5mbGFncyAmPSB+UlBDX0ZMR19GSVJTVDsKICB9CgogIHJldHVybiBSUENfU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfQXV0aE5lZ290aWF0ZSAoaW50ZXJuYWwpCiAqLwpzdGF0aWMgdm9pZCBSUENSVDRfQXV0aE5lZ290aWF0ZShScGNDb25uZWN0aW9uICpjb25uLCBTZWNCdWZmZXIgKm91dCkKewogIFNFQ1VSSVRZX1NUQVRVUyByOwogIFNlY0J1ZmZlckRlc2Mgb3V0X2Rlc2M7CiAgdW5zaWduZWQgY2hhciAqYnVmZmVyOwoKICBidWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgMHgxMDApOwoKICBvdXQtPkJ1ZmZlclR5cGUgPSBTRUNCVUZGRVJfVE9LRU47CiAgb3V0LT5jYkJ1ZmZlciA9IDB4MTAwOwogIG91dC0+cHZCdWZmZXIgPSBidWZmZXI7CgogIG91dF9kZXNjLnVsVmVyc2lvbiA9IDA7CiAgb3V0X2Rlc2MuY0J1ZmZlcnMgPSAxOwogIG91dF9kZXNjLnBCdWZmZXJzID0gb3V0OwoKICBjb25uLT5hdHRyID0gMDsKICBjb25uLT5jdHguZHdMb3dlciA9IDA7CiAgY29ubi0+Y3R4LmR3VXBwZXIgPSAwOwoKICByID0gSW5pdGlhbGl6ZVNlY3VyaXR5Q29udGV4dEEoJmNvbm4tPkF1dGhJbmZvLT5jcmVkLCBOVUxMLCBOVUxMLAogICAgICAgIElTQ19SRVFfQ09OTkVDVElPTiB8IElTQ19SRVFfVVNFX0RDRV9TVFlMRSB8IElTQ19SRVFfTVVUVUFMX0FVVEggfAogICAgICAgIElTQ19SRVFfREVMRUdBVEUsIDAsIFNFQ1VSSVRZX05FVFdPUktfRFJFUCwKICAgICAgICBOVUxMLCAwLCAmY29ubi0+Y3R4LCAmb3V0X2Rlc2MsICZjb25uLT5hdHRyLCAmY29ubi0+ZXhwKTsKCiAgVFJBQ0UoInIgPSAlMDhseCBjYkJ1ZmZlciA9ICVsZCBhdHRyID0gJTA4bHhcbiIsIHIsIG91dC0+Y2JCdWZmZXIsIGNvbm4tPmF0dHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIFJQQ1JUNF9BdXRob3JpemVCaW5kaW5nIChpbnRlcm5hbCkKICovCnN0YXRpYyBSUENfU1RBVFVTIFJQQ1JUX0F1dGhvcml6ZUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogY29ubiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCWVRFICpjaGFsbGVuZ2UsIFVMT05HIGNvdW50KQp7CiAgU2VjQnVmZmVyRGVzYyBpbnBfZGVzYywgb3V0X2Rlc2M7CiAgU2VjQnVmZmVyIGlucCwgb3V0OwogIFNFQ1VSSVRZX1NUQVRVUyByOwogIHVuc2lnbmVkIGNoYXIgYnVmZmVyWzB4MTAwXTsKICBScGNQa3RIZHIgKnJlc3BfaGRyOwogIFJQQ19TVEFUVVMgc3RhdHVzOwoKICBUUkFDRSgiY2hhbGxlbmdlICVzLCAlbGQgYnl0ZXNcbiIsIGNoYWxsZW5nZSwgY291bnQpOwoKICBvdXQuQnVmZmVyVHlwZSA9IFNFQ0JVRkZFUl9UT0tFTjsKICBvdXQuY2JCdWZmZXIgPSBzaXplb2YgYnVmZmVyOwogIG91dC5wdkJ1ZmZlciA9IGJ1ZmZlcjsKCiAgb3V0X2Rlc2MudWxWZXJzaW9uID0gMDsKICBvdXRfZGVzYy5jQnVmZmVycyA9IDE7CiAgb3V0X2Rlc2MucEJ1ZmZlcnMgPSAmb3V0OwoKICBpbnAuQnVmZmVyVHlwZSA9IFNFQ0JVRkZFUl9UT0tFTjsKICBpbnAucHZCdWZmZXIgPSBjaGFsbGVuZ2U7CiAgaW5wLmNiQnVmZmVyID0gY291bnQ7CgogIGlucF9kZXNjLmNCdWZmZXJzID0gMTsKICBpbnBfZGVzYy5wQnVmZmVycyA9ICZpbnA7CiAgaW5wX2Rlc2MudWxWZXJzaW9uID0gMDsKCiAgciA9IEluaXRpYWxpemVTZWN1cml0eUNvbnRleHRBKCZjb25uLT5BdXRoSW5mby0+Y3JlZCwgJmNvbm4tPmN0eCwgTlVMTCwKICAgICAgICBJU0NfUkVRX0NPTk5FQ1RJT04gfCBJU0NfUkVRX1VTRV9EQ0VfU1RZTEUgfCBJU0NfUkVRX01VVFVBTF9BVVRIIHwKICAgICAgICBJU0NfUkVRX0RFTEVHQVRFLCAwLCBTRUNVUklUWV9ORVRXT1JLX0RSRVAsCiAgICAgICAgJmlucF9kZXNjLCAwLCAmY29ubi0+Y3R4LCAmb3V0X2Rlc2MsICZjb25uLT5hdHRyLCAmY29ubi0+ZXhwKTsKICBpZiAocikKICB7CiAgICBXQVJOKCJJbml0aWFsaXplU2VjdXJpdHlDb250ZXh0IGZhaWxlZCB3aXRoIGVycm9yIDB4JTA4bHhcbiIsIHIpOwogICAgcmV0dXJuIEVSUk9SX0FDQ0VTU19ERU5JRUQ7CiAgfQoKICByZXNwX2hkciA9IFJQQ1JUNF9CdWlsZEF1dGhIZWFkZXIoTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04pOwogIGlmICghcmVzcF9oZHIpCiAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgc3RhdHVzID0gUlBDUlQ0X1NlbmRBdXRoKGNvbm4sIHJlc3BfaGRyLCBOVUxMLCAwLCBvdXQucHZCdWZmZXIsIG91dC5jYkJ1ZmZlcik7CgogIFJQQ1JUNF9GcmVlSGVhZGVyKHJlc3BfaGRyKTsKCiAgcmV0dXJuIHN0YXR1czsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICBSUENSVDRfU2VuZCAoaW50ZXJuYWwpCiAqIAogKiBUcmFuc21pdCBhIHBhY2tldCBvdmVyIGNvbm5lY3Rpb24gaW4gYWNjZXB0YWJsZSBmcmFnbWVudHMuCiAqLwpSUENfU1RBVFVTIFJQQ1JUNF9TZW5kKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sIFJwY1BrdEhkciAqSGVhZGVyLAogICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKkJ1ZmZlciwgdW5zaWduZWQgaW50IEJ1ZmZlckxlbmd0aCkKewogIFJQQ19TVEFUVVMgcjsKICBTZWNCdWZmZXIgb3V0OwoKICAvKiBpZiB3ZSd2ZSBhbHJlYWR5IGF1dGhlbnRpY2F0ZWQsIGp1c3Qgc2VuZCB0aGUgY29udGV4dCAqLwogIGlmIChDb25uZWN0aW9uLT5jdHguZHdVcHBlciB8fCBDb25uZWN0aW9uLT5jdHguZHdMb3dlcikKICB7CiAgICB1bnNpZ25lZCBjaGFyIGJ1ZmZlclsweDEwXTsKCiAgICBtZW1zZXQoYnVmZmVyLCAwLCBzaXplb2YgYnVmZmVyKTsKICAgIGJ1ZmZlclswXSA9IDE7IC8qIHZlcnNpb24gbnVtYmVyIGxzYiAqLwoKICAgIHJldHVybiBSUENSVDRfU2VuZEF1dGgoQ29ubmVjdGlvbiwgSGVhZGVyLCBCdWZmZXIsIEJ1ZmZlckxlbmd0aCwgYnVmZmVyLCBzaXplb2YgYnVmZmVyKTsKICB9CgogIGlmICghQ29ubmVjdGlvbi0+QXV0aEluZm8gfHwKICAgICAgQ29ubmVjdGlvbi0+QXV0aEluZm8tPkF1dGhuTGV2ZWwgPT0gUlBDX0NfQVVUSE5fTEVWRUxfREVGQVVMVCB8fAogICAgICBDb25uZWN0aW9uLT5BdXRoSW5mby0+QXV0aG5MZXZlbCA9PSBSUENfQ19BVVRITl9MRVZFTF9OT05FKQogIHsKICAgIHJldHVybiBSUENSVDRfU2VuZEF1dGgoQ29ubmVjdGlvbiwgSGVhZGVyLCBCdWZmZXIsIEJ1ZmZlckxlbmd0aCwgTlVMTCwgMCk7CiAgfQoKICBvdXQuQnVmZmVyVHlwZSA9IFNFQ0JVRkZFUl9UT0tFTjsKICBvdXQuY2JCdWZmZXIgPSAwOwogIG91dC5wdkJ1ZmZlciA9IE5VTEw7CgogIC8qIHRhY2sgb24gYSBuZWdvdGlhdGUgcGFja2V0ICovCiAgUlBDUlQ0X0F1dGhOZWdvdGlhdGUoQ29ubmVjdGlvbiwgJm91dCk7CiAgciA9IFJQQ1JUNF9TZW5kQXV0aChDb25uZWN0aW9uLCBIZWFkZXIsIEJ1ZmZlciwgQnVmZmVyTGVuZ3RoLCBvdXQucHZCdWZmZXIsIG91dC5jYkJ1ZmZlcik7CiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb3V0LnB2QnVmZmVyKTsKCiAgcmV0dXJuIHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgUlBDUlQ0X1JlY2VpdmUgKGludGVybmFsKQogKiAKICogUmVjZWl2ZSBhIHBhY2tldCBmcm9tIGNvbm5lY3Rpb24gYW5kIG1lcmdlIHRoZSBmcmFnbWVudHMuCiAqLwpSUENfU1RBVFVTIFJQQ1JUNF9SZWNlaXZlKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sIFJwY1BrdEhkciAqKkhlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICBQUlBDX01FU1NBR0UgcE1zZykKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIERXT1JEIGhkcl9sZW5ndGg7CiAgTE9ORyBkd1JlYWQ7CiAgdW5zaWduZWQgc2hvcnQgZmlyc3RfZmxhZzsKICB1bnNpZ25lZCBsb25nIGRhdGFfbGVuZ3RoOwogIHVuc2lnbmVkIGxvbmcgYnVmZmVyX2xlbmd0aDsKICB1bnNpZ25lZCBjaGFyICpidWZmZXJfcHRyOwogIFJwY1BrdENvbW1vbkhkciBjb21tb25faGRyOwoKICAqSGVhZGVyID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwgJXAsICVwKVxuIiwgQ29ubmVjdGlvbiwgSGVhZGVyLCBwTXNnKTsKCiAgLyogcmVhZCBwYWNrZXQgY29tbW9uIGhlYWRlciAqLwogIGR3UmVhZCA9IHJwY3J0NF9jb25uX3JlYWQoQ29ubmVjdGlvbiwgJmNvbW1vbl9oZHIsIHNpemVvZihjb21tb25faGRyKSk7CiAgaWYgKGR3UmVhZCAhPSBzaXplb2YoY29tbW9uX2hkcikpIHsKICAgIFdBUk4oIlNob3J0IHJlYWQgb2YgaGVhZGVyLCAlbGQgYnl0ZXNcbiIsIGR3UmVhZCk7CiAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgIGdvdG8gZmFpbDsKICB9CgogIC8qIHZlcmlmeSBpZiB0aGUgaGVhZGVyIHJlYWxseSBtYWtlcyBzZW5zZSAqLwogIGlmIChjb21tb25faGRyLnJwY192ZXIgIT0gUlBDX1ZFUl9NQUpPUiB8fAogICAgICBjb21tb25faGRyLnJwY192ZXJfbWlub3IgIT0gUlBDX1ZFUl9NSU5PUikgewogICAgV0FSTigidW5oYW5kbGVkIHBhY2tldCB2ZXJzaW9uXG4iKTsKICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgZ290byBmYWlsOwogIH0KCiAgaGRyX2xlbmd0aCA9IFJQQ1JUNF9HZXRIZWFkZXJTaXplKChScGNQa3RIZHIqKSZjb21tb25faGRyKTsKICBpZiAoaGRyX2xlbmd0aCA9PSAwKSB7CiAgICBXQVJOKCJoZWFkZXIgbGVuZ3RoID09IDBcbiIpOwogICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICBnb3RvIGZhaWw7CiAgfQoKICAqSGVhZGVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGhkcl9sZW5ndGgpOwogIG1lbWNweSgqSGVhZGVyLCAmY29tbW9uX2hkciwgc2l6ZW9mKGNvbW1vbl9oZHIpKTsKCiAgLyogcmVhZCB0aGUgcmVzdCBvZiBwYWNrZXQgaGVhZGVyICovCiAgZHdSZWFkID0gcnBjcnQ0X2Nvbm5fcmVhZChDb25uZWN0aW9uLCAmKCpIZWFkZXIpLT5jb21tb24gKyAxLCBoZHJfbGVuZ3RoIC0gc2l6ZW9mKGNvbW1vbl9oZHIpKTsKICBpZiAoZHdSZWFkICE9IGhkcl9sZW5ndGggLSBzaXplb2YoY29tbW9uX2hkcikpIHsKICAgIFdBUk4oImJhZCBoZWFkZXIgbGVuZ3RoLCAlbGQvJWxkIGJ5dGVzXG4iLCBkd1JlYWQsIGhkcl9sZW5ndGggLSBzaXplb2YoY29tbW9uX2hkcikpOwogICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICBnb3RvIGZhaWw7CiAgfQoKICAvKiByZWFkIHBhY2tldCBib2R5ICovCiAgc3dpdGNoIChjb21tb25faGRyLnB0eXBlKSB7CiAgY2FzZSBQS1RfUkVTUE9OU0U6CiAgICBwTXNnLT5CdWZmZXJMZW5ndGggPSAoKkhlYWRlciktPnJlc3BvbnNlLmFsbG9jX2hpbnQ7CiAgICBicmVhazsKICBjYXNlIFBLVF9SRVFVRVNUOgogICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gKCpIZWFkZXIpLT5yZXF1ZXN0LmFsbG9jX2hpbnQ7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgcE1zZy0+QnVmZmVyTGVuZ3RoID0gY29tbW9uX2hkci5mcmFnX2xlbiAtIGhkcl9sZW5ndGg7CiAgfQoKICBUUkFDRSgiYnVmZmVyIGxlbmd0aCA9ICV1XG4iLCBwTXNnLT5CdWZmZXJMZW5ndGgpOwoKICBzdGF0dXMgPSBJX1JwY0dldEJ1ZmZlcihwTXNnKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSBnb3RvIGZhaWw7CgogIGZpcnN0X2ZsYWcgPSBSUENfRkxHX0ZJUlNUOwogIGJ1ZmZlcl9sZW5ndGggPSAwOwogIGJ1ZmZlcl9wdHIgPSBwTXNnLT5CdWZmZXI7CiAgd2hpbGUgKGJ1ZmZlcl9sZW5ndGggPCBwTXNnLT5CdWZmZXJMZW5ndGgpCiAgewogICAgZGF0YV9sZW5ndGggPSAoKkhlYWRlciktPmNvbW1vbi5mcmFnX2xlbiAtIGhkcl9sZW5ndGg7CiAgICBpZiAoKCgqSGVhZGVyKS0+Y29tbW9uLmZsYWdzICYgUlBDX0ZMR19GSVJTVCkgIT0gZmlyc3RfZmxhZyB8fAogICAgICAgIGRhdGFfbGVuZ3RoICsgYnVmZmVyX2xlbmd0aCA+IHBNc2ctPkJ1ZmZlckxlbmd0aCkgewogICAgICBUUkFDRSgiaW52YWxpZCBwYWNrZXQgZmxhZ3Mgb3IgYnVmZmVyIGxlbmd0aFxuIik7CiAgICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgICBnb3RvIGZhaWw7CiAgICB9CgogICAgaWYgKGRhdGFfbGVuZ3RoID09IDApIGR3UmVhZCA9IDA7IGVsc2UKICAgIGR3UmVhZCA9IHJwY3J0NF9jb25uX3JlYWQoQ29ubmVjdGlvbiwgYnVmZmVyX3B0ciwgZGF0YV9sZW5ndGgpOwogICAgaWYgKGR3UmVhZCAhPSBkYXRhX2xlbmd0aCkgewogICAgICBXQVJOKCJiYWQgZGF0YSBsZW5ndGgsICVsZC8lbGRcbiIsIGR3UmVhZCwgZGF0YV9sZW5ndGgpOwogICAgICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKICAgICAgZ290byBmYWlsOwogICAgfQoKICAgIC8qIHdoZW4gdGhlcmUgaXMgbm8gbW9yZSBkYXRhIGxlZnQsIGl0IHNob3VsZCBiZSB0aGUgbGFzdCBwYWNrZXQgKi8KICAgIGlmIChidWZmZXJfbGVuZ3RoID09IHBNc2ctPkJ1ZmZlckxlbmd0aCAmJgogICAgICAgICgoKkhlYWRlciktPmNvbW1vbi5mbGFncyAmIFJQQ19GTEdfTEFTVCkgPT0gMCkgewogICAgICBXQVJOKCJubyBtb3JlIGRhdGEgbGVmdCwgYnV0IG5vdCBsYXN0IHBhY2tldFxuIik7CiAgICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgICBnb3RvIGZhaWw7CiAgICB9CgogICAgYnVmZmVyX2xlbmd0aCArPSBkYXRhX2xlbmd0aDsKICAgIGlmIChidWZmZXJfbGVuZ3RoIDwgcE1zZy0+QnVmZmVyTGVuZ3RoKSB7CiAgICAgIFRSQUNFKCJuZXh0IGhlYWRlclxuIik7CgogICAgICAvKiByZWFkIHRoZSBoZWFkZXIgb2YgbmV4dCBwYWNrZXQgKi8KICAgICAgZHdSZWFkID0gcnBjcnQ0X2Nvbm5fcmVhZChDb25uZWN0aW9uLCAqSGVhZGVyLCBoZHJfbGVuZ3RoKTsKICAgICAgaWYgKGR3UmVhZCAhPSBoZHJfbGVuZ3RoKSB7CiAgICAgICAgV0FSTigiaW52YWxpZCBwYWNrZXQgaGVhZGVyIHNpemUgKCVsZClcbiIsIGR3UmVhZCk7CiAgICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgICAgZ290byBmYWlsOwogICAgICB9CgogICAgICBidWZmZXJfcHRyICs9IGRhdGFfbGVuZ3RoOwogICAgICBmaXJzdF9mbGFnID0gMDsKICAgIH0KICB9CgogIC8qIHJlc3BvbmQgdG8gYXV0aG9yaXphdGlvbiByZXF1ZXN0ICovCiAgaWYgKGNvbW1vbl9oZHIucHR5cGUgPT0gUEtUX0JJTkRfQUNLICYmIGNvbW1vbl9oZHIuYXV0aF9sZW4gPiA4KQogIHsKICAgIHVuc2lnbmVkIGludCBvZmZzZXQ7CgogICAgb2Zmc2V0ID0gY29tbW9uX2hkci5mcmFnX2xlbiAtIGhkcl9sZW5ndGggLSBjb21tb25faGRyLmF1dGhfbGVuOwogICAgc3RhdHVzID0gUlBDUlRfQXV0aG9yaXplQ29ubmVjdGlvbihDb25uZWN0aW9uLCAoTFBCWVRFKXBNc2ctPkJ1ZmZlciArIG9mZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX2hkci5hdXRoX2xlbik7CiAgICBpZiAoc3RhdHVzKQogICAgICAgIGdvdG8gZmFpbDsKICB9CgogIC8qIHN1Y2Nlc3MgKi8KICBzdGF0dXMgPSBSUENfU19PSzsKCmZhaWw6CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSyAmJiAqSGVhZGVyKSB7CiAgICBSUENSVDRfRnJlZUhlYWRlcigqSGVhZGVyKTsKICAgICpIZWFkZXIgPSBOVUxMOwogIH0KICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElfUnBjR2V0QnVmZmVyIFtSUENSVDQuQF0KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjR2V0QnVmZmVyKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgVFJBQ0UoIiglcCk6IEJ1ZmZlckxlbmd0aD0lZFxuIiwgcE1zZywgcE1zZy0+QnVmZmVyTGVuZ3RoKTsKICAvKiBGSVhNRTogcGZuQWxsb2NhdGU/ICovCiAgcE1zZy0+QnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHBNc2ctPkJ1ZmZlckxlbmd0aCk7CgogIFRSQUNFKCJCdWZmZXI9JXBcbiIsIHBNc2ctPkJ1ZmZlcik7CiAgLyogRklYTUU6IHdoaWNoIGVycm9ycyB0byByZXR1cm4/ICovCiAgcmV0dXJuIHBNc2ctPkJ1ZmZlciA/IFNfT0sgOiBFX09VVE9GTUVNT1JZOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElfUnBjRnJlZUJ1ZmZlciBbUlBDUlQ0LkBdCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY0ZyZWVCdWZmZXIoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBUUkFDRSgiKCVwKSBCdWZmZXI9JXBcbiIsIHBNc2csIHBNc2ctPkJ1ZmZlcik7CiAgLyogRklYTUU6IHBmbkZyZWU/ICovCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcE1zZy0+QnVmZmVyKTsKICBwTXNnLT5CdWZmZXIgPSBOVUxMOwogIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIElfUnBjU2VuZCBbUlBDUlQ0LkBdCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY1NlbmQoUFJQQ19NRVNTQUdFIHBNc2cpCnsKICBScGNCaW5kaW5nKiBiaW5kID0gKFJwY0JpbmRpbmcqKXBNc2ctPkhhbmRsZTsKICBScGNDb25uZWN0aW9uKiBjb25uOwogIFJQQ19DTElFTlRfSU5URVJGQUNFKiBjaWYgPSBOVUxMOwogIFJQQ19TRVJWRVJfSU5URVJGQUNFKiBzaWYgPSBOVUxMOwogIFJQQ19TVEFUVVMgc3RhdHVzOwogIFJwY1BrdEhkciAqaGRyOwoKICBUUkFDRSgiKCVwKVxuIiwgcE1zZyk7CiAgaWYgKCFiaW5kKSByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwoKICBpZiAoYmluZC0+c2VydmVyKSB7CiAgICBzaWYgPSBwTXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbjsKICAgIGlmICghc2lmKSByZXR1cm4gUlBDX1NfSU5URVJGQUNFX05PVF9GT1VORDsgLyogPyAqLwogICAgc3RhdHVzID0gUlBDUlQ0X09wZW5CaW5kaW5nKGJpbmQsICZjb25uLCAmc2lmLT5UcmFuc2ZlclN5bnRheCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2lmLT5JbnRlcmZhY2VJZCk7CiAgfSBlbHNlIHsKICAgIGNpZiA9IHBNc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uOwogICAgaWYgKCFjaWYpIHJldHVybiBSUENfU19JTlRFUkZBQ0VfTk9UX0ZPVU5EOyAvKiA/ICovCgogICAgaWYgKCFiaW5kLT5FbmRwb2ludCB8fCAhYmluZC0+RW5kcG9pbnRbMF0pCiAgICB7CiAgICAgIFRSQUNFKCJhdXRvbWF0aWNhbGx5IHJlc29sdmluZyBwYXJ0aWFsbHkgYm91bmQgYmluZGluZ1xuIik7CiAgICAgIHN0YXR1cyA9IFJwY0VwUmVzb2x2ZUJpbmRpbmcoYmluZCwgY2lmKTsKICAgICAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgcmV0dXJuIHN0YXR1czsKICAgIH0KCiAgICBzdGF0dXMgPSBSUENSVDRfT3BlbkJpbmRpbmcoYmluZCwgJmNvbm4sICZjaWYtPlRyYW5zZmVyU3ludGF4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjaWYtPkludGVyZmFjZUlkKTsKICB9CgogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHJldHVybiBzdGF0dXM7CgogIGlmIChiaW5kLT5zZXJ2ZXIpIHsKICAgIGlmIChwTXNnLT5ScGNGbGFncyAmIFdJTkVfUlBDRkxBR19FWENFUFRJT04pIHsKICAgICAgaGRyID0gUlBDUlQ0X0J1aWxkRmF1bHRIZWFkZXIocE1zZy0+RGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfU19DQUxMX0ZBSUxFRCk7CiAgICB9IGVsc2UgewogICAgICBoZHIgPSBSUENSVDRfQnVpbGRSZXNwb25zZUhlYWRlcihwTXNnLT5EYXRhUmVwcmVzZW50YXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBNc2ctPkJ1ZmZlckxlbmd0aCk7CiAgICB9CiAgfSBlbHNlIHsKICAgIGhkciA9IFJQQ1JUNF9CdWlsZFJlcXVlc3RIZWFkZXIocE1zZy0+RGF0YVJlcHJlc2VudGF0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwTXNnLT5CdWZmZXJMZW5ndGgsIHBNc2ctPlByb2NOdW0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZiaW5kLT5PYmplY3RVdWlkKTsKICAgIGhkci0+Y29tbW9uLmNhbGxfaWQgPSBjb25uLT5OZXh0Q2FsbElkKys7CiAgfQoKICBzdGF0dXMgPSBSUENSVDRfU2VuZChjb25uLCBoZHIsIHBNc2ctPkJ1ZmZlciwgcE1zZy0+QnVmZmVyTGVuZ3RoKTsKCiAgUlBDUlQ0X0ZyZWVIZWFkZXIoaGRyKTsKCiAgLyogc3VjY2VzcyAqLwogIGlmICghYmluZC0+c2VydmVyKSB7CiAgICAvKiBzYXZlIHRoZSBjb25uZWN0aW9uLCBzbyB0aGUgcmVzcG9uc2UgY2FuIGJlIHJlYWQgZnJvbSBpdCAqLwogICAgcE1zZy0+UmVzZXJ2ZWRGb3JSdW50aW1lID0gY29ubjsKICAgIHJldHVybiBzdGF0dXM7CiAgfQogIFJQQ1JUNF9DbG9zZUJpbmRpbmcoYmluZCwgY29ubik7CgogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNSZWNlaXZlIFtSUENSVDQuQF0KICovClJQQ19TVEFUVVMgV0lOQVBJIElfUnBjUmVjZWl2ZShQUlBDX01FU1NBR0UgcE1zZykKewogIFJwY0JpbmRpbmcqIGJpbmQgPSAoUnBjQmluZGluZyopcE1zZy0+SGFuZGxlOwogIFJwY0Nvbm5lY3Rpb24qIGNvbm47CiAgUlBDX0NMSUVOVF9JTlRFUkZBQ0UqIGNpZiA9IE5VTEw7CiAgUlBDX1NFUlZFUl9JTlRFUkZBQ0UqIHNpZiA9IE5VTEw7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgUnBjUGt0SGRyICpoZHIgPSBOVUxMOwoKICBUUkFDRSgiKCVwKVxuIiwgcE1zZyk7CiAgaWYgKCFiaW5kKSByZXR1cm4gUlBDX1NfSU5WQUxJRF9CSU5ESU5HOwoKICBpZiAocE1zZy0+UmVzZXJ2ZWRGb3JSdW50aW1lKSB7CiAgICBjb25uID0gcE1zZy0+UmVzZXJ2ZWRGb3JSdW50aW1lOwogICAgcE1zZy0+UmVzZXJ2ZWRGb3JSdW50aW1lID0gTlVMTDsKICB9IGVsc2UgewogICAgaWYgKGJpbmQtPnNlcnZlcikgewogICAgICBzaWYgPSBwTXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbjsKICAgICAgaWYgKCFzaWYpIHJldHVybiBSUENfU19JTlRFUkZBQ0VfTk9UX0ZPVU5EOyAvKiA/ICovCiAgICAgIHN0YXR1cyA9IFJQQ1JUNF9PcGVuQmluZGluZyhiaW5kLCAmY29ubiwgJnNpZi0+VHJhbnNmZXJTeW50YXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc2lmLT5JbnRlcmZhY2VJZCk7CiAgICB9IGVsc2UgewogICAgICBjaWYgPSBwTXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbjsKICAgICAgaWYgKCFjaWYpIHJldHVybiBSUENfU19JTlRFUkZBQ0VfTk9UX0ZPVU5EOyAvKiA/ICovCgogICAgICBpZiAoIWJpbmQtPkVuZHBvaW50IHx8ICFiaW5kLT5FbmRwb2ludFswXSkKICAgICAgewogICAgICAgIFRSQUNFKCJhdXRvbWF0aWNhbGx5IHJlc29sdmluZyBwYXJ0aWFsbHkgYm91bmQgYmluZGluZ1xuIik7CiAgICAgICAgc3RhdHVzID0gUnBjRXBSZXNvbHZlQmluZGluZyhiaW5kLCBjaWYpOwogICAgICAgIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spIHJldHVybiBzdGF0dXM7CiAgICAgIH0KCiAgICAgIHN0YXR1cyA9IFJQQ1JUNF9PcGVuQmluZGluZyhiaW5kLCAmY29ubiwgJmNpZi0+VHJhbnNmZXJTeW50YXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY2lmLT5JbnRlcmZhY2VJZCk7CiAgICB9CiAgICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKSByZXR1cm4gc3RhdHVzOwogIH0KCiAgc3RhdHVzID0gUlBDUlQ0X1JlY2VpdmUoY29ubiwgJmhkciwgcE1zZyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykgewogICAgV0FSTigicmVjZWl2ZSBmYWlsZWQgd2l0aCBlcnJvciAlbHhcbiIsIHN0YXR1cyk7CiAgICBnb3RvIGZhaWw7CiAgfQoKICBzdGF0dXMgPSBSUENfU19QUk9UT0NPTF9FUlJPUjsKCiAgc3dpdGNoIChoZHItPmNvbW1vbi5wdHlwZSkgewogIGNhc2UgUEtUX1JFU1BPTlNFOgogICAgaWYgKGJpbmQtPnNlcnZlcikgZ290byBmYWlsOwogICAgYnJlYWs7CiAgY2FzZSBQS1RfUkVRVUVTVDoKICAgIGlmICghYmluZC0+c2VydmVyKSBnb3RvIGZhaWw7CiAgICBicmVhazsKICBjYXNlIFBLVF9GQVVMVDoKICAgIHBNc2ctPlJwY0ZsYWdzIHw9IFdJTkVfUlBDRkxBR19FWENFUFRJT047CiAgICBFUlIgKCJ3ZSBnb3QgZmF1bHQgcGFja2V0IHdpdGggc3RhdHVzIDB4JWx4XG4iLCBoZHItPmZhdWx0LnN0YXR1cyk7CiAgICBzdGF0dXMgPSBoZHItPmZhdWx0LnN0YXR1czsgLyogRklYTUU6IGRvIHRyYW5zbGF0aW9uIGZyb20gbmNhIGVycm9yIGNvZGVzICovCiAgICBnb3RvIGZhaWw7CiAgZGVmYXVsdDoKICAgIFdBUk4oImJhZCBwYWNrZXQgdHlwZSAlZFxuIiwgaGRyLT5jb21tb24ucHR5cGUpOwogICAgZ290byBmYWlsOwogIH0KCiAgLyogc3VjY2VzcyAqLwogIHN0YXR1cyA9IFJQQ19TX09LOwoKZmFpbDoKICBpZiAoaGRyKSB7CiAgICBSUENSVDRfRnJlZUhlYWRlcihoZHIpOwogIH0KICBSUENSVDRfQ2xvc2VCaW5kaW5nKGJpbmQsIGNvbm4pOwogIHJldHVybiBzdGF0dXM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgSV9ScGNTZW5kUmVjZWl2ZSBbUlBDUlQ0LkBdCiAqLwpSUENfU1RBVFVTIFdJTkFQSSBJX1JwY1NlbmRSZWNlaXZlKFBSUENfTUVTU0FHRSBwTXNnKQp7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCIoJXApXG4iLCBwTXNnKTsKICBzdGF0dXMgPSBJX1JwY1NlbmQocE1zZyk7CiAgaWYgKHN0YXR1cyA9PSBSUENfU19PSykKICAgIHN0YXR1cyA9IElfUnBjUmVjZWl2ZShwTXNnKTsKICByZXR1cm4gc3RhdHVzOwp9Cg==