LyoKICogUlBDIHRyYW5zcG9ydCBsYXllcgogKgogKiBDb3B5cmlnaHQgMjAwMSBPdmUgS+V2ZW4sIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcwogKiBDb3B5cmlnaHQgMjAwMyBNaWtlIEhlYXJuCiAqIENvcHlyaWdodCAyMDA0IEZpbGlwIE5hdmFyYQogKiBDb3B5cmlnaHQgMjAwNiBNaWtlIE1jQ29ybWFjawogKiBDb3B5cmlnaHQgMjAwNiBEYW1qYW4gSm92YW5vdmljCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8ZXJybm8uaD4KCiNpZmRlZiBIQVZFX1VOSVNURF9ICiMgaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZmRlZiBIQVZFX1NZU19TT0NLRVRfSAojIGluY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2VuZGlmCiNpZmRlZiBIQVZFX05FVElORVRfSU5fSAojIGluY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZmRlZiBIQVZFX05FVElORVRfVENQX0gKIyBpbmNsdWRlIDxuZXRpbmV0L3RjcC5oPgojZW5kaWYKI2lmZGVmIEhBVkVfQVJQQV9JTkVUX0gKIyBpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2VuZGlmCiNpZmRlZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaWZkZWYgSEFWRV9TWVNfUE9MTF9ICiNpbmNsdWRlIDxzeXMvcG9sbC5oPgojZW5kaWYKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnRlcm5sLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgInJwY25kci5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCiNpbmNsdWRlICJycGNfYmluZGluZy5oIgojaW5jbHVkZSAicnBjX21lc3NhZ2UuaCIKI2luY2x1ZGUgInJwY19zZXJ2ZXIuaCIKI2luY2x1ZGUgImVwbV90b3dlcnMuaCIKCiNpZm5kZWYgU09MX1RDUAojIGRlZmluZSBTT0xfVENQIElQUFJPVE9fVENQCiNlbmRpZgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocnBjKTsKCnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGFzc29jX2xpc3RfY3M7CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OX0RFQlVHIGFzc29jX2xpc3RfY3NfZGVidWcgPQp7CiAgICAwLCAwLCAmYXNzb2NfbGlzdF9jcywKICAgIHsgJmFzc29jX2xpc3RfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCwgJmFzc29jX2xpc3RfY3NfZGVidWcuUHJvY2Vzc0xvY2tzTGlzdCB9LAogICAgICAwLCAwLCB7IChEV09SRF9QVFIpKF9fRklMRV9fICI6IGFzc29jX2xpc3RfY3MiKSB9Cn07CnN0YXRpYyBDUklUSUNBTF9TRUNUSU9OIGFzc29jX2xpc3RfY3MgPSB7ICZhc3NvY19saXN0X2NzX2RlYnVnLCAtMSwgMCwgMCwgMCwgMCB9OwoKc3RhdGljIHN0cnVjdCBsaXN0IGFzc29jX2xpc3QgPSBMSVNUX0lOSVQoYXNzb2NfbGlzdCk7CgovKioqKiBuY2Fjbl9ucCBzdXBwb3J0ICoqKiovCgp0eXBlZGVmIHN0cnVjdCBfUnBjQ29ubmVjdGlvbl9ucAp7CiAgUnBjQ29ubmVjdGlvbiBjb21tb247CiAgSEFORExFIHBpcGU7CiAgT1ZFUkxBUFBFRCBvdmw7CiAgQk9PTCBsaXN0ZW5pbmc7Cn0gUnBjQ29ubmVjdGlvbl9ucDsKCnN0YXRpYyBScGNDb25uZWN0aW9uICpycGNydDRfY29ubl9ucF9hbGxvYyh2b2lkKQp7CiAgUnBjQ29ubmVjdGlvbl9ucCAqbnBjID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZihScGNDb25uZWN0aW9uX25wKSk7CiAgaWYgKG5wYykKICB7CiAgICBucGMtPnBpcGUgPSBOVUxMOwogICAgbWVtc2V0KCZucGMtPm92bCwgMCwgc2l6ZW9mKG5wYy0+b3ZsKSk7CiAgICBucGMtPmxpc3RlbmluZyA9IEZBTFNFOwogIH0KICByZXR1cm4gJm5wYy0+Y29tbW9uOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBycGNydDRfY29ubl9saXN0ZW5fcGlwZShScGNDb25uZWN0aW9uX25wICpucGMpCnsKICBpZiAobnBjLT5saXN0ZW5pbmcpCiAgICByZXR1cm4gUlBDX1NfT0s7CgogIG5wYy0+bGlzdGVuaW5nID0gVFJVRTsKICBpZiAoQ29ubmVjdE5hbWVkUGlwZShucGMtPnBpcGUsICZucGMtPm92bCkpCiAgICByZXR1cm4gUlBDX1NfT0s7CgogIGlmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9QSVBFX0NPTk5FQ1RFRCkgewogICAgU2V0RXZlbnQobnBjLT5vdmwuaEV2ZW50KTsKICAgIHJldHVybiBSUENfU19PSzsKICB9CiAgaWYgKEdldExhc3RFcnJvcigpID09IEVSUk9SX0lPX1BFTkRJTkcpIHsKICAgIC8qIHdpbGwgYmUgY29tcGxldGVkIGluIHJwY3J0NF9wcm90c2VxX25wX3dhaXRfZm9yX25ld19jb25uZWN0aW9uICovCiAgICByZXR1cm4gUlBDX1NfT0s7CiAgfQogIG5wYy0+bGlzdGVuaW5nID0gRkFMU0U7CiAgV0FSTigiQ291bGRuJ3QgQ29ubmVjdE5hbWVkUGlwZSAoZXJyb3Igd2FzICVkKVxuIiwgR2V0TGFzdEVycm9yKCkpOwogIHJldHVybiBSUENfU19PVVRfT0ZfUkVTT1VSQ0VTOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBycGNydDRfY29ubl9jcmVhdGVfcGlwZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLCBMUENTVFIgcG5hbWUpCnsKICBScGNDb25uZWN0aW9uX25wICpucGMgPSAoUnBjQ29ubmVjdGlvbl9ucCAqKSBDb25uZWN0aW9uOwogIFRSQUNFKCJsaXN0ZW5pbmcgb24gJXNcbiIsIHBuYW1lKTsKCiAgbnBjLT5waXBlID0gQ3JlYXRlTmFtZWRQaXBlQShwbmFtZSwgUElQRV9BQ0NFU1NfRFVQTEVYLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUElQRV9UWVBFX01FU1NBR0UgfCBQSVBFX1JFQURNT0RFX01FU1NBR0UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSVBFX1VOTElNSVRFRF9JTlNUQU5DRVMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSUENfTUFYX1BBQ0tFVF9TSVpFLCBSUENfTUFYX1BBQ0tFVF9TSVpFLCA1MDAwLCBOVUxMKTsKICBpZiAobnBjLT5waXBlID09IElOVkFMSURfSEFORExFX1ZBTFVFKSB7CiAgICBXQVJOKCJDcmVhdGVOYW1lZFBpcGUgZmFpbGVkIHdpdGggZXJyb3IgJWRcbiIsIEdldExhc3RFcnJvcigpKTsKICAgIGlmIChHZXRMYXN0RXJyb3IoKSA9PSBFUlJPUl9GSUxFX0VYSVNUUykKICAgICAgcmV0dXJuIFJQQ19TX0RVUExJQ0FURV9FTkRQT0lOVDsKICAgIGVsc2UKICAgICAgcmV0dXJuIFJQQ19TX0NBTlRfQ1JFQVRFX0VORFBPSU5UOwogIH0KCiAgbWVtc2V0KCZucGMtPm92bCwgMCwgc2l6ZW9mKG5wYy0+b3ZsKSk7CiAgbnBjLT5vdmwuaEV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKCiAgLyogTm90ZTogd2UgZG9uJ3QgY2FsbCBDb25uZWN0TmFtZWRQaXBlIGhlcmUgYmVjYXVzZSBpdCBtdXN0IGJlIGRvbmUgaW4gdGhlCiAgICogc2VydmVyIHRocmVhZCBhcyB0aGUgdGhyZWFkIG11c3QgYmUgYWxlcnRhYmxlICovCiAgcmV0dXJuIFJQQ19TX09LOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBycGNydDRfY29ubl9vcGVuX3BpcGUoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwgTFBDU1RSIHBuYW1lLCBCT09MIHdhaXQpCnsKICBScGNDb25uZWN0aW9uX25wICpucGMgPSAoUnBjQ29ubmVjdGlvbl9ucCAqKSBDb25uZWN0aW9uOwogIEhBTkRMRSBwaXBlOwogIERXT1JEIGVyciwgZHdNb2RlOwoKICBUUkFDRSgiY29ubmVjdGluZyB0byAlc1xuIiwgcG5hbWUpOwoKICB3aGlsZSAoVFJVRSkgewogICAgRFdPUkQgZHdGbGFncyA9IDA7CiAgICBpZiAoQ29ubmVjdGlvbi0+UU9TKQogICAgewogICAgICAgIGR3RmxhZ3MgPSBTRUNVUklUWV9TUU9TX1BSRVNFTlQ7CiAgICAgICAgc3dpdGNoIChDb25uZWN0aW9uLT5RT1MtPnFvcy0+SW1wZXJzb25hdGlvblR5cGUpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIFJQQ19DX0lNUF9MRVZFTF9ERUZBVUxUOgogICAgICAgICAgICAgICAgLyogRklYTUU6IHdoYXQgdG8gZG8gaGVyZT8gKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJQQ19DX0lNUF9MRVZFTF9BTk9OWU1PVVM6CiAgICAgICAgICAgICAgICBkd0ZsYWdzIHw9IFNFQ1VSSVRZX0FOT05ZTU9VUzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJQQ19DX0lNUF9MRVZFTF9JREVOVElGWToKICAgICAgICAgICAgICAgIGR3RmxhZ3MgfD0gU0VDVVJJVFlfSURFTlRJRklDQVRJT047CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSUENfQ19JTVBfTEVWRUxfSU1QRVJTT05BVEU6CiAgICAgICAgICAgICAgICBkd0ZsYWdzIHw9IFNFQ1VSSVRZX0lNUEVSU09OQVRJT047CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSUENfQ19JTVBfTEVWRUxfREVMRUdBVEU6CiAgICAgICAgICAgICAgICBkd0ZsYWdzIHw9IFNFQ1VSSVRZX0RFTEVHQVRJT047CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgaWYgKENvbm5lY3Rpb24tPlFPUy0+cW9zLT5JZGVudGl0eVRyYWNraW5nID09IFJQQ19DX1FPU19JREVOVElGWV9EWU5BTUlDKQogICAgICAgICAgICBkd0ZsYWdzIHw9IFNFQ1VSSVRZX0NPTlRFWFRfVFJBQ0tJTkc7CiAgICB9CiAgICBwaXBlID0gQ3JlYXRlRmlsZUEocG5hbWUsIEdFTkVSSUNfUkVBRHxHRU5FUklDX1dSSVRFLCAwLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgIE9QRU5fRVhJU1RJTkcsIGR3RmxhZ3MsIDApOwogICAgaWYgKHBpcGUgIT0gSU5WQUxJRF9IQU5ETEVfVkFMVUUpIGJyZWFrOwogICAgZXJyID0gR2V0TGFzdEVycm9yKCk7CiAgICBpZiAoZXJyID09IEVSUk9SX1BJUEVfQlVTWSkgewogICAgICBUUkFDRSgiY29ubmVjdGlvbiBmYWlsZWQsIGVycm9yPSV4XG4iLCBlcnIpOwogICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1RPT19CVVNZOwogICAgfQogICAgaWYgKCF3YWl0KQogICAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwogICAgaWYgKCFXYWl0TmFtZWRQaXBlQShwbmFtZSwgTk1QV0FJVF9XQUlUX0ZPUkVWRVIpKSB7CiAgICAgIGVyciA9IEdldExhc3RFcnJvcigpOwogICAgICBXQVJOKCJjb25uZWN0aW9uIGZhaWxlZCwgZXJyb3I9JXhcbiIsIGVycik7CiAgICAgIHJldHVybiBSUENfU19TRVJWRVJfVU5BVkFJTEFCTEU7CiAgICB9CiAgfQoKICAvKiBzdWNjZXNzICovCiAgbWVtc2V0KCZucGMtPm92bCwgMCwgc2l6ZW9mKG5wYy0+b3ZsKSk7CiAgLyogcGlwZSBpcyBjb25uZWN0ZWQ7IGNoYW5nZSB0byBtZXNzYWdlLXJlYWQgbW9kZS4gKi8KICBkd01vZGUgPSBQSVBFX1JFQURNT0RFX01FU1NBR0U7CiAgU2V0TmFtZWRQaXBlSGFuZGxlU3RhdGUocGlwZSwgJmR3TW9kZSwgTlVMTCwgTlVMTCk7CiAgbnBjLT5vdmwuaEV2ZW50ID0gQ3JlYXRlRXZlbnRXKE5VTEwsIFRSVUUsIEZBTFNFLCBOVUxMKTsKICBucGMtPnBpcGUgPSBwaXBlOwoKICByZXR1cm4gUlBDX1NfT0s7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIHJwY3J0NF9uY2FscnBjX29wZW4oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgc3RhdGljIGNvbnN0IGNoYXIgcHJlZml4W10gPSAiXFxcXC5cXHBpcGVcXGxycGNcXCI7CiAgUlBDX1NUQVRVUyByOwogIExQU1RSIHBuYW1lOwoKICAvKiBhbHJlYWR5IGNvbm5lY3RlZD8gKi8KICBpZiAobnBjLT5waXBlKQogICAgcmV0dXJuIFJQQ19TX09LOwoKICAvKiBwcm90c2VxPW5jYWxycGM6IHN1cHBvc2VkIHRvIHVzZSBOVCBMUEMgcG9ydHMsCiAgICogYnV0IHdlJ2xsIGltcGxlbWVudCBpdCB3aXRoIG5hbWVkIHBpcGVzIGZvciBub3cgKi8KICBwbmFtZSA9IElfUnBjQWxsb2NhdGUoc3RybGVuKHByZWZpeCkgKyBzdHJsZW4oQ29ubmVjdGlvbi0+RW5kcG9pbnQpICsgMSk7CiAgc3RyY2F0KHN0cmNweShwbmFtZSwgcHJlZml4KSwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIHIgPSBycGNydDRfY29ubl9vcGVuX3BpcGUoQ29ubmVjdGlvbiwgcG5hbWUsIFRSVUUpOwogIElfUnBjRnJlZShwbmFtZSk7CgogIHJldHVybiByOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBycGNydDRfcHJvdHNlcV9uY2FscnBjX29wZW5fZW5kcG9pbnQoUnBjU2VydmVyUHJvdHNlcSogcHJvdHNlcSwgTFBTVFIgZW5kcG9pbnQpCnsKICBzdGF0aWMgY29uc3QgY2hhciBwcmVmaXhbXSA9ICJcXFxcLlxccGlwZVxcbHJwY1xcIjsKICBSUENfU1RBVFVTIHI7CiAgTFBTVFIgcG5hbWU7CiAgUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbjsKCiAgciA9IFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKCZDb25uZWN0aW9uLCBUUlVFLCBwcm90c2VxLT5Qcm90c2VxLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRwb2ludCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgaWYgKHIgIT0gUlBDX1NfT0spCiAgICAgIHJldHVybiByOwoKICAvKiBwcm90c2VxPW5jYWxycGM6IHN1cHBvc2VkIHRvIHVzZSBOVCBMUEMgcG9ydHMsCiAgICogYnV0IHdlJ2xsIGltcGxlbWVudCBpdCB3aXRoIG5hbWVkIHBpcGVzIGZvciBub3cgKi8KICBwbmFtZSA9IElfUnBjQWxsb2NhdGUoc3RybGVuKHByZWZpeCkgKyBzdHJsZW4oQ29ubmVjdGlvbi0+RW5kcG9pbnQpICsgMSk7CiAgc3RyY2F0KHN0cmNweShwbmFtZSwgcHJlZml4KSwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIHIgPSBycGNydDRfY29ubl9jcmVhdGVfcGlwZShDb25uZWN0aW9uLCBwbmFtZSk7CiAgSV9ScGNGcmVlKHBuYW1lKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnByb3RzZXEtPmNzKTsKICBDb25uZWN0aW9uLT5OZXh0ID0gcHJvdHNlcS0+Y29ubjsKICBwcm90c2VxLT5jb25uID0gQ29ubmVjdGlvbjsKICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcHJvdHNlcS0+Y3MpOwoKICByZXR1cm4gcjsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X25jYWNuX25wX29wZW4oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgc3RhdGljIGNvbnN0IGNoYXIgcHJlZml4W10gPSAiXFxcXC4iOwogIFJQQ19TVEFUVVMgcjsKICBMUFNUUiBwbmFtZTsKCiAgLyogYWxyZWFkeSBjb25uZWN0ZWQ/ICovCiAgaWYgKG5wYy0+cGlwZSkKICAgIHJldHVybiBSUENfU19PSzsKCiAgLyogcHJvdHNlcT1uY2Fjbl9ucDogbmFtZWQgcGlwZXMgKi8KICBwbmFtZSA9IElfUnBjQWxsb2NhdGUoc3RybGVuKHByZWZpeCkgKyBzdHJsZW4oQ29ubmVjdGlvbi0+RW5kcG9pbnQpICsgMSk7CiAgc3RyY2F0KHN0cmNweShwbmFtZSwgcHJlZml4KSwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIHIgPSBycGNydDRfY29ubl9vcGVuX3BpcGUoQ29ubmVjdGlvbiwgcG5hbWUsIEZBTFNFKTsKICBJX1JwY0ZyZWUocG5hbWUpOwoKICByZXR1cm4gcjsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X3Byb3RzZXFfbmNhY25fbnBfb3Blbl9lbmRwb2ludChScGNTZXJ2ZXJQcm90c2VxICpwcm90c2VxLCBMUFNUUiBlbmRwb2ludCkKewogIHN0YXRpYyBjb25zdCBjaGFyIHByZWZpeFtdID0gIlxcXFwuIjsKICBSUENfU1RBVFVTIHI7CiAgTFBTVFIgcG5hbWU7CiAgUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbjsKCiAgciA9IFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKCZDb25uZWN0aW9uLCBUUlVFLCBwcm90c2VxLT5Qcm90c2VxLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRwb2ludCwgTlVMTCwgTlVMTCwgTlVMTCk7CiAgaWYgKHIgIT0gUlBDX1NfT0spCiAgICByZXR1cm4gcjsKCiAgLyogcHJvdHNlcT1uY2Fjbl9ucDogbmFtZWQgcGlwZXMgKi8KICBwbmFtZSA9IElfUnBjQWxsb2NhdGUoc3RybGVuKHByZWZpeCkgKyBzdHJsZW4oQ29ubmVjdGlvbi0+RW5kcG9pbnQpICsgMSk7CiAgc3RyY2F0KHN0cmNweShwbmFtZSwgcHJlZml4KSwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIHIgPSBycGNydDRfY29ubl9jcmVhdGVfcGlwZShDb25uZWN0aW9uLCBwbmFtZSk7CiAgSV9ScGNGcmVlKHBuYW1lKTsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnByb3RzZXEtPmNzKTsKICBDb25uZWN0aW9uLT5OZXh0ID0gcHJvdHNlcS0+Y29ubjsKICBwcm90c2VxLT5jb25uID0gQ29ubmVjdGlvbjsKICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcHJvdHNlcS0+Y3MpOwoKICByZXR1cm4gcjsKfQoKc3RhdGljIHZvaWQgcnBjcnQ0X2Nvbm5fbnBfaGFuZG9mZihScGNDb25uZWN0aW9uX25wICpvbGRfbnBjLCBScGNDb25uZWN0aW9uX25wICpuZXdfbnBjKQp7ICAgIAogIC8qIGJlY2F1c2Ugb2YgdGhlIHdheSBuYW1lZCBwaXBlcyB3b3JrLCB3ZSdsbCB0cmFuc2ZlciB0aGUgY29ubmVjdGVkIHBpcGUKICAgKiB0byB0aGUgY2hpbGQsIHRoZW4gcmVvcGVuIHRoZSBzZXJ2ZXIgYmluZGluZyB0byBjb250aW51ZSBsaXN0ZW5pbmcgKi8KCiAgbmV3X25wYy0+cGlwZSA9IG9sZF9ucGMtPnBpcGU7CiAgbmV3X25wYy0+b3ZsID0gb2xkX25wYy0+b3ZsOwogIG9sZF9ucGMtPnBpcGUgPSAwOwogIG1lbXNldCgmb2xkX25wYy0+b3ZsLCAwLCBzaXplb2Yob2xkX25wYy0+b3ZsKSk7CiAgb2xkX25wYy0+bGlzdGVuaW5nID0gRkFMU0U7Cn0KCnN0YXRpYyBSUENfU1RBVFVTIHJwY3J0NF9uY2Fjbl9ucF9oYW5kb2ZmKFJwY0Nvbm5lY3Rpb24gKm9sZF9jb25uLCBScGNDb25uZWN0aW9uICpuZXdfY29ubikKewogIFJQQ19TVEFUVVMgc3RhdHVzOwogIExQU1RSIHBuYW1lOwogIHN0YXRpYyBjb25zdCBjaGFyIHByZWZpeFtdID0gIlxcXFwuIjsKCiAgcnBjcnQ0X2Nvbm5fbnBfaGFuZG9mZigoUnBjQ29ubmVjdGlvbl9ucCAqKW9sZF9jb25uLCAoUnBjQ29ubmVjdGlvbl9ucCAqKW5ld19jb25uKTsKCiAgcG5hbWUgPSBJX1JwY0FsbG9jYXRlKHN0cmxlbihwcmVmaXgpICsgc3RybGVuKG9sZF9jb25uLT5FbmRwb2ludCkgKyAxKTsKICBzdHJjYXQoc3RyY3B5KHBuYW1lLCBwcmVmaXgpLCBvbGRfY29ubi0+RW5kcG9pbnQpOwogIHN0YXR1cyA9IHJwY3J0NF9jb25uX2NyZWF0ZV9waXBlKG9sZF9jb25uLCBwbmFtZSk7CiAgSV9ScGNGcmVlKHBuYW1lKTsKCiAgcmV0dXJuIHN0YXR1czsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X25jYWxycGNfaGFuZG9mZihScGNDb25uZWN0aW9uICpvbGRfY29ubiwgUnBjQ29ubmVjdGlvbiAqbmV3X2Nvbm4pCnsKICBSUENfU1RBVFVTIHN0YXR1czsKICBMUFNUUiBwbmFtZTsKICBzdGF0aWMgY29uc3QgY2hhciBwcmVmaXhbXSA9ICJcXFxcLlxccGlwZVxcbHJwY1xcIjsKCiAgVFJBQ0UoIiVzXG4iLCBvbGRfY29ubi0+RW5kcG9pbnQpOwoKICBycGNydDRfY29ubl9ucF9oYW5kb2ZmKChScGNDb25uZWN0aW9uX25wICopb2xkX2Nvbm4sIChScGNDb25uZWN0aW9uX25wICopbmV3X2Nvbm4pOwoKICBwbmFtZSA9IElfUnBjQWxsb2NhdGUoc3RybGVuKHByZWZpeCkgKyBzdHJsZW4ob2xkX2Nvbm4tPkVuZHBvaW50KSArIDEpOwogIHN0cmNhdChzdHJjcHkocG5hbWUsIHByZWZpeCksIG9sZF9jb25uLT5FbmRwb2ludCk7CiAgc3RhdHVzID0gcnBjcnQ0X2Nvbm5fY3JlYXRlX3BpcGUob2xkX2Nvbm4sIHBuYW1lKTsKICBJX1JwY0ZyZWUocG5hbWUpOwogICAgCiAgcmV0dXJuIHN0YXR1czsKfQoKc3RhdGljIGludCBycGNydDRfY29ubl9ucF9yZWFkKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgaW50IGNvdW50KQp7CiAgUnBjQ29ubmVjdGlvbl9ucCAqbnBjID0gKFJwY0Nvbm5lY3Rpb25fbnAgKikgQ29ubmVjdGlvbjsKICBjaGFyICpidWYgPSBidWZmZXI7CiAgQk9PTCByZXQgPSBUUlVFOwogIHVuc2lnbmVkIGludCBieXRlc19sZWZ0ID0gY291bnQ7CgogIHdoaWxlIChieXRlc19sZWZ0KQogIHsKICAgIERXT1JEIGJ5dGVzX3JlYWQ7CiAgICByZXQgPSBSZWFkRmlsZShucGMtPnBpcGUsIGJ1ZiwgYnl0ZXNfbGVmdCwgJmJ5dGVzX3JlYWQsIE5VTEwpOwogICAgaWYgKCFyZXQgfHwgIWJ5dGVzX3JlYWQpCiAgICAgICAgYnJlYWs7CiAgICBieXRlc19sZWZ0IC09IGJ5dGVzX3JlYWQ7CiAgICBidWYgKz0gYnl0ZXNfcmVhZDsKICB9CiAgcmV0dXJuIHJldCA/IGNvdW50IDogLTE7Cn0KCnN0YXRpYyBpbnQgcnBjcnQ0X2Nvbm5fbnBfd3JpdGUoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBjb3VudCkKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgY29uc3QgY2hhciAqYnVmID0gYnVmZmVyOwogIEJPT0wgcmV0ID0gVFJVRTsKICB1bnNpZ25lZCBpbnQgYnl0ZXNfbGVmdCA9IGNvdW50OwoKICB3aGlsZSAoYnl0ZXNfbGVmdCkKICB7CiAgICBEV09SRCBieXRlc193cml0dGVuOwogICAgcmV0ID0gV3JpdGVGaWxlKG5wYy0+cGlwZSwgYnVmLCBjb3VudCwgJmJ5dGVzX3dyaXR0ZW4sIE5VTEwpOwogICAgaWYgKCFyZXQgfHwgIWJ5dGVzX3dyaXR0ZW4pCiAgICAgICAgYnJlYWs7CiAgICBieXRlc19sZWZ0IC09IGJ5dGVzX3dyaXR0ZW47CiAgICBidWYgKz0gYnl0ZXNfd3JpdHRlbjsKICB9CiAgcmV0dXJuIHJldCA/IGNvdW50IDogLTE7Cn0KCnN0YXRpYyBpbnQgcnBjcnQ0X2Nvbm5fbnBfY2xvc2UoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb25fbnAgKm5wYyA9IChScGNDb25uZWN0aW9uX25wICopIENvbm5lY3Rpb247CiAgaWYgKG5wYy0+cGlwZSkgewogICAgRmx1c2hGaWxlQnVmZmVycyhucGMtPnBpcGUpOwogICAgQ2xvc2VIYW5kbGUobnBjLT5waXBlKTsKICAgIG5wYy0+cGlwZSA9IDA7CiAgfQogIGlmIChucGMtPm92bC5oRXZlbnQpIHsKICAgIENsb3NlSGFuZGxlKG5wYy0+b3ZsLmhFdmVudCk7CiAgICBucGMtPm92bC5oRXZlbnQgPSAwOwogIH0KICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcnBjcnQ0X2Nvbm5fbnBfY2FuY2VsX2NhbGwoUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbikKewogICAgLyogRklYTUU6IGltcGxlbWVudCB3aGVuIG5hbWVkIHBpcGUgd3JpdGVzIHVzZSBvdmVybGFwcGVkIEkvTyAqLwp9CgpzdGF0aWMgc2l6ZV90IHJwY3J0NF9uY2Fjbl9ucF9nZXRfdG9wX29mX3Rvd2VyKHVuc2lnbmVkIGNoYXIgKnRvd2VyX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqbmV0d29ya2FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5kcG9pbnQpCnsKICAgIHR3cl9lbXB0eV9mbG9vcl90ICpzbWJfZmxvb3I7CiAgICB0d3JfZW1wdHlfZmxvb3JfdCAqbmJfZmxvb3I7CiAgICBzaXplX3Qgc2l6ZTsKICAgIHNpemVfdCBuZXR3b3JrYWRkcl9zaXplOwogICAgc2l6ZV90IGVuZHBvaW50X3NpemU7CgogICAgVFJBQ0UoIiglcCwgJXMsICVzKVxuIiwgdG93ZXJfZGF0YSwgbmV0d29ya2FkZHIsIGVuZHBvaW50KTsKCiAgICBuZXR3b3JrYWRkcl9zaXplID0gc3RybGVuKG5ldHdvcmthZGRyKSArIDE7CiAgICBlbmRwb2ludF9zaXplID0gc3RybGVuKGVuZHBvaW50KSArIDE7CiAgICBzaXplID0gc2l6ZW9mKCpzbWJfZmxvb3IpICsgZW5kcG9pbnRfc2l6ZSArIHNpemVvZigqbmJfZmxvb3IpICsgbmV0d29ya2FkZHJfc2l6ZTsKCiAgICBpZiAoIXRvd2VyX2RhdGEpCiAgICAgICAgcmV0dXJuIHNpemU7CgogICAgc21iX2Zsb29yID0gKHR3cl9lbXB0eV9mbG9vcl90ICopdG93ZXJfZGF0YTsKCiAgICB0b3dlcl9kYXRhICs9IHNpemVvZigqc21iX2Zsb29yKTsKCiAgICBzbWJfZmxvb3ItPmNvdW50X2xocyA9IHNpemVvZihzbWJfZmxvb3ItPnByb3RpZCk7CiAgICBzbWJfZmxvb3ItPnByb3RpZCA9IEVQTV9QUk9UT0NPTF9TTUI7CiAgICBzbWJfZmxvb3ItPmNvdW50X3JocyA9IGVuZHBvaW50X3NpemU7CgogICAgbWVtY3B5KHRvd2VyX2RhdGEsIGVuZHBvaW50LCBlbmRwb2ludF9zaXplKTsKICAgIHRvd2VyX2RhdGEgKz0gZW5kcG9pbnRfc2l6ZTsKCiAgICBuYl9mbG9vciA9ICh0d3JfZW1wdHlfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CgogICAgdG93ZXJfZGF0YSArPSBzaXplb2YoKm5iX2Zsb29yKTsKCiAgICBuYl9mbG9vci0+Y291bnRfbGhzID0gc2l6ZW9mKG5iX2Zsb29yLT5wcm90aWQpOwogICAgbmJfZmxvb3ItPnByb3RpZCA9IEVQTV9QUk9UT0NPTF9ORVRCSU9TOwogICAgbmJfZmxvb3ItPmNvdW50X3JocyA9IG5ldHdvcmthZGRyX3NpemU7CgogICAgbWVtY3B5KHRvd2VyX2RhdGEsIG5ldHdvcmthZGRyLCBuZXR3b3JrYWRkcl9zaXplKTsKICAgIHRvd2VyX2RhdGEgKz0gbmV0d29ya2FkZHJfc2l6ZTsKCiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X25jYWNuX25wX3BhcnNlX3RvcF9vZl90b3dlcihjb25zdCB1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCB0b3dlcl9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKipuZXR3b3JrYWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICoqZW5kcG9pbnQpCnsKICAgIGNvbnN0IHR3cl9lbXB0eV9mbG9vcl90ICpzbWJfZmxvb3IgPSAoY29uc3QgdHdyX2VtcHR5X2Zsb29yX3QgKil0b3dlcl9kYXRhOwogICAgY29uc3QgdHdyX2VtcHR5X2Zsb29yX3QgKm5iX2Zsb29yOwoKICAgIFRSQUNFKCIoJXAsICVkLCAlcCwgJXApXG4iLCB0b3dlcl9kYXRhLCAoaW50KXRvd2VyX3NpemUsIG5ldHdvcmthZGRyLCBlbmRwb2ludCk7CgogICAgaWYgKHRvd2VyX3NpemUgPCBzaXplb2YoKnNtYl9mbG9vcikpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIHRvd2VyX2RhdGEgKz0gc2l6ZW9mKCpzbWJfZmxvb3IpOwogICAgdG93ZXJfc2l6ZSAtPSBzaXplb2YoKnNtYl9mbG9vcik7CgogICAgaWYgKChzbWJfZmxvb3ItPmNvdW50X2xocyAhPSBzaXplb2Yoc21iX2Zsb29yLT5wcm90aWQpKSB8fAogICAgICAgIChzbWJfZmxvb3ItPnByb3RpZCAhPSBFUE1fUFJPVE9DT0xfU01CKSB8fAogICAgICAgIChzbWJfZmxvb3ItPmNvdW50X3JocyA+IHRvd2VyX3NpemUpKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICBpZiAoZW5kcG9pbnQpCiAgICB7CiAgICAgICAgKmVuZHBvaW50ID0gSV9ScGNBbGxvY2F0ZShzbWJfZmxvb3ItPmNvdW50X3Jocyk7CiAgICAgICAgaWYgKCEqZW5kcG9pbnQpCiAgICAgICAgICAgIHJldHVybiBSUENfU19PVVRfT0ZfUkVTT1VSQ0VTOwogICAgICAgIG1lbWNweSgqZW5kcG9pbnQsIHRvd2VyX2RhdGEsIHNtYl9mbG9vci0+Y291bnRfcmhzKTsKICAgIH0KICAgIHRvd2VyX2RhdGEgKz0gc21iX2Zsb29yLT5jb3VudF9yaHM7CiAgICB0b3dlcl9zaXplIC09IHNtYl9mbG9vci0+Y291bnRfcmhzOwoKICAgIGlmICh0b3dlcl9zaXplIDwgc2l6ZW9mKCpuYl9mbG9vcikpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIG5iX2Zsb29yID0gKGNvbnN0IHR3cl9lbXB0eV9mbG9vcl90ICopdG93ZXJfZGF0YTsKCiAgICB0b3dlcl9kYXRhICs9IHNpemVvZigqbmJfZmxvb3IpOwogICAgdG93ZXJfc2l6ZSAtPSBzaXplb2YoKm5iX2Zsb29yKTsKCiAgICBpZiAoKG5iX2Zsb29yLT5jb3VudF9saHMgIT0gc2l6ZW9mKG5iX2Zsb29yLT5wcm90aWQpKSB8fAogICAgICAgIChuYl9mbG9vci0+cHJvdGlkICE9IEVQTV9QUk9UT0NPTF9ORVRCSU9TKSB8fAogICAgICAgIChuYl9mbG9vci0+Y291bnRfcmhzID4gdG93ZXJfc2l6ZSkpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIGlmIChuZXR3b3JrYWRkcikKICAgIHsKICAgICAgICAqbmV0d29ya2FkZHIgPSBJX1JwY0FsbG9jYXRlKG5iX2Zsb29yLT5jb3VudF9yaHMpOwogICAgICAgIGlmICghKm5ldHdvcmthZGRyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGVuZHBvaW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJX1JwY0ZyZWUoKmVuZHBvaW50KTsKICAgICAgICAgICAgICAgICplbmRwb2ludCA9IE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgfQogICAgICAgIG1lbWNweSgqbmV0d29ya2FkZHIsIHRvd2VyX2RhdGEsIG5iX2Zsb29yLT5jb3VudF9yaHMpOwogICAgfQoKICAgIHJldHVybiBSUENfU19PSzsKfQoKdHlwZWRlZiBzdHJ1Y3QgX1JwY1NlcnZlclByb3RzZXFfbnAKewogICAgUnBjU2VydmVyUHJvdHNlcSBjb21tb247CiAgICBIQU5ETEUgbWdyX2V2ZW50Owp9IFJwY1NlcnZlclByb3RzZXFfbnA7CgpzdGF0aWMgUnBjU2VydmVyUHJvdHNlcSAqcnBjcnQ0X3Byb3RzZXFfbnBfYWxsb2Modm9pZCkKewogICAgUnBjU2VydmVyUHJvdHNlcV9ucCAqcHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCpwcykpOwogICAgaWYgKHBzKQogICAgICAgIHBzLT5tZ3JfZXZlbnQgPSBDcmVhdGVFdmVudFcoTlVMTCwgRkFMU0UsIEZBTFNFLCBOVUxMKTsKICAgIHJldHVybiAmcHMtPmNvbW1vbjsKfQoKc3RhdGljIHZvaWQgcnBjcnQ0X3Byb3RzZXFfbnBfc2lnbmFsX3N0YXRlX2NoYW5nZWQoUnBjU2VydmVyUHJvdHNlcSAqcHJvdHNlcSkKewogICAgUnBjU2VydmVyUHJvdHNlcV9ucCAqbnBwcyA9IENPTlRBSU5JTkdfUkVDT1JEKHByb3RzZXEsIFJwY1NlcnZlclByb3RzZXFfbnAsIGNvbW1vbik7CiAgICBTZXRFdmVudChucHBzLT5tZ3JfZXZlbnQpOwp9CgpzdGF0aWMgdm9pZCAqcnBjcnQ0X3Byb3RzZXFfbnBfZ2V0X3dhaXRfYXJyYXkoUnBjU2VydmVyUHJvdHNlcSAqcHJvdHNlcSwgdm9pZCAqcHJldl9hcnJheSwgdW5zaWduZWQgaW50ICpjb3VudCkKewogICAgSEFORExFICpvYmpzID0gcHJldl9hcnJheTsKICAgIFJwY0Nvbm5lY3Rpb25fbnAgKmNvbm47CiAgICBScGNTZXJ2ZXJQcm90c2VxX25wICpucHBzID0gQ09OVEFJTklOR19SRUNPUkQocHJvdHNlcSwgUnBjU2VydmVyUHJvdHNlcV9ucCwgY29tbW9uKTsKICAgIAogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnByb3RzZXEtPmNzKTsKICAgIAogICAgLyogb3BlbiBhbmQgY291bnQgY29ubmVjdGlvbnMgKi8KICAgICpjb3VudCA9IDE7CiAgICBjb25uID0gQ09OVEFJTklOR19SRUNPUkQocHJvdHNlcS0+Y29ubiwgUnBjQ29ubmVjdGlvbl9ucCwgY29tbW9uKTsKICAgIHdoaWxlIChjb25uKSB7CiAgICAgICAgcnBjcnQ0X2Nvbm5fbGlzdGVuX3BpcGUoY29ubik7CiAgICAgICAgaWYgKGNvbm4tPm92bC5oRXZlbnQpCiAgICAgICAgICAgICgqY291bnQpKys7CiAgICAgICAgY29ubiA9IENPTlRBSU5JTkdfUkVDT1JEKGNvbm4tPmNvbW1vbi5OZXh0LCBScGNDb25uZWN0aW9uX25wLCBjb21tb24pOwogICAgfQogICAgCiAgICAvKiBtYWtlIGFycmF5IG9mIGNvbm5lY3Rpb25zICovCiAgICBpZiAob2JqcykKICAgICAgICBvYmpzID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgb2JqcywgKmNvdW50KnNpemVvZihIQU5ETEUpKTsKICAgIGVsc2UKICAgICAgICBvYmpzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsICpjb3VudCpzaXplb2YoSEFORExFKSk7CiAgICBpZiAoIW9ianMpCiAgICB7CiAgICAgICAgRVJSKCJjb3VsZG4ndCBhbGxvY2F0ZSBvYmpzXG4iKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcHJvdHNlcS0+Y3MpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgCiAgICBvYmpzWzBdID0gbnBwcy0+bWdyX2V2ZW50OwogICAgKmNvdW50ID0gMTsKICAgIGNvbm4gPSBDT05UQUlOSU5HX1JFQ09SRChwcm90c2VxLT5jb25uLCBScGNDb25uZWN0aW9uX25wLCBjb21tb24pOwogICAgd2hpbGUgKGNvbm4pIHsKICAgICAgICBpZiAoKG9ianNbKmNvdW50XSA9IGNvbm4tPm92bC5oRXZlbnQpKQogICAgICAgICAgICAoKmNvdW50KSsrOwogICAgICAgIGNvbm4gPSBDT05UQUlOSU5HX1JFQ09SRChjb25uLT5jb21tb24uTmV4dCwgUnBjQ29ubmVjdGlvbl9ucCwgY29tbW9uKTsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZwcm90c2VxLT5jcyk7CiAgICByZXR1cm4gb2JqczsKfQoKc3RhdGljIHZvaWQgcnBjcnQ0X3Byb3RzZXFfbnBfZnJlZV93YWl0X2FycmF5KFJwY1NlcnZlclByb3RzZXEgKnByb3RzZXEsIHZvaWQgKmFycmF5KQp7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhcnJheSk7Cn0KCnN0YXRpYyBpbnQgcnBjcnQ0X3Byb3RzZXFfbnBfd2FpdF9mb3JfbmV3X2Nvbm5lY3Rpb24oUnBjU2VydmVyUHJvdHNlcSAqcHJvdHNlcSwgdW5zaWduZWQgaW50IGNvdW50LCB2b2lkICp3YWl0X2FycmF5KQp7CiAgICBIQU5ETEUgYl9oYW5kbGU7CiAgICBIQU5ETEUgKm9ianMgPSB3YWl0X2FycmF5OwogICAgRFdPUkQgcmVzOwogICAgUnBjQ29ubmVjdGlvbiAqY2Nvbm47CiAgICBScGNDb25uZWN0aW9uX25wICpjb25uOwogICAgCiAgICBpZiAoIW9ianMpCiAgICAgICAgcmV0dXJuIC0xOwoKICAgIGRvCiAgICB7CiAgICAgICAgLyogYW4gYWxlcnRhYmxlIHdhaXQgaXNuJ3Qgc3RyaWN0bHkgbmVjZXNzYXJ5LCBidXQgZHVlIHRvIG91cgogICAgICAgICAqIG92ZXJsYXBwZWQgSS9PIGltcGxlbWVudGF0aW9uIGluIFdpbmUgd2UgbmVlZCB0byBmcmVlIHNvbWUgbWVtb3J5CiAgICAgICAgICogYnkgdGhlIGZpbGUgdXNlciBBUEMgYmVpbmcgY2FsbGVkLCBldmVuIGlmIG5vIGNvbXBsZXRpb24gcm91dGluZSB3YXMKICAgICAgICAgKiBzcGVjaWZpZWQgYXQgdGhlIHRpbWUgb2Ygc3RhcnRpbmcgdGhlIGFzeW5jIG9wZXJhdGlvbiAqLwogICAgICAgIHJlcyA9IFdhaXRGb3JNdWx0aXBsZU9iamVjdHNFeChjb3VudCwgb2JqcywgRkFMU0UsIElORklOSVRFLCBUUlVFKTsKICAgIH0gd2hpbGUgKHJlcyA9PSBXQUlUX0lPX0NPTVBMRVRJT04pOwoKICAgIGlmIChyZXMgPT0gV0FJVF9PQkpFQ1RfMCkKICAgICAgICByZXR1cm4gMDsKICAgIGVsc2UgaWYgKHJlcyA9PSBXQUlUX0ZBSUxFRCkKICAgIHsKICAgICAgICBFUlIoIndhaXQgZmFpbGVkIHdpdGggZXJyb3IgJWRcbiIsIEdldExhc3RFcnJvcigpKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgYl9oYW5kbGUgPSBvYmpzW3JlcyAtIFdBSVRfT0JKRUNUXzBdOwogICAgICAgIC8qIGZpbmQgd2hpY2ggY29ubmVjdGlvbiBnb3QgYSBSUEMgKi8KICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmcHJvdHNlcS0+Y3MpOwogICAgICAgIGNvbm4gPSBDT05UQUlOSU5HX1JFQ09SRChwcm90c2VxLT5jb25uLCBScGNDb25uZWN0aW9uX25wLCBjb21tb24pOwogICAgICAgIHdoaWxlIChjb25uKSB7CiAgICAgICAgICAgIGlmIChiX2hhbmRsZSA9PSBjb25uLT5vdmwuaEV2ZW50KSBicmVhazsKICAgICAgICAgICAgY29ubiA9IENPTlRBSU5JTkdfUkVDT1JEKGNvbm4tPmNvbW1vbi5OZXh0LCBScGNDb25uZWN0aW9uX25wLCBjb21tb24pOwogICAgICAgIH0KICAgICAgICBjY29ubiA9IE5VTEw7CiAgICAgICAgaWYgKGNvbm4pCiAgICAgICAgICAgIFJQQ1JUNF9TcGF3bkNvbm5lY3Rpb24oJmNjb25uLCAmY29ubi0+Y29tbW9uKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIEVSUigiZmFpbGVkIHRvIGxvY2F0ZSBjb25uZWN0aW9uIGZvciBoYW5kbGUgJXBcbiIsIGJfaGFuZGxlKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcHJvdHNlcS0+Y3MpOwogICAgICAgIGlmIChjY29ubikKICAgICAgICB7CiAgICAgICAgICAgIFJQQ1JUNF9uZXdfY2xpZW50KGNjb25uKTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgICAgIGVsc2UgcmV0dXJuIC0xOwogICAgfQp9CgpzdGF0aWMgc2l6ZV90IHJwY3J0NF9uY2FscnBjX2dldF90b3Bfb2ZfdG93ZXIodW5zaWduZWQgY2hhciAqdG93ZXJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5ldHdvcmthZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5kcG9pbnQpCnsKICAgIHR3cl9lbXB0eV9mbG9vcl90ICpwaXBlX2Zsb29yOwogICAgc2l6ZV90IHNpemU7CiAgICBzaXplX3QgZW5kcG9pbnRfc2l6ZTsKCiAgICBUUkFDRSgiKCVwLCAlcywgJXMpXG4iLCB0b3dlcl9kYXRhLCBuZXR3b3JrYWRkciwgZW5kcG9pbnQpOwoKICAgIGVuZHBvaW50X3NpemUgPSBzdHJsZW4obmV0d29ya2FkZHIpICsgMTsKICAgIHNpemUgPSBzaXplb2YoKnBpcGVfZmxvb3IpICsgZW5kcG9pbnRfc2l6ZTsKCiAgICBpZiAoIXRvd2VyX2RhdGEpCiAgICAgICAgcmV0dXJuIHNpemU7CgogICAgcGlwZV9mbG9vciA9ICh0d3JfZW1wdHlfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CgogICAgdG93ZXJfZGF0YSArPSBzaXplb2YoKnBpcGVfZmxvb3IpOwoKICAgIHBpcGVfZmxvb3ItPmNvdW50X2xocyA9IHNpemVvZihwaXBlX2Zsb29yLT5wcm90aWQpOwogICAgcGlwZV9mbG9vci0+cHJvdGlkID0gRVBNX1BST1RPQ09MX1NNQjsKICAgIHBpcGVfZmxvb3ItPmNvdW50X3JocyA9IGVuZHBvaW50X3NpemU7CgogICAgbWVtY3B5KHRvd2VyX2RhdGEsIGVuZHBvaW50LCBlbmRwb2ludF9zaXplKTsKICAgIHRvd2VyX2RhdGEgKz0gZW5kcG9pbnRfc2l6ZTsKCiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X25jYWxycGNfcGFyc2VfdG9wX29mX3Rvd2VyKGNvbnN0IHVuc2lnbmVkIGNoYXIgKnRvd2VyX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgdG93ZXJfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKipuZXR3b3JrYWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKiplbmRwb2ludCkKewogICAgY29uc3QgdHdyX2VtcHR5X2Zsb29yX3QgKnBpcGVfZmxvb3IgPSAoY29uc3QgdHdyX2VtcHR5X2Zsb29yX3QgKil0b3dlcl9kYXRhOwoKICAgIFRSQUNFKCIoJXAsICVkLCAlcCwgJXApXG4iLCB0b3dlcl9kYXRhLCAoaW50KXRvd2VyX3NpemUsIG5ldHdvcmthZGRyLCBlbmRwb2ludCk7CgogICAgKm5ldHdvcmthZGRyID0gTlVMTDsKICAgICplbmRwb2ludCA9IE5VTEw7CgogICAgaWYgKHRvd2VyX3NpemUgPCBzaXplb2YoKnBpcGVfZmxvb3IpKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICB0b3dlcl9kYXRhICs9IHNpemVvZigqcGlwZV9mbG9vcik7CiAgICB0b3dlcl9zaXplIC09IHNpemVvZigqcGlwZV9mbG9vcik7CgogICAgaWYgKChwaXBlX2Zsb29yLT5jb3VudF9saHMgIT0gc2l6ZW9mKHBpcGVfZmxvb3ItPnByb3RpZCkpIHx8CiAgICAgICAgKHBpcGVfZmxvb3ItPnByb3RpZCAhPSBFUE1fUFJPVE9DT0xfU01CKSB8fAogICAgICAgIChwaXBlX2Zsb29yLT5jb3VudF9yaHMgPiB0b3dlcl9zaXplKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgaWYgKGVuZHBvaW50KQogICAgewogICAgICAgICplbmRwb2ludCA9IElfUnBjQWxsb2NhdGUocGlwZV9mbG9vci0+Y291bnRfcmhzKTsKICAgICAgICBpZiAoISplbmRwb2ludCkKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgbWVtY3B5KCplbmRwb2ludCwgdG93ZXJfZGF0YSwgcGlwZV9mbG9vci0+Y291bnRfcmhzKTsKICAgIH0KCiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KCi8qKioqIG5jYWNuX2lwX3RjcCBzdXBwb3J0ICoqKiovCgp0eXBlZGVmIHN0cnVjdCBfUnBjQ29ubmVjdGlvbl90Y3AKewogIFJwY0Nvbm5lY3Rpb24gY29tbW9uOwogIGludCBzb2NrOwogIGludCBjYW5jZWxfZmRzWzJdOwp9IFJwY0Nvbm5lY3Rpb25fdGNwOwoKc3RhdGljIFJwY0Nvbm5lY3Rpb24gKnJwY3J0NF9jb25uX3RjcF9hbGxvYyh2b2lkKQp7CiAgUnBjQ29ubmVjdGlvbl90Y3AgKnRjcGM7CiAgdGNwYyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoUnBjQ29ubmVjdGlvbl90Y3ApKTsKICBpZiAodGNwYyA9PSBOVUxMKQogICAgcmV0dXJuIE5VTEw7CiAgdGNwYy0+c29jayA9IC0xOwogIGlmIChzb2NrZXRwYWlyKFBGX1VOSVgsIFNPQ0tfU1RSRUFNLCAwLCB0Y3BjLT5jYW5jZWxfZmRzKSA8IDApCiAgewogICAgRVJSKCJzb2NrZXRwYWlyKCkgZmFpbGVkOiAlc1xuIiwgc3RyZXJyb3IoZXJybm8pKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHRjcGMpOwogICAgcmV0dXJuIE5VTEw7CiAgfQogIHJldHVybiAmdGNwYy0+Y29tbW9uOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBycGNydDRfbmNhY25faXBfdGNwX29wZW4oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFJwY0Nvbm5lY3Rpb25fdGNwICp0Y3BjID0gKFJwY0Nvbm5lY3Rpb25fdGNwICopIENvbm5lY3Rpb247CiAgaW50IHNvY2s7CiAgaW50IHJldDsKICBzdHJ1Y3QgYWRkcmluZm8gKmFpOwogIHN0cnVjdCBhZGRyaW5mbyAqYWlfY3VyOwogIHN0cnVjdCBhZGRyaW5mbyBoaW50czsKCiAgVFJBQ0UoIiglcywgJXMpXG4iLCBDb25uZWN0aW9uLT5OZXR3b3JrQWRkciwgQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwoKICBpZiAodGNwYy0+c29jayAhPSAtMSkKICAgIHJldHVybiBSUENfU19PSzsKCiAgaGludHMuYWlfZmxhZ3MgICAgICAgICAgPSAwOwogIGhpbnRzLmFpX2ZhbWlseSAgICAgICAgID0gUEZfVU5TUEVDOwogIGhpbnRzLmFpX3NvY2t0eXBlICAgICAgID0gU09DS19TVFJFQU07CiAgaGludHMuYWlfcHJvdG9jb2wgICAgICAgPSBJUFBST1RPX1RDUDsKICBoaW50cy5haV9hZGRybGVuICAgICAgICA9IDA7CiAgaGludHMuYWlfYWRkciAgICAgICAgICAgPSBOVUxMOwogIGhpbnRzLmFpX2Nhbm9ubmFtZSAgICAgID0gTlVMTDsKICBoaW50cy5haV9uZXh0ICAgICAgICAgICA9IE5VTEw7CgogIHJldCA9IGdldGFkZHJpbmZvKENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyLCBDb25uZWN0aW9uLT5FbmRwb2ludCwgJmhpbnRzLCAmYWkpOwogIGlmIChyZXQpCiAgewogICAgRVJSKCJnZXRhZGRyaW5mbyBmb3IgJXM6JXMgZmFpbGVkOiAlc1xuIiwgQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIsCiAgICAgIENvbm5lY3Rpb24tPkVuZHBvaW50LCBnYWlfc3RyZXJyb3IocmV0KSk7CiAgICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwogIH0KCiAgZm9yIChhaV9jdXIgPSBhaTsgYWlfY3VyOyBhaV9jdXIgPSBhaV9jdXItPmFpX25leHQpCiAgewogICAgaW50IHZhbDsKCiAgICBpZiAoVFJBQ0VfT04ocnBjKSkKICAgIHsKICAgICAgY2hhciBob3N0WzI1Nl07CiAgICAgIGNoYXIgc2VydmljZVsyNTZdOwogICAgICBnZXRuYW1laW5mbyhhaV9jdXItPmFpX2FkZHIsIGFpX2N1ci0+YWlfYWRkcmxlbiwKICAgICAgICBob3N0LCBzaXplb2YoaG9zdCksIHNlcnZpY2UsIHNpemVvZihzZXJ2aWNlKSwKICAgICAgICBOSV9OVU1FUklDSE9TVCB8IE5JX05VTUVSSUNTRVJWKTsKICAgICAgVFJBQ0UoInRyeWluZyAlczolc1xuIiwgaG9zdCwgc2VydmljZSk7CiAgICB9CgogICAgc29jayA9IHNvY2tldChhaV9jdXItPmFpX2ZhbWlseSwgYWlfY3VyLT5haV9zb2NrdHlwZSwgYWlfY3VyLT5haV9wcm90b2NvbCk7CiAgICBpZiAoc29jayA9PSAtMSkKICAgIHsKICAgICAgV0FSTigic29ja2V0KCkgZmFpbGVkOiAlc1xuIiwgc3RyZXJyb3IoZXJybm8pKTsKICAgICAgY29udGludWU7CiAgICB9CgogICAgaWYgKDA+Y29ubmVjdChzb2NrLCBhaV9jdXItPmFpX2FkZHIsIGFpX2N1ci0+YWlfYWRkcmxlbikpCiAgICB7CiAgICAgIFdBUk4oImNvbm5lY3QoKSBmYWlsZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykpOwogICAgICBjbG9zZShzb2NrKTsKICAgICAgY29udGludWU7CiAgICB9CgogICAgLyogUlBDIGRlcGVuZHMgb24gaGF2aW5nIG1pbmltYWwgbGF0ZW5jeSBzbyBkaXNhYmxlIHRoZSBOYWdsZSBhbGdvcml0aG0gKi8KICAgIHZhbCA9IDE7CiAgICBzZXRzb2Nrb3B0KHNvY2ssIFNPTF9UQ1AsIFRDUF9OT0RFTEFZLCAmdmFsLCBzaXplb2YodmFsKSk7CiAgICBmY250bChzb2NrLCBGX1NFVEZMLCBPX05PTkJMT0NLKTsgLyogbWFrZSBzb2NrZXQgbm9uYmxvY2tpbmcgKi8KCiAgICB0Y3BjLT5zb2NrID0gc29jazsKCiAgICBmcmVlYWRkcmluZm8oYWkpOwogICAgVFJBQ0UoImNvbm5lY3RlZFxuIik7CiAgICByZXR1cm4gUlBDX1NfT0s7CiAgfQoKICBmcmVlYWRkcmluZm8oYWkpOwogIEVSUigiY291bGRuJ3QgY29ubmVjdCB0byAlczolc1xuIiwgQ29ubmVjdGlvbi0+TmV0d29ya0FkZHIsIENvbm5lY3Rpb24tPkVuZHBvaW50KTsKICByZXR1cm4gUlBDX1NfU0VSVkVSX1VOQVZBSUxBQkxFOwp9CgpzdGF0aWMgUlBDX1NUQVRVUyBycGNydDRfcHJvdHNlcV9uY2Fjbl9pcF90Y3Bfb3Blbl9lbmRwb2ludChScGNTZXJ2ZXJQcm90c2VxICpwcm90c2VxLCBMUFNUUiBlbmRwb2ludCkKewogICAgUlBDX1NUQVRVUyBzdGF0dXMgPSBSUENfU19DQU5UX0NSRUFURV9FTkRQT0lOVDsKICAgIGludCBzb2NrOwogICAgaW50IHJldDsKICAgIHN0cnVjdCBhZGRyaW5mbyAqYWk7CiAgICBzdHJ1Y3QgYWRkcmluZm8gKmFpX2N1cjsKICAgIHN0cnVjdCBhZGRyaW5mbyBoaW50czsKICAgIFJwY0Nvbm5lY3Rpb24gKmZpcnN0X2Nvbm5lY3Rpb24gPSBOVUxMOwoKICAgIFRSQUNFKCIoJXAsICVzKVxuIiwgcHJvdHNlcSwgZW5kcG9pbnQpOwoKICAgIGhpbnRzLmFpX2ZsYWdzICAgICAgICAgID0gQUlfUEFTU0lWRSAvKiBmb3Igbm9uLWxvY2FsaG9zdCBhZGRyZXNzZXMgKi87CiAgICBoaW50cy5haV9mYW1pbHkgICAgICAgICA9IFBGX1VOU1BFQzsKICAgIGhpbnRzLmFpX3NvY2t0eXBlICAgICAgID0gU09DS19TVFJFQU07CiAgICBoaW50cy5haV9wcm90b2NvbCAgICAgICA9IElQUFJPVE9fVENQOwogICAgaGludHMuYWlfYWRkcmxlbiAgICAgICAgPSAwOwogICAgaGludHMuYWlfYWRkciAgICAgICAgICAgPSBOVUxMOwogICAgaGludHMuYWlfY2Fub25uYW1lICAgICAgPSBOVUxMOwogICAgaGludHMuYWlfbmV4dCAgICAgICAgICAgPSBOVUxMOwoKICAgIHJldCA9IGdldGFkZHJpbmZvKE5VTEwsIGVuZHBvaW50LCAmaGludHMsICZhaSk7CiAgICBpZiAocmV0KQogICAgewogICAgICAgIEVSUigiZ2V0YWRkcmluZm8gZm9yIHBvcnQgJXMgZmFpbGVkOiAlc1xuIiwgZW5kcG9pbnQsCiAgICAgICAgICAgIGdhaV9zdHJlcnJvcihyZXQpKTsKICAgICAgICBpZiAoKHJldCA9PSBFQUlfU0VSVklDRSkgfHwgKHJldCA9PSBFQUlfTk9OQU1FKSkKICAgICAgICAgICAgcmV0dXJuIFJQQ19TX0lOVkFMSURfRU5EUE9JTlRfRk9STUFUOwogICAgICAgIHJldHVybiBSUENfU19DQU5UX0NSRUFURV9FTkRQT0lOVDsKICAgIH0KCiAgICBmb3IgKGFpX2N1ciA9IGFpOyBhaV9jdXI7IGFpX2N1ciA9IGFpX2N1ci0+YWlfbmV4dCkKICAgIHsKICAgICAgICBScGNDb25uZWN0aW9uX3RjcCAqdGNwYzsKICAgICAgICBSUENfU1RBVFVTIGNyZWF0ZV9zdGF0dXM7CgogICAgICAgIGlmIChUUkFDRV9PTihycGMpKQogICAgICAgIHsKICAgICAgICAgICAgY2hhciBob3N0WzI1Nl07CiAgICAgICAgICAgIGNoYXIgc2VydmljZVsyNTZdOwogICAgICAgICAgICBnZXRuYW1laW5mbyhhaV9jdXItPmFpX2FkZHIsIGFpX2N1ci0+YWlfYWRkcmxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgaG9zdCwgc2l6ZW9mKGhvc3QpLCBzZXJ2aWNlLCBzaXplb2Yoc2VydmljZSksCiAgICAgICAgICAgICAgICAgICAgICAgIE5JX05VTUVSSUNIT1NUIHwgTklfTlVNRVJJQ1NFUlYpOwogICAgICAgICAgICBUUkFDRSgidHJ5aW5nICVzOiVzXG4iLCBob3N0LCBzZXJ2aWNlKTsKICAgICAgICB9CgogICAgICAgIHNvY2sgPSBzb2NrZXQoYWlfY3VyLT5haV9mYW1pbHksIGFpX2N1ci0+YWlfc29ja3R5cGUsIGFpX2N1ci0+YWlfcHJvdG9jb2wpOwogICAgICAgIGlmIChzb2NrID09IC0xKQogICAgICAgIHsKICAgICAgICAgICAgV0FSTigic29ja2V0KCkgZmFpbGVkOiAlc1xuIiwgc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgc3RhdHVzID0gUlBDX1NfQ0FOVF9DUkVBVEVfRU5EUE9JTlQ7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgcmV0ID0gYmluZChzb2NrLCBhaV9jdXItPmFpX2FkZHIsIGFpX2N1ci0+YWlfYWRkcmxlbik7CiAgICAgICAgaWYgKHJldCA8IDApCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJiaW5kIGZhaWxlZDogJXNcbiIsIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgIGNsb3NlKHNvY2spOwogICAgICAgICAgICBpZiAoZXJybm8gPT0gRUFERFJJTlVTRSkKICAgICAgICAgICAgICBzdGF0dXMgPSBSUENfU19EVVBMSUNBVEVfRU5EUE9JTlQ7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICBzdGF0dXMgPSBSUENfU19DQU5UX0NSRUFURV9FTkRQT0lOVDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIGNyZWF0ZV9zdGF0dXMgPSBSUENSVDRfQ3JlYXRlQ29ubmVjdGlvbigoUnBjQ29ubmVjdGlvbiAqKikmdGNwYywgVFJVRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvdHNlcS0+UHJvdHNlcSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kcG9pbnQsIE5VTEwsIE5VTEwsIE5VTEwpOwogICAgICAgIGlmIChjcmVhdGVfc3RhdHVzICE9IFJQQ19TX09LKQogICAgICAgIHsKICAgICAgICAgICAgY2xvc2Uoc29jayk7CiAgICAgICAgICAgIHN0YXR1cyA9IGNyZWF0ZV9zdGF0dXM7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgdGNwYy0+c29jayA9IHNvY2s7CiAgICAgICAgcmV0ID0gbGlzdGVuKHNvY2ssIHByb3RzZXEtPk1heENhbGxzKTsKICAgICAgICBpZiAocmV0IDwgMCkKICAgICAgICB7CiAgICAgICAgICAgIFdBUk4oImxpc3RlbiBmYWlsZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykpOwogICAgICAgICAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oJnRjcGMtPmNvbW1vbik7CiAgICAgICAgICAgIHN0YXR1cyA9IFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICAvKiBuZWVkIGEgbm9uLWJsb2NraW5nIHNvY2tldCwgb3RoZXJ3aXNlIGFjY2VwdCgpIGhhcyBhIHBvdGVudGlhbAogICAgICAgICAqIHJhY2UtY29uZGl0aW9uIChwb2xsKCkgc2F5cyBpdCBpcyByZWFkYWJsZSwgY29ubmVjdGlvbiBkcm9wcywKICAgICAgICAgKiBhbmQgYWNjZXB0KCkgYmxvY2tzIHVudGlsIHRoZSBuZXh0IGNvbm5lY3Rpb24gY29tZXMuLi4pCiAgICAgICAgICovCiAgICAgICAgcmV0ID0gZmNudGwoc29jaywgRl9TRVRGTCwgT19OT05CTE9DSyk7CiAgICAgICAgaWYgKHJldCA8IDApCiAgICAgICAgewogICAgICAgICAgICBXQVJOKCJjb3VsZG4ndCBtYWtlIHNvY2tldCBub24tYmxvY2tpbmcsIGVycm9yICVkXG4iLCByZXQpOwogICAgICAgICAgICBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oJnRjcGMtPmNvbW1vbik7CiAgICAgICAgICAgIHN0YXR1cyA9IFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgdGNwYy0+Y29tbW9uLk5leHQgPSBmaXJzdF9jb25uZWN0aW9uOwogICAgICAgIGZpcnN0X2Nvbm5lY3Rpb24gPSAmdGNwYy0+Y29tbW9uOwogICAgfQoKICAgIGZyZWVhZGRyaW5mbyhhaSk7CgogICAgLyogaWYgYXQgbGVhc3Qgb25lIGNvbm5lY3Rpb24gd2FzIGNyZWF0ZWQgZm9yIGFuIGVuZHBvaW50IHRoZW4KICAgICAqIHJldHVybiBzdWNjZXNzICovCiAgICBpZiAoZmlyc3RfY29ubmVjdGlvbikKICAgIHsKICAgICAgICBScGNDb25uZWN0aW9uICpjb25uOwoKICAgICAgICAvKiBmaW5kIGxhc3QgZWxlbWVudCBpbiBsaXN0ICovCiAgICAgICAgZm9yIChjb25uID0gZmlyc3RfY29ubmVjdGlvbjsgY29ubi0+TmV4dDsgY29ubiA9IGNvbm4tPk5leHQpCiAgICAgICAgICAgIDsKCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnByb3RzZXEtPmNzKTsKICAgICAgICBjb25uLT5OZXh0ID0gcHJvdHNlcS0+Y29ubjsKICAgICAgICBwcm90c2VxLT5jb25uID0gZmlyc3RfY29ubmVjdGlvbjsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcHJvdHNlcS0+Y3MpOwogICAgICAgIAogICAgICAgIFRSQUNFKCJsaXN0ZW5pbmcgb24gJXNcbiIsIGVuZHBvaW50KTsKICAgICAgICByZXR1cm4gUlBDX1NfT0s7CiAgICB9CgogICAgRVJSKCJjb3VsZG4ndCBsaXN0ZW4gb24gcG9ydCAlc1xuIiwgZW5kcG9pbnQpOwogICAgcmV0dXJuIHN0YXR1czsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X2Nvbm5fdGNwX2hhbmRvZmYoUnBjQ29ubmVjdGlvbiAqb2xkX2Nvbm4sIFJwY0Nvbm5lY3Rpb24gKm5ld19jb25uKQp7CiAgaW50IHJldDsKICBzdHJ1Y3Qgc29ja2FkZHJfaW4gYWRkcmVzczsKICBzb2NrbGVuX3QgYWRkcnNpemU7CiAgUnBjQ29ubmVjdGlvbl90Y3AgKnNlcnZlciA9IChScGNDb25uZWN0aW9uX3RjcCopIG9sZF9jb25uOwogIFJwY0Nvbm5lY3Rpb25fdGNwICpjbGllbnQgPSAoUnBjQ29ubmVjdGlvbl90Y3AqKSBuZXdfY29ubjsKCiAgYWRkcnNpemUgPSBzaXplb2YoYWRkcmVzcyk7CiAgcmV0ID0gYWNjZXB0KHNlcnZlci0+c29jaywgKHN0cnVjdCBzb2NrYWRkciopICZhZGRyZXNzLCAmYWRkcnNpemUpOwogIGlmIChyZXQgPCAwKQogIHsKICAgIEVSUigiRmFpbGVkIHRvIGFjY2VwdCBhIFRDUCBjb25uZWN0aW9uOiBlcnJvciAlZFxuIiwgcmV0KTsKICAgIHJldHVybiBSUENfU19PVVRfT0ZfUkVTT1VSQ0VTOwogIH0KICAvKiByZXNldCB0byBibG9ja2luZyBiZWhhdmlvdXIgKi8KICBmY250bChyZXQsIEZfU0VURkwsIDApOwogIGNsaWVudC0+c29jayA9IHJldDsKICBUUkFDRSgiQWNjZXB0ZWQgYSBuZXcgVENQIGNvbm5lY3Rpb25cbiIpOwogIHJldHVybiBSUENfU19PSzsKfQoKc3RhdGljIGludCBycGNydDRfY29ubl90Y3BfcmVhZChScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKmJ1ZmZlciwgdW5zaWduZWQgaW50IGNvdW50KQp7CiAgUnBjQ29ubmVjdGlvbl90Y3AgKnRjcGMgPSAoUnBjQ29ubmVjdGlvbl90Y3AgKikgQ29ubmVjdGlvbjsKICBpbnQgYnl0ZXNfcmVhZCA9IDA7CiAgZG8KICB7CiAgICBpbnQgciA9IHJlY3YodGNwYy0+c29jaywgKGNoYXIgKilidWZmZXIgKyBieXRlc19yZWFkLCBjb3VudCAtIGJ5dGVzX3JlYWQsIDApOwogICAgaWYgKHIgPj0gMCkKICAgICAgYnl0ZXNfcmVhZCArPSByOwogICAgZWxzZSBpZiAoZXJybm8gIT0gRUFHQUlOKQogICAgICByZXR1cm4gLTE7CiAgICBlbHNlCiAgICB7CiAgICAgIHN0cnVjdCBwb2xsZmQgcGZkc1syXTsKICAgICAgcGZkc1swXS5mZCA9IHRjcGMtPnNvY2s7CiAgICAgIHBmZHNbMF0uZXZlbnRzID0gUE9MTElOOwogICAgICBwZmRzWzFdLmZkID0gdGNwYy0+Y2FuY2VsX2Zkc1swXTsKICAgICAgcGZkc1sxXS5ldmVudHMgPSBQT0xMSU47CiAgICAgIGlmIChwb2xsKHBmZHMsIDIsIC0xIC8qIGluZmluaXRlICovKSA9PSAtMSAmJiBlcnJubyAhPSBFSU5UUikKICAgICAgewogICAgICAgIEVSUigicG9sbCgpIGZhaWxlZDogJXNcbiIsIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIC0xOwogICAgICB9CiAgICAgIGlmIChwZmRzWzFdLnJldmVudHMgJiBQT0xMSU4pIC8qIGNhbmNlbGVkICovCiAgICAgIHsKICAgICAgICBjaGFyIGR1bW15OwogICAgICAgIHJlYWQocGZkc1sxXS5mZCwgJmR1bW15LCBzaXplb2YoZHVtbXkpKTsKICAgICAgICByZXR1cm4gLTE7CiAgICAgIH0KICAgIH0KICB9IHdoaWxlIChieXRlc19yZWFkICE9IGNvdW50KTsKICBUUkFDRSgiJWQgJXAgJXUgLT4gJWRcbiIsIHRjcGMtPnNvY2ssIGJ1ZmZlciwgY291bnQsIGJ5dGVzX3JlYWQpOwogIHJldHVybiBieXRlc19yZWFkOwp9CgpzdGF0aWMgaW50IHJwY3J0NF9jb25uX3RjcF93cml0ZShScGNDb25uZWN0aW9uICpDb25uZWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICpidWZmZXIsIHVuc2lnbmVkIGludCBjb3VudCkKewogIFJwY0Nvbm5lY3Rpb25fdGNwICp0Y3BjID0gKFJwY0Nvbm5lY3Rpb25fdGNwICopIENvbm5lY3Rpb247CiAgaW50IGJ5dGVzX3dyaXR0ZW4gPSAwOwogIGRvCiAgewogICAgaW50IHIgPSB3cml0ZSh0Y3BjLT5zb2NrLCAoY29uc3QgY2hhciAqKWJ1ZmZlciArIGJ5dGVzX3dyaXR0ZW4sIGNvdW50IC0gYnl0ZXNfd3JpdHRlbik7CiAgICBpZiAociA+PSAwKQogICAgICBieXRlc193cml0dGVuICs9IHI7CiAgICBlbHNlIGlmIChlcnJubyAhPSBFQUdBSU4pCiAgICAgIHJldHVybiAtMTsKICAgIGVsc2UKICAgIHsKICAgICAgc3RydWN0IHBvbGxmZCBwZmQ7CiAgICAgIHBmZC5mZCA9IHRjcGMtPnNvY2s7CiAgICAgIHBmZC5ldmVudHMgPSBQT0xMT1VUOwogICAgICBpZiAocG9sbCgmcGZkLCAxLCAtMSAvKiBpbmZpbml0ZSAqLykgPT0gLTEgJiYgZXJybm8gIT0gRUlOVFIpCiAgICAgIHsKICAgICAgICBFUlIoInBvbGwoKSBmYWlsZWQ6ICVzXG4iLCBzdHJlcnJvcihlcnJubykpOwogICAgICAgIHJldHVybiAtMTsKICAgICAgfQogICAgfQogIH0gd2hpbGUgKGJ5dGVzX3dyaXR0ZW4gIT0gY291bnQpOwogIFRSQUNFKCIlZCAlcCAldSAtPiAlZFxuIiwgdGNwYy0+c29jaywgYnVmZmVyLCBjb3VudCwgYnl0ZXNfd3JpdHRlbik7CiAgcmV0dXJuIGJ5dGVzX3dyaXR0ZW47Cn0KCnN0YXRpYyBpbnQgcnBjcnQ0X2Nvbm5fdGNwX2Nsb3NlKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICBScGNDb25uZWN0aW9uX3RjcCAqdGNwYyA9IChScGNDb25uZWN0aW9uX3RjcCAqKSBDb25uZWN0aW9uOwoKICBUUkFDRSgiJWRcbiIsIHRjcGMtPnNvY2spOwoKICBpZiAodGNwYy0+c29jayAhPSAtMSkKICAgIGNsb3NlKHRjcGMtPnNvY2spOwogIHRjcGMtPnNvY2sgPSAtMTsKICBjbG9zZSh0Y3BjLT5jYW5jZWxfZmRzWzBdKTsKICBjbG9zZSh0Y3BjLT5jYW5jZWxfZmRzWzFdKTsKICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgcnBjcnQ0X2Nvbm5fdGNwX2NhbmNlbF9jYWxsKFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICAgIFJwY0Nvbm5lY3Rpb25fdGNwICp0Y3BjID0gKFJwY0Nvbm5lY3Rpb25fdGNwICopIENvbm5lY3Rpb247CiAgICBjaGFyIGR1bW15ID0gMTsKCiAgICBUUkFDRSgiJXBcbiIsIENvbm5lY3Rpb24pOwoKICAgIHdyaXRlKHRjcGMtPmNhbmNlbF9mZHNbMV0sICZkdW1teSwgMSk7Cn0KCnN0YXRpYyBzaXplX3QgcnBjcnQ0X25jYWNuX2lwX3RjcF9nZXRfdG9wX29mX3Rvd2VyKHVuc2lnbmVkIGNoYXIgKnRvd2VyX2RhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKm5ldHdvcmthZGRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplbmRwb2ludCkKewogICAgdHdyX3RjcF9mbG9vcl90ICp0Y3BfZmxvb3I7CiAgICB0d3JfaXB2NF9mbG9vcl90ICppcHY0X2Zsb29yOwogICAgc3RydWN0IGFkZHJpbmZvICphaTsKICAgIHN0cnVjdCBhZGRyaW5mbyBoaW50czsKICAgIGludCByZXQ7CiAgICBzaXplX3Qgc2l6ZSA9IHNpemVvZigqdGNwX2Zsb29yKSArIHNpemVvZigqaXB2NF9mbG9vcik7CgogICAgVFJBQ0UoIiglcCwgJXMsICVzKVxuIiwgdG93ZXJfZGF0YSwgbmV0d29ya2FkZHIsIGVuZHBvaW50KTsKCiAgICBpZiAoIXRvd2VyX2RhdGEpCiAgICAgICAgcmV0dXJuIHNpemU7CgogICAgdGNwX2Zsb29yID0gKHR3cl90Y3BfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CiAgICB0b3dlcl9kYXRhICs9IHNpemVvZigqdGNwX2Zsb29yKTsKCiAgICBpcHY0X2Zsb29yID0gKHR3cl9pcHY0X2Zsb29yX3QgKil0b3dlcl9kYXRhOwoKICAgIHRjcF9mbG9vci0+Y291bnRfbGhzID0gc2l6ZW9mKHRjcF9mbG9vci0+cHJvdGlkKTsKICAgIHRjcF9mbG9vci0+cHJvdGlkID0gRVBNX1BST1RPQ09MX1RDUDsKICAgIHRjcF9mbG9vci0+Y291bnRfcmhzID0gc2l6ZW9mKHRjcF9mbG9vci0+cG9ydCk7CgogICAgaXB2NF9mbG9vci0+Y291bnRfbGhzID0gc2l6ZW9mKGlwdjRfZmxvb3ItPnByb3RpZCk7CiAgICBpcHY0X2Zsb29yLT5wcm90aWQgPSBFUE1fUFJPVE9DT0xfSVA7CiAgICBpcHY0X2Zsb29yLT5jb3VudF9yaHMgPSBzaXplb2YoaXB2NF9mbG9vci0+aXB2NGFkZHIpOwoKICAgIGhpbnRzLmFpX2ZsYWdzICAgICAgICAgID0gQUlfTlVNRVJJQ0hPU1Q7CiAgICAvKiBGSVhNRTogb25seSBzdXBwb3J0IElQdjQgYXQgdGhlIG1vbWVudC4gaG93IGlzIElQdjYgcmVwcmVzZW50ZWQgYnkgdGhlIEVQTT8gKi8KICAgIGhpbnRzLmFpX2ZhbWlseSAgICAgICAgID0gUEZfSU5FVDsKICAgIGhpbnRzLmFpX3NvY2t0eXBlICAgICAgID0gU09DS19TVFJFQU07CiAgICBoaW50cy5haV9wcm90b2NvbCAgICAgICA9IElQUFJPVE9fVENQOwogICAgaGludHMuYWlfYWRkcmxlbiAgICAgICAgPSAwOwogICAgaGludHMuYWlfYWRkciAgICAgICAgICAgPSBOVUxMOwogICAgaGludHMuYWlfY2Fub25uYW1lICAgICAgPSBOVUxMOwogICAgaGludHMuYWlfbmV4dCAgICAgICAgICAgPSBOVUxMOwoKICAgIHJldCA9IGdldGFkZHJpbmZvKG5ldHdvcmthZGRyLCBlbmRwb2ludCwgJmhpbnRzLCAmYWkpOwogICAgaWYgKHJldCkKICAgIHsKICAgICAgICByZXQgPSBnZXRhZGRyaW5mbygiMC4wLjAuMCIsIGVuZHBvaW50LCAmaGludHMsICZhaSk7CiAgICAgICAgaWYgKHJldCkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiZ2V0YWRkcmluZm8gZmFpbGVkOiAlc1xuIiwgZ2FpX3N0cmVycm9yKHJldCkpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGFpLT5haV9mYW1pbHkgPT0gUEZfSU5FVCkKICAgIHsKICAgICAgICBjb25zdCBzdHJ1Y3Qgc29ja2FkZHJfaW4gKnNpbiA9IChjb25zdCBzdHJ1Y3Qgc29ja2FkZHJfaW4gKilhaS0+YWlfYWRkcjsKICAgICAgICB0Y3BfZmxvb3ItPnBvcnQgPSBzaW4tPnNpbl9wb3J0OwogICAgICAgIGlwdjRfZmxvb3ItPmlwdjRhZGRyID0gc2luLT5zaW5fYWRkci5zX2FkZHI7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRVJSKCJ1bmV4cGVjdGVkIHByb3RvY29sIGZhbWlseSAlZFxuIiwgYWktPmFpX2ZhbWlseSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgZnJlZWFkZHJpbmZvKGFpKTsKCiAgICByZXR1cm4gc2l6ZTsKfQoKc3RhdGljIFJQQ19TVEFUVVMgcnBjcnQ0X25jYWNuX2lwX3RjcF9wYXJzZV90b3Bfb2ZfdG93ZXIoY29uc3QgdW5zaWduZWQgY2hhciAqdG93ZXJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHRvd2VyX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKipuZXR3b3JrYWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqKmVuZHBvaW50KQp7CiAgICBjb25zdCB0d3JfdGNwX2Zsb29yX3QgKnRjcF9mbG9vciA9IChjb25zdCB0d3JfdGNwX2Zsb29yX3QgKil0b3dlcl9kYXRhOwogICAgY29uc3QgdHdyX2lwdjRfZmxvb3JfdCAqaXB2NF9mbG9vcjsKICAgIHN0cnVjdCBpbl9hZGRyIGluX2FkZHI7CgogICAgVFJBQ0UoIiglcCwgJWQsICVwLCAlcClcbiIsIHRvd2VyX2RhdGEsIChpbnQpdG93ZXJfc2l6ZSwgbmV0d29ya2FkZHIsIGVuZHBvaW50KTsKCiAgICBpZiAodG93ZXJfc2l6ZSA8IHNpemVvZigqdGNwX2Zsb29yKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CgogICAgdG93ZXJfZGF0YSArPSBzaXplb2YoKnRjcF9mbG9vcik7CiAgICB0b3dlcl9zaXplIC09IHNpemVvZigqdGNwX2Zsb29yKTsKCiAgICBpZiAodG93ZXJfc2l6ZSA8IHNpemVvZigqaXB2NF9mbG9vcikpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIGlwdjRfZmxvb3IgPSAoY29uc3QgdHdyX2lwdjRfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CgogICAgaWYgKCh0Y3BfZmxvb3ItPmNvdW50X2xocyAhPSBzaXplb2YodGNwX2Zsb29yLT5wcm90aWQpKSB8fAogICAgICAgICh0Y3BfZmxvb3ItPnByb3RpZCAhPSBFUE1fUFJPVE9DT0xfVENQKSB8fAogICAgICAgICh0Y3BfZmxvb3ItPmNvdW50X3JocyAhPSBzaXplb2YodGNwX2Zsb29yLT5wb3J0KSkgfHwKICAgICAgICAoaXB2NF9mbG9vci0+Y291bnRfbGhzICE9IHNpemVvZihpcHY0X2Zsb29yLT5wcm90aWQpKSB8fAogICAgICAgIChpcHY0X2Zsb29yLT5wcm90aWQgIT0gRVBNX1BST1RPQ09MX0lQKSB8fAogICAgICAgIChpcHY0X2Zsb29yLT5jb3VudF9yaHMgIT0gc2l6ZW9mKGlwdjRfZmxvb3ItPmlwdjRhZGRyKSkpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIGlmIChlbmRwb2ludCkKICAgIHsKICAgICAgICAqZW5kcG9pbnQgPSBJX1JwY0FsbG9jYXRlKDYgLyogc2l6ZW9mKCI2NTUzNSIpICsgMSAqLyk7CiAgICAgICAgaWYgKCEqZW5kcG9pbnQpCiAgICAgICAgICAgIHJldHVybiBSUENfU19PVVRfT0ZfUkVTT1VSQ0VTOwogICAgICAgIHNwcmludGYoKmVuZHBvaW50LCAiJXUiLCBudG9ocyh0Y3BfZmxvb3ItPnBvcnQpKTsKICAgIH0KCiAgICBpZiAobmV0d29ya2FkZHIpCiAgICB7CiAgICAgICAgKm5ldHdvcmthZGRyID0gSV9ScGNBbGxvY2F0ZShJTkVUX0FERFJTVFJMRU4pOwogICAgICAgIGlmICghKm5ldHdvcmthZGRyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGVuZHBvaW50KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBJX1JwY0ZyZWUoKmVuZHBvaW50KTsKICAgICAgICAgICAgICAgICplbmRwb2ludCA9IE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgICAgICAgfQogICAgICAgIGluX2FkZHIuc19hZGRyID0gaXB2NF9mbG9vci0+aXB2NGFkZHI7CiAgICAgICAgaWYgKCFpbmV0X250b3AoQUZfSU5FVCwgJmluX2FkZHIsICpuZXR3b3JrYWRkciwgSU5FVF9BRERSU1RSTEVOKSkKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiaW5ldF9udG9wOiAlc1xuIiwgc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgSV9ScGNGcmVlKCpuZXR3b3JrYWRkcik7CiAgICAgICAgICAgICpuZXR3b3JrYWRkciA9IE5VTEw7CiAgICAgICAgICAgIGlmIChlbmRwb2ludCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgSV9ScGNGcmVlKCplbmRwb2ludCk7CiAgICAgICAgICAgICAgICAqZW5kcG9pbnQgPSBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFJQQ19TX09LOwp9Cgp0eXBlZGVmIHN0cnVjdCBfUnBjU2VydmVyUHJvdHNlcV9zb2NrCnsKICAgIFJwY1NlcnZlclByb3RzZXEgY29tbW9uOwogICAgaW50IG1ncl9ldmVudF9yY3Y7CiAgICBpbnQgbWdyX2V2ZW50X3NuZDsKfSBScGNTZXJ2ZXJQcm90c2VxX3NvY2s7CgpzdGF0aWMgUnBjU2VydmVyUHJvdHNlcSAqcnBjcnQ0X3Byb3RzZXFfc29ja19hbGxvYyh2b2lkKQp7CiAgICBScGNTZXJ2ZXJQcm90c2VxX3NvY2sgKnBzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemVvZigqcHMpKTsKICAgIGlmIChwcykKICAgIHsKICAgICAgICBpbnQgZmRzWzJdOwogICAgICAgIGlmICghc29ja2V0cGFpcihQRl9VTklYLCBTT0NLX0RHUkFNLCAwLCBmZHMpKQogICAgICAgIHsKICAgICAgICAgICAgZmNudGwoZmRzWzBdLCBGX1NFVEZMLCBPX05PTkJMT0NLKTsKICAgICAgICAgICAgZmNudGwoZmRzWzFdLCBGX1NFVEZMLCBPX05PTkJMT0NLKTsKICAgICAgICAgICAgcHMtPm1ncl9ldmVudF9yY3YgPSBmZHNbMF07CiAgICAgICAgICAgIHBzLT5tZ3JfZXZlbnRfc25kID0gZmRzWzFdOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBFUlIoInNvY2tldHBhaXIgZmFpbGVkIHdpdGggZXJyb3IgJXNcbiIsIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBzKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuICZwcy0+Y29tbW9uOwp9CgpzdGF0aWMgdm9pZCBycGNydDRfcHJvdHNlcV9zb2NrX3NpZ25hbF9zdGF0ZV9jaGFuZ2VkKFJwY1NlcnZlclByb3RzZXEgKnByb3RzZXEpCnsKICAgIFJwY1NlcnZlclByb3RzZXFfc29jayAqc29ja3BzID0gQ09OVEFJTklOR19SRUNPUkQocHJvdHNlcSwgUnBjU2VydmVyUHJvdHNlcV9zb2NrLCBjb21tb24pOwogICAgY2hhciBkdW1teSA9IDE7CiAgICB3cml0ZShzb2NrcHMtPm1ncl9ldmVudF9zbmQsICZkdW1teSwgc2l6ZW9mKGR1bW15KSk7Cn0KCnN0YXRpYyB2b2lkICpycGNydDRfcHJvdHNlcV9zb2NrX2dldF93YWl0X2FycmF5KFJwY1NlcnZlclByb3RzZXEgKnByb3RzZXEsIHZvaWQgKnByZXZfYXJyYXksIHVuc2lnbmVkIGludCAqY291bnQpCnsKICAgIHN0cnVjdCBwb2xsZmQgKnBvbGxfaW5mbyA9IHByZXZfYXJyYXk7CiAgICBScGNDb25uZWN0aW9uX3RjcCAqY29ubjsKICAgIFJwY1NlcnZlclByb3RzZXFfc29jayAqc29ja3BzID0gQ09OVEFJTklOR19SRUNPUkQocHJvdHNlcSwgUnBjU2VydmVyUHJvdHNlcV9zb2NrLCBjb21tb24pOwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZwcm90c2VxLT5jcyk7CiAgICAKICAgIC8qIG9wZW4gYW5kIGNvdW50IGNvbm5lY3Rpb25zICovCiAgICAqY291bnQgPSAxOwogICAgY29ubiA9IChScGNDb25uZWN0aW9uX3RjcCAqKXByb3RzZXEtPmNvbm47CiAgICB3aGlsZSAoY29ubikgewogICAgICAgIGlmIChjb25uLT5zb2NrICE9IC0xKQogICAgICAgICAgICAoKmNvdW50KSsrOwogICAgICAgIGNvbm4gPSAoUnBjQ29ubmVjdGlvbl90Y3AgKiljb25uLT5jb21tb24uTmV4dDsKICAgIH0KICAgIAogICAgLyogbWFrZSBhcnJheSBvZiBjb25uZWN0aW9ucyAqLwogICAgaWYgKHBvbGxfaW5mbykKICAgICAgICBwb2xsX2luZm8gPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBwb2xsX2luZm8sICpjb3VudCpzaXplb2YoKnBvbGxfaW5mbykpOwogICAgZWxzZQogICAgICAgIHBvbGxfaW5mbyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCAqY291bnQqc2l6ZW9mKCpwb2xsX2luZm8pKTsKICAgIGlmICghcG9sbF9pbmZvKQogICAgewogICAgICAgIEVSUigiY291bGRuJ3QgYWxsb2NhdGUgcG9sbF9pbmZvXG4iKTsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcHJvdHNlcS0+Y3MpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHBvbGxfaW5mb1swXS5mZCA9IHNvY2twcy0+bWdyX2V2ZW50X3JjdjsKICAgIHBvbGxfaW5mb1swXS5ldmVudHMgPSBQT0xMSU47CiAgICAqY291bnQgPSAxOwogICAgY29ubiA9ICBDT05UQUlOSU5HX1JFQ09SRChwcm90c2VxLT5jb25uLCBScGNDb25uZWN0aW9uX3RjcCwgY29tbW9uKTsKICAgIHdoaWxlIChjb25uKSB7CiAgICAgICAgaWYgKGNvbm4tPnNvY2sgIT0gLTEpCiAgICAgICAgewogICAgICAgICAgICBwb2xsX2luZm9bKmNvdW50XS5mZCA9IGNvbm4tPnNvY2s7CiAgICAgICAgICAgIHBvbGxfaW5mb1sqY291bnRdLmV2ZW50cyA9IFBPTExJTjsKICAgICAgICAgICAgKCpjb3VudCkrKzsKICAgICAgICB9CiAgICAgICAgY29ubiA9IENPTlRBSU5JTkdfUkVDT1JEKGNvbm4tPmNvbW1vbi5OZXh0LCBScGNDb25uZWN0aW9uX3RjcCwgY29tbW9uKTsKICAgIH0KICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZwcm90c2VxLT5jcyk7CiAgICByZXR1cm4gcG9sbF9pbmZvOwp9CgpzdGF0aWMgdm9pZCBycGNydDRfcHJvdHNlcV9zb2NrX2ZyZWVfd2FpdF9hcnJheShScGNTZXJ2ZXJQcm90c2VxICpwcm90c2VxLCB2b2lkICphcnJheSkKewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYXJyYXkpOwp9CgpzdGF0aWMgaW50IHJwY3J0NF9wcm90c2VxX3NvY2tfd2FpdF9mb3JfbmV3X2Nvbm5lY3Rpb24oUnBjU2VydmVyUHJvdHNlcSAqcHJvdHNlcSwgdW5zaWduZWQgaW50IGNvdW50LCB2b2lkICp3YWl0X2FycmF5KQp7CiAgICBzdHJ1Y3QgcG9sbGZkICpwb2xsX2luZm8gPSB3YWl0X2FycmF5OwogICAgaW50IHJldCwgaTsKICAgIFJwY0Nvbm5lY3Rpb24gKmNjb25uOwogICAgUnBjQ29ubmVjdGlvbl90Y3AgKmNvbm47CiAgICAKICAgIGlmICghcG9sbF9pbmZvKQogICAgICAgIHJldHVybiAtMTsKICAgIAogICAgcmV0ID0gcG9sbChwb2xsX2luZm8sIGNvdW50LCAtMSk7CiAgICBpZiAocmV0IDwgMCkKICAgIHsKICAgICAgICBFUlIoInBvbGwgZmFpbGVkIHdpdGggZXJyb3IgJWRcbiIsIHJldCk7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKQogICAgICAgIGlmIChwb2xsX2luZm9baV0ucmV2ZW50cyAmIFBPTExJTikKICAgICAgICB7CiAgICAgICAgICAgIC8qIFJQQyBzZXJ2ZXIgZXZlbnQgKi8KICAgICAgICAgICAgaWYgKGkgPT0gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2hhciBkdW1teTsKICAgICAgICAgICAgICAgIHJlYWQocG9sbF9pbmZvWzBdLmZkLCAmZHVtbXksIHNpemVvZihkdW1teSkpOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGZpbmQgd2hpY2ggY29ubmVjdGlvbiBnb3QgYSBSUEMgKi8KICAgICAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJnByb3RzZXEtPmNzKTsKICAgICAgICAgICAgY29ubiA9IENPTlRBSU5JTkdfUkVDT1JEKHByb3RzZXEtPmNvbm4sIFJwY0Nvbm5lY3Rpb25fdGNwLCBjb21tb24pOwogICAgICAgICAgICB3aGlsZSAoY29ubikgewogICAgICAgICAgICAgICAgaWYgKHBvbGxfaW5mb1tpXS5mZCA9PSBjb25uLT5zb2NrKSBicmVhazsKICAgICAgICAgICAgICAgIGNvbm4gPSBDT05UQUlOSU5HX1JFQ09SRChjb25uLT5jb21tb24uTmV4dCwgUnBjQ29ubmVjdGlvbl90Y3AsIGNvbW1vbik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY2Nvbm4gPSBOVUxMOwogICAgICAgICAgICBpZiAoY29ubikKICAgICAgICAgICAgICAgIFJQQ1JUNF9TcGF3bkNvbm5lY3Rpb24oJmNjb25uLCAmY29ubi0+Y29tbW9uKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgRVJSKCJmYWlsZWQgdG8gbG9jYXRlIGNvbm5lY3Rpb24gZm9yIGZkICVkXG4iLCBwb2xsX2luZm9baV0uZmQpOwogICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmcHJvdHNlcS0+Y3MpOwogICAgICAgICAgICBpZiAoY2Nvbm4pCiAgICAgICAgICAgICAgICBSUENSVDRfbmV3X2NsaWVudChjY29ubik7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgcmV0dXJuIDE7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgY29ubmVjdGlvbl9vcHMgY29ubl9wcm90c2VxX2xpc3RbXSA9IHsKICB7ICJuY2Fjbl9ucCIsCiAgICB7IEVQTV9QUk9UT0NPTF9OQ0FDTiwgRVBNX1BST1RPQ09MX1NNQiB9LAogICAgcnBjcnQ0X2Nvbm5fbnBfYWxsb2MsCiAgICBycGNydDRfbmNhY25fbnBfb3BlbiwKICAgIHJwY3J0NF9uY2Fjbl9ucF9oYW5kb2ZmLAogICAgcnBjcnQ0X2Nvbm5fbnBfcmVhZCwKICAgIHJwY3J0NF9jb25uX25wX3dyaXRlLAogICAgcnBjcnQ0X2Nvbm5fbnBfY2xvc2UsCiAgICBycGNydDRfY29ubl9ucF9jYW5jZWxfY2FsbCwKICAgIHJwY3J0NF9uY2Fjbl9ucF9nZXRfdG9wX29mX3Rvd2VyLAogICAgcnBjcnQ0X25jYWNuX25wX3BhcnNlX3RvcF9vZl90b3dlciwKICB9LAogIHsgIm5jYWxycGMiLAogICAgeyBFUE1fUFJPVE9DT0xfTkNBTFJQQywgRVBNX1BST1RPQ09MX1BJUEUgfSwKICAgIHJwY3J0NF9jb25uX25wX2FsbG9jLAogICAgcnBjcnQ0X25jYWxycGNfb3BlbiwKICAgIHJwY3J0NF9uY2FscnBjX2hhbmRvZmYsCiAgICBycGNydDRfY29ubl9ucF9yZWFkLAogICAgcnBjcnQ0X2Nvbm5fbnBfd3JpdGUsCiAgICBycGNydDRfY29ubl9ucF9jbG9zZSwKICAgIHJwY3J0NF9jb25uX25wX2NhbmNlbF9jYWxsLAogICAgcnBjcnQ0X25jYWxycGNfZ2V0X3RvcF9vZl90b3dlciwKICAgIHJwY3J0NF9uY2FscnBjX3BhcnNlX3RvcF9vZl90b3dlciwKICB9LAogIHsgIm5jYWNuX2lwX3RjcCIsCiAgICB7IEVQTV9QUk9UT0NPTF9OQ0FDTiwgRVBNX1BST1RPQ09MX1RDUCB9LAogICAgcnBjcnQ0X2Nvbm5fdGNwX2FsbG9jLAogICAgcnBjcnQ0X25jYWNuX2lwX3RjcF9vcGVuLAogICAgcnBjcnQ0X2Nvbm5fdGNwX2hhbmRvZmYsCiAgICBycGNydDRfY29ubl90Y3BfcmVhZCwKICAgIHJwY3J0NF9jb25uX3RjcF93cml0ZSwKICAgIHJwY3J0NF9jb25uX3RjcF9jbG9zZSwKICAgIHJwY3J0NF9jb25uX3RjcF9jYW5jZWxfY2FsbCwKICAgIHJwY3J0NF9uY2Fjbl9pcF90Y3BfZ2V0X3RvcF9vZl90b3dlciwKICAgIHJwY3J0NF9uY2Fjbl9pcF90Y3BfcGFyc2VfdG9wX29mX3Rvd2VyLAogIH0KfTsKCgpzdGF0aWMgY29uc3Qgc3RydWN0IHByb3RzZXFfb3BzIHByb3RzZXFfbGlzdFtdID0KewogICAgewogICAgICAgICJuY2Fjbl9ucCIsCiAgICAgICAgcnBjcnQ0X3Byb3RzZXFfbnBfYWxsb2MsCiAgICAgICAgcnBjcnQ0X3Byb3RzZXFfbnBfc2lnbmFsX3N0YXRlX2NoYW5nZWQsCiAgICAgICAgcnBjcnQ0X3Byb3RzZXFfbnBfZ2V0X3dhaXRfYXJyYXksCiAgICAgICAgcnBjcnQ0X3Byb3RzZXFfbnBfZnJlZV93YWl0X2FycmF5LAogICAgICAgIHJwY3J0NF9wcm90c2VxX25wX3dhaXRfZm9yX25ld19jb25uZWN0aW9uLAogICAgICAgIHJwY3J0NF9wcm90c2VxX25jYWNuX25wX29wZW5fZW5kcG9pbnQsCiAgICB9LAogICAgewogICAgICAgICJuY2FscnBjIiwKICAgICAgICBycGNydDRfcHJvdHNlcV9ucF9hbGxvYywKICAgICAgICBycGNydDRfcHJvdHNlcV9ucF9zaWduYWxfc3RhdGVfY2hhbmdlZCwKICAgICAgICBycGNydDRfcHJvdHNlcV9ucF9nZXRfd2FpdF9hcnJheSwKICAgICAgICBycGNydDRfcHJvdHNlcV9ucF9mcmVlX3dhaXRfYXJyYXksCiAgICAgICAgcnBjcnQ0X3Byb3RzZXFfbnBfd2FpdF9mb3JfbmV3X2Nvbm5lY3Rpb24sCiAgICAgICAgcnBjcnQ0X3Byb3RzZXFfbmNhbHJwY19vcGVuX2VuZHBvaW50LAogICAgfSwKICAgIHsKICAgICAgICAibmNhY25faXBfdGNwIiwKICAgICAgICBycGNydDRfcHJvdHNlcV9zb2NrX2FsbG9jLAogICAgICAgIHJwY3J0NF9wcm90c2VxX3NvY2tfc2lnbmFsX3N0YXRlX2NoYW5nZWQsCiAgICAgICAgcnBjcnQ0X3Byb3RzZXFfc29ja19nZXRfd2FpdF9hcnJheSwKICAgICAgICBycGNydDRfcHJvdHNlcV9zb2NrX2ZyZWVfd2FpdF9hcnJheSwKICAgICAgICBycGNydDRfcHJvdHNlcV9zb2NrX3dhaXRfZm9yX25ld19jb25uZWN0aW9uLAogICAgICAgIHJwY3J0NF9wcm90c2VxX25jYWNuX2lwX3RjcF9vcGVuX2VuZHBvaW50LAogICAgfSwKfTsKCiNkZWZpbmUgQVJSQVlTSVpFKGEpIChzaXplb2YoKGEpKSAvIHNpemVvZigoYSlbMF0pKQoKY29uc3Qgc3RydWN0IHByb3RzZXFfb3BzICpycGNydDRfZ2V0X3Byb3RzZXFfb3BzKGNvbnN0IGNoYXIgKnByb3RzZXEpCnsKICBpbnQgaTsKICBmb3IoaT0wOyBpPEFSUkFZU0laRShwcm90c2VxX2xpc3QpOyBpKyspCiAgICBpZiAoIXN0cmNtcChwcm90c2VxX2xpc3RbaV0ubmFtZSwgcHJvdHNlcSkpCiAgICAgIHJldHVybiAmcHJvdHNlcV9saXN0W2ldOwogIHJldHVybiBOVUxMOwp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IGNvbm5lY3Rpb25fb3BzICpycGNydDRfZ2V0X2Nvbm5fcHJvdHNlcV9vcHMoY29uc3QgY2hhciAqcHJvdHNlcSkKewogICAgaW50IGk7CiAgICBmb3IoaT0wOyBpPEFSUkFZU0laRShjb25uX3Byb3RzZXFfbGlzdCk7IGkrKykKICAgICAgICBpZiAoIXN0cmNtcChjb25uX3Byb3RzZXFfbGlzdFtpXS5uYW1lLCBwcm90c2VxKSkKICAgICAgICAgICAgcmV0dXJuICZjb25uX3Byb3RzZXFfbGlzdFtpXTsKICAgIHJldHVybiBOVUxMOwp9CgovKioqKiBpbnRlcmZhY2UgdG8gcmVzdCBvZiBjb2RlICoqKiovCgpSUENfU1RBVFVTIFJQQ1JUNF9PcGVuQ2xpZW50Q29ubmVjdGlvbihScGNDb25uZWN0aW9uKiBDb25uZWN0aW9uKQp7CiAgVFJBQ0UoIihDb25uZWN0aW9uID09IF4lcClcbiIsIENvbm5lY3Rpb24pOwoKICBhc3NlcnQoIUNvbm5lY3Rpb24tPnNlcnZlcik7CiAgcmV0dXJuIENvbm5lY3Rpb24tPm9wcy0+b3Blbl9jb25uZWN0aW9uX2NsaWVudChDb25uZWN0aW9uKTsKfQoKUlBDX1NUQVRVUyBSUENSVDRfQ2xvc2VDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qIENvbm5lY3Rpb24pCnsKICBUUkFDRSgiKENvbm5lY3Rpb24gPT0gXiVwKVxuIiwgQ29ubmVjdGlvbik7CiAgaWYgKFNlY0lzVmFsaWRIYW5kbGUoJkNvbm5lY3Rpb24tPmN0eCkpCiAgewogICAgRGVsZXRlU2VjdXJpdHlDb250ZXh0KCZDb25uZWN0aW9uLT5jdHgpOwogICAgU2VjSW52YWxpZGF0ZUhhbmRsZSgmQ29ubmVjdGlvbi0+Y3R4KTsKICB9CiAgcnBjcnQ0X2Nvbm5fY2xvc2UoQ29ubmVjdGlvbik7CiAgcmV0dXJuIFJQQ19TX09LOwp9CgpSUENfU1RBVFVTIFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBCT09MIHNlcnZlciwKICAgIExQQ1NUUiBQcm90c2VxLCBMUENTVFIgTmV0d29ya0FkZHIsIExQQ1NUUiBFbmRwb2ludCwKICAgIExQQ1dTVFIgTmV0d29ya09wdGlvbnMsIFJwY0F1dGhJbmZvKiBBdXRoSW5mbywgUnBjUXVhbGl0eU9mU2VydmljZSAqUU9TKQp7CiAgY29uc3Qgc3RydWN0IGNvbm5lY3Rpb25fb3BzICpvcHM7CiAgUnBjQ29ubmVjdGlvbiogTmV3Q29ubmVjdGlvbjsKCiAgb3BzID0gcnBjcnQ0X2dldF9jb25uX3Byb3RzZXFfb3BzKFByb3RzZXEpOwogIGlmICghb3BzKQogIHsKICAgIEZJWE1FKCJub3Qgc3VwcG9ydGVkIGZvciBwcm90c2VxICVzXG4iLCBQcm90c2VxKTsKICAgIHJldHVybiBSUENfU19QUk9UU0VRX05PVF9TVVBQT1JURUQ7CiAgfQoKICBOZXdDb25uZWN0aW9uID0gb3BzLT5hbGxvYygpOwogIE5ld0Nvbm5lY3Rpb24tPk5leHQgPSBOVUxMOwogIE5ld0Nvbm5lY3Rpb24tPnNlcnZlciA9IHNlcnZlcjsKICBOZXdDb25uZWN0aW9uLT5vcHMgPSBvcHM7CiAgTmV3Q29ubmVjdGlvbi0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShOZXR3b3JrQWRkcik7CiAgTmV3Q29ubmVjdGlvbi0+RW5kcG9pbnQgPSBSUENSVDRfc3RyZHVwQShFbmRwb2ludCk7CiAgTmV3Q29ubmVjdGlvbi0+TmV0d29ya09wdGlvbnMgPSBSUENSVDRfc3RyZHVwVyhOZXR3b3JrT3B0aW9ucyk7CiAgTmV3Q29ubmVjdGlvbi0+TWF4VHJhbnNtaXNzaW9uU2l6ZSA9IFJQQ19NQVhfUEFDS0VUX1NJWkU7CiAgbWVtc2V0KCZOZXdDb25uZWN0aW9uLT5BY3RpdmVJbnRlcmZhY2UsIDAsIHNpemVvZihOZXdDb25uZWN0aW9uLT5BY3RpdmVJbnRlcmZhY2UpKTsKICBOZXdDb25uZWN0aW9uLT5OZXh0Q2FsbElkID0gMTsKCiAgU2VjSW52YWxpZGF0ZUhhbmRsZSgmTmV3Q29ubmVjdGlvbi0+Y3R4KTsKICBtZW1zZXQoJk5ld0Nvbm5lY3Rpb24tPmV4cCwgMCwgc2l6ZW9mKE5ld0Nvbm5lY3Rpb24tPmV4cCkpOwogIE5ld0Nvbm5lY3Rpb24tPmF0dHIgPSAwOwogIGlmIChBdXRoSW5mbykgUnBjQXV0aEluZm9fQWRkUmVmKEF1dGhJbmZvKTsKICBOZXdDb25uZWN0aW9uLT5BdXRoSW5mbyA9IEF1dGhJbmZvOwogIE5ld0Nvbm5lY3Rpb24tPmVuY3J5cHRpb25fYXV0aF9sZW4gPSAwOwogIE5ld0Nvbm5lY3Rpb24tPnNpZ25hdHVyZV9hdXRoX2xlbiA9IDA7CiAgaWYgKFFPUykgUnBjUXVhbGl0eU9mU2VydmljZV9BZGRSZWYoUU9TKTsKICBOZXdDb25uZWN0aW9uLT5RT1MgPSBRT1M7CgogIGxpc3RfaW5pdCgmTmV3Q29ubmVjdGlvbi0+Y29ubl9wb29sX2VudHJ5KTsKCiAgVFJBQ0UoImNvbm5lY3Rpb246ICVwXG4iLCBOZXdDb25uZWN0aW9uKTsKICAqQ29ubmVjdGlvbiA9IE5ld0Nvbm5lY3Rpb247CgogIHJldHVybiBSUENfU19PSzsKfQoKUlBDX1NUQVRVUyBSUENSVDRfR2V0QXNzb2NpYXRpb24oTFBDU1RSIFByb3RzZXEsIExQQ1NUUiBOZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIEVuZHBvaW50LCBMUENXU1RSIE5ldHdvcmtPcHRpb25zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBScGNBc3NvYyAqKmFzc29jX291dCkKewogIFJwY0Fzc29jICphc3NvYzsKCiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmFzc29jX2xpc3RfY3MpOwogIExJU1RfRk9SX0VBQ0hfRU5UUlkoYXNzb2MsICZhc3NvY19saXN0LCBScGNBc3NvYywgZW50cnkpCiAgewogICAgaWYgKCFzdHJjbXAoUHJvdHNlcSwgYXNzb2MtPlByb3RzZXEpICYmCiAgICAgICAgIXN0cmNtcChOZXR3b3JrQWRkciwgYXNzb2MtPk5ldHdvcmtBZGRyKSAmJgogICAgICAgICFzdHJjbXAoRW5kcG9pbnQsIGFzc29jLT5FbmRwb2ludCkgJiYKICAgICAgICAoKCFhc3NvYy0+TmV0d29ya09wdGlvbnMgJiYgIU5ldHdvcmtPcHRpb25zKSB8fCAhc3RyY21wVyhOZXR3b3JrT3B0aW9ucywgYXNzb2MtPk5ldHdvcmtPcHRpb25zKSkpCiAgICB7CiAgICAgIGFzc29jLT5yZWZzKys7CiAgICAgICphc3NvY19vdXQgPSBhc3NvYzsKICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmFzc29jX2xpc3RfY3MpOwogICAgICBUUkFDRSgidXNpbmcgZXhpc3RpbmcgYXNzb2MgJXBcbiIsIGFzc29jKTsKICAgICAgcmV0dXJuIFJQQ19TX09LOwogICAgfQogIH0KCiAgYXNzb2MgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKCphc3NvYykpOwogIGlmICghYXNzb2MpCiAgewogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmFzc29jX2xpc3RfY3MpOwogICAgcmV0dXJuIFJQQ19TX09VVF9PRl9SRVNPVVJDRVM7CiAgfQogIGFzc29jLT5yZWZzID0gMTsKICBsaXN0X2luaXQoJmFzc29jLT5jb25uZWN0aW9uX3Bvb2wpOwogIEluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJmFzc29jLT5jcyk7CiAgYXNzb2MtPlByb3RzZXEgPSBSUENSVDRfc3RyZHVwQShQcm90c2VxKTsKICBhc3NvYy0+TmV0d29ya0FkZHIgPSBSUENSVDRfc3RyZHVwQShOZXR3b3JrQWRkcik7CiAgYXNzb2MtPkVuZHBvaW50ID0gUlBDUlQ0X3N0cmR1cEEoRW5kcG9pbnQpOwogIGFzc29jLT5OZXR3b3JrT3B0aW9ucyA9IE5ldHdvcmtPcHRpb25zID8gUlBDUlQ0X3N0cmR1cFcoTmV0d29ya09wdGlvbnMpIDogTlVMTDsKICBhc3NvYy0+YXNzb2NfZ3JvdXBfaWQgPSAwOwogIGxpc3RfYWRkX2hlYWQoJmFzc29jX2xpc3QsICZhc3NvYy0+ZW50cnkpOwogICphc3NvY19vdXQgPSBhc3NvYzsKCiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmFzc29jX2xpc3RfY3MpOwoKICBUUkFDRSgibmV3IGFzc29jICVwXG4iLCBhc3NvYyk7CgogIHJldHVybiBSUENfU19PSzsKfQoKVUxPTkcgUnBjQXNzb2NfUmVsZWFzZShScGNBc3NvYyAqYXNzb2MpCnsKICBVTE9ORyByZWZzOwoKICBFbnRlckNyaXRpY2FsU2VjdGlvbigmYXNzb2NfbGlzdF9jcyk7CiAgcmVmcyA9IC0tYXNzb2MtPnJlZnM7CiAgaWYgKCFyZWZzKQogICAgbGlzdF9yZW1vdmUoJmFzc29jLT5lbnRyeSk7CiAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmFzc29jX2xpc3RfY3MpOwoKICBpZiAoIXJlZnMpCiAgewogICAgUnBjQ29ubmVjdGlvbiAqQ29ubmVjdGlvbiwgKmN1cnNvcjI7CgogICAgVFJBQ0UoImRlc3Ryb3lpbmcgYXNzb2MgJXBcbiIsIGFzc29jKTsKCiAgICBMSVNUX0ZPUl9FQUNIX0VOVFJZX1NBRkUoQ29ubmVjdGlvbiwgY3Vyc29yMiwgJmFzc29jLT5jb25uZWN0aW9uX3Bvb2wsIFJwY0Nvbm5lY3Rpb24sIGNvbm5fcG9vbF9lbnRyeSkKICAgIHsKICAgICAgbGlzdF9yZW1vdmUoJkNvbm5lY3Rpb24tPmNvbm5fcG9vbF9lbnRyeSk7CiAgICAgIFJQQ1JUNF9EZXN0cm95Q29ubmVjdGlvbihDb25uZWN0aW9uKTsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhc3NvYy0+TmV0d29ya09wdGlvbnMpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYXNzb2MtPkVuZHBvaW50KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGFzc29jLT5OZXR3b3JrQWRkcik7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhc3NvYy0+UHJvdHNlcSk7CgogICAgRGVsZXRlQ3JpdGljYWxTZWN0aW9uKCZhc3NvYy0+Y3MpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGFzc29jKTsKICB9CgogIHJldHVybiByZWZzOwp9CgojZGVmaW5lIFJPVU5EX1VQKHZhbHVlLCBhbGlnbm1lbnQpICgoKHZhbHVlKSArICgoYWxpZ25tZW50KSAtIDEpKSAmIH4oKGFsaWdubWVudCktMSkpCgpzdGF0aWMgUlBDX1NUQVRVUyBScGNBc3NvY19CaW5kQ29ubmVjdGlvbihjb25zdCBScGNBc3NvYyAqYXNzb2MsIFJwY0Nvbm5lY3Rpb24gKmNvbm4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqSW50ZXJmYWNlSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqVHJhbnNmZXJTeW50YXgpCnsKICBScGNQa3RIZHIgKmhkcjsKICBScGNQa3RIZHIgKnJlc3BvbnNlX2hkcjsKICBSUENfTUVTU0FHRSBtc2c7CiAgUlBDX1NUQVRVUyBzdGF0dXM7CgogIFRSQUNFKCJzZW5kaW5nIGJpbmQgcmVxdWVzdCB0byBzZXJ2ZXJcbiIpOwoKICBoZHIgPSBSUENSVDRfQnVpbGRCaW5kSGVhZGVyKE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUlBDX01BWF9QQUNLRVRfU0laRSwgUlBDX01BWF9QQUNLRVRfU0laRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzc29jLT5hc3NvY19ncm91cF9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludGVyZmFjZUlkLCBUcmFuc2ZlclN5bnRheCk7CgogIHN0YXR1cyA9IFJQQ1JUNF9TZW5kKGNvbm4sIGhkciwgTlVMTCwgMCk7CiAgUlBDUlQ0X0ZyZWVIZWFkZXIoaGRyKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgcmV0dXJuIHN0YXR1czsKCiAgc3RhdHVzID0gUlBDUlQ0X1JlY2VpdmUoY29ubiwgJnJlc3BvbnNlX2hkciwgJm1zZyk7CiAgaWYgKHN0YXR1cyAhPSBSUENfU19PSykKICB7CiAgICBFUlIoInJlY2VpdmUgZmFpbGVkXG4iKTsKICAgIHJldHVybiBzdGF0dXM7CiAgfQoKICBzd2l0Y2ggKHJlc3BvbnNlX2hkci0+Y29tbW9uLnB0eXBlKQogIHsKICBjYXNlIFBLVF9CSU5EX0FDSzoKICB7CiAgICBScGNBZGRyZXNzU3RyaW5nICpzZXJ2ZXJfYWRkcmVzcyA9IG1zZy5CdWZmZXI7CiAgICBpZiAoKG1zZy5CdWZmZXJMZW5ndGggPj0gRklFTERfT0ZGU0VUKFJwY0FkZHJlc3NTdHJpbmcsIHN0cmluZ1swXSkpIHx8CiAgICAgICAgKG1zZy5CdWZmZXJMZW5ndGggPj0gUk9VTkRfVVAoRklFTERfT0ZGU0VUKFJwY0FkZHJlc3NTdHJpbmcsIHN0cmluZ1tzZXJ2ZXJfYWRkcmVzcy0+bGVuZ3RoXSksIDQpKSkKICAgIHsKICAgICAgICB1bnNpZ25lZCBzaG9ydCByZW1haW5pbmcgPSBtc2cuQnVmZmVyTGVuZ3RoIC0KICAgICAgICAgICAgUk9VTkRfVVAoRklFTERfT0ZGU0VUKFJwY0FkZHJlc3NTdHJpbmcsIHN0cmluZ1tzZXJ2ZXJfYWRkcmVzcy0+bGVuZ3RoXSksIDQpOwogICAgICAgIFJwY1Jlc3VsdHMgKnJlc3VsdHMgPSAoUnBjUmVzdWx0cyopKChVTE9OR19QVFIpc2VydmVyX2FkZHJlc3MgKwogICAgICAgICAgICBST1VORF9VUChGSUVMRF9PRkZTRVQoUnBjQWRkcmVzc1N0cmluZywgc3RyaW5nW3NlcnZlcl9hZGRyZXNzLT5sZW5ndGhdKSwgNCkpOwogICAgICAgIGlmICgocmVzdWx0cy0+bnVtX3Jlc3VsdHMgPT0gMSkgJiYgKHJlbWFpbmluZyA+PSBzaXplb2YoKnJlc3VsdHMpKSkKICAgICAgICB7CiAgICAgICAgICAgIHN3aXRjaCAocmVzdWx0cy0+cmVzdWx0c1swXS5yZXN1bHQpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBSRVNVTFRfQUNDRVBUOgogICAgICAgICAgICAgICAgY29ubi0+YXNzb2NfZ3JvdXBfaWQgPSByZXNwb25zZV9oZHItPmJpbmRfYWNrLmFzc29jX2dpZDsKICAgICAgICAgICAgICAgIGNvbm4tPk1heFRyYW5zbWlzc2lvblNpemUgPSByZXNwb25zZV9oZHItPmJpbmRfYWNrLm1heF90c2l6ZTsKICAgICAgICAgICAgICAgIGNvbm4tPkFjdGl2ZUludGVyZmFjZSA9ICpJbnRlcmZhY2VJZDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFU1VMVF9QUk9WSURFUl9SRUpFQ1RJT046CiAgICAgICAgICAgICAgICBzd2l0Y2ggKHJlc3VsdHMtPnJlc3VsdHNbMF0ucmVhc29uKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY2FzZSBSRUFTT05fQUJTVFJBQ1RfU1lOVEFYX05PVF9TVVBQT1JURUQ6CiAgICAgICAgICAgICAgICAgICAgRVJSKCJzeW50YXggJXMsICVkLiVkIG5vdCBzdXBwb3J0ZWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIGRlYnVnc3RyX2d1aWQoJkludGVyZmFjZUlkLT5TeW50YXhHVUlEKSwKICAgICAgICAgICAgICAgICAgICAgICAgSW50ZXJmYWNlSWQtPlN5bnRheFZlcnNpb24uTWFqb3JWZXJzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICBJbnRlcmZhY2VJZC0+U3ludGF4VmVyc2lvbi5NaW5vclZlcnNpb24pOwogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IFJQQ19TX1VOS05PV05fSUY7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIFJFQVNPTl9UUkFOU0ZFUl9TWU5UQVhFU19OT1RfU1VQUE9SVEVEOgogICAgICAgICAgICAgICAgICAgIEVSUigidHJhbnNmZXIgc3ludGF4IG5vdCBzdXBwb3J0ZWRcbiIpOwogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IFJQQ19TX1NFUlZFUl9VTkFWQUlMQUJMRTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgUkVBU09OX05PTkU6CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IFJQQ19TX0NBTExfRkFJTEVEX0RORTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFU1VMVF9VU0VSX1JFSkVDVElPTjoKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEVSUigicmVqZWN0aW9uIHJlc3VsdCAlZFxuIiwgcmVzdWx0cy0+cmVzdWx0c1swXS5yZXN1bHQpOwogICAgICAgICAgICAgICAgc3RhdHVzID0gUlBDX1NfQ0FMTF9GQUlMRURfRE5FOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiaW5jb3JyZWN0IHJlc3VsdHMgc2l6ZVxuIik7CiAgICAgICAgICAgIHN0YXR1cyA9IFJQQ19TX0NBTExfRkFJTEVEX0RORTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRVJSKCJiaW5kIGFjayBwYWNrZXQgdG9vIHNtYWxsICglZClcbiIsIG1zZy5CdWZmZXJMZW5ndGgpOwogICAgICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgfQogICAgYnJlYWs7CiAgfQogIGNhc2UgUEtUX0JJTkRfTkFDSzoKICAgIHN3aXRjaCAocmVzcG9uc2VfaGRyLT5iaW5kX25hY2sucmVqZWN0X3JlYXNvbikKICAgIHsKICAgIGNhc2UgUkVKRUNUX0xPQ0FMX0xJTUlUX0VYQ0VFREVEOgogICAgY2FzZSBSRUpFQ1RfVEVNUE9SQVJZX0NPTkdFU1RJT046CiAgICAgICAgRVJSKCJzZXJ2ZXIgdG9vIGJ1c3lcbiIpOwogICAgICAgIHN0YXR1cyA9IFJQQ19TX1NFUlZFUl9UT09fQlVTWTsKICAgICAgICBicmVhazsKICAgIGNhc2UgUkVKRUNUX1BST1RPQ09MX1ZFUlNJT05fTk9UX1NVUFBPUlRFRDoKICAgICAgICBFUlIoInByb3RvY29sIHZlcnNpb24gbm90IHN1cHBvcnRlZFxuIik7CiAgICAgICAgc3RhdHVzID0gUlBDX1NfUFJPVE9DT0xfRVJST1I7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFJFSkVDVF9VTktOT1dOX0FVVEhOX1NFUlZJQ0U6CiAgICAgICAgRVJSKCJ1bmtub3duIGF1dGhlbnRpY2F0aW9uIHNlcnZpY2VcbiIpOwogICAgICAgIHN0YXR1cyA9IFJQQ19TX1VOS05PV05fQVVUSE5fU0VSVklDRTsKICAgICAgICBicmVhazsKICAgIGNhc2UgUkVKRUNUX0lOVkFMSURfQ0hFQ0tTVU06CiAgICAgICAgRVJSKCJpbnZhbGlkIGNoZWNrc3VtXG4iKTsKICAgICAgICBzdGF0dXMgPSBFUlJPUl9BQ0NFU1NfREVOSUVEOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBFUlIoInJlamVjdGVkIGJpbmQgZm9yIHJlYXNvbiAlZFxuIiwgcmVzcG9uc2VfaGRyLT5iaW5kX25hY2sucmVqZWN0X3JlYXNvbik7CiAgICAgICAgc3RhdHVzID0gUlBDX1NfQ0FMTF9GQUlMRURfRE5FOwogICAgfQogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIEVSUigid3JvbmcgcGFja2V0IHR5cGUgcmVjZWl2ZWQgJWRcbiIsIHJlc3BvbnNlX2hkci0+Y29tbW9uLnB0eXBlKTsKICAgIHN0YXR1cyA9IFJQQ19TX1BST1RPQ09MX0VSUk9SOwogICAgYnJlYWs7CiAgfQoKICBJX1JwY0ZyZWVCdWZmZXIoJm1zZyk7CiAgUlBDUlQ0X0ZyZWVIZWFkZXIocmVzcG9uc2VfaGRyKTsKICByZXR1cm4gc3RhdHVzOwp9CgpzdGF0aWMgUnBjQ29ubmVjdGlvbiAqUnBjQXNzb2NfR2V0SWRsZUNvbm5lY3Rpb24oUnBjQXNzb2MgKmFzc29jLAogICAgY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICpJbnRlcmZhY2VJZCwKICAgIGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqVHJhbnNmZXJTeW50YXgsIGNvbnN0IFJwY0F1dGhJbmZvICpBdXRoSW5mbywKICAgIGNvbnN0IFJwY1F1YWxpdHlPZlNlcnZpY2UgKlFPUykKewogIFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb247CiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmFzc29jLT5jcyk7CiAgLyogdHJ5IHRvIGZpbmQgYSBjb21wYXRpYmxlIGNvbm5lY3Rpb24gZnJvbSB0aGUgY29ubmVjdGlvbiBwb29sICovCiAgTElTVF9GT1JfRUFDSF9FTlRSWShDb25uZWN0aW9uLCAmYXNzb2MtPmNvbm5lY3Rpb25fcG9vbCwgUnBjQ29ubmVjdGlvbiwgY29ubl9wb29sX2VudHJ5KQogIHsKICAgIGlmICghbWVtY21wKCZDb25uZWN0aW9uLT5BY3RpdmVJbnRlcmZhY2UsIEludGVyZmFjZUlkLAogICAgICAgICAgICAgICAgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpICYmCiAgICAgICAgUnBjQXV0aEluZm9fSXNFcXVhbChDb25uZWN0aW9uLT5BdXRoSW5mbywgQXV0aEluZm8pICYmCiAgICAgICAgUnBjUXVhbGl0eU9mU2VydmljZV9Jc0VxdWFsKENvbm5lY3Rpb24tPlFPUywgUU9TKSkKICAgIHsKICAgICAgbGlzdF9yZW1vdmUoJkNvbm5lY3Rpb24tPmNvbm5fcG9vbF9lbnRyeSk7CiAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZhc3NvYy0+Y3MpOwogICAgICBUUkFDRSgiZ290IGNvbm5lY3Rpb24gZnJvbSBwb29sICVwXG4iLCBDb25uZWN0aW9uKTsKICAgICAgcmV0dXJuIENvbm5lY3Rpb247CiAgICB9CiAgfQoKICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmYXNzb2MtPmNzKTsKICByZXR1cm4gTlVMTDsKfQoKUlBDX1NUQVRVUyBScGNBc3NvY19HZXRDbGllbnRDb25uZWN0aW9uKFJwY0Fzc29jICphc3NvYywKICAgIGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqSW50ZXJmYWNlSWQsCiAgICBjb25zdCBSUENfU1lOVEFYX0lERU5USUZJRVIgKlRyYW5zZmVyU3ludGF4LCBScGNBdXRoSW5mbyAqQXV0aEluZm8sCiAgICBScGNRdWFsaXR5T2ZTZXJ2aWNlICpRT1MsIFJwY0Nvbm5lY3Rpb24gKipDb25uZWN0aW9uKQp7CiAgUnBjQ29ubmVjdGlvbiAqTmV3Q29ubmVjdGlvbjsKICBSUENfU1RBVFVTIHN0YXR1czsKCiAgKkNvbm5lY3Rpb24gPSBScGNBc3NvY19HZXRJZGxlQ29ubmVjdGlvbihhc3NvYywgSW50ZXJmYWNlSWQsIFRyYW5zZmVyU3ludGF4LCBBdXRoSW5mbywgUU9TKTsKICBpZiAoKkNvbm5lY3Rpb24pCiAgICByZXR1cm4gUlBDX1NfT0s7CgogIC8qIGNyZWF0ZSBhIG5ldyBjb25uZWN0aW9uICovCiAgc3RhdHVzID0gUlBDUlQ0X0NyZWF0ZUNvbm5lY3Rpb24oJk5ld0Nvbm5lY3Rpb24sIEZBTFNFIC8qIGlzIHRoaXMgYSBzZXJ2ZXIgY29ubmVjdGlvbj8gKi8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXNzb2MtPlByb3RzZXEsIGFzc29jLT5OZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhc3NvYy0+RW5kcG9pbnQsIGFzc29jLT5OZXR3b3JrT3B0aW9ucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBdXRoSW5mbywgUU9TKTsKICBpZiAoc3RhdHVzICE9IFJQQ19TX09LKQogICAgcmV0dXJuIHN0YXR1czsKCiAgc3RhdHVzID0gUlBDUlQ0X09wZW5DbGllbnRDb25uZWN0aW9uKE5ld0Nvbm5lY3Rpb24pOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgewogICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKE5ld0Nvbm5lY3Rpb24pOwogICAgcmV0dXJuIHN0YXR1czsKICB9CgogIHN0YXR1cyA9IFJwY0Fzc29jX0JpbmRDb25uZWN0aW9uKGFzc29jLCBOZXdDb25uZWN0aW9uLCBJbnRlcmZhY2VJZCwgVHJhbnNmZXJTeW50YXgpOwogIGlmIChzdGF0dXMgIT0gUlBDX1NfT0spCiAgewogICAgUlBDUlQ0X0Rlc3Ryb3lDb25uZWN0aW9uKE5ld0Nvbm5lY3Rpb24pOwogICAgcmV0dXJuIHN0YXR1czsKICB9CgogICpDb25uZWN0aW9uID0gTmV3Q29ubmVjdGlvbjsKCiAgcmV0dXJuIFJQQ19TX09LOwp9Cgp2b2lkIFJwY0Fzc29jX1JlbGVhc2VJZGxlQ29ubmVjdGlvbihScGNBc3NvYyAqYXNzb2MsIFJwY0Nvbm5lY3Rpb24gKkNvbm5lY3Rpb24pCnsKICBhc3NlcnQoIUNvbm5lY3Rpb24tPnNlcnZlcik7CiAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmFzc29jLT5jcyk7CiAgaWYgKCFhc3NvYy0+YXNzb2NfZ3JvdXBfaWQpIGFzc29jLT5hc3NvY19ncm91cF9pZCA9IENvbm5lY3Rpb24tPmFzc29jX2dyb3VwX2lkOwogIGxpc3RfYWRkX2hlYWQoJmFzc29jLT5jb25uZWN0aW9uX3Bvb2wsICZDb25uZWN0aW9uLT5jb25uX3Bvb2xfZW50cnkpOwogIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZhc3NvYy0+Y3MpOwp9CgoKUlBDX1NUQVRVUyBSUENSVDRfU3Bhd25Db25uZWN0aW9uKFJwY0Nvbm5lY3Rpb24qKiBDb25uZWN0aW9uLCBScGNDb25uZWN0aW9uKiBPbGRDb25uZWN0aW9uKQp7CiAgUlBDX1NUQVRVUyBlcnI7CgogIGVyciA9IFJQQ1JUNF9DcmVhdGVDb25uZWN0aW9uKENvbm5lY3Rpb24sIE9sZENvbm5lY3Rpb24tPnNlcnZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBycGNydDRfY29ubl9nZXRfbmFtZShPbGRDb25uZWN0aW9uKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPbGRDb25uZWN0aW9uLT5OZXR3b3JrQWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPbGRDb25uZWN0aW9uLT5FbmRwb2ludCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPbGRDb25uZWN0aW9uLT5BdXRoSW5mbywgT2xkQ29ubmVjdGlvbi0+UU9TKTsKICBpZiAoZXJyID09IFJQQ19TX09LKQogICAgcnBjcnQ0X2Nvbm5faGFuZG9mZihPbGRDb25uZWN0aW9uLCAqQ29ubmVjdGlvbik7CiAgcmV0dXJuIGVycjsKfQoKUlBDX1NUQVRVUyBSUENSVDRfRGVzdHJveUNvbm5lY3Rpb24oUnBjQ29ubmVjdGlvbiogQ29ubmVjdGlvbikKewogIFRSQUNFKCJjb25uZWN0aW9uOiAlcFxuIiwgQ29ubmVjdGlvbik7CgogIFJQQ1JUNF9DbG9zZUNvbm5lY3Rpb24oQ29ubmVjdGlvbik7CiAgUlBDUlQ0X3N0cmZyZWUoQ29ubmVjdGlvbi0+RW5kcG9pbnQpOwogIFJQQ1JUNF9zdHJmcmVlKENvbm5lY3Rpb24tPk5ldHdvcmtBZGRyKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBDb25uZWN0aW9uLT5OZXR3b3JrT3B0aW9ucyk7CiAgaWYgKENvbm5lY3Rpb24tPkF1dGhJbmZvKSBScGNBdXRoSW5mb19SZWxlYXNlKENvbm5lY3Rpb24tPkF1dGhJbmZvKTsKICBpZiAoQ29ubmVjdGlvbi0+UU9TKSBScGNRdWFsaXR5T2ZTZXJ2aWNlX1JlbGVhc2UoQ29ubmVjdGlvbi0+UU9TKTsKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBDb25uZWN0aW9uKTsKICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUnBjVHJhbnNwb3J0X0dldFRvcE9mVG93ZXIodW5zaWduZWQgY2hhciAqdG93ZXJfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKnRvd2VyX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqcHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpuZXR3b3JrYWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplbmRwb2ludCkKewogICAgdHdyX2VtcHR5X2Zsb29yX3QgKnByb3RvY29sX2Zsb29yOwogICAgY29uc3Qgc3RydWN0IGNvbm5lY3Rpb25fb3BzICpwcm90c2VxX29wcyA9IHJwY3J0NF9nZXRfY29ubl9wcm90c2VxX29wcyhwcm90c2VxKTsKCiAgICAqdG93ZXJfc2l6ZSA9IDA7CgogICAgaWYgKCFwcm90c2VxX29wcykKICAgICAgICByZXR1cm4gUlBDX1NfSU5WQUxJRF9SUENfUFJPVFNFUTsKCiAgICBpZiAoIXRvd2VyX2RhdGEpCiAgICB7CiAgICAgICAgKnRvd2VyX3NpemUgPSBzaXplb2YoKnByb3RvY29sX2Zsb29yKTsKICAgICAgICAqdG93ZXJfc2l6ZSArPSBwcm90c2VxX29wcy0+Z2V0X3RvcF9vZl90b3dlcihOVUxMLCBuZXR3b3JrYWRkciwgZW5kcG9pbnQpOwogICAgICAgIHJldHVybiBSUENfU19PSzsKICAgIH0KCiAgICBwcm90b2NvbF9mbG9vciA9ICh0d3JfZW1wdHlfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CiAgICBwcm90b2NvbF9mbG9vci0+Y291bnRfbGhzID0gc2l6ZW9mKHByb3RvY29sX2Zsb29yLT5wcm90aWQpOwogICAgcHJvdG9jb2xfZmxvb3ItPnByb3RpZCA9IHByb3RzZXFfb3BzLT5lcG1fcHJvdG9jb2xzWzBdOwogICAgcHJvdG9jb2xfZmxvb3ItPmNvdW50X3JocyA9IDA7CgogICAgdG93ZXJfZGF0YSArPSBzaXplb2YoKnByb3RvY29sX2Zsb29yKTsKCiAgICAqdG93ZXJfc2l6ZSA9IHByb3RzZXFfb3BzLT5nZXRfdG9wX29mX3Rvd2VyKHRvd2VyX2RhdGEsIG5ldHdvcmthZGRyLCBlbmRwb2ludCk7CiAgICBpZiAoISp0b3dlcl9zaXplKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICAqdG93ZXJfc2l6ZSArPSBzaXplb2YoKnByb3RvY29sX2Zsb29yKTsKCiAgICByZXR1cm4gUlBDX1NfT0s7Cn0KClJQQ19TVEFUVVMgUnBjVHJhbnNwb3J0X1BhcnNlVG9wT2ZUb3dlcihjb25zdCB1bnNpZ25lZCBjaGFyICp0b3dlcl9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHRvd2VyX3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyICoqcHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKipuZXR3b3JrYWRkciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgKiplbmRwb2ludCkKewogICAgY29uc3QgdHdyX2VtcHR5X2Zsb29yX3QgKnByb3RvY29sX2Zsb29yOwogICAgY29uc3QgdHdyX2VtcHR5X2Zsb29yX3QgKmZsb29yNDsKICAgIGNvbnN0IHN0cnVjdCBjb25uZWN0aW9uX29wcyAqcHJvdHNlcV9vcHMgPSBOVUxMOwogICAgUlBDX1NUQVRVUyBzdGF0dXM7CiAgICBpbnQgaTsKCiAgICBpZiAodG93ZXJfc2l6ZSA8IHNpemVvZigqcHJvdG9jb2xfZmxvb3IpKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICBwcm90b2NvbF9mbG9vciA9IChjb25zdCB0d3JfZW1wdHlfZmxvb3JfdCAqKXRvd2VyX2RhdGE7CiAgICB0b3dlcl9kYXRhICs9IHNpemVvZigqcHJvdG9jb2xfZmxvb3IpOwogICAgdG93ZXJfc2l6ZSAtPSBzaXplb2YoKnByb3RvY29sX2Zsb29yKTsKICAgIGlmICgocHJvdG9jb2xfZmxvb3ItPmNvdW50X2xocyAhPSBzaXplb2YocHJvdG9jb2xfZmxvb3ItPnByb3RpZCkpIHx8CiAgICAgICAgKHByb3RvY29sX2Zsb29yLT5jb3VudF9yaHMgPiB0b3dlcl9zaXplKSkKICAgICAgICByZXR1cm4gRVBUX1NfTk9UX1JFR0lTVEVSRUQ7CiAgICB0b3dlcl9kYXRhICs9IHByb3RvY29sX2Zsb29yLT5jb3VudF9yaHM7CiAgICB0b3dlcl9zaXplIC09IHByb3RvY29sX2Zsb29yLT5jb3VudF9yaHM7CgogICAgZmxvb3I0ID0gKGNvbnN0IHR3cl9lbXB0eV9mbG9vcl90ICopdG93ZXJfZGF0YTsKICAgIGlmICgodG93ZXJfc2l6ZSA8IHNpemVvZigqZmxvb3I0KSkgfHwKICAgICAgICAoZmxvb3I0LT5jb3VudF9saHMgIT0gc2l6ZW9mKGZsb29yNC0+cHJvdGlkKSkpCiAgICAgICAgcmV0dXJuIEVQVF9TX05PVF9SRUdJU1RFUkVEOwoKICAgIGZvcihpID0gMDsgaSA8IEFSUkFZU0laRShjb25uX3Byb3RzZXFfbGlzdCk7IGkrKykKICAgICAgICBpZiAoKHByb3RvY29sX2Zsb29yLT5wcm90aWQgPT0gY29ubl9wcm90c2VxX2xpc3RbaV0uZXBtX3Byb3RvY29sc1swXSkgJiYKICAgICAgICAgICAgKGZsb29yNC0+cHJvdGlkID09IGNvbm5fcHJvdHNlcV9saXN0W2ldLmVwbV9wcm90b2NvbHNbMV0pKQogICAgICAgIHsKICAgICAgICAgICAgcHJvdHNlcV9vcHMgPSAmY29ubl9wcm90c2VxX2xpc3RbaV07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KCiAgICBpZiAoIXByb3RzZXFfb3BzKQogICAgICAgIHJldHVybiBFUFRfU19OT1RfUkVHSVNURVJFRDsKCiAgICBzdGF0dXMgPSBwcm90c2VxX29wcy0+cGFyc2VfdG9wX29mX3Rvd2VyKHRvd2VyX2RhdGEsIHRvd2VyX3NpemUsIG5ldHdvcmthZGRyLCBlbmRwb2ludCk7CgogICAgaWYgKChzdGF0dXMgPT0gUlBDX1NfT0spICYmIHByb3RzZXEpCiAgICB7CiAgICAgICAgKnByb3RzZXEgPSBJX1JwY0FsbG9jYXRlKHN0cmxlbihwcm90c2VxX29wcy0+bmFtZSkgKyAxKTsKICAgICAgICBzdHJjcHkoKnByb3RzZXEsIHByb3RzZXFfb3BzLT5uYW1lKTsKICAgIH0KCiAgICByZXR1cm4gc3RhdHVzOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyAoUlBDUlQ0LkApCiAqCiAqIENoZWNrcyBpZiB0aGUgZ2l2ZW4gcHJvdG9jb2wgc2VxdWVuY2UgaXMga25vd24gYnkgdGhlIFJQQyBzeXN0ZW0uCiAqIElmIGl0IGlzLCByZXR1cm5zIFJQQ19TX09LLCBvdGhlcndpc2UgUlBDX1NfUFJPVFNFUV9OT1RfU1VQUE9SVEVELgogKgogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkVyhSUENfV1NUUiBwcm90c2VxKQp7CiAgY2hhciBwc1sweDEwXTsKCiAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHByb3RzZXEsIC0xLAogICAgICAgICAgICAgICAgICAgICAgcHMsIHNpemVvZiBwcywgTlVMTCwgTlVMTCk7CiAgaWYgKHJwY3J0NF9nZXRfY29ubl9wcm90c2VxX29wcyhwcykpCiAgICByZXR1cm4gUlBDX1NfT0s7CgogIEZJWE1FKCJVbmtub3duIHByb3RzZXEgJXNcbiIsIGRlYnVnc3RyX3cocHJvdHNlcSkpOwoKICByZXR1cm4gUlBDX1NfSU5WQUxJRF9SUENfUFJPVFNFUTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgIFJwY05ldHdvcmtJc1Byb3RzZXFWYWxpZEEgKFJQQ1JUNC5AKQogKi8KUlBDX1NUQVRVUyBXSU5BUEkgUnBjTmV0d29ya0lzUHJvdHNlcVZhbGlkQShSUENfQ1NUUiBwcm90c2VxKQp7CiAgVU5JQ09ERV9TVFJJTkcgcHJvdHNlcVc7CgogIGlmIChSdGxDcmVhdGVVbmljb2RlU3RyaW5nRnJvbUFzY2lpeigmcHJvdHNlcVcsIChjaGFyKilwcm90c2VxKSkKICB7CiAgICBSUENfU1RBVFVTIHJldCA9IFJwY05ldHdvcmtJc1Byb3RzZXFWYWxpZFcocHJvdHNlcVcuQnVmZmVyKTsKICAgIFJ0bEZyZWVVbmljb2RlU3RyaW5nKCZwcm90c2VxVyk7CiAgICByZXR1cm4gcmV0OwogIH0KICByZXR1cm4gUlBDX1NfT1VUX09GX01FTU9SWTsKfQo=