LyoKIElNUE9SVEFOVDogIFRoaXMgQXBwbGUgc29mdHdhcmUgaXMgc3VwcGxpZWQgdG8geW91IGJ5IEFwcGxlIENvbXB1dGVyLCBJbmMuICgiQXBwbGUiKSBpbgogY29uc2lkZXJhdGlvbiBvZiB5b3VyIGFncmVlbWVudCB0byB0aGUgZm9sbG93aW5nIHRlcm1zLCBhbmQgeW91ciB1c2UsIGluc3RhbGxhdGlvbiwgCiBtb2RpZmljYXRpb24gb3IgcmVkaXN0cmlidXRpb24gb2YgdGhpcyBBcHBsZSBzb2Z0d2FyZSBjb25zdGl0dXRlcyBhY2NlcHRhbmNlIG9mIHRoZXNlIAogdGVybXMuICBJZiB5b3UgZG8gbm90IGFncmVlIHdpdGggdGhlc2UgdGVybXMsIHBsZWFzZSBkbyBub3QgdXNlLCBpbnN0YWxsLCBtb2RpZnkgb3IgCiByZWRpc3RyaWJ1dGUgdGhpcyBBcHBsZSBzb2Z0d2FyZS4KIAogSW4gY29uc2lkZXJhdGlvbiBvZiB5b3VyIGFncmVlbWVudCB0byBhYmlkZSBieSB0aGUgZm9sbG93aW5nIHRlcm1zLCBhbmQgc3ViamVjdCB0byB0aGVzZSAKIHRlcm1zLCBBcHBsZSBncmFudHMgeW91IGEgcGVyc29uYWwsIG5vbi1leGNsdXNpdmUgbGljZW5zZSwgdW5kZXIgQXBwbGXVcyBjb3B5cmlnaHRzIGluIAogdGhpcyBvcmlnaW5hbCBBcHBsZSBzb2Z0d2FyZSAodGhlICJBcHBsZSBTb2Z0d2FyZSIpLCB0byB1c2UsIHJlcHJvZHVjZSwgbW9kaWZ5IGFuZCAKIHJlZGlzdHJpYnV0ZSB0aGUgQXBwbGUgU29mdHdhcmUsIHdpdGggb3Igd2l0aG91dCBtb2RpZmljYXRpb25zLCBpbiBzb3VyY2UgYW5kL29yIGJpbmFyeSAKIGZvcm1zOyBwcm92aWRlZCB0aGF0IGlmIHlvdSByZWRpc3RyaWJ1dGUgdGhlIEFwcGxlIFNvZnR3YXJlIGluIGl0cyBlbnRpcmV0eSBhbmQgd2l0aG91dCAKIG1vZGlmaWNhdGlvbnMsIHlvdSBtdXN0IHJldGFpbiB0aGlzIG5vdGljZSBhbmQgdGhlIGZvbGxvd2luZyB0ZXh0IGFuZCBkaXNjbGFpbWVycyBpbiBhbGwgCiBzdWNoIHJlZGlzdHJpYnV0aW9ucyBvZiB0aGUgQXBwbGUgU29mdHdhcmUuICBOZWl0aGVyIHRoZSBuYW1lLCB0cmFkZW1hcmtzLCBzZXJ2aWNlIG1hcmtzIAogb3IgbG9nb3Mgb2YgQXBwbGUgQ29tcHV0ZXIsIEluYy4gbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSAKIHRoZSBBcHBsZSBTb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBmcm9tIEFwcGxlLiBFeGNlcHQgYXMgZXhwcmVzc2x5CiBzdGF0ZWQgaW4gdGhpcyBub3RpY2UsIG5vIG90aGVyIHJpZ2h0cyBvciBsaWNlbnNlcywgZXhwcmVzcyBvciBpbXBsaWVkLCBhcmUgZ3JhbnRlZCBieSBBcHBsZQogaGVyZWluLCBpbmNsdWRpbmcgYnV0IG5vdCBsaW1pdGVkIHRvIGFueSBwYXRlbnQgcmlnaHRzIHRoYXQgbWF5IGJlIGluZnJpbmdlZCBieSB5b3VyIAogZGVyaXZhdGl2ZSB3b3JrcyBvciBieSBvdGhlciB3b3JrcyBpbiB3aGljaCB0aGUgQXBwbGUgU29mdHdhcmUgbWF5IGJlIGluY29ycG9yYXRlZC4KIAogVGhlIEFwcGxlIFNvZnR3YXJlIGlzIHByb3ZpZGVkIGJ5IEFwcGxlIG9uIGFuICJBUyBJUyIgYmFzaXMuICBBUFBMRSBNQUtFUyBOTyBXQVJSQU5USUVTLCAKIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIFdJVEhPVVQgTElNSVRBVElPTiBUSEUgSU1QTElFRCBXQVJSQU5USUVTIE9GIE5PTi1JTkZSSU5HRU1FTlQsIAogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSwgUkVHQVJESU5HIFRIRSBBUFBMRSBTT0ZUV0FSRSBPUiBJVFMgCiBVU0UgQU5EIE9QRVJBVElPTiBBTE9ORSBPUiBJTiBDT01CSU5BVElPTiBXSVRIIFlPVVIgUFJPRFVDVFMuCiAKIElOIE5PIEVWRU5UIFNIQUxMIEFQUExFIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNULCBJTkNJREVOVEFMIE9SIENPTlNFUVVFTlRJQUwgCiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyAKIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UsIAogUkVQUk9EVUNUSU9OLCBNT0RJRklDQVRJT04gQU5EL09SIERJU1RSSUJVVElPTiBPRiBUSEUgQVBQTEUgU09GVFdBUkUsIEhPV0VWRVIgQ0FVU0VEIEFORCAKIFdIRVRIRVIgVU5ERVIgVEhFT1JZIE9GIENPTlRSQUNULCBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSksIFNUUklDVCBMSUFCSUxJVFkgT1IgCiBPVEhFUldJU0UsIEVWRU4gSUYgQVBQTEUgSEFTIEJFRU4gQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuCiAqLwoKI2luY2x1ZGUgIlBsdWdpbk9iamVjdC5oIgoKI2luY2x1ZGUgIlRlc3RPYmplY3QuaCIKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KCnN0YXRpYyB2b2lkIHBsdWdpbkludmFsaWRhdGUoTlBPYmplY3QgKm9iaik7CnN0YXRpYyBib29sIHBsdWdpbkhhc1Byb3BlcnR5KE5QT2JqZWN0ICpvYmosIE5QSWRlbnRpZmllciBuYW1lKTsKc3RhdGljIGJvb2wgcGx1Z2luSGFzTWV0aG9kKE5QT2JqZWN0ICpvYmosIE5QSWRlbnRpZmllciBuYW1lKTsKc3RhdGljIGJvb2wgcGx1Z2luR2V0UHJvcGVydHkoTlBPYmplY3QgKm9iaiwgTlBJZGVudGlmaWVyIG5hbWUsIE5QVmFyaWFudCAqdmFyaWFudCk7CnN0YXRpYyBib29sIHBsdWdpblNldFByb3BlcnR5KE5QT2JqZWN0ICpvYmosIE5QSWRlbnRpZmllciBuYW1lLCBjb25zdCBOUFZhcmlhbnQgKnZhcmlhbnQpOwpzdGF0aWMgYm9vbCBwbHVnaW5JbnZva2UoTlBPYmplY3QgKm9iaiwgTlBJZGVudGlmaWVyIG5hbWUsIGNvbnN0IE5QVmFyaWFudCAqYXJncywgdWludDMyX3QgYXJnQ291bnQsIE5QVmFyaWFudCAqcmVzdWx0KTsKc3RhdGljIGJvb2wgcGx1Z2luSW52b2tlRGVmYXVsdChOUE9iamVjdCAqb2JqLCBjb25zdCBOUFZhcmlhbnQgKmFyZ3MsIHVpbnQzMl90IGFyZ0NvdW50LCBOUFZhcmlhbnQgKnJlc3VsdCk7CnN0YXRpYyBOUE9iamVjdCAqcGx1Z2luQWxsb2NhdGUoTlBQIG5wcCwgTlBDbGFzcyAqdGhlQ2xhc3MpOwpzdGF0aWMgdm9pZCBwbHVnaW5EZWFsbG9jYXRlKE5QT2JqZWN0ICpvYmopOwoKTlBOZXRzY2FwZUZ1bmNzICpicm93c2VyOwoKc3RhdGljIE5QQ2xhc3MgcGx1Z2luQ2xhc3MgPSB7IAogICAgTlBfQ0xBU1NfU1RSVUNUX1ZFUlNJT04sCiAgICBwbHVnaW5BbGxvY2F0ZSwgCiAgICBwbHVnaW5EZWFsbG9jYXRlLCAKICAgIHBsdWdpbkludmFsaWRhdGUsCiAgICBwbHVnaW5IYXNNZXRob2QsCiAgICBwbHVnaW5JbnZva2UsCiAgICBwbHVnaW5JbnZva2VEZWZhdWx0LAogICAgcGx1Z2luSGFzUHJvcGVydHksCiAgICBwbHVnaW5HZXRQcm9wZXJ0eSwKICAgIHBsdWdpblNldFByb3BlcnR5LAp9OwogCk5QQ2xhc3MgKmdldFBsdWdpbkNsYXNzKHZvaWQpCnsKICAgIHJldHVybiAmcGx1Z2luQ2xhc3M7Cn0KCnN0YXRpYyBib29sIGlkZW50aWZpZXJzSW5pdGlhbGl6ZWQgPSBmYWxzZTsKCiNkZWZpbmUgSURfUFJPUEVSVFlfUFJPUEVSVFkgICAgICAgIDAKI2RlZmluZSBJRF9QUk9QRVJUWV9FVkVOVF9MT0dHSU5HICAgMQojZGVmaW5lIElEX1BST1BFUlRZX0hBU19TVFJFQU0gICAgICAyCiNkZWZpbmUgSURfUFJPUEVSVFlfVEVTVF9PQkpFQ1QgICAgIDMKI2RlZmluZSBJRF9QUk9QRVJUWV9MT0dfREVTVFJPWSAgICAgNAojZGVmaW5lIE5VTV9QUk9QRVJUWV9JREVOVElGSUVSUyAgICA1CgpzdGF0aWMgTlBJZGVudGlmaWVyIHBsdWdpblByb3BlcnR5SWRlbnRpZmllcnNbTlVNX1BST1BFUlRZX0lERU5USUZJRVJTXTsKc3RhdGljIGNvbnN0IE5QVVRGOCAqcGx1Z2luUHJvcGVydHlJZGVudGlmaWVyTmFtZXNbTlVNX1BST1BFUlRZX0lERU5USUZJRVJTXSA9IHsKICAgICJwcm9wZXJ0eSIsCiAgICAiZXZlbnRMb2dnaW5nRW5hYmxlZCIsCiAgICAiaGFzU3RyZWFtIiwKICAgICJ0ZXN0T2JqZWN0IiwKICAgICJsb2dEZXN0cm95IiwKfTsKCiNkZWZpbmUgSURfVEVTVF9DQUxMQkFDS19NRVRIT0QgICAgIDAKI2RlZmluZSBJRF9URVNUX0dFVFVSTCAgICAgICAgICAgICAgMQojZGVmaW5lIElEX1JFTU9WRV9ERUZBVUxUX01FVEhPRCAgICAyCiNkZWZpbmUgSURfVEVTVF9ET01fQUNDRVNTICAgICAgICAgIDMKI2RlZmluZSBJRF9URVNUX0dFVF9VUkxfTk9USUZZICAgICAgNAojZGVmaW5lIElEX1RFU1RfSU5WT0tFX0RFRkFVTFQgICAgICA1CiNkZWZpbmUgSURfREVTVFJPWV9TVFJFQU0gICAgICAgICAgIDYKI2RlZmluZSBJRF9URVNUX0VOVU1FUkFURSAgICAgICAgICAgNwojZGVmaW5lIE5VTV9NRVRIT0RfSURFTlRJRklFUlMgICAgICA4CgpzdGF0aWMgTlBJZGVudGlmaWVyIHBsdWdpbk1ldGhvZElkZW50aWZpZXJzW05VTV9NRVRIT0RfSURFTlRJRklFUlNdOwpzdGF0aWMgY29uc3QgTlBVVEY4ICpwbHVnaW5NZXRob2RJZGVudGlmaWVyTmFtZXNbTlVNX01FVEhPRF9JREVOVElGSUVSU10gPSB7CiAgICAidGVzdENhbGxiYWNrIiwKICAgICJnZXRVUkwiLAogICAgInJlbW92ZURlZmF1bHRNZXRob2QiLAogICAgInRlc3RET01BY2Nlc3MiLAogICAgImdldFVSTE5vdGlmeSIsCiAgICAidGVzdEludm9rZURlZmF1bHQiLAogICAgImRlc3Ryb3lTdHJlYW0iLAogICAgInRlc3RFbnVtZXJhdGUiCn07CgpzdGF0aWMgTlBVVEY4KiBjcmVhdGVDU3RyaW5nRnJvbU5QVmFyaWFudChjb25zdCBOUFZhcmlhbnQgKnZhcmlhbnQpCnsKICAgIHNpemVfdCBsZW5ndGggPSBOUFZBUklBTlRfVE9fU1RSSU5HKCp2YXJpYW50KS5VVEY4TGVuZ3RoOwogICAgTlBVVEY4KiByZXN1bHQgPSAoTlBVVEY4KiltYWxsb2MobGVuZ3RoICsgMSk7CiAgICBtZW1jcHkocmVzdWx0LCBOUFZBUklBTlRfVE9fU1RSSU5HKCp2YXJpYW50KS5VVEY4Q2hhcmFjdGVycywgbGVuZ3RoKTsKICAgIHJlc3VsdFtsZW5ndGhdID0gJ1wwJzsKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyB2b2lkIGluaXRpYWxpemVJZGVudGlmaWVycyh2b2lkKQp7CiAgICBicm93c2VyLT5nZXRzdHJpbmdpZGVudGlmaWVycyhwbHVnaW5Qcm9wZXJ0eUlkZW50aWZpZXJOYW1lcywgTlVNX1BST1BFUlRZX0lERU5USUZJRVJTLCBwbHVnaW5Qcm9wZXJ0eUlkZW50aWZpZXJzKTsKICAgIGJyb3dzZXItPmdldHN0cmluZ2lkZW50aWZpZXJzKHBsdWdpbk1ldGhvZElkZW50aWZpZXJOYW1lcywgTlVNX01FVEhPRF9JREVOVElGSUVSUywgcGx1Z2luTWV0aG9kSWRlbnRpZmllcnMpOwp9CgpzdGF0aWMgYm9vbCBwbHVnaW5IYXNQcm9wZXJ0eShOUE9iamVjdCAqb2JqLCBOUElkZW50aWZpZXIgbmFtZSkKewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBOVU1fUFJPUEVSVFlfSURFTlRJRklFUlM7IGkrKykKICAgICAgICBpZiAobmFtZSA9PSBwbHVnaW5Qcm9wZXJ0eUlkZW50aWZpZXJzW2ldKQogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIHJldHVybiBmYWxzZTsKfQoKc3RhdGljIGJvb2wgcGx1Z2luSGFzTWV0aG9kKE5QT2JqZWN0ICpvYmosIE5QSWRlbnRpZmllciBuYW1lKQp7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IE5VTV9NRVRIT0RfSURFTlRJRklFUlM7IGkrKykKICAgICAgICBpZiAobmFtZSA9PSBwbHVnaW5NZXRob2RJZGVudGlmaWVyc1tpXSkKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICByZXR1cm4gZmFsc2U7Cn0KCnN0YXRpYyBib29sIHBsdWdpbkdldFByb3BlcnR5KE5QT2JqZWN0ICpvYmosIE5QSWRlbnRpZmllciBuYW1lLCBOUFZhcmlhbnQgKnZhcmlhbnQpCnsKICAgIGlmIChuYW1lID09IHBsdWdpblByb3BlcnR5SWRlbnRpZmllcnNbSURfUFJPUEVSVFlfUFJPUEVSVFldKSB7CiAgICAgICAgU1RSSU5HWl9UT19OUFZBUklBTlQoInByb3BlcnR5IiwgKnZhcmlhbnQpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfSBlbHNlIGlmIChuYW1lID09IHBsdWdpblByb3BlcnR5SWRlbnRpZmllcnNbSURfUFJPUEVSVFlfRVZFTlRfTE9HR0lOR10pIHsKICAgICAgICBCT09MRUFOX1RPX05QVkFSSUFOVCgoKFBsdWdpbk9iamVjdCAqKW9iaiktPmV2ZW50TG9nZ2luZywgKnZhcmlhbnQpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfSBlbHNlIGlmIChuYW1lID09IHBsdWdpblByb3BlcnR5SWRlbnRpZmllcnNbSURfUFJPUEVSVFlfTE9HX0RFU1RST1ldKSB7CiAgICAgICAgQk9PTEVBTl9UT19OUFZBUklBTlQoKChQbHVnaW5PYmplY3QgKilvYmopLT5sb2dEZXN0cm95LCAqdmFyaWFudCk7CiAgICAgICAgcmV0dXJuIHRydWU7ICAgICAgICAgICAgCiAgICB9IGVsc2UgaWYgKG5hbWUgPT0gcGx1Z2luUHJvcGVydHlJZGVudGlmaWVyc1tJRF9QUk9QRVJUWV9IQVNfU1RSRUFNXSkgewogICAgICAgIEJPT0xFQU5fVE9fTlBWQVJJQU5UKCgoUGx1Z2luT2JqZWN0ICopb2JqKS0+c3RyZWFtICE9IDAsICp2YXJpYW50KTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0gZWxzZSBpZiAobmFtZSA9PSBwbHVnaW5Qcm9wZXJ0eUlkZW50aWZpZXJzW0lEX1BST1BFUlRZX1RFU1RfT0JKRUNUXSkgewogICAgICAgIE5QT2JqZWN0ICp0ZXN0T2JqZWN0ID0gKChQbHVnaW5PYmplY3QgKilvYmopLT50ZXN0T2JqZWN0OwogICAgICAgIGJyb3dzZXItPnJldGFpbm9iamVjdCh0ZXN0T2JqZWN0KTsKICAgICAgICBPQkpFQ1RfVE9fTlBWQVJJQU5UKHRlc3RPYmplY3QsICp2YXJpYW50KTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0KICAgIHJldHVybiBmYWxzZTsKfQoKc3RhdGljIGJvb2wgcGx1Z2luU2V0UHJvcGVydHkoTlBPYmplY3QgKm9iaiwgTlBJZGVudGlmaWVyIG5hbWUsIGNvbnN0IE5QVmFyaWFudCAqdmFyaWFudCkKewogICAgaWYgKG5hbWUgPT0gcGx1Z2luUHJvcGVydHlJZGVudGlmaWVyc1tJRF9QUk9QRVJUWV9FVkVOVF9MT0dHSU5HXSkgewogICAgICAgICgoUGx1Z2luT2JqZWN0ICopb2JqKS0+ZXZlbnRMb2dnaW5nID0gTlBWQVJJQU5UX1RPX0JPT0xFQU4oKnZhcmlhbnQpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfSBlbHNlIGlmIChuYW1lID09IHBsdWdpblByb3BlcnR5SWRlbnRpZmllcnNbSURfUFJPUEVSVFlfTE9HX0RFU1RST1ldKSB7CiAgICAgICAgKChQbHVnaW5PYmplY3QgKilvYmopLT5sb2dEZXN0cm95ID0gTlBWQVJJQU5UX1RPX0JPT0xFQU4oKnZhcmlhbnQpOwogICAgICAgIHJldHVybiB0cnVlOwogICAgfQogICAgCiAgICByZXR1cm4gZmFsc2U7Cn0KCnN0YXRpYyB2b2lkIHRlc3RET01BY2Nlc3MoUGx1Z2luT2JqZWN0ICpvYmopCnsKICAgIC8vIEdldCBwbHVnLWluJ3MgRE9NIGVsZW1lbnQKICAgIE5QT2JqZWN0ICplbGVtZW50T2JqZWN0OwogICAgaWYgKGJyb3dzZXItPmdldHZhbHVlKG9iai0+bnBwLCBOUE5WUGx1Z2luRWxlbWVudE5QT2JqZWN0LCAmZWxlbWVudE9iamVjdCkgPT0gTlBFUlJfTk9fRVJST1IpIHsKICAgICAgICAvLyBHZXQgc3R5bGUKICAgICAgICBOUFZhcmlhbnQgc3R5bGVWYXJpYW50OwogICAgICAgIE5QSWRlbnRpZmllciBzdHlsZUlkZW50aWZpZXIgPSBicm93c2VyLT5nZXRzdHJpbmdpZGVudGlmaWVyKCJzdHlsZSIpOwogICAgICAgIGlmIChicm93c2VyLT5nZXRwcm9wZXJ0eShvYmotPm5wcCwgZWxlbWVudE9iamVjdCwgc3R5bGVJZGVudGlmaWVyLCAmc3R5bGVWYXJpYW50KSAmJiBOUFZBUklBTlRfSVNfT0JKRUNUKHN0eWxlVmFyaWFudCkpIHsKICAgICAgICAgICAgLy8gU2V0IHN0eWxlLmJvcmRlcgogICAgICAgICAgICBOUElkZW50aWZpZXIgYm9yZGVySWRlbnRpZmllciA9IGJyb3dzZXItPmdldHN0cmluZ2lkZW50aWZpZXIoImJvcmRlciIpOwogICAgICAgICAgICBOUFZhcmlhbnQgYm9yZGVyVmFyaWFudDsKICAgICAgICAgICAgU1RSSU5HWl9UT19OUFZBUklBTlQoIjNweCBzb2xpZCByZWQiLCBib3JkZXJWYXJpYW50KTsKICAgICAgICAgICAgYnJvd3Nlci0+c2V0cHJvcGVydHkob2JqLT5ucHAsIE5QVkFSSUFOVF9UT19PQkpFQ1Qoc3R5bGVWYXJpYW50KSwgYm9yZGVySWRlbnRpZmllciwgJmJvcmRlclZhcmlhbnQpOwogICAgICAgICAgICBicm93c2VyLT5yZWxlYXNldmFyaWFudHZhbHVlKCZzdHlsZVZhcmlhbnQpOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBicm93c2VyLT5yZWxlYXNlb2JqZWN0KGVsZW1lbnRPYmplY3QpOwogICAgfQp9CgpzdGF0aWMgYm9vbCBwbHVnaW5JbnZva2UoTlBPYmplY3QgKmhlYWRlciwgTlBJZGVudGlmaWVyIG5hbWUsIGNvbnN0IE5QVmFyaWFudCAqYXJncywgdWludDMyX3QgYXJnQ291bnQsIE5QVmFyaWFudCAqcmVzdWx0KQp7CiAgICBQbHVnaW5PYmplY3QgKm9iaiA9IChQbHVnaW5PYmplY3QgKiloZWFkZXI7CiAgICBpZiAobmFtZSA9PSBwbHVnaW5NZXRob2RJZGVudGlmaWVyc1tJRF9URVNUX0NBTExCQUNLX01FVEhPRF0pIHsKICAgICAgICAvLyBjYWxsIHdoYXRldmVyIG1ldGhvZCBuYW1lIHdlJ3JlIGdpdmVuCiAgICAgICAgaWYgKGFyZ0NvdW50ID4gMCAmJiBOUFZBUklBTlRfSVNfU1RSSU5HKGFyZ3NbMF0pKSB7CiAgICAgICAgICAgIE5QT2JqZWN0ICp3aW5kb3dTY3JpcHRPYmplY3Q7CiAgICAgICAgICAgIGJyb3dzZXItPmdldHZhbHVlKG9iai0+bnBwLCBOUE5WV2luZG93TlBPYmplY3QsICZ3aW5kb3dTY3JpcHRPYmplY3QpOwoKICAgICAgICAgICAgTlBVVEY4KiBjYWxsYmFja1N0cmluZyA9IGNyZWF0ZUNTdHJpbmdGcm9tTlBWYXJpYW50KCZhcmdzWzBdKTsKICAgICAgICAgICAgTlBJZGVudGlmaWVyIGNhbGxiYWNrSWRlbnRpZmllciA9IGJyb3dzZXItPmdldHN0cmluZ2lkZW50aWZpZXIoY2FsbGJhY2tTdHJpbmcpOwogICAgICAgICAgICBmcmVlKGNhbGxiYWNrU3RyaW5nKTsKCiAgICAgICAgICAgIE5QVmFyaWFudCBicm93c2VyUmVzdWx0OwogICAgICAgICAgICBicm93c2VyLT5pbnZva2Uob2JqLT5ucHAsIHdpbmRvd1NjcmlwdE9iamVjdCwgY2FsbGJhY2tJZGVudGlmaWVyLCAwLCAwLCAmYnJvd3NlclJlc3VsdCk7CiAgICAgICAgICAgIGJyb3dzZXItPnJlbGVhc2V2YXJpYW50dmFsdWUoJmJyb3dzZXJSZXN1bHQpOwoKICAgICAgICAgICAgVk9JRF9UT19OUFZBUklBTlQoKnJlc3VsdCk7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAobmFtZSA9PSBwbHVnaW5NZXRob2RJZGVudGlmaWVyc1tJRF9URVNUX0dFVFVSTF0pIHsKICAgICAgICBpZiAoYXJnQ291bnQgPT0gMiAmJiBOUFZBUklBTlRfSVNfU1RSSU5HKGFyZ3NbMF0pICYmIE5QVkFSSUFOVF9JU19TVFJJTkcoYXJnc1sxXSkpIHsKICAgICAgICAgICAgTlBVVEY4KiB1cmxTdHJpbmcgPSBjcmVhdGVDU3RyaW5nRnJvbU5QVmFyaWFudCgmYXJnc1swXSk7CiAgICAgICAgICAgIE5QVVRGOCogdGFyZ2V0U3RyaW5nID0gY3JlYXRlQ1N0cmluZ0Zyb21OUFZhcmlhbnQoJmFyZ3NbMV0pOwogICAgICAgICAgICBicm93c2VyLT5nZXR1cmwob2JqLT5ucHAsIHVybFN0cmluZywgdGFyZ2V0U3RyaW5nKTsKICAgICAgICAgICAgZnJlZSh1cmxTdHJpbmcpOwogICAgICAgICAgICBmcmVlKHRhcmdldFN0cmluZyk7CgogICAgICAgICAgICBWT0lEX1RPX05QVkFSSUFOVCgqcmVzdWx0KTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfSBlbHNlIGlmIChhcmdDb3VudCA9PSAxICYmIE5QVkFSSUFOVF9JU19TVFJJTkcoYXJnc1swXSkpIHsKICAgICAgICAgICAgTlBVVEY4KiB1cmxTdHJpbmcgPSBjcmVhdGVDU3RyaW5nRnJvbU5QVmFyaWFudCgmYXJnc1swXSk7CiAgICAgICAgICAgIGJyb3dzZXItPmdldHVybChvYmotPm5wcCwgdXJsU3RyaW5nLCAwKTsKICAgICAgICAgICAgZnJlZSh1cmxTdHJpbmcpOwoKICAgICAgICAgICAgVk9JRF9UT19OUFZBUklBTlQoKnJlc3VsdCk7CiAgICAgICAgICAgIHJldHVybiB0cnVlOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAobmFtZSA9PSBwbHVnaW5NZXRob2RJZGVudGlmaWVyc1tJRF9SRU1PVkVfREVGQVVMVF9NRVRIT0RdKSB7CiAgICAgICAgcGx1Z2luQ2xhc3MuaW52b2tlRGVmYXVsdCA9IDA7CiAgICAgICAgVk9JRF9UT19OUFZBUklBTlQoKnJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICB9IGVsc2UgaWYgKG5hbWUgPT0gcGx1Z2luTWV0aG9kSWRlbnRpZmllcnNbSURfVEVTVF9ET01fQUNDRVNTXSkgewogICAgICAgIHRlc3RET01BY2Nlc3Mob2JqKTsKICAgICAgICBWT0lEX1RPX05QVkFSSUFOVCgqcmVzdWx0KTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0gZWxzZSBpZiAobmFtZSA9PSBwbHVnaW5NZXRob2RJZGVudGlmaWVyc1tJRF9URVNUX0dFVF9VUkxfTk9USUZZXSkgewogICAgICAgIGlmIChhcmdDb3VudCA9PSAzCiAgICAgICAgICAmJiBOUFZBUklBTlRfSVNfU1RSSU5HKGFyZ3NbMF0pCiAgICAgICAgICAmJiAoTlBWQVJJQU5UX0lTX1NUUklORyhhcmdzWzFdKSB8fCBOUFZBUklBTlRfSVNfTlVMTChhcmdzWzFdKSkKICAgICAgICAgICYmIE5QVkFSSUFOVF9JU19TVFJJTkcoYXJnc1syXSkpIHsKICAgICAgICAgICAgTlBVVEY4KiB1cmxTdHJpbmcgPSBjcmVhdGVDU3RyaW5nRnJvbU5QVmFyaWFudCgmYXJnc1swXSk7CiAgICAgICAgICAgIE5QVVRGOCogdGFyZ2V0U3RyaW5nID0gKE5QVkFSSUFOVF9JU19TVFJJTkcoYXJnc1sxXSkgPyBjcmVhdGVDU3RyaW5nRnJvbU5QVmFyaWFudCgmYXJnc1sxXSkgOiBOVUxMKTsKICAgICAgICAgICAgTlBVVEY4KiBjYWxsYmFja1N0cmluZyA9IGNyZWF0ZUNTdHJpbmdGcm9tTlBWYXJpYW50KCZhcmdzWzJdKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIE5QSWRlbnRpZmllciBjYWxsYmFja0lkZW50aWZpZXIgPSBicm93c2VyLT5nZXRzdHJpbmdpZGVudGlmaWVyKGNhbGxiYWNrU3RyaW5nKTsKICAgICAgICAgICAgYnJvd3Nlci0+Z2V0dXJsbm90aWZ5KG9iai0+bnBwLCB1cmxTdHJpbmcsIHRhcmdldFN0cmluZywgY2FsbGJhY2tJZGVudGlmaWVyKTsKCiAgICAgICAgICAgIGZyZWUodXJsU3RyaW5nKTsKICAgICAgICAgICAgZnJlZSh0YXJnZXRTdHJpbmcpOwogICAgICAgICAgICBmcmVlKGNhbGxiYWNrU3RyaW5nKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIFZPSURfVE9fTlBWQVJJQU5UKCpyZXN1bHQpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9IGVsc2UgaWYgKG5hbWUgPT0gcGx1Z2luTWV0aG9kSWRlbnRpZmllcnNbSURfVEVTVF9JTlZPS0VfREVGQVVMVF0gJiYgTlBWQVJJQU5UX0lTX09CSkVDVChhcmdzWzBdKSkgewogICAgICAgIE5QT2JqZWN0ICpjYWxsYmFjayA9IE5QVkFSSUFOVF9UT19PQkpFQ1QoYXJnc1swXSk7CiAgICAgICAgCiAgICAgICAgTlBWYXJpYW50IGFyZ3NbMV07CiAgICAgICAgTlBWYXJpYW50IGJyb3dzZXJSZXN1bHQ7CiAgICAgICAgCiAgICAgICAgU1RSSU5HWl9UT19OUFZBUklBTlQoInRlc3QiLCBhcmdzWzBdKTsKICAgICAgICBib29sIHJldHZhbCA9IGJyb3dzZXItPmludm9rZURlZmF1bHQob2JqLT5ucHAsIGNhbGxiYWNrLCBhcmdzLCAxLCAmYnJvd3NlclJlc3VsdCk7CiAgICAgICAgCiAgICAgICAgaWYgKHJldHZhbCkKICAgICAgICAgICAgYnJvd3Nlci0+cmVsZWFzZXZhcmlhbnR2YWx1ZSgmYnJvd3NlclJlc3VsdCk7CiAgICAgICAgCiAgICAgICAgQk9PTEVBTl9UT19OUFZBUklBTlQocmV0dmFsLCAqcmVzdWx0KTsKICAgICAgICByZXR1cm4gdHJ1ZTsKICAgIH0gZWxzZSBpZiAobmFtZSA9PSBwbHVnaW5NZXRob2RJZGVudGlmaWVyc1tJRF9URVNUX0VOVU1FUkFURV0pIHsKICAgICAgICBpZiAoYXJnQ291bnQgPT0gMiAmJiBOUFZBUklBTlRfSVNfT0JKRUNUKGFyZ3NbMF0pICYmIE5QVkFSSUFOVF9JU19PQkpFQ1QoYXJnc1sxXSkpIHsKICAgICAgICAgICAgdWludDMyX3QgY291bnQ7ICAgICAgICAgICAgCiAgICAgICAgICAgIE5QSWRlbnRpZmllciogaWRlbnRpZmllcnM7CgogICAgICAgICAgICBpZiAoYnJvd3Nlci0+ZW51bWVyYXRlKG9iai0+bnBwLCBOUFZBUklBTlRfVE9fT0JKRUNUKGFyZ3NbMF0pLCAmaWRlbnRpZmllcnMsICZjb3VudCkpIHsKICAgICAgICAgICAgICAgIE5QT2JqZWN0KiBvdXRBcnJheSA9IE5QVkFSSUFOVF9UT19PQkpFQ1QoYXJnc1sxXSk7CiAgICAgICAgICAgICAgICBOUElkZW50aWZpZXIgcHVzaElkZW50aWZpZXIgPSBicm93c2VyLT5nZXRzdHJpbmdpZGVudGlmaWVyKCJwdXNoIik7CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGZvciAodWludDMyX3QgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CiAgICAgICAgICAgICAgICAgICAgTlBVVEY4KiBzdHJpbmcgPSBicm93c2VyLT51dGY4ZnJvbWlkZW50aWZpZXIoaWRlbnRpZmllcnNbaV0pOwogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIGlmICghc3RyaW5nKQogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIE5QVmFyaWFudCBhcmdzWzFdOwogICAgICAgICAgICAgICAgICAgIFNUUklOR1pfVE9fTlBWQVJJQU5UKHN0cmluZywgYXJnc1swXSk7CiAgICAgICAgICAgICAgICAgICAgTlBWYXJpYW50IGJyb3dzZXJSZXN1bHQ7CiAgICAgICAgICAgICAgICAgICAgYnJvd3Nlci0+aW52b2tlKG9iai0+bnBwLCBvdXRBcnJheSwgcHVzaElkZW50aWZpZXIsIGFyZ3MsIDEsICZicm93c2VyUmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICBicm93c2VyLT5yZWxlYXNldmFyaWFudHZhbHVlKCZicm93c2VyUmVzdWx0KTsKICAgICAgICAgICAgICAgICAgICBicm93c2VyLT5tZW1mcmVlKHN0cmluZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIGJyb3dzZXItPm1lbWZyZWUoaWRlbnRpZmllcnMpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgICAgICBWT0lEX1RPX05QVkFSSUFOVCgqcmVzdWx0KTsKICAgICAgICAgICAgcmV0dXJuIHRydWU7ICAgICAgICAgICAgCiAgICAgICAgfQogICAgfSBlbHNlIGlmIChuYW1lID09IHBsdWdpbk1ldGhvZElkZW50aWZpZXJzW0lEX0RFU1RST1lfU1RSRUFNXSkgewogICAgICAgIE5QRXJyb3IgbnBFcnJvciA9IGJyb3dzZXItPmRlc3Ryb3lzdHJlYW0ob2JqLT5ucHAsIG9iai0+c3RyZWFtLCBOUFJFU19VU0VSX0JSRUFLKTsKICAgICAgICBJTlQzMl9UT19OUFZBUklBTlQobnBFcnJvciwgKnJlc3VsdCk7CiAgICAgICAgcmV0dXJuIHRydWU7ICAgICAgICAKICAgIH0gCiAgICByZXR1cm4gZmFsc2U7Cn0KCnN0YXRpYyBib29sIHBsdWdpbkludm9rZURlZmF1bHQoTlBPYmplY3QgKm9iaiwgY29uc3QgTlBWYXJpYW50ICphcmdzLCB1aW50MzJfdCBhcmdDb3VudCwgTlBWYXJpYW50ICpyZXN1bHQpCnsKICAgIElOVDMyX1RPX05QVkFSSUFOVCgxLCAqcmVzdWx0KTsKICAgIHJldHVybiB0cnVlOwp9CgpzdGF0aWMgdm9pZCBwbHVnaW5JbnZhbGlkYXRlKE5QT2JqZWN0ICpvYmopCnsKfQoKc3RhdGljIE5QT2JqZWN0ICpwbHVnaW5BbGxvY2F0ZShOUFAgbnBwLCBOUENsYXNzICp0aGVDbGFzcykKewogICAgUGx1Z2luT2JqZWN0ICpuZXdJbnN0YW5jZSA9IChQbHVnaW5PYmplY3QqKW1hbGxvYyhzaXplb2YoUGx1Z2luT2JqZWN0KSk7CiAgICAKICAgIGlmICghaWRlbnRpZmllcnNJbml0aWFsaXplZCkgewogICAgICAgIGlkZW50aWZpZXJzSW5pdGlhbGl6ZWQgPSB0cnVlOwogICAgICAgIGluaXRpYWxpemVJZGVudGlmaWVycygpOwogICAgfQoKICAgIG5ld0luc3RhbmNlLT5ucHAgPSBucHA7CiAgICBuZXdJbnN0YW5jZS0+dGVzdE9iamVjdCA9IGJyb3dzZXItPmNyZWF0ZW9iamVjdChucHAsIGdldFRlc3RDbGFzcygpKTsKICAgIG5ld0luc3RhbmNlLT5ldmVudExvZ2dpbmcgPSBGQUxTRTsKICAgIG5ld0luc3RhbmNlLT5sb2dEZXN0cm95ID0gRkFMU0U7CiAgICBuZXdJbnN0YW5jZS0+bG9nU2V0V2luZG93ID0gRkFMU0U7CiAgICBuZXdJbnN0YW5jZS0+cmV0dXJuRXJyb3JGcm9tTmV3U3RyZWFtID0gRkFMU0U7CiAgICBuZXdJbnN0YW5jZS0+c3RyZWFtID0gMDsKICAgIAogICAgbmV3SW5zdGFuY2UtPmZpcnN0VXJsID0gTlVMTDsKICAgIG5ld0luc3RhbmNlLT5maXJzdEhlYWRlcnMgPSBOVUxMOwogICAgbmV3SW5zdGFuY2UtPmxhc3RVcmwgPSBOVUxMOwogICAgbmV3SW5zdGFuY2UtPmxhc3RIZWFkZXJzID0gTlVMTDsKICAgIAogICAgcmV0dXJuIChOUE9iamVjdCAqKW5ld0luc3RhbmNlOwp9CgpzdGF0aWMgdm9pZCBwbHVnaW5EZWFsbG9jYXRlKE5QT2JqZWN0ICpoZWFkZXIpIAp7CiAgICBQbHVnaW5PYmplY3QqIG9iaiA9IChQbHVnaW5PYmplY3QqKWhlYWRlcjsKICAgIAogICAgYnJvd3Nlci0+cmVsZWFzZW9iamVjdChvYmotPnRlc3RPYmplY3QpOwoKICAgIGZyZWUob2JqLT5maXJzdFVybCk7CiAgICBmcmVlKG9iai0+Zmlyc3RIZWFkZXJzKTsKICAgIGZyZWUob2JqLT5sYXN0VXJsKTsKICAgIGZyZWUob2JqLT5sYXN0SGVhZGVycyk7CgogICAgZnJlZShvYmopOwp9Cgp2b2lkIGhhbmRsZUNhbGxiYWNrKFBsdWdpbk9iamVjdCogb2JqZWN0LCBjb25zdCBjaGFyICp1cmwsIE5QUmVhc29uIHJlYXNvbiwgdm9pZCAqbm90aWZ5RGF0YSkKewogICAgYXNzZXJ0KG9iamVjdCk7CiAgICAKICAgIE5QVmFyaWFudCBhcmdzWzJdOwogICAgCiAgICBOUE9iamVjdCAqd2luZG93U2NyaXB0T2JqZWN0OwogICAgYnJvd3Nlci0+Z2V0dmFsdWUob2JqZWN0LT5ucHAsIE5QTlZXaW5kb3dOUE9iamVjdCwgJndpbmRvd1NjcmlwdE9iamVjdCk7CiAgICAKICAgIE5QSWRlbnRpZmllciBjYWxsYmFja0lkZW50aWZpZXIgPSBub3RpZnlEYXRhOwoKICAgIElOVDMyX1RPX05QVkFSSUFOVChyZWFzb24sIGFyZ3NbMF0pOwoKICAgIGNoYXIgKnN0ckhkciA9IE5VTEw7CiAgICBpZiAob2JqZWN0LT5maXJzdFVybCAmJiBvYmplY3QtPmZpcnN0SGVhZGVycyAmJiBvYmplY3QtPmxhc3RVcmwgJiYgb2JqZWN0LT5sYXN0SGVhZGVycykgewogICAgICAgIC8vIEZvcm1hdCBleHBlY3RlZCBieSBKYXZhU2NyaXB0IHZhbGlkYXRvcjogZm91ciBmaWVsZHMgc2VwYXJhdGVkIGJ5IFxuXG46CiAgICAgICAgLy8gRmlyc3QgVVJMOyBmaXJzdCBoZWFkZXIgYmxvY2s7IGxhc3QgVVJMOyBsYXN0IGhlYWRlciBibG9jay4KICAgICAgICAvLyBOb3RlIHRoYXQgaGVhZGVyIGJsb2NrcyBhbHJlYWR5IGVuZCB3aXRoIFxuIGR1ZSB0byBob3cgTlBTdHJlYW06OmhlYWRlcnMgd29ya3MuCiAgICAgICAgaW50IGxlbiA9IHN0cmxlbihvYmplY3QtPmZpcnN0VXJsKSArIDIKICAgICAgICAgICAgKyBzdHJsZW4ob2JqZWN0LT5maXJzdEhlYWRlcnMpICsgMQogICAgICAgICAgICArIHN0cmxlbihvYmplY3QtPmxhc3RVcmwpICsgMgogICAgICAgICAgICArIHN0cmxlbihvYmplY3QtPmxhc3RIZWFkZXJzKSArIDE7CiAgICAgICAgc3RySGRyID0gKGNoYXIqKW1hbGxvYyhsZW4gKyAxKTsKICAgICAgICBzbnByaW50ZihzdHJIZHIsIGxlbiArIDEsICIlc1xuXG4lc1xuJXNcblxuJXNcbiIsCiAgICAgICAgICAgICAgICAgb2JqZWN0LT5maXJzdFVybCwgb2JqZWN0LT5maXJzdEhlYWRlcnMsIG9iamVjdC0+bGFzdFVybCwgb2JqZWN0LT5sYXN0SGVhZGVycyk7CiAgICAgICAgU1RSSU5HTl9UT19OUFZBUklBTlQoc3RySGRyLCBsZW4sIGFyZ3NbMV0pOwogICAgfSBlbHNlCiAgICAgICAgTlVMTF9UT19OUFZBUklBTlQoYXJnc1sxXSk7CgogICAgTlBWYXJpYW50IGJyb3dzZXJSZXN1bHQ7CiAgICBicm93c2VyLT5pbnZva2Uob2JqZWN0LT5ucHAsIHdpbmRvd1NjcmlwdE9iamVjdCwgY2FsbGJhY2tJZGVudGlmaWVyLCBhcmdzLCAyLCAmYnJvd3NlclJlc3VsdCk7CiAgICBicm93c2VyLT5yZWxlYXNldmFyaWFudHZhbHVlKCZicm93c2VyUmVzdWx0KTsKCiAgICBmcmVlKHN0ckhkcik7Cn0KCnZvaWQgbm90aWZ5U3RyZWFtKFBsdWdpbk9iamVjdCogb2JqZWN0LCBjb25zdCBjaGFyICp1cmwsIGNvbnN0IGNoYXIgKmhlYWRlcnMpCnsKICAgIGlmIChvYmplY3QtPmZpcnN0VXJsID09IE5VTEwpIHsKICAgICAgICBpZiAodXJsKQogICAgICAgICAgICBvYmplY3QtPmZpcnN0VXJsID0gc3RyZHVwKHVybCk7CiAgICAgICAgaWYgKGhlYWRlcnMpCiAgICAgICAgICAgIG9iamVjdC0+Zmlyc3RIZWFkZXJzID0gc3RyZHVwKGhlYWRlcnMpOwogICAgfSBlbHNlIHsKICAgICAgICBmcmVlKG9iamVjdC0+bGFzdFVybCk7CiAgICAgICAgZnJlZShvYmplY3QtPmxhc3RIZWFkZXJzKTsKICAgICAgICBvYmplY3QtPmxhc3RVcmwgPSAodXJsID8gc3RyZHVwKHVybCkgOiBOVUxMKTsKICAgICAgICBvYmplY3QtPmxhc3RIZWFkZXJzID0gKGhlYWRlcnMgPyBzdHJkdXAoaGVhZGVycykgOiBOVUxMKTsKICAgIH0KfQo=