LyoKICogTkRSIC1PaSwtT2lmLC1PaWNmIEludGVycHJldGVyCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzLTUgUm9iZXJ0IFNoZWFybWFuIChmb3IgQ29kZVdlYXZlcnMpCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBUT0RPOgogKiAgLSBQaXBlcwogKiAgLSBTb21lIHR5cGVzIG9mIGJpbmRpbmcgaGFuZGxlcwogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjcHJveHkuaCIKI2luY2x1ZGUgIm5kcnR5cGVzLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS9ycGNmYy5oIgoKI2luY2x1ZGUgIm5kcl9taXNjLmgiCiNpbmNsdWRlICJjcHNmLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKI2RlZmluZSBORFJfVEFCTEVfTUFTSyAxMjcKCnN0YXRpYyBpbmxpbmUgdm9pZCBjYWxsX2J1ZmZlcl9zaXplcihQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIHVuc2lnbmVkIGNoYXIgKnBNZW1vcnksIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICAgIE5EUl9CVUZGRVJTSVpFIG0gPSBOZHJCdWZmZXJTaXplcltwRm9ybWF0WzBdICYgTkRSX1RBQkxFX01BU0tdOwogICAgaWYgKG0pIG0ocFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogICAgZWxzZQogICAgewogICAgICAgIEZJWE1FKCJmb3JtYXQgdHlwZSAweCV4IG5vdCBpbXBsZW1lbnRlZFxuIiwgcEZvcm1hdFswXSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgY2hhciAqY2FsbF9tYXJzaGFsbGVyKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogICAgTkRSX01BUlNIQUxMIG0gPSBOZHJNYXJzaGFsbGVyW3BGb3JtYXRbMF0gJiBORFJfVEFCTEVfTUFTS107CiAgICBpZiAobSkgcmV0dXJuIG0ocFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogICAgZWxzZQogICAgewogICAgICAgIEZJWE1FKCJmb3JtYXQgdHlwZSAweCV4IG5vdCBpbXBsZW1lbnRlZFxuIiwgcEZvcm1hdFswXSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgY2hhciAqY2FsbF91bm1hcnNoYWxsZXIoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCB1bnNpZ25lZCBjaGFyICoqcHBNZW1vcnksIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQsIHVuc2lnbmVkIGNoYXIgZk11c3RBbGxvYykKewogICAgTkRSX1VOTUFSU0hBTEwgbSA9IE5kclVubWFyc2hhbGxlcltwRm9ybWF0WzBdICYgTkRSX1RBQkxFX01BU0tdOwogICAgaWYgKG0pIHJldHVybiBtKHBTdHViTXNnLCBwcE1lbW9yeSwgcEZvcm1hdCwgZk11c3RBbGxvYyk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgRklYTUUoImZvcm1hdCB0eXBlIDB4JXggbm90IGltcGxlbWVudGVkXG4iLCBwRm9ybWF0WzBdKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KfQoKc3RhdGljIGlubGluZSB2b2lkIGNhbGxfZnJlZXIoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LCBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgICBORFJfRlJFRSBtID0gTmRyRnJlZXJbcEZvcm1hdFswXSAmIE5EUl9UQUJMRV9NQVNLXTsKICAgIGlmIChtKSBtKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKfQoKc3RhdGljIGlubGluZSB1bnNpZ25lZCBsb25nIGNhbGxfbWVtb3J5X3NpemVyKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogICAgTkRSX01FTU9SWVNJWkUgbSA9IE5kck1lbW9yeVNpemVyW3BGb3JtYXRbMF0gJiBORFJfVEFCTEVfTUFTS107CiAgICBpZiAobSkKICAgIHsKICAgICAgICB1bnNpZ25lZCBjaGFyICpzYXZlZF9idWZmZXIgPSBwU3R1Yk1zZy0+QnVmZmVyOwogICAgICAgIHVuc2lnbmVkIGxvbmcgcmV0OwogICAgICAgIGludCBzYXZlZF9pZ25vcmVfZW1iZWRkZWRfcG9pbnRlcnMgPSBwU3R1Yk1zZy0+SWdub3JlRW1iZWRkZWRQb2ludGVyczsKICAgICAgICBwU3R1Yk1zZy0+TWVtb3J5U2l6ZSA9IDA7CiAgICAgICAgcFN0dWJNc2ctPklnbm9yZUVtYmVkZGVkUG9pbnRlcnMgPSAxOwogICAgICAgIHJldCA9IG0ocFN0dWJNc2csIHBGb3JtYXQpOwogICAgICAgIHBTdHViTXNnLT5JZ25vcmVFbWJlZGRlZFBvaW50ZXJzID0gc2F2ZWRfaWdub3JlX2VtYmVkZGVkX3BvaW50ZXJzOwogICAgICAgIHBTdHViTXNnLT5CdWZmZXIgPSBzYXZlZF9idWZmZXI7CiAgICAgICAgcmV0dXJuIHJldDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBGSVhNRSgiZm9ybWF0IHR5cGUgMHgleCBub3QgaW1wbGVtZW50ZWRcbiIsIHBGb3JtYXRbMF0pOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgICAgIHJldHVybiAwOwogICAgfQp9CgovKiB0aGVyZSBjYW4ndCBiZSBhbnkgYWxpZ25tZW50IHdpdGggdGhlIHN0cnVjdHVyZXMgaW4gdGhpcyBmaWxlICovCiNpbmNsdWRlICJwc2hwYWNrMS5oIgoKI2RlZmluZSBTVFVCTEVTU19VTk1BUlNIQUwgIDEKI2RlZmluZSBTVFVCTEVTU19DQUxMU0VSVkVSIDIKI2RlZmluZSBTVFVCTEVTU19DQUxDU0laRSAgIDMKI2RlZmluZSBTVFVCTEVTU19HRVRCVUZGRVIgIDQKI2RlZmluZSBTVFVCTEVTU19NQVJTSEFMICAgIDUKCi8qIEZyb20gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2RlZmF1bHQuYXNwP3VybD0vbGlicmFyeS9lbi11cy9ycGMvcnBjL3BhcmFtZXRlcl9kZXNjcmlwdG9ycy5hc3AgKi8KdHlwZWRlZiBzdHJ1Y3QgX05EUl9QUk9DX0hFQURFUgp7CiAgICAvKiB0eXBlIG9mIGhhbmRsZSB0byB1c2U6CiAgICAgKiBSUENfRkNfQklORF9FWFBMSUNJVCA9IDAgLSBFeHBsaWNpdCBoYW5kbGUuCiAgICAgKiAgIEhhbmRsZSBpcyBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIgdG8gdGhlIGZ1bmN0aW9uLgogICAgICogICBJbmRpY2F0ZXMgdGhhdCBleHBsaWNpdCBoYW5kbGUgaW5mb3JtYXRpb24gZm9sbG93cyB0aGUgaGVhZGVyLAogICAgICogICB3aGljaCBhY3R1YWxseSBkZXNjcmliZXMgdGhlIGhhbmRsZS4KICAgICAqIFJQQ19GQ19CSU5EX0dFTkVSSUMgPSAzMSAtIEltcGxpY2l0IGhhbmRsZSB3aXRoIGN1c3RvbSBiaW5kaW5nIHJvdXRpbmVzCiAgICAgKiAgIChNSURMX1NUVUJfREVTQzo6SU1QTElDSVRfSEFORExFX0lORk86OnBHZW5lcmljQmluZGluZ0luZm8pCiAgICAgKiBSUENfRkNfQklORF9QUklNSVRJVkUgPSAzMiAtIEltcGxpY2l0IGhhbmRsZSB1c2luZyBoYW5kbGVfdCBjcmVhdGVkIGJ5CiAgICAgKiAgIGNhbGxpbmcgYXBwbGljYXRpb24KICAgICAqIFJQQ19GQ19BVVRPX0hBTkRMRSA9IDMzIC0gQXV0b21hdGljIGhhbmRsZQogICAgICogUlBDX0ZDX0NBTExCQUNLX0hBTkRMRSA9IDM0IC0gdW5kb2NtZW50ZWQKICAgICAqLwogICAgdW5zaWduZWQgY2hhciBoYW5kbGVfdHlwZTsKCiAgICAvKiBwcm9jZWR1cmUgZmxhZ3M6CiAgICAgKiBPaV9GVUxMX1BUUl9VU0VEID0gMHgwMSAtIEEgZnVsbCBwb2ludGVyIGNhbiBoYXZlIHRoZSB2YWx1ZSBOVUxMIGFuZCBjYW4KICAgICAqICAgY2hhbmdlIGR1cmluZyB0aGUgY2FsbCBmcm9tIE5VTEwgdG8gbm9uLU5VTEwgYW5kIHN1cHBvcnRzIGFsaWFzaW5nCiAgICAgKiAgIGFuZCBjeWNsZXMuIEluZGljYXRlcyB0aGF0IHRoZSBOZHJGdWxsUG9pbnRlclhsYXRJbml0IGZ1bmN0aW9uCiAgICAgKiAgIHNob3VsZCBiZSBjYWxsZWQuCiAgICAgKiBPaV9SUENTU19BTExPQ19VU0VEID0gMHgwMiAtIFVzZSBScGNTUyBhbGxvY2F0ZS9mcmVlIHJvdXRpbmVzIGluc3RlYWQgb2YKICAgICAqICAgbm9ybWFsIGFsbG9jYXRlL2ZyZWUgcm91dGluZXMKICAgICAqIE9pX09CSkVDVF9QUk9DID0gMHgwNCAtIEluZGljYXRlcyBhIHByb2NlZHVyZSB0aGF0IGlzIHBhcnQgb2YgYW4gT0xFCiAgICAgKiAgIGludGVyZmFjZSwgcmF0aGVyIHRoYW4gYSBEQ0UgUlBDIGludGVyZmFjZS4KICAgICAqIE9pX0hBU19SUENGTEFHUyA9IDB4MDggLSBJbmRpY2F0ZXMgdGhhdCB0aGUgcnBjX2ZsYWdzIGVsZW1lbnQgaXMgCiAgICAgKiAgIHByZXNlbnQgaW4gdGhlIGhlYWRlci4KICAgICAqIE9pX0hBU19DT01NX09SX0ZBVUxUID0gMHgyMCAtIElmIE9pX09CSkVDVF9QUk9DIG5vdCBwcmVzZW50IG9ubHkgdGhlbgogICAgICogICBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvY2VkdXJlIGhhcyB0aGUgY29tbV9zdGF0dXMgb3IgZmF1bHRfc3RhdHVzCiAgICAgKiAgIE1JREwgYXR0cmlidXRlLgogICAgICogT2lfT0JKX1VTRV9WMl9JTlRFUlBSRVRFUiA9IDB4MjAgLSBJZiBPaV9PQkpFQ1RfUFJPQyBwcmVzZW50IG9ubHkKICAgICAqICAgdGhlbiBpbmRpY2F0ZXMgdGhhdCB0aGUgZm9ybWF0IHN0cmluZyBpcyBpbiAtT2lmIG9yIC1PaWNmIGZvcm1hdAogICAgICogT2lfVVNFX05FV19JTklUX1JPVVRJTkVTID0gMHg0MCAtIFVzZSBOZHJYSW5pdGlhbGl6ZU5ldyBpbnN0ZWFkIG9mCiAgICAgKiAgIE5kclhJbml0aWFsaXplPwogICAgICovCiAgICB1bnNpZ25lZCBjaGFyIE9pX2ZsYWdzOwoKICAgIC8qIHRoZSB6ZXJvLWJhc2VkIGluZGV4IG9mIHRoZSBwcm9jZWR1cmUgKi8KICAgIHVuc2lnbmVkIHNob3J0IHByb2NfbnVtOwoKICAgIC8qIHRvdGFsIHNpemUgb2YgYWxsIHBhcmFtZXRlcnMgb24gdGhlIHN0YWNrLCBpbmNsdWRpbmcgYW55ICJ0aGlzIgogICAgICogcG9pbnRlciBhbmQvb3IgcmV0dXJuIHZhbHVlICovCiAgICB1bnNpZ25lZCBzaG9ydCBzdGFja19zaXplOwp9IE5EUl9QUk9DX0hFQURFUjsKCi8qIHNhbWUgYXMgYWJvdmUgc3RydWN0IGV4Y2VwdCBhZGRpdGlvbmFsIGVsZW1lbnQgcnBjX2ZsYWdzICovCnR5cGVkZWYgc3RydWN0IF9ORFJfUFJPQ19IRUFERVJfUlBDCnsKICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CiAgICB1bnNpZ25lZCBjaGFyIE9pX2ZsYWdzOwoKICAgIC8qCiAgICAgKiBSUENGX0lkZW1wb3RlbnQgPSAweDAwMDEgLSBbaWRlbXBvdGVudF0gTUlETCBhdHRyaWJ1dGUKICAgICAqIFJQQ0ZfQnJvYWRjYXN0ID0gMHgwMDAyIC0gW2Jyb2FkY2FzdF0gTUlETCBhdHRyaWJ1dGUKICAgICAqIFJQQ0ZfTWF5YmUgPSAweDAwMDQgLSBbbWF5YmVdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSZXNlcnZlZCA9IDB4MDAwOCAtIDB4MDA4MAogICAgICogUlBDRl9NZXNzYWdlID0gMHgwMTAwIC0gW21lc3NhZ2VdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSZXNlcnZlZCA9IDB4MDIwMCAtIDB4MTAwMAogICAgICogUlBDRl9JbnB1dFN5bmNocm9ub3VzID0gMHgyMDAwIC0gdW5rbm93bgogICAgICogUlBDRl9Bc3luY2hyb25vdXMgPSAweDQwMDAgLSBbYXN5bmNdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSZXNlcnZlZCA9IDB4ODAwMAogICAgICovCiAgICB1bnNpZ25lZCBsb25nIHJwY19mbGFnczsKICAgIHVuc2lnbmVkIHNob3J0IHByb2NfbnVtOwogICAgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZTsKCn0gTkRSX1BST0NfSEVBREVSX1JQQzsKCnR5cGVkZWYgc3RydWN0IF9ORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIKewogICAgLyogdGhlIHByZS1jb21wdXRlZCBjbGllbnQgYnVmZmVyIHNpemUgc28gdGhhdCBpbnRlcnByZXRlciBjYW4gc2tpcCBhbGwKICAgICAqIG9yIHNvbWUgKGlmIHRoZSBmbGFnIFJQQ19GQ19QUk9DX09JMkZfQ0xUTVVTVFNJWkUgaXMgc3BlY2lmaWVkKSBvZiB0aGUKICAgICAqIHNpemluZyBwYXNzICovCiAgICB1bnNpZ25lZCBzaG9ydCBjb25zdGFudF9jbGllbnRfYnVmZmVyX3NpemU7CgogICAgLyogdGhlIHByZS1jb21wdXRlZCBzZXJ2ZXIgYnVmZmVyIHNpemUgc28gdGhhdCBpbnRlcnByZXRlciBjYW4gc2tpcCBhbGwKICAgICAqIG9yIHNvbWUgKGlmIHRoZSBmbGFnIFJQQ19GQ19QUk9DX09JMkZfU1JWTVVTVFNJWkUgaXMgc3BlY2lmaWVkKSBvZiB0aGUKICAgICAqIHNpemluZyBwYXNzICovCiAgICB1bnNpZ25lZCBzaG9ydCBjb25zdGFudF9zZXJ2ZXJfYnVmZmVyX3NpemU7CgogICAgSU5URVJQUkVURVJfT1BUX0ZMQUdTIE9pMkZsYWdzOwoKICAgIC8qIG51bWJlciBvZiBwYXJhbXMgKi8KICAgIHVuc2lnbmVkIGNoYXIgbnVtYmVyX29mX3BhcmFtczsKfSBORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVI7Cgp0eXBlZGVmIHN0cnVjdCBfTkRSX1BBUkFNX09JX0JBU0VUWVBFCnsKICAgIC8qIHBhcmFtZXRlciBkaXJlY3Rpb24uIE9uZSBvZjoKICAgICAqIEZDX0lOX1BBUkFNX0JBU0VUWVBFID0gMHg0ZSAtIGFuIGluIHBhcmFtCiAgICAgKiBGQ19SRVRVUk5fUEFSQU1fQkFTRVRZUEUgPSAweDUzIC0gYSByZXR1cm4gcGFyYW0KICAgICAqLwogICAgdW5zaWduZWQgY2hhciBwYXJhbV9kaXJlY3Rpb247CgogICAgLyogT25lIG9mOiBGQ19CWVRFLEZDX0NIQVIsRkNfU01BTEwsRkNfVVNNQUxMLEZDX1dDSEFSLEZDX1NIT1JULEZDX1VTSE9SVCwKICAgICAqIEZDX0xPTkcsRkNfVUxPTkcsRkNfRkxPQVQsRkNfSFlQRVIsRkNfRE9VQkxFLEZDX0VOVU0xNixGQ19FTlVNMzIsCiAgICAgKiBGQ19FUlJPUl9TVEFUVVNfVCxGQ19JTlQzMjY0LEZDX1VJTlQzMjY0ICovCiAgICB1bnNpZ25lZCBjaGFyIHR5cGVfZm9ybWF0X2NoYXI7Cn0gTkRSX1BBUkFNX09JX0JBU0VUWVBFOwoKdHlwZWRlZiBzdHJ1Y3QgX05EUl9QQVJBTV9PSV9PVEhFUgp7CiAgICAvKiBPbmUgb2Y6CiAgICAgKiBGQ19JTl9QQVJBTSA9IDB4NGQgLSBBbiBpbiBwYXJhbQogICAgICogRkNfSU5fT1VUX1BBUkFNID0gMHg1MCAtIEFuIGluL291dCBwYXJhbQogICAgICogRkNfT1VUX1BBUkFNID0gMHg1MSAtIEFuIG91dCBwYXJhbQogICAgICogRkNfUkVUVVJOX1BBUkFNID0gMHg1MiAtIEEgcmV0dXJuIHZhbHVlCiAgICAgKiBGQ19JTl9QQVJBTV9OT19GUkVFX0lOU1QgPSAweDRmIC0gQSBwYXJhbSBmb3Igd2hpY2ggbm8gZnJlZWluZyBpcyBkb25lCiAgICAgKi8KICAgIHVuc2lnbmVkIGNoYXIgcGFyYW1fZGlyZWN0aW9uOwoKICAgIC8qIFNpemUgb2YgcGFyYW0gb24gc3RhY2sgaW4gTlVNQkVSUyBPRiBJTlRTICovCiAgICB1bnNpZ25lZCBjaGFyIHN0YWNrX3NpemU7CgogICAgLyogb2Zmc2V0IGluIHRoZSB0eXBlIGZvcm1hdCBzdHJpbmcgdGFibGUgKi8KICAgIHVuc2lnbmVkIHNob3J0IHR5cGVfb2Zmc2V0Owp9IE5EUl9QQVJBTV9PSV9PVEhFUjsKCnR5cGVkZWYgc3RydWN0IF9ORFJfUEFSQU1fT0lGX0JBU0VUWVBFCnsKICAgIFBBUkFNX0FUVFJJQlVURVMgcGFyYW1fYXR0cmlidXRlczsKCiAgICAvKiB0aGUgb2Zmc2V0IG9uIHRoZSBjYWxsaW5nIHN0YWNrIHdoZXJlIHRoZSBwYXJhbWV0ZXIgaXMgbG9jYXRlZCAqLwogICAgdW5zaWduZWQgc2hvcnQgc3RhY2tfb2Zmc2V0OwoKICAgIC8qIHNlZSBORFJfUEFSQU1fT0lfQkFTRVRZUEU6OnR5cGVfZm9ybWF0X2NoYXIgKi8KICAgIHVuc2lnbmVkIGNoYXIgdHlwZV9mb3JtYXRfY2hhcjsKCiAgICAvKiBhbHdheXMgRkNfUEFEICovCiAgICB1bnNpZ25lZCBjaGFyIHVudXNlZDsKfSBORFJfUEFSQU1fT0lGX0JBU0VUWVBFOwoKdHlwZWRlZiBzdHJ1Y3QgX05EUl9QQVJBTV9PSUZfT1RIRVIKewogICAgUEFSQU1fQVRUUklCVVRFUyBwYXJhbV9hdHRyaWJ1dGVzOwoKICAgIC8qIHNlZSBORFJfUEFSQU1fT0lGX0JBU0VUWVBFOjpzdGFja19vZmZzZXQgKi8KICAgIHVuc2lnbmVkIHNob3J0IHN0YWNrX29mZnNldDsKCiAgICAvKiBvZmZzZXQgaW50byB0aGUgcHJvdmlkZWQgdHlwZSBmb3JtYXQgc3RyaW5nIHdoZXJlIHRoZSB0eXBlIGZvciB0aGlzCiAgICAgKiBwYXJhbWV0ZXIgc3RhcnRzICovCiAgICB1bnNpZ25lZCBzaG9ydCB0eXBlX29mZnNldDsKfSBORFJfUEFSQU1fT0lGX09USEVSOwoKLyogZXhwbGljaXQgaGFuZGxlIGRlc2NyaXB0aW9uIGZvciBGQ19CSU5EX1BSSU1JVElWRSB0eXBlICovCnR5cGVkZWYgc3RydWN0IF9ORFJfRUhEX1BSSU1JVElWRQp7CiAgICAvKiBGQ19CSU5EX1BSSU1JVElWRSAqLwogICAgdW5zaWduZWQgY2hhciBoYW5kbGVfdHlwZTsKCiAgICAvKiBpcyB0aGUgaGFuZGxlIHBhc3NlZCBpbiB2aWEgYSBwb2ludGVyPyAqLwogICAgdW5zaWduZWQgY2hhciBmbGFnOwoKICAgIC8qIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0YWNrIHRvIHRoZSBoYW5kbGUgaW4gYnl0ZXMgKi8KICAgIHVuc2lnbmVkIHNob3J0IG9mZnNldDsKfSBORFJfRUhEX1BSSU1JVElWRTsKCi8qIGV4cGxpY2l0IGhhbmRsZSBkZXNjcmlwdGlvbiBmb3IgRkNfQklORF9HRU5FUklDIHR5cGUgKi8KdHlwZWRlZiBzdHJ1Y3QgX05EUl9FSERfR0VORVJJQwp7CiAgICAvKiBGQ19CSU5EX0dFTkVSSUMgKi8KICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CgogICAgLyogdXBwZXIgNGJpdHMgaXMgYSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgaGFuZGxlIGlzIHBhc3NlZCBpbgogICAgICogdmlhIGEgcG9pbnRlci4gbG93ZXIgNGJpdHMgaXMgdGhlIHNpemUgb2YgdGhlIHVzZXIgZGVmaW5lZCBnZW5lcmljCiAgICAgKiBoYW5kbGUgdHlwZS4gdGhlIHNpemUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG1hY2hpbmUKICAgICAqIHJlZ2lzdGVyIHNpemUgKi8KICAgIHVuc2lnbmVkIGNoYXIgZmxhZ19hbmRfc2l6ZTsKCiAgICAvKiBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdGFjayB0byB0aGUgaGFuZGxlIGluIGJ5dGVzICovCiAgICB1bnNpZ25lZCBzaG9ydCBvZmZzZXQ7CgogICAgLyogdGhlIGluZGV4IGludG8gdGhlIGFHZW5lcmljQmluZGluZ1JvdXRpbmVzUGFpcnMgZmllbGQgb2YgTUlETF9TVFVCX0RFU0MKICAgICAqIGdpdmluZyB0aGUgYmluZCBhbmQgdW5iaW5kIHJvdXRpbmVzIGZvciB0aGUgaGFuZGxlICovCiAgICB1bnNpZ25lZCBjaGFyIGJpbmRpbmdfcm91dGluZV9wYWlyX2luZGV4OwoKICAgIC8qIEZDX1BBRCAqLwogICAgdW5zaWduZWQgY2hhciB1bnVzZWQ7Cn0gTkRSX0VIRF9HRU5FUklDOwoKLyogZXhwbGljaXQgaGFuZGxlIGRlc2NyaXB0aW9uIGZvciBGQ19CSU5EX0NPTlRFWFQgdHlwZSAqLwp0eXBlZGVmIHN0cnVjdCBfTkRSX0VIRF9DT05URVhUCnsKICAgIC8qIEZDX0JJTkRfQ09OVEVYVCAqLwogICAgdW5zaWduZWQgY2hhciBoYW5kbGVfdHlwZTsKCiAgICAvKiBBbnkgb2YgdGhlIGZvbGxvd2luZyBmbGFnczoKICAgICAqIE5EUl9DT05URVhUX0hBTkRMRV9DQU5OT1RfQkVfTlVMTCA9IDB4MDEKICAgICAqIE5EUl9DT05URVhUX0hBTkRMRV9TRVJJQUxJWkUgPSAweDAyCiAgICAgKiBORFJfQ09OVEVYVF9IQU5ETEVfTk9fU0VSSUFMSVpFID0gMHgwNAogICAgICogTkRSX1NUUklDVF9DT05URVhUX0hBTkRMRSA9IDB4MDgKICAgICAqIEhBTkRMRV9QQVJBTV9JU19PVVQgPSAweDIwCiAgICAgKiBIQU5ETEVfUEFSQU1fSVNfUkVUVVJOID0gMHgyMQogICAgICogSEFORExFX1BBUkFNX0lTX0lOID0gMHg0MAogICAgICogSEFORExFX1BBUkFNX0lTX1ZJQV9QVFIgPSAweDgwCiAgICAgKi8KICAgIHVuc2lnbmVkIGNoYXIgZmxhZ3M7CgogICAgLyogb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RhY2sgdG8gdGhlIGhhbmRsZSBpbiBieXRlcyAqLwogICAgdW5zaWduZWQgc2hvcnQgb2Zmc2V0OwoKICAgIC8qIHplcm8tYmFzZWQgaW5kZXggb24gcnVuZG93biByb3V0aW5lIGluIGFwZm5OZHJSdW5kb3duUm91dGluZXMgZmllbGQKICAgICAqIG9mIE1JRExfU1RVQl9ERVNDICovCiAgICB1bnNpZ25lZCBjaGFyIGNvbnRleHRfcnVuZG93bl9yb3V0aW5lX2luZGV4OwoKICAgIC8qIHZhcmllcyBkZXBlbmRpbmcgb24gTkRSIHZlcnNpb24gdXNlZC4KICAgICAqIFYxOiB6ZXJvLWJhc2VkIGluZGV4IGludG8gcGFyYW1ldGVycyAKICAgICAqIFYyOiB6ZXJvLWJhc2VkIGluZGV4IGludG8gaGFuZGxlcyB0aGF0IGFyZSBwYXJhbWV0ZXJzICovCiAgICB1bnNpZ25lZCBjaGFyIHBhcmFtX251bTsKfSBORFJfRUhEX0NPTlRFWFQ7CgojaW5jbHVkZSAicG9wcGFjay5oIgoKdm9pZCBXSU5BUEkgTmRyUnBjU21TZXRDbGllbnRUb09zZihQTUlETF9TVFVCX01FU1NBR0UgcE1lc3NhZ2UpCnsKI2lmIDAgLyogdGhlc2UgZnVuY3Rpb25zIGFyZSBub3QgZGVmaW5lZCB5ZXQgKi8KICAgIHBNZXNzYWdlLT5wZm5BbGxvY2F0ZSA9IE5kclJwY1NtQ2xpZW50QWxsb2NhdGU7CiAgICBwTWVzc2FnZS0+cGZuRnJlZSA9IE5kclJwY1NtQ2xpZW50RnJlZTsKI2VuZGlmCn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBkdW1wX1JQQ19GQ19QUk9DX1BGKFBBUkFNX0FUVFJJQlVURVMgcGFyYW1fYXR0cmlidXRlcykKewogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuTXVzdFNpemUpIFRSQUNFKCIgTXVzdFNpemUiKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLk11c3RGcmVlKSBUUkFDRSgiIE11c3RGcmVlIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc1BpcGUpIFRSQUNFKCIgSXNQaXBlIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc0luKSBUUkFDRSgiIElzSW4iKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLklzT3V0KSBUUkFDRSgiIElzT3V0Iik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikgVFJBQ0UoIiBJc1JldHVybiIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNCYXNldHlwZSkgVFJBQ0UoIiBJc0Jhc2V0eXBlIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpIFRSQUNFKCIgSXNCeVZhbHVlIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc1NpbXBsZVJlZikgVFJBQ0UoIiBJc1NpbXBsZVJlZiIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNEb250Q2FsbEZyZWVJbnN0KSBUUkFDRSgiIElzRG9udENhbGxGcmVlSW5zdCIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuU2F2ZUZvckFzeW5jRmluaXNoKSBUUkFDRSgiIFNhdmVGb3JBc3luY0ZpbmlzaCIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuU2VydmVyQWxsb2NTaXplKSBUUkFDRSgiIFNlcnZlckFsbG9jU2l6ZSA9ICVkIiwgcGFyYW1fYXR0cmlidXRlcy5TZXJ2ZXJBbGxvY1NpemUgKiA4KTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIGR1bXBfSU5URVJQUkVURVJfT1BUX0ZMQUdTKElOVEVSUFJFVEVSX09QVF9GTEFHUyBPaTJGbGFncykKewogICAgaWYgKE9pMkZsYWdzLlNlcnZlck11c3RTaXplKSBUUkFDRSgiIFNlcnZlck11c3RTaXplIik7CiAgICBpZiAoT2kyRmxhZ3MuQ2xpZW50TXVzdFNpemUpIFRSQUNFKCIgQ2xpZW50TXVzdFNpemUiKTsKICAgIGlmIChPaTJGbGFncy5IYXNSZXR1cm4pIFRSQUNFKCIgSGFzUmV0dXJuIik7CiAgICBpZiAoT2kyRmxhZ3MuSGFzUGlwZXMpIFRSQUNFKCIgSGFzUGlwZXMiKTsKICAgIGlmIChPaTJGbGFncy5VbnVzZWQpIFRSQUNFKCIgVW51c2VkIik7CiAgICBpZiAoT2kyRmxhZ3MuSGFzQXN5bmNVdWlkKSBUUkFDRSgiIEhhc0FzeW5jVXVpZCIpOwogICAgaWYgKE9pMkZsYWdzLkhhc0V4dGVuc2lvbnMpIFRSQUNFKCIgSGFzRXh0ZW5zaW9ucyIpOwogICAgaWYgKE9pMkZsYWdzLkhhc0FzeW5jSGFuZGxlKSBUUkFDRSgiIEhhc0FzeW5jSGFuZGxlIik7CiAgICBUUkFDRSgiXG4iKTsKfQoKI2RlZmluZSBBUkdfRlJPTV9PRkZTRVQoc3R1Yk1zZywgb2Zmc2V0KSAoKHN0dWJNc2cpLlN0YWNrVG9wICsgKG9mZnNldCkpCgpzdGF0aWMgUEZPUk1BVF9TVFJJTkcgY2xpZW50X2dldF9oYW5kbGUoCiAgICBQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIGNvbnN0IE5EUl9QUk9DX0hFQURFUiAqcFByb2NIZWFkZXIsCiAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0LCBoYW5kbGVfdCAqcGhCaW5kaW5nKQp7CiAgICAvKiBiaW5kaW5nICovCiAgICBzd2l0Y2ggKHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSkKICAgIHsKICAgIC8qIGV4cGxpY2l0IGJpbmRpbmc6IHBhcnNlIGFkZGl0aW9uYWwgc2VjdGlvbiAqLwogICAgY2FzZSBSUENfRkNfQklORF9FWFBMSUNJVDoKICAgICAgICBzd2l0Y2ggKCpwRm9ybWF0KSAvKiBoYW5kbGVfdHlwZSAqLwogICAgICAgIHsKICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX1BSSU1JVElWRTogLyogZXhwbGljaXQgcHJpbWl0aXZlICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IE5EUl9FSERfUFJJTUlUSVZFICpwRGVzYyA9IChjb25zdCBORFJfRUhEX1BSSU1JVElWRSAqKXBGb3JtYXQ7CgogICAgICAgICAgICAgICAgVFJBQ0UoIkV4cGxpY2l0IHByaW1pdGl2ZSBoYW5kbGUgQCAlZFxuIiwgcERlc2MtPm9mZnNldCk7CgogICAgICAgICAgICAgICAgaWYgKHBEZXNjLT5mbGFnKSAvKiBwb2ludGVyIHRvIGJpbmRpbmcgKi8KICAgICAgICAgICAgICAgICAgICAqcGhCaW5kaW5nID0gKiooaGFuZGxlX3QgKiopQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgcERlc2MtPm9mZnNldCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgKnBoQmluZGluZyA9ICooaGFuZGxlX3QgKilBUkdfRlJPTV9PRkZTRVQoKnBTdHViTXNnLCBwRGVzYy0+b2Zmc2V0KTsKICAgICAgICAgICAgICAgIHJldHVybiBwRm9ybWF0ICsgc2l6ZW9mKE5EUl9FSERfUFJJTUlUSVZFKTsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfR0VORVJJQzogLyogZXhwbGljaXQgZ2VuZXJpYyAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb25zdCBORFJfRUhEX0dFTkVSSUMgKnBEZXNjID0gKGNvbnN0IE5EUl9FSERfR0VORVJJQyAqKXBGb3JtYXQ7CiAgICAgICAgICAgICAgICB2b2lkICpwT2JqZWN0ID0gTlVMTDsKICAgICAgICAgICAgICAgIHZvaWQgKnBBcmc7CiAgICAgICAgICAgICAgICBjb25zdCBHRU5FUklDX0JJTkRJTkdfUk9VVElORV9QQUlSICpwR2VuUGFpcjsKCiAgICAgICAgICAgICAgICBUUkFDRSgiRXhwbGljaXQgZ2VuZXJpYyBiaW5kaW5nIGhhbmRsZSAjJWRcbiIsIHBEZXNjLT5iaW5kaW5nX3JvdXRpbmVfcGFpcl9pbmRleCk7CgogICAgICAgICAgICAgICAgaWYgKHBEZXNjLT5mbGFnX2FuZF9zaXplICYgSEFORExFX1BBUkFNX0lTX1ZJQV9QVFIpCiAgICAgICAgICAgICAgICAgICAgcEFyZyA9ICoodm9pZCAqKilBUkdfRlJPTV9PRkZTRVQoKnBTdHViTXNnLCBwRGVzYy0+b2Zmc2V0KTsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBwQXJnID0gKHZvaWQgKilBUkdfRlJPTV9PRkZTRVQoKnBTdHViTXNnLCBwRGVzYy0+b2Zmc2V0KTsKICAgICAgICAgICAgICAgIG1lbWNweSgmcE9iamVjdCwgcEFyZywgcERlc2MtPmZsYWdfYW5kX3NpemUgJiAweGYpOwogICAgICAgICAgICAgICAgcEdlblBhaXIgPSAmcFN0dWJNc2ctPlN0dWJEZXNjLT5hR2VuZXJpY0JpbmRpbmdSb3V0aW5lUGFpcnNbcERlc2MtPmJpbmRpbmdfcm91dGluZV9wYWlyX2luZGV4XTsKICAgICAgICAgICAgICAgICpwaEJpbmRpbmcgPSBwR2VuUGFpci0+cGZuQmluZChwT2JqZWN0KTsKICAgICAgICAgICAgICAgIHJldHVybiBwRm9ybWF0ICsgc2l6ZW9mKE5EUl9FSERfR0VORVJJQyk7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0NPTlRFWFQ6IC8qIGV4cGxpY2l0IGNvbnRleHQgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29uc3QgTkRSX0VIRF9DT05URVhUICpwRGVzYyA9IChjb25zdCBORFJfRUhEX0NPTlRFWFQgKilwRm9ybWF0OwogICAgICAgICAgICAgICAgTkRSX0NDT05URVhUIGNvbnRleHRfaGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0UoIkV4cGxpY2l0IGJpbmQgY29udGV4dFxuIik7CiAgICAgICAgICAgICAgICBpZiAocERlc2MtPmZsYWdzICYgSEFORExFX1BBUkFNX0lTX1ZJQV9QVFIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0SEFORExFX1BBUkFNX0lTX1ZJQV9QVFJcbiIpOwogICAgICAgICAgICAgICAgICAgIGNvbnRleHRfaGFuZGxlID0gKiooTkRSX0NDT05URVhUICoqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGNvbnRleHRfaGFuZGxlID0gKihORFJfQ0NPTlRFWFQgKilBUkdfRlJPTV9PRkZTRVQoKnBTdHViTXNnLCBwRGVzYy0+b2Zmc2V0KTsKICAgICAgICAgICAgICAgIGlmICgocERlc2MtPmZsYWdzICYgTkRSX0NPTlRFWFRfSEFORExFX0NBTk5PVF9CRV9OVUxMKSAmJgogICAgICAgICAgICAgICAgICAgICFjb250ZXh0X2hhbmRsZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlIoIm51bGwgY29udGV4dCBoYW5kbGUgaXNuJ3QgYWxsb3dlZFxuIik7CiAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfU1NfSU5fTlVMTF9DT05URVhUKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICpwaEJpbmRpbmcgPSBORFJDQ29udGV4dEJpbmRpbmcoY29udGV4dF9oYW5kbGUpOwogICAgICAgICAgICAgICAgLyogRklYTUU6IHNob3VsZCB3ZSBzdG9yZSB0aGlzIHN0cnVjdHVyZSBpbiBzdHViTXNnLnBDb250ZXh0PyAqLwogICAgICAgICAgICAgICAgcmV0dXJuIHBGb3JtYXQgKyBzaXplb2YoTkRSX0VIRF9DT05URVhUKTsKICAgICAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiYmFkIGV4cGxpY2l0IGJpbmRpbmcgaGFuZGxlIHR5cGUgKDB4JTAyeClcbiIsIHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSk7CiAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0JJTkRfR0VORVJJQzogLyogaW1wbGljaXQgZ2VuZXJpYyAqLwogICAgICAgIEZJWE1FKCJSUENfRkNfQklORF9HRU5FUklDXG4iKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsgLyogRklYTUU6IHJlbW92ZSB3aGVuIGltcGxlbWVudGVkICovCiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFJQQ19GQ19CSU5EX1BSSU1JVElWRTogLyogaW1wbGljaXQgcHJpbWl0aXZlICovCiAgICAgICAgVFJBQ0UoIkltcGxpY2l0IHByaW1pdGl2ZSBoYW5kbGVcbiIpOwogICAgICAgICpwaEJpbmRpbmcgPSAqcFN0dWJNc2ctPlN0dWJEZXNjLT5JTVBMSUNJVF9IQU5ETEVfSU5GTy5wUHJpbWl0aXZlSGFuZGxlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfQ0FMTEJBQ0tfSEFORExFOiAvKiBpbXBsaWNpdCBjYWxsYmFjayAqLwogICAgICAgIEZJWE1FKCJSUENfRkNfQ0FMTEJBQ0tfSEFORExFXG4iKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0FVVE9fSEFORExFOiAvKiBpbXBsaWNpdCBhdXRvIGhhbmRsZSAqLwogICAgICAgIC8qIHN0cmljdGx5IHNwZWFraW5nLCBpdCBpc24ndCBuZWNlc3NhcnkgdG8gc2V0IGhCaW5kaW5nIGhlcmUKICAgICAgICAgKiBzaW5jZSBpdCBpc24ndCBhY3R1YWxseSB1c2VkIChoZW5jZSB0aGUgYXV0b21hdGljIGluIGl0cyBuYW1lKSwKICAgICAgICAgKiBidXQgdGhlbiB3aHkgZG9lcyBNSURMIGdlbmVyYXRlIGEgdmFsaWQgZW50cnkgaW4gdGhlCiAgICAgICAgICogTUlETF9TVFVCX0RFU0MgZm9yIGl0PyAqLwogICAgICAgIFRSQUNFKCJJbXBsaWNpdCBhdXRvIGhhbmRsZVxuIik7CiAgICAgICAgKnBoQmluZGluZyA9ICpwU3R1Yk1zZy0+U3R1YkRlc2MtPklNUExJQ0lUX0hBTkRMRV9JTkZPLnBBdXRvSGFuZGxlOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBFUlIoImJhZCBpbXBsaWNpdCBiaW5kaW5nIGhhbmRsZSB0eXBlICgweCUwMngpXG4iLCBwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgfQogICAgcmV0dXJuIHBGb3JtYXQ7Cn0KCnN0YXRpYyB2b2lkIGNsaWVudF9mcmVlX2hhbmRsZSgKICAgIFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgY29uc3QgTkRSX1BST0NfSEVBREVSICpwUHJvY0hlYWRlciwKICAgIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQsIGhhbmRsZV90IGhCaW5kaW5nKQp7CiAgICAvKiBiaW5kaW5nICovCiAgICBzd2l0Y2ggKHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSkKICAgIHsKICAgIC8qIGV4cGxpY2l0IGJpbmRpbmc6IHBhcnNlIGFkZGl0aW9uYWwgc2VjdGlvbiAqLwogICAgY2FzZSBSUENfRkNfQklORF9FWFBMSUNJVDoKICAgICAgICBzd2l0Y2ggKCpwRm9ybWF0KSAvKiBoYW5kbGVfdHlwZSAqLwogICAgICAgIHsKICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0dFTkVSSUM6IC8qIGV4cGxpY2l0IGdlbmVyaWMgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29uc3QgTkRSX0VIRF9HRU5FUklDICpwRGVzYyA9IChjb25zdCBORFJfRUhEX0dFTkVSSUMgKilwRm9ybWF0OwogICAgICAgICAgICAgICAgdm9pZCAqcE9iamVjdCA9IE5VTEw7CiAgICAgICAgICAgICAgICB2b2lkICpwQXJnOwogICAgICAgICAgICAgICAgY29uc3QgR0VORVJJQ19CSU5ESU5HX1JPVVRJTkVfUEFJUiAqcEdlblBhaXI7CgogICAgICAgICAgICAgICAgVFJBQ0UoIkV4cGxpY2l0IGdlbmVyaWMgYmluZGluZyBoYW5kbGUgIyVkXG4iLCBwRGVzYy0+YmluZGluZ19yb3V0aW5lX3BhaXJfaW5kZXgpOwoKICAgICAgICAgICAgICAgIGlmIChwRGVzYy0+ZmxhZ19hbmRfc2l6ZSAmIEhBTkRMRV9QQVJBTV9JU19WSUFfUFRSKQogICAgICAgICAgICAgICAgICAgIHBBcmcgPSAqKHZvaWQgKiopQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgcERlc2MtPm9mZnNldCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcEFyZyA9ICh2b2lkICopQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgcERlc2MtPm9mZnNldCk7CiAgICAgICAgICAgICAgICBtZW1jcHkoJnBPYmplY3QsIHBBcmcsIHBEZXNjLT5mbGFnX2FuZF9zaXplICYgMHhmKTsKICAgICAgICAgICAgICAgIHBHZW5QYWlyID0gJnBTdHViTXNnLT5TdHViRGVzYy0+YUdlbmVyaWNCaW5kaW5nUm91dGluZVBhaXJzW3BEZXNjLT5iaW5kaW5nX3JvdXRpbmVfcGFpcl9pbmRleF07CiAgICAgICAgICAgICAgICBwR2VuUGFpci0+cGZuVW5iaW5kKHBPYmplY3QsIGhCaW5kaW5nKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBSUENfRkNfQklORF9DT05URVhUOiAvKiBleHBsaWNpdCBjb250ZXh0ICovCiAgICAgICAgY2FzZSBSUENfRkNfQklORF9QUklNSVRJVkU6IC8qIGV4cGxpY2l0IHByaW1pdGl2ZSAqLwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoImJhZCBleHBsaWNpdCBiaW5kaW5nIGhhbmRsZSB0eXBlICgweCUwMngpXG4iLCBwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpOwogICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFJQQ19GQ19CSU5EX0dFTkVSSUM6IC8qIGltcGxpY2l0IGdlbmVyaWMgKi8KICAgICAgICBGSVhNRSgiUlBDX0ZDX0JJTkRfR0VORVJJQ1xuIik7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7IC8qIEZJWE1FOiByZW1vdmUgd2hlbiBpbXBsZW1lbnRlZCAqLwogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfQ0FMTEJBQ0tfSEFORExFOiAvKiBpbXBsaWNpdCBjYWxsYmFjayAqLwogICAgY2FzZSBSUENfRkNfQklORF9QUklNSVRJVkU6IC8qIGltcGxpY2l0IHByaW1pdGl2ZSAqLwogICAgY2FzZSBSUENfRkNfQVVUT19IQU5ETEU6IC8qIGltcGxpY2l0IGF1dG8gaGFuZGxlICovCiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIEVSUigiYmFkIGltcGxpY2l0IGJpbmRpbmcgaGFuZGxlIHR5cGUgKDB4JTAyeClcbiIsIHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGNsaWVudF9kb19hcmdzKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCwKICAgIGludCBwaGFzZSwgdW5zaWduZWQgc2hvcnQgbnVtYmVyX29mX3BhcmFtcywgdW5zaWduZWQgY2hhciAqcFJldFZhbCkKewogICAgLyogY3VycmVudCBmb3JtYXQgc3RyaW5nIG9mZnNldCAqLwogICAgaW50IGN1cnJlbnRfb2Zmc2V0ID0gMDsKICAgIC8qIGN1cnJlbnQgc3RhY2sgb2Zmc2V0ICovCiAgICB1bnNpZ25lZCBzaG9ydCBjdXJyZW50X3N0YWNrX29mZnNldCA9IDA7CiAgICAvKiBjb3VudGVyICovCiAgICB1bnNpZ25lZCBzaG9ydCBpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBudW1iZXJfb2ZfcGFyYW1zOyBpKyspCiAgICB7CiAgICAgICAgY29uc3QgTkRSX1BBUkFNX09JRl9CQVNFVFlQRSAqcFBhcmFtID0KICAgICAgICAgICAgKGNvbnN0IE5EUl9QQVJBTV9PSUZfQkFTRVRZUEUgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CiAgICAgICAgdW5zaWduZWQgY2hhciAqIHBBcmc7CgogICAgICAgIGN1cnJlbnRfc3RhY2tfb2Zmc2V0ID0gcFBhcmFtLT5zdGFja19vZmZzZXQ7CiAgICAgICAgcEFyZyA9IEFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIGN1cnJlbnRfc3RhY2tfb2Zmc2V0KTsKCiAgICAgICAgVFJBQ0UoInBhcmFtWyVkXTogbmV3IGZvcm1hdFxuIiwgaSk7CiAgICAgICAgVFJBQ0UoIlx0cGFyYW1fYXR0cmlidXRlczoiKTsgZHVtcF9SUENfRkNfUFJPQ19QRihwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMpOyBUUkFDRSgiXG4iKTsKICAgICAgICBUUkFDRSgiXHRzdGFja19vZmZzZXQ6IDB4JXhcbiIsIGN1cnJlbnRfc3RhY2tfb2Zmc2V0KTsKICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYmVmb3JlKTogJXBcbiIsIHBBcmcpOwoKICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzQmFzZXR5cGUpCiAgICAgICAgewogICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyICogcFR5cGVGb3JtYXQgPQogICAgICAgICAgICAgICAgJnBQYXJhbS0+dHlwZV9mb3JtYXRfY2hhcjsKCiAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpCiAgICAgICAgICAgICAgICBwQXJnID0gKih1bnNpZ25lZCBjaGFyICoqKXBBcmc7CgogICAgICAgICAgICBUUkFDRSgiXHRiYXNlIHR5cGU6IDB4JTAyeFxuIiwgKnBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgIHN3aXRjaCAocGhhc2UpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBQUk9YWV9DQUxDU0laRToKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNJbikKICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcihwU3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfTUFSU0hBTDoKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNJbikKICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIocFN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNPdXQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIocFN0dWJNc2csICZwUmV0VmFsLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgicFJldFZhbCA9ICVwXG4iLCBwUmV0VmFsKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JRl9CQVNFVFlQRSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGNvbnN0IE5EUl9QQVJBTV9PSUZfT1RIRVIgKnBQYXJhbU90aGVyID0KICAgICAgICAgICAgICAgIChjb25zdCBORFJfUEFSQU1fT0lGX09USEVSICopJnBGb3JtYXRbY3VycmVudF9vZmZzZXRdOwoKICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqIHBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICYocFN0dWJNc2ctPlN0dWJEZXNjLT5wRm9ybWF0VHlwZXNbcFBhcmFtT3RoZXItPnR5cGVfb2Zmc2V0XSk7CgogICAgICAgICAgICAvKiBpZiBhIHNpbXBsZSByZWYgcG9pbnRlciB0aGVuIHdlIGhhdmUgdG8gZG8gdGhlCiAgICAgICAgICAgICAqIGNoZWNrIGZvciB0aGUgcG9pbnRlciBiZWluZyBub24tTlVMTC4gKi8KICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1NpbXBsZVJlZikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCEqKHVuc2lnbmVkIGNoYXIgKiopcEFyZykKICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9OVUxMX1JFRl9QT0lOVEVSKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVFJBQ0UoIlx0Y29tcGxleCB0eXBlOiAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKHBTdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcihwU3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBST1hZX01BUlNIQUw6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcihwU3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKHBTdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfVU5NQVJTSEFMOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzUmV0dXJuKQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgJnBSZXRWYWwsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKHBTdHViTXNnLCAodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSUZfT1RIRVIpOwogICAgICAgIH0KICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYWZ0ZXIpOiAlcFxuIiwgcEFyZyk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGNsaWVudF9kb19hcmdzX29sZF9mb3JtYXQoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLAogICAgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCwgaW50IHBoYXNlLCB1bnNpZ25lZCBzaG9ydCBzdGFja19zaXplLAogICAgdW5zaWduZWQgY2hhciAqcFJldFZhbCwgQk9PTCBvYmplY3RfcHJvYykKewogICAgLyogY3VycmVudCBmb3JtYXQgc3RyaW5nIG9mZnNldCAqLwogICAgaW50IGN1cnJlbnRfb2Zmc2V0ID0gMDsKICAgIC8qIGN1cnJlbnQgc3RhY2sgb2Zmc2V0ICovCiAgICB1bnNpZ25lZCBzaG9ydCBjdXJyZW50X3N0YWNrX29mZnNldCA9IDA7CiAgICAvKiBjb3VudGVyICovCiAgICB1bnNpZ25lZCBzaG9ydCBpOwoKICAgIC8qIE5PVEU6IFYxIHN0eWxlIGZvcm1hdCBkb2VzJ3QgdGVybWluYXRlIG9uIHRoZSBudW1iZXJfb2ZfcGFyYW1zCiAgICAgKiBjb25kaXRpb24gYXMgaXQgZG9lc24ndCBoYXZlIHRoaXMgYXR0cmlidXRlLiBJbnN0ZWFkIGl0CiAgICAgKiB0ZXJtaW5hdGVzIHdoZW4gdGhlIHN0YWNrIHNpemUgZ2l2ZW4gaW4gdGhlIGhlYWRlciBpcyBleGNlZWRlZC4KICAgICAqLwogICAgZm9yIChpID0gMDsgVFJVRTsgaSsrKQogICAgewogICAgICAgIGNvbnN0IE5EUl9QQVJBTV9PSV9CQVNFVFlQRSAqcFBhcmFtID0KICAgICAgICAgICAgKGNvbnN0IE5EUl9QQVJBTV9PSV9CQVNFVFlQRSAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKICAgICAgICAvKiBub3RlOiBjdXJyZW50X3N0YWNrX29mZnNldCBzdGFydHMgYWZ0ZXIgdGhlIFRoaXMgcG9pbnRlcgogICAgICAgICAqIGlmIHByZXNlbnQsIHNvIGFkanVzdCB0aGlzICovCiAgICAgICAgdW5zaWduZWQgc2hvcnQgY3VycmVudF9zdGFja19vZmZzZXRfYWRqdXN0ZWQgPSBjdXJyZW50X3N0YWNrX29mZnNldCArCiAgICAgICAgICAgIChvYmplY3RfcHJvYyA/IHNpemVvZih2b2lkICopIDogMCk7CiAgICAgICAgdW5zaWduZWQgY2hhciAqIHBBcmcgPSBBUkdfRlJPTV9PRkZTRVQoKnBTdHViTXNnLCBjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCk7CgogICAgICAgIC8qIG5vIG1vcmUgcGFyYW1ldGVyczsgZXhpdCBsb29wICovCiAgICAgICAgaWYgKGN1cnJlbnRfc3RhY2tfb2Zmc2V0X2FkanVzdGVkID49IHN0YWNrX3NpemUpCiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBUUkFDRSgicGFyYW1bJWRdOiBvbGQgZm9ybWF0XG4iLCBpKTsKICAgICAgICBUUkFDRSgiXHRwYXJhbV9kaXJlY3Rpb246IDB4JXhcbiIsIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uKTsKICAgICAgICBUUkFDRSgiXHRzdGFja19vZmZzZXQ6IDB4JXhcbiIsIGN1cnJlbnRfc3RhY2tfb2Zmc2V0X2FkanVzdGVkKTsKICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYmVmb3JlKTogJXBcbiIsIHBBcmcpOwoKICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX1BBUkFNX0JBU0VUWVBFIHx8CiAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgewogICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyICogcFR5cGVGb3JtYXQgPQogICAgICAgICAgICAgICAgJnBQYXJhbS0+dHlwZV9mb3JtYXRfY2hhcjsKCiAgICAgICAgICAgIFRSQUNFKCJcdGJhc2UgdHlwZSAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKHBTdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQUk9YWV9NQVJTSEFMOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIocFN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiAmIFJQQ19GQ19SRVRVUk5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKHBTdHViTXNnLCAodW5zaWduZWQgY2hhciAqKilwUmV0VmFsLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCArPSBjYWxsX21lbW9yeV9zaXplcihwU3R1Yk1zZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JX0JBU0VUWVBFKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgTkRSX1BBUkFNX09JX09USEVSICpwUGFyYW1PdGhlciA9IAogICAgICAgICAgICAgICAgKGNvbnN0IE5EUl9QQVJBTV9PSV9PVEhFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICZwU3R1Yk1zZy0+U3R1YkRlc2MtPnBGb3JtYXRUeXBlc1twUGFyYW1PdGhlci0+dHlwZV9vZmZzZXRdOwoKICAgICAgICAgICAgVFJBQ0UoIlx0Y29tcGxleCB0eXBlIDB4JTAyeFxuIiwgKnBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgIHN3aXRjaCAocGhhc2UpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgY2FzZSBQUk9YWV9DQUxDU0laRToKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU0gfHwKICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiAmIFJQQ19GQ19JTl9PVVRfUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIocFN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQUk9YWV9NQVJTSEFMOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uICYgUlBDX0ZDX0lOX09VVF9QQVJBTSkKICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIocFN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQUk9YWV9VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX09VVF9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19PVVRfUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIocFN0dWJNc2csICh1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIocFN0dWJNc2csICh1bnNpZ25lZCBjaGFyICoqKXBSZXRWYWwsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCArPSBwUGFyYW1PdGhlci0+c3RhY2tfc2l6ZSAqIHNpemVvZihJTlQpOwogICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JX09USEVSKTsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIlx0bWVtb3J5IGFkZHIgKGFmdGVyKTogJXBcbiIsIHBBcmcpOwogICAgfQp9CgovKiB0aGUgcmV0dXJuIHR5cGUgc2hvdWxkIGJlIENMSUVOVF9DQUxMX1JFVFVSTiwgYnV0IHRoaXMgaXMgaW5jb21wYXRpYmxlCiAqIHdpdGggdGhlIHdheSBnY2MgcmV0dXJucyBzdHJ1Y3R1cmVzLiAidm9pZCAqIiBzaG91bGQgYmUgdGhlIGxhcmdlc3QgdHlwZQogKiB0aGF0IE1JREwgc2hvdWxkIGFsbG93IHlvdSB0byByZXR1cm4gYW55d2F5ICovCkxPTkdfUFRSIFdJTkFQSVYgTmRyQ2xpZW50Q2FsbDIoUE1JRExfU1RVQl9ERVNDIHBTdHViRGVzYywgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCwgLi4uKQp7CiAgICAvKiBwb2ludGVyIHRvIHN0YXJ0IG9mIHN0YWNrIHdoZXJlIGFyZ3VtZW50cyBzdGFydCAqLwogICAgUlBDX01FU1NBR0UgcnBjTXNnOwogICAgTUlETF9TVFVCX01FU1NBR0Ugc3R1Yk1zZzsKICAgIGhhbmRsZV90IGhCaW5kaW5nID0gTlVMTDsKICAgIC8qIHByb2NlZHVyZSBudW1iZXIgKi8KICAgIHVuc2lnbmVkIHNob3J0IHByb2NlZHVyZV9udW1iZXI7CiAgICAvKiBzaXplIG9mIHN0YWNrICovCiAgICB1bnNpZ25lZCBzaG9ydCBzdGFja19zaXplOwogICAgLyogbnVtYmVyIG9mIHBhcmFtZXRlcnMuIG9wdGlvbmFsIGZvciBjbGllbnQgdG8gZ2l2ZSBpdCB0byB1cyAqLwogICAgdW5zaWduZWQgY2hhciBudW1iZXJfb2ZfcGFyYW1zID0gfjA7CiAgICAvKiBjYWNoZSBvZiBPaWZfZmxhZ3MgZnJvbSB2MiBwcm9jZWR1cmUgaGVhZGVyICovCiAgICBJTlRFUlBSRVRFUl9PUFRfRkxBR1MgT2lmX2ZsYWdzID0geyAwIH07CiAgICAvKiBjYWNoZSBvZiBleHRlbnNpb24gZmxhZ3MgZnJvbSBORFJfUFJPQ19IRUFERVJfRVhUUyAqLwogICAgSU5URVJQUkVURVJfT1BUX0ZMQUdTMiBleHRfZmxhZ3MgPSB7IDAgfTsKICAgIC8qIHRoZSB0eXBlIG9mIHBhc3Mgd2UgYXJlIGN1cnJlbnRseSBkb2luZyAqLwogICAgaW50IHBoYXNlOwogICAgLyogaGVhZGVyIGZvciBwcm9jZWR1cmUgc3RyaW5nICovCiAgICBjb25zdCBORFJfUFJPQ19IRUFERVIgKiBwUHJvY0hlYWRlciA9IChjb25zdCBORFJfUFJPQ19IRUFERVIgKikmcEZvcm1hdFswXTsKICAgIC8qIC1PaWYgb3IgLU9pY2YgZ2VuZXJhdGVkIGZvcm1hdCAqLwogICAgQk9PTCBiVjJGb3JtYXQgPSBGQUxTRTsKICAgIC8qIHRoZSB2YWx1ZSB0byByZXR1cm4gdG8gdGhlIGNsaWVudCBmcm9tIHRoZSByZW1vdGUgcHJvY2VkdXJlICovCiAgICBMT05HX1BUUiBSZXRWYWwgPSAwOwogICAgLyogdGhlIHBvaW50ZXIgdG8gdGhlIG9iamVjdCB3aGVuIGluIE9MRSBtb2RlICovCiAgICB2b2lkICogVGhpcyA9IE5VTEw7CiAgICBQRk9STUFUX1NUUklORyBwSGFuZGxlRm9ybWF0OwoKICAgIFRSQUNFKCJwU3R1YkRlc2MgJXAsIHBGb3JtYXQgJXAsIC4uLlxuIiwgcFN0dWJEZXNjLCBwRm9ybWF0KTsKCiAgICAvKiBMYXRlciBORFIgbGFuZ3VhZ2UgdmVyc2lvbnMgcHJvYmFibHkgd29uJ3QgYmUgYmFja3dhcmRzIGNvbXBhdGlibGUgKi8KICAgIGlmIChwU3R1YkRlc2MtPlZlcnNpb24gPiAweDUwMDAyKQogICAgewogICAgICAgIEZJWE1FKCJJbmNvbXBhdGlibGUgc3R1YiBkZXNjcmlwdGlvbiB2ZXJzaW9uOiAweCV4XG4iLCBwU3R1YkRlc2MtPlZlcnNpb24pOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX1dST05HX1NUVUJfVkVSU0lPTik7CiAgICB9CgogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENGTEFHUykKICAgIHsKICAgICAgICBjb25zdCBORFJfUFJPQ19IRUFERVJfUlBDICpwUHJvY0hlYWRlciA9IChjb25zdCBORFJfUFJPQ19IRUFERVJfUlBDICopJnBGb3JtYXRbMF07CiAgICAgICAgc3RhY2tfc2l6ZSA9IHBQcm9jSGVhZGVyLT5zdGFja19zaXplOwogICAgICAgIHByb2NlZHVyZV9udW1iZXIgPSBwUHJvY0hlYWRlci0+cHJvY19udW07CiAgICAgICAgcEZvcm1hdCArPSBzaXplb2YoTkRSX1BST0NfSEVBREVSX1JQQyk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc3RhY2tfc2l6ZSA9IHBQcm9jSGVhZGVyLT5zdGFja19zaXplOwogICAgICAgIHByb2NlZHVyZV9udW1iZXIgPSBwUHJvY0hlYWRlci0+cHJvY19udW07CiAgICAgICAgcEZvcm1hdCArPSBzaXplb2YoTkRSX1BST0NfSEVBREVSKTsKICAgIH0KICAgIFRSQUNFKCJzdGFjayBzaXplOiAweCV4XG4iLCBzdGFja19zaXplKTsKICAgIFRSQUNFKCJwcm9jIG51bTogJWRcbiIsIHByb2NlZHVyZV9udW1iZXIpOwoKICAgIC8qIGNyZWF0ZSB0aGUgZnVsbCBwb2ludGVyIHRyYW5zbGF0aW9uIHRhYmxlcywgaWYgcmVxdWVzdGVkICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX0ZVTExQVFIpCiAgICAgICAgc3R1Yk1zZy5GdWxsUHRyWGxhdFRhYmxlcyA9IE5kckZ1bGxQb2ludGVyWGxhdEluaXQoMCxYTEFUX0NMSUVOVCk7CgogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpCiAgICB7CiAgICAgICAgLyogb2JqZWN0IGlzIGFsd2F5cyB0aGUgZmlyc3QgYXJndW1lbnQgKi8KICAgICAgICBUaGlzID0gKioodm9pZCAqY29uc3QgKiopKCZwRm9ybWF0KzEpOwogICAgICAgIE5kclByb3h5SW5pdGlhbGl6ZShUaGlzLCAmcnBjTXNnLCAmc3R1Yk1zZywgcFN0dWJEZXNjLCBwcm9jZWR1cmVfbnVtYmVyKTsKICAgIH0KICAgIGVsc2UKICAgICAgICBOZHJDbGllbnRJbml0aWFsaXplTmV3KCZycGNNc2csICZzdHViTXNnLCBwU3R1YkRlc2MsIHByb2NlZHVyZV9udW1iZXIpOwoKICAgIFRSQUNFKCJPaV9mbGFncyA9IDB4JTAyeFxuIiwgcFByb2NIZWFkZXItPk9pX2ZsYWdzKTsKICAgIFRSQUNFKCJNSURMIHN0dWIgdmVyc2lvbiA9IDB4JXhcbiIsIHBTdHViRGVzYy0+TUlETFZlcnNpb24pOwoKICAgIC8qIG5lZWRlZCBmb3IgY29uZm9ybWFuY2Ugb2YgdG9wLWxldmVsIG9iamVjdHMgKi8KI2lmZGVmIF9faTM4Nl9fCiAgICBzdHViTXNnLlN0YWNrVG9wID0gKih1bnNpZ25lZCBjaGFyICoqKSgmcEZvcm1hdCsxKTsKI2Vsc2UKIyB3YXJuaW5nIFN0YWNrIG5vdCByZXRyaWV2ZWQgZm9yIHlvdXIgQ1BVIGFyY2hpdGVjdHVyZQojZW5kaWYKCiAgICBwSGFuZGxlRm9ybWF0ID0gcEZvcm1hdDsKCiAgICAvKiB3ZSBvbmx5IG5lZWQgYSBoYW5kbGUgaWYgdGhpcyBpc24ndCBhbiBvYmplY3QgbWV0aG9kICovCiAgICBpZiAoIShwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKSkKICAgIHsKICAgICAgICBwRm9ybWF0ID0gY2xpZW50X2dldF9oYW5kbGUoJnN0dWJNc2csIHBQcm9jSGVhZGVyLCBwSGFuZGxlRm9ybWF0LCAmaEJpbmRpbmcpOwogICAgICAgIGlmICghcEZvcm1hdCkgcmV0dXJuIDA7CiAgICB9CgogICAgYlYyRm9ybWF0ID0gKHBTdHViRGVzYy0+VmVyc2lvbiA+PSAweDIwMDAwKTsKCiAgICBpZiAoYlYyRm9ybWF0KQogICAgewogICAgICAgIGNvbnN0IE5EUl9QUk9DX1BBUlRJQUxfT0lGX0hFQURFUiAqcE9JRkhlYWRlciA9CiAgICAgICAgICAgIChjb25zdCBORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIgKilwRm9ybWF0OwoKICAgICAgICBPaWZfZmxhZ3MgPSBwT0lGSGVhZGVyLT5PaTJGbGFnczsKICAgICAgICBudW1iZXJfb2ZfcGFyYW1zID0gcE9JRkhlYWRlci0+bnVtYmVyX29mX3BhcmFtczsKCiAgICAgICAgcEZvcm1hdCArPSBzaXplb2YoTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSKTsKICAgIH0KCiAgICBUUkFDRSgiT2lmX2ZsYWdzID0gIik7IGR1bXBfSU5URVJQUkVURVJfT1BUX0ZMQUdTKE9pZl9mbGFncyk7CgogICAgaWYgKE9pZl9mbGFncy5IYXNFeHRlbnNpb25zKQogICAgewogICAgICAgIGNvbnN0IE5EUl9QUk9DX0hFQURFUl9FWFRTICpwRXh0ZW5zaW9ucyA9CiAgICAgICAgICAgIChjb25zdCBORFJfUFJPQ19IRUFERVJfRVhUUyAqKXBGb3JtYXQ7CiAgICAgICAgZXh0X2ZsYWdzID0gcEV4dGVuc2lvbnMtPkZsYWdzMjsKICAgICAgICBwRm9ybWF0ICs9IHBFeHRlbnNpb25zLT5TaXplOwogICAgfQoKICAgIHN0dWJNc2cuQnVmZmVyTGVuZ3RoID0gMDsKCiAgICAvKiBzdG9yZSB0aGUgUlBDIGZsYWdzIGF3YXkgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfUlBDRkxBR1MpCiAgICAgICAgcnBjTXNnLlJwY0ZsYWdzID0gKChjb25zdCBORFJfUFJPQ19IRUFERVJfUlBDICopcFByb2NIZWFkZXIpLT5ycGNfZmxhZ3M7CgogICAgLyogdXNlIGFsdGVybmF0ZSBtZW1vcnkgYWxsb2NhdGlvbiByb3V0aW5lcyAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENTU0FMTE9DKQogICAgICAgIE5kclJwY1NtU2V0Q2xpZW50VG9Pc2YoJnN0dWJNc2cpOwoKICAgIGlmIChPaWZfZmxhZ3MuSGFzUGlwZXMpCiAgICB7CiAgICAgICAgRklYTUUoInBpcGVzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9XUk9OR19TVFVCX1ZFUlNJT04pOyAvKiBGSVhNRTogcmVtb3ZlIHdoZW4gaW1wbGVtZW50ZWQgKi8KICAgICAgICAvKiBpbml0IHBpcGVzIHBhY2thZ2UgKi8KICAgICAgICAvKiBOZHJQaXBlc0luaXRpYWxpemUoLi4uKSAqLwogICAgfQogICAgaWYgKGV4dF9mbGFncy5IYXNOZXdDb3JyRGVzYykKICAgIHsKICAgICAgICAvKiBpbml0aWFsaXplIGV4dHJhIGNvcnJlbGF0aW9uIHBhY2thZ2UgKi8KICAgICAgICBGSVhNRSgibmV3IGNvcnJlbGF0aW9uIGRlc2NyaXB0aW9uIG5vdCBpbXBsZW1lbnRlZFxuIik7CiAgICAgICAgc3R1Yk1zZy5mSGFzTmV3Q29yckRlc2MgPSBUUlVFOwogICAgfQoKICAgIC8qIG9yZGVyIG9mIHBoYXNlczoKICAgICAqIDEuIFBST1hZX0NBTENTSVpFIC0gY2FsY3VsYXRlIHRoZSBidWZmZXIgc2l6ZQogICAgICogMi4gUFJPWFlfR0VUQlVGRkVSIC0gYWxsb2NhdGUgdGhlIGJ1ZmZlcgogICAgICogMy4gUFJPWFlfTUFSSFNBTCAtIG1hcnNoYWwgW2luXSBwYXJhbXMgaW50byB0aGUgYnVmZmVyCiAgICAgKiA0LiBQUk9YWV9TRU5EUkVDRUlWRSAtIHNlbmQvcmVjZWl2ZSBidWZmZXIKICAgICAqIDUuIFBST1hZX1VOTUFSSFNBTCAtIHVubWFyc2hhbCBbb3V0XSBwYXJhbXMgZnJvbSBidWZmZXIKICAgICAqLwogICAgZm9yIChwaGFzZSA9IFBST1hZX0NBTENTSVpFOyBwaGFzZSA8PSBQUk9YWV9VTk1BUlNIQUw7IHBoYXNlKyspCiAgICB7CiAgICAgICAgVFJBQ0UoInBoYXNlID0gJWRcbiIsIHBoYXNlKTsKICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgIHsKICAgICAgICBjYXNlIFBST1hZX0dFVEJVRkZFUjoKICAgICAgICAgICAgLyogYWxsb2NhdGUgdGhlIGJ1ZmZlciAqLwogICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX09CSkVDVCkKICAgICAgICAgICAgICAgIE5kclByb3h5R2V0QnVmZmVyKFRoaXMsICZzdHViTXNnKTsKICAgICAgICAgICAgZWxzZSBpZiAoT2lmX2ZsYWdzLkhhc1BpcGVzKQogICAgICAgICAgICAgICAgLyogTmRyR2V0UGlwZUJ1ZmZlciguLi4pICovCiAgICAgICAgICAgICAgICBGSVhNRSgicGlwZXMgbm90IHN1cHBvcnRlZCB5ZXRcbiIpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUgPT0gUlBDX0ZDX0FVVE9fSEFORExFKQojaWYgMAogICAgICAgICAgICAgICAgICAgIE5kck5zR2V0QnVmZmVyKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlckxlbmd0aCwgaEJpbmRpbmcpOwojZWxzZQogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJ1c2luZyBhdXRvIGhhbmRsZSAtIGNhbGwgTmRyTnNHZXRCdWZmZXIgd2hlbiBpdCBnZXRzIGltcGxlbWVudGVkXG4iKTsKI2VuZGlmCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgTmRyR2V0QnVmZmVyKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlckxlbmd0aCwgaEJpbmRpbmcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUFJPWFlfU0VORFJFQ0VJVkU6CiAgICAgICAgICAgIC8qIHNlbmQgdGhlIFtpbl0gcGFyYW1zIGFuZCByZWNlaXZlIHRoZSBbb3V0XSBhbmQgW3JldHZhbF0KICAgICAgICAgICAgICogcGFyYW1zICovCiAgICAgICAgICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgICAgICAgICAgTmRyUHJveHlTZW5kUmVjZWl2ZShUaGlzLCAmc3R1Yk1zZyk7CiAgICAgICAgICAgIGVsc2UgaWYgKE9pZl9mbGFncy5IYXNQaXBlcykKICAgICAgICAgICAgICAgIC8qIE5kclBpcGVzU2VuZFJlY2VpdmUoLi4uKSAqLwogICAgICAgICAgICAgICAgRklYTUUoInBpcGVzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPmhhbmRsZV90eXBlID09IFJQQ19GQ19BVVRPX0hBTkRMRSkKI2lmIDAKICAgICAgICAgICAgICAgICAgICBOZHJOc1NlbmRSZWNlaXZlKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlciwgcFN0dWJEZXNjLT5JTVBMSUNJVF9IQU5ETEVfSU5GTy5wQXV0b0hhbmRsZSk7CiNlbHNlCiAgICAgICAgICAgICAgICAgICAgRklYTUUoInVzaW5nIGF1dG8gaGFuZGxlIC0gY2FsbCBOZHJOc1NlbmRSZWNlaXZlIHdoZW4gaXQgZ2V0cyBpbXBsZW1lbnRlZFxuIik7CiNlbmRpZgogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIE5kclNlbmRSZWNlaXZlKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGNvbnZlcnQgc3RyaW5ncywgZmxvYXRpbmcgcG9pbnQgdmFsdWVzIGFuZCBlbmRpYW5lc3MgaW50byBvdXIKICAgICAgICAgICAgICogcHJlZmVycmVkIGZvcm1hdCAqLwogICAgICAgICAgICBpZiAoKHJwY01zZy5EYXRhUmVwcmVzZW50YXRpb24gJiAweDAwMDBGRkZGVUwpICE9IE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OKQogICAgICAgICAgICAgICAgTmRyQ29udmVydCgmc3R1Yk1zZywgcEZvcm1hdCk7CgogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFBST1hZX0NBTENTSVpFOgogICAgICAgIGNhc2UgUFJPWFlfTUFSU0hBTDoKICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgaWYgKGJWMkZvcm1hdCkKICAgICAgICAgICAgICAgIGNsaWVudF9kb19hcmdzKCZzdHViTXNnLCBwRm9ybWF0LCBwaGFzZSwgbnVtYmVyX29mX3BhcmFtcywKICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgY2hhciAqKSZSZXRWYWwpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBjbGllbnRfZG9fYXJnc19vbGRfZm9ybWF0KCZzdHViTXNnLCBwRm9ybWF0LCBwaGFzZSwgc3RhY2tfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgY2hhciAqKSZSZXRWYWwsCiAgICAgICAgICAgICAgICAgICAgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJzaG91bGRuJ3QgcmVhY2ggaGVyZS4gcGhhc2UgJWRcbiIsIHBoYXNlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChleHRfZmxhZ3MuSGFzTmV3Q29yckRlc2MpCiAgICB7CiAgICAgICAgLyogZnJlZSBleHRyYSBjb3JyZWxhdGlvbiBwYWNrYWdlICovCiAgICAgICAgLyogTmRyQ29ycmVsYXRpb25GcmVlKCZzdHViTXNnKTsgKi8KICAgIH0KCiAgICBpZiAoT2lmX2ZsYWdzLkhhc1BpcGVzKQogICAgewogICAgICAgIC8qIE5kclBpcGVzRG9uZSguLi4pICovCiAgICB9CgogICAgLyogZnJlZSB0aGUgZnVsbCBwb2ludGVyIHRyYW5zbGF0aW9uIHRhYmxlcyAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9GVUxMUFRSKQogICAgICAgIE5kckZ1bGxQb2ludGVyWGxhdEZyZWUoc3R1Yk1zZy5GdWxsUHRyWGxhdFRhYmxlcyk7CgogICAgLyogZnJlZSBtYXJzaGFsbGluZyBidWZmZXIgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgIE5kclByb3h5RnJlZUJ1ZmZlcihUaGlzLCAmc3R1Yk1zZyk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgTmRyRnJlZUJ1ZmZlcigmc3R1Yk1zZyk7CiAgICAgICAgY2xpZW50X2ZyZWVfaGFuZGxlKCZzdHViTXNnLCBwUHJvY0hlYWRlciwgcEhhbmRsZUZvcm1hdCwgaEJpbmRpbmcpOwogICAgfQoKICAgIFRSQUNFKCJSZXRWYWwgPSAweCVseFxuIiwgUmV0VmFsKTsKCiAgICByZXR1cm4gUmV0VmFsOwp9CgovKiBjYWxscyBhIGZ1bmN0aW9uIHdpdGggdGhlIHNwZWNpZmljZWQgYXJndW1lbnRzLCByZXN0b3JpbmcgdGhlIHN0YWNrCiAqIHByb3Blcmx5IGFmdGVyd2FyZHMgYXMgd2UgZG9uJ3Qga25vdyB0aGUgY2FsbGluZyBjb252ZW50aW9uIG9mIHRoZQogKiBmdW5jdGlvbiAqLwojaWYgZGVmaW5lZCBfX2kzODZfXyAmJiBkZWZpbmVkIF9NU0NfVkVSCl9fZGVjbHNwZWMobmFrZWQpIExPTkdfUFRSIF9fY2RlY2wgY2FsbF9zZXJ2ZXJfZnVuYyhTRVJWRVJfUk9VVElORSBmdW5jLCB1bnNpZ25lZCBjaGFyICogYXJncywgdW5zaWduZWQgaW50IHN0YWNrX3NpemUpCnsKICAgIF9fYXNtCiAgICB7CiAgICAgICAgcHVzaCBlYnAKICAgICAgICBwdXNoIGVkaSAgICAgICAgICAgIDsgU2F2ZSByZWdpc3RlcnMKICAgICAgICBwdXNoIGVzaQogICAgICAgIG1vdiBlYnAsIGVzcAogICAgICAgIG1vdiBlYXgsIFtlYnArMTZdICAgOyBHZXQgc3RhY2sgc2l6ZQogICAgICAgIHN1YiBlc3AsIGVheCAgICAgICAgOyBNYWtlIHJvb20gaW4gc3RhY2sgZm9yIGFyZ3VtZW50cwogICAgICAgIG1vdiBlZGksIGVzcAogICAgICAgIG1vdiBlY3gsIGVheAogICAgICAgIG1vdiBlc2ksIFtlYnArMTJdCiAgICAgICAgc2hyIGVjeCwgMgogICAgICAgIGNsZAogICAgICAgIHJlcCBtb3ZzZCAgICAgICAgICAgOyBDb3B5IGR3b3JkIGJsb2NrcwogICAgICAgIGNhbGwgW2VicCs4XSAgICAgICAgOyBDYWxsIGZ1bmN0aW9uCiAgICAgICAgbGVhIGVzcCwgW2VicC04XSAgICA7IFJlc3RvcmUgc3RhY2sKICAgICAgICBwb3AgZXNpICAgICAgICAgICAgIDsgUmVzdG9yZSByZWdpc3RlcnMKICAgICAgICBwb3AgZWRpCiAgICAgICAgcG9wIGVicAogICAgICAgIHJldAogICAgfQp9CiNlbGlmIGRlZmluZWQgX19pMzg2X18gJiYgZGVmaW5lZCBfX0dOVUNfXwpMT05HX1BUUiBfX2NkZWNsIGNhbGxfc2VydmVyX2Z1bmMoU0VSVkVSX1JPVVRJTkUgZnVuYywgdW5zaWduZWQgY2hhciAqIGFyZ3MsIHVuc2lnbmVkIGludCBzdGFja19zaXplKTsKX19BU01fR0xPQkFMX0ZVTkMoY2FsbF9zZXJ2ZXJfZnVuYywKICAgICJwdXNobCAlZWJwXG5cdCIKICAgICJtb3ZsICVlc3AsICVlYnBcblx0IgogICAgInB1c2hsICVlZGlcblx0IiAgICAgICAgICAgIC8qIFNhdmUgcmVnaXN0ZXJzICovCiAgICAicHVzaGwgJWVzaVxuXHQiCiAgICAibW92bCAxNiglZWJwKSwgJWVheFxuXHQiICAgLyogR2V0IHN0YWNrIHNpemUgKi8KICAgICJzdWJsICVlYXgsICVlc3Bcblx0IiAgICAgICAvKiBNYWtlIHJvb20gaW4gc3RhY2sgZm9yIGFyZ3VtZW50cyAqLwogICAgImFuZGwgJH4xNSwgJWVzcFxuXHQiCS8qIE1ha2Ugc3VyZSBzdGFjayBoYXMgMTYtYnl0ZSBhbGlnbm1lbnQgZm9yIE1hYyBPUyBYICovCiAgICAibW92bCAlZXNwLCAlZWRpXG5cdCIKICAgICJtb3ZsICVlYXgsICVlY3hcblx0IgogICAgIm1vdmwgMTIoJWVicCksICVlc2lcblx0IgogICAgInNocmwgJDIsICVlY3hcblx0IiAgICAgICAgIC8qIGRpdmlkZSBieSA0ICovCiAgICAiY2xkXG5cdCIKICAgICJyZXA7IG1vdnNsXG5cdCIgICAgICAgICAgICAvKiBDb3B5IGR3b3JkIGJsb2NrcyAqLwogICAgImNhbGwgKjgoJWVicClcblx0IiAgICAgICAgIC8qIENhbGwgZnVuY3Rpb24gKi8KICAgICJsZWFsIC04KCVlYnApLCAlZXNwXG5cdCIgICAvKiBSZXN0b3JlIHN0YWNrICovCiAgICAicG9wbCAlZXNpXG5cdCIgICAgICAgICAgICAgLyogUmVzdG9yZSByZWdpc3RlcnMgKi8KICAgICJwb3BsICVlZGlcblx0IgogICAgInBvcGwgJWVicFxuXHQiCiAgICAicmV0XG4iICkKI2Vsc2UKI3dhcm5pbmcgY2FsbF9zZXJ2ZXJfZnVuYyBub3QgaW1wbGVtZW50ZWQgZm9yIHlvdXIgYXJjaGl0ZWN0dXJlCkxPTkdfUFRSIF9fY2RlY2wgY2FsbF9zZXJ2ZXJfZnVuYyhTRVJWRVJfUk9VVElORSBmdW5jLCB1bnNpZ25lZCBjaGFyICogYXJncywgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZSkKewogICAgRklYTUUoIk5vdCBpbXBsZW1lbnRlZCBmb3IgeW91ciBhcmNoaXRlY3R1cmVcbiIpOwogICAgcmV0dXJuIDA7Cn0KI2VuZGlmCgpzdGF0aWMgRFdPUkQgY2FsY19hcmdfc2l6ZShNSURMX1NUVUJfTUVTU0FHRSAqcFN0dWJNc2csIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICAgIERXT1JEIHNpemU7CiAgICBzd2l0Y2goKnBGb3JtYXQpCiAgICB7CiAgICBjYXNlIFJQQ19GQ19TVFJVQ1Q6CiAgICAgICAgc2l6ZSA9ICooY29uc3QgV09SRCopKHBGb3JtYXQgKyAyKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0NBUlJBWToKICAgICAgICBzaXplID0gKihjb25zdCBXT1JEKikocEZvcm1hdCArIDIpOwogICAgICAgIENvbXB1dGVDb25mb3JtYW5jZShwU3R1Yk1zZywgTlVMTCwgcEZvcm1hdCArIDQsIDApOwogICAgICAgIHNpemUgKj0gcFN0dWJNc2ctPk1heENvdW50OwogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfU01GQVJSQVk6CiAgICAgICAgc2l6ZSA9ICooY29uc3QgV09SRCopKHBGb3JtYXQgKyAyKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0xHRkFSUkFZOgogICAgICAgIHNpemUgPSAqKGNvbnN0IERXT1JEKikocEZvcm1hdCArIDIpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiVW5oYW5kbGVkIHR5cGUgJTAyeFxuIiwgKnBGb3JtYXQpOwogICAgICAgIC8qIGZhbGx0aHJvdWdoICovCiAgICBjYXNlIFJQQ19GQ19SUDoKICAgICAgICBzaXplID0gc2l6ZW9mKHZvaWQgKik7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gc2l6ZTsKfQoKLyogRklYTUU6IG5lZWQgdG8gZnJlZSBzb21lIHN0dWZmIGluIGhlcmUgdG9vICovCkxPTkcgV0lOQVBJIE5kclN0dWJDYWxsMigKICAgIHN0cnVjdCBJUnBjU3R1YkJ1ZmZlciAqIHBUaGlzLAogICAgc3RydWN0IElScGNDaGFubmVsQnVmZmVyICogcENoYW5uZWwsCiAgICBQUlBDX01FU1NBR0UgcFJwY01zZywKICAgIERXT1JEICogcGR3U3R1YlBoYXNlKQp7CiAgICBjb25zdCBNSURMX1NFUlZFUl9JTkZPICpwU2VydmVySW5mbzsKICAgIGNvbnN0IE1JRExfU1RVQl9ERVNDICpwU3R1YkRlc2M7CiAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0OwogICAgTUlETF9TVFVCX01FU1NBR0Ugc3R1Yk1zZzsKICAgIC8qIHBvaW50ZXIgdG8gc3RhcnQgb2Ygc3RhY2sgdG8gcGFzcyBpbnRvIHN0dWIgaW1wbGVtZW50YXRpb24gKi8KICAgIHVuc2lnbmVkIGNoYXIgKiBhcmdzOwogICAgLyogc2l6ZSBvZiBzdGFjayAqLwogICAgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZTsKICAgIC8qIGN1cnJlbnQgc3RhY2sgb2Zmc2V0ICovCiAgICB1bnNpZ25lZCBzaG9ydCBjdXJyZW50X3N0YWNrX29mZnNldDsKICAgIC8qIG51bWJlciBvZiBwYXJhbWV0ZXJzLiBvcHRpb25hbCBmb3IgY2xpZW50IHRvIGdpdmUgaXQgdG8gdXMgKi8KICAgIHVuc2lnbmVkIGNoYXIgbnVtYmVyX29mX3BhcmFtcyA9IH4wOwogICAgLyogY291bnRlciAqLwogICAgdW5zaWduZWQgc2hvcnQgaTsKICAgIC8qIGNhY2hlIG9mIE9pZl9mbGFncyBmcm9tIHYyIHByb2NlZHVyZSBoZWFkZXIgKi8KICAgIElOVEVSUFJFVEVSX09QVF9GTEFHUyBPaWZfZmxhZ3MgPSB7IDAgfTsKICAgIC8qIGNhY2hlIG9mIGV4dGVuc2lvbiBmbGFncyBmcm9tIE5EUl9QUk9DX0hFQURFUl9FWFRTICovCiAgICBJTlRFUlBSRVRFUl9PUFRfRkxBR1MyIGV4dF9mbGFncyA9IHsgMCB9OwogICAgLyogdGhlIHR5cGUgb2YgcGFzcyB3ZSBhcmUgY3VycmVudGx5IGRvaW5nICovCiAgICBpbnQgcGhhc2U7CiAgICAvKiBoZWFkZXIgZm9yIHByb2NlZHVyZSBzdHJpbmcgKi8KICAgIGNvbnN0IE5EUl9QUk9DX0hFQURFUiAqcFByb2NIZWFkZXI7CiAgICAvKiBvZmZzZXQgaW4gZm9ybWF0IHN0cmluZyBmb3Igc3RhcnQgb2YgcGFyYW1zICovCiAgICBpbnQgcGFyYW1ldGVyX3N0YXJ0X29mZnNldDsKICAgIC8qIGN1cnJlbnQgZm9ybWF0IHN0cmluZyBvZmZzZXQgKi8KICAgIGludCBjdXJyZW50X29mZnNldDsKICAgIC8qIC1PaWYgb3IgLU9pY2YgZ2VuZXJhdGVkIGZvcm1hdCAqLwogICAgQk9PTCBiVjJGb3JtYXQgPSBGQUxTRTsKICAgIC8qIGxvY2F0aW9uIHRvIHB1dCByZXR2YWwgaW50byAqLwogICAgTE9OR19QVFIgKnJldHZhbF9wdHIgPSBOVUxMOwoKICAgIFRSQUNFKCJwVGhpcyAlcCwgcENoYW5uZWwgJXAsIHBScGNNc2cgJXAsIHBkd1N0dWJQaGFzZSAlcFxuIiwgcFRoaXMsIHBDaGFubmVsLCBwUnBjTXNnLCBwZHdTdHViUGhhc2UpOwoKICAgIGlmIChwVGhpcykKICAgICAgICBwU2VydmVySW5mbyA9IENTdGRTdHViQnVmZmVyX0dldFNlcnZlckluZm8ocFRoaXMpOwogICAgZWxzZQogICAgICAgIHBTZXJ2ZXJJbmZvID0gKChSUENfU0VSVkVSX0lOVEVSRkFDRSAqKXBScGNNc2ctPlJwY0ludGVyZmFjZUluZm9ybWF0aW9uKS0+SW50ZXJwcmV0ZXJJbmZvOwoKICAgIHBTdHViRGVzYyA9IHBTZXJ2ZXJJbmZvLT5wU3R1YkRlc2M7CiAgICBwRm9ybWF0ID0gcFNlcnZlckluZm8tPlByb2NTdHJpbmcgKyBwU2VydmVySW5mby0+Rm10U3RyaW5nT2Zmc2V0W3BScGNNc2ctPlByb2NOdW1dOwogICAgcFByb2NIZWFkZXIgPSAoY29uc3QgTkRSX1BST0NfSEVBREVSICopJnBGb3JtYXRbMF07CgogICAgLyogTGF0ZXIgTkRSIGxhbmd1YWdlIHZlcnNpb25zIHByb2JhYmx5IHdvbid0IGJlIGJhY2t3YXJkcyBjb21wYXRpYmxlICovCiAgICBpZiAocFN0dWJEZXNjLT5WZXJzaW9uID4gMHg1MDAwMikKICAgIHsKICAgICAgICBGSVhNRSgiSW5jb21wYXRpYmxlIHN0dWIgZGVzY3JpcHRpb24gdmVyc2lvbjogMHgleFxuIiwgcFN0dWJEZXNjLT5WZXJzaW9uKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9XUk9OR19TVFVCX1ZFUlNJT04pOwogICAgfQoKICAgIC8qIGNyZWF0ZSB0aGUgZnVsbCBwb2ludGVyIHRyYW5zbGF0aW9uIHRhYmxlcywgaWYgcmVxdWVzdGVkICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX0ZVTExQVFIpCiAgICAgICAgc3R1Yk1zZy5GdWxsUHRyWGxhdFRhYmxlcyA9IE5kckZ1bGxQb2ludGVyWGxhdEluaXQoMCxYTEFUX1NFUlZFUik7CgogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENGTEFHUykKICAgIHsKICAgICAgICBjb25zdCBORFJfUFJPQ19IRUFERVJfUlBDICpwUHJvY0hlYWRlciA9IChjb25zdCBORFJfUFJPQ19IRUFERVJfUlBDICopJnBGb3JtYXRbMF07CiAgICAgICAgc3RhY2tfc2l6ZSA9IHBQcm9jSGVhZGVyLT5zdGFja19zaXplOwogICAgICAgIGN1cnJlbnRfb2Zmc2V0ID0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUl9SUEMpOwoKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBzdGFja19zaXplID0gcFByb2NIZWFkZXItPnN0YWNrX3NpemU7CiAgICAgICAgY3VycmVudF9vZmZzZXQgPSBzaXplb2YoTkRSX1BST0NfSEVBREVSKTsKICAgIH0KCiAgICBUUkFDRSgiT2lfZmxhZ3MgPSAweCUwMnhcbiIsIHBQcm9jSGVhZGVyLT5PaV9mbGFncyk7CgogICAgLyogYmluZGluZyAqLwogICAgc3dpdGNoIChwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpCiAgICB7CiAgICAvKiBleHBsaWNpdCBiaW5kaW5nOiBwYXJzZSBhZGRpdGlvbmFsIHNlY3Rpb24gKi8KICAgIGNhc2UgUlBDX0ZDX0JJTkRfRVhQTElDSVQ6CiAgICAgICAgc3dpdGNoIChwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XSkgLyogaGFuZGxlX3R5cGUgKi8KICAgICAgICB7CiAgICAgICAgY2FzZSBSUENfRkNfQklORF9QUklNSVRJVkU6IC8qIGV4cGxpY2l0IHByaW1pdGl2ZSAqLwogICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX0VIRF9QUklNSVRJVkUpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0dFTkVSSUM6IC8qIGV4cGxpY2l0IGdlbmVyaWMgKi8KICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9FSERfR0VORVJJQyk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfQ09OVEVYVDogLyogZXhwbGljaXQgY29udGV4dCAqLwogICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX0VIRF9DT05URVhUKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJiYWQgZXhwbGljaXQgYmluZGluZyBoYW5kbGUgdHlwZSAoMHglMDJ4KVxuIiwgcFByb2NIZWFkZXItPmhhbmRsZV90eXBlKTsKICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfQklORF9HRU5FUklDOiAvKiBpbXBsaWNpdCBnZW5lcmljICovCiAgICBjYXNlIFJQQ19GQ19CSU5EX1BSSU1JVElWRTogLyogaW1wbGljaXQgcHJpbWl0aXZlICovCiAgICBjYXNlIFJQQ19GQ19DQUxMQkFDS19IQU5ETEU6IC8qIGltcGxpY2l0IGNhbGxiYWNrICovCiAgICBjYXNlIFJQQ19GQ19BVVRPX0hBTkRMRTogLyogaW1wbGljaXQgYXV0byBoYW5kbGUgKi8KICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgRVJSKCJiYWQgaW1wbGljaXQgYmluZGluZyBoYW5kbGUgdHlwZSAoMHglMDJ4KVxuIiwgcFByb2NIZWFkZXItPmhhbmRsZV90eXBlKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgIH0KCiAgICBiVjJGb3JtYXQgPSAocFN0dWJEZXNjLT5WZXJzaW9uID49IDB4MjAwMDApOwoKICAgIGlmIChiVjJGb3JtYXQpCiAgICB7CiAgICAgICAgY29uc3QgTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSICpwT0lGSGVhZGVyID0KICAgICAgICAgICAgKGNvbnN0IE5EUl9QUk9DX1BBUlRJQUxfT0lGX0hFQURFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgT2lmX2ZsYWdzID0gcE9JRkhlYWRlci0+T2kyRmxhZ3M7CiAgICAgICAgbnVtYmVyX29mX3BhcmFtcyA9IHBPSUZIZWFkZXItPm51bWJlcl9vZl9wYXJhbXM7CgogICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIpOwogICAgfQoKICAgIFRSQUNFKCJPaWZfZmxhZ3MgPSAiKTsgZHVtcF9JTlRFUlBSRVRFUl9PUFRfRkxBR1MoT2lmX2ZsYWdzKTsKCiAgICBpZiAoT2lmX2ZsYWdzLkhhc0V4dGVuc2lvbnMpCiAgICB7CiAgICAgICAgY29uc3QgTkRSX1BST0NfSEVBREVSX0VYVFMgKnBFeHRlbnNpb25zID0KICAgICAgICAgICAgKGNvbnN0IE5EUl9QUk9DX0hFQURFUl9FWFRTICopJnBGb3JtYXRbY3VycmVudF9vZmZzZXRdOwogICAgICAgIGV4dF9mbGFncyA9IHBFeHRlbnNpb25zLT5GbGFnczI7CiAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gcEV4dGVuc2lvbnMtPlNpemU7CiAgICB9CgogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpCiAgICAgICAgTmRyU3R1YkluaXRpYWxpemUocFJwY01zZywgJnN0dWJNc2csIHBTdHViRGVzYywgcENoYW5uZWwpOwogICAgZWxzZQogICAgICAgIE5kclNlcnZlckluaXRpYWxpemVOZXcocFJwY01zZywgJnN0dWJNc2csIHBTdHViRGVzYyk7CgogICAgLyogc3RvcmUgdGhlIFJQQyBmbGFncyBhd2F5ICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX1JQQ0ZMQUdTKQogICAgICAgIHBScGNNc2ctPlJwY0ZsYWdzID0gKChjb25zdCBORFJfUFJPQ19IRUFERVJfUlBDICopcFByb2NIZWFkZXIpLT5ycGNfZmxhZ3M7CgogICAgLyogdXNlIGFsdGVybmF0ZSBtZW1vcnkgYWxsb2NhdGlvbiByb3V0aW5lcyAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENTU0FMTE9DKQojaWYgMAogICAgICAgICAgTmRyUnBjU3NFbmFibGVBbGxvY2F0ZSgmc3R1Yk1zZyk7CiNlbHNlCiAgICAgICAgICBGSVhNRSgiU2V0IFJQQ1NTIG1lbW9yeSBhbGxvY2F0aW9uIHJvdXRpbmVzXG4iKTsKI2VuZGlmCgogICAgaWYgKE9pZl9mbGFncy5IYXNQaXBlcykKICAgIHsKICAgICAgICBGSVhNRSgicGlwZXMgbm90IHN1cHBvcnRlZCB5ZXRcbiIpOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX1dST05HX1NUVUJfVkVSU0lPTik7IC8qIEZJWE1FOiByZW1vdmUgd2hlbiBpbXBsZW1lbnRlZCAqLwogICAgICAgIC8qIGluaXQgcGlwZXMgcGFja2FnZSAqLwogICAgICAgIC8qIE5kclBpcGVzSW5pdGlhbGl6ZSguLi4pICovCiAgICB9CiAgICBpZiAoZXh0X2ZsYWdzLkhhc05ld0NvcnJEZXNjKQogICAgewogICAgICAgIC8qIGluaXRpYWxpemUgZXh0cmEgY29ycmVsYXRpb24gcGFja2FnZSAqLwogICAgICAgIEZJWE1FKCJuZXcgY29ycmVsYXRpb24gZGVzY3JpcHRpb24gbm90IGltcGxlbWVudGVkXG4iKTsKICAgICAgICBzdHViTXNnLmZIYXNOZXdDb3JyRGVzYyA9IFRSVUU7CiAgICB9CgogICAgLyogY29udmVydCBzdHJpbmdzLCBmbG9hdGluZyBwb2ludCB2YWx1ZXMgYW5kIGVuZGlhbmVzcyBpbnRvIG91cgogICAgICogcHJlZmVycmVkIGZvcm1hdCAqLwogICAgaWYgKChwUnBjTXNnLT5EYXRhUmVwcmVzZW50YXRpb24gJiAweDAwMDBGRkZGVUwpICE9IE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OKQogICAgICAgIE5kckNvbnZlcnQoJnN0dWJNc2csIHBGb3JtYXQpOwoKICAgIHBhcmFtZXRlcl9zdGFydF9vZmZzZXQgPSBjdXJyZW50X29mZnNldDsKCiAgICBUUkFDRSgiYWxsb2NhdGluZyBtZW1vcnkgZm9yIHN0YWNrIG9mIHNpemUgJXhcbiIsIHN0YWNrX3NpemUpOwoKICAgIGFyZ3MgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc3RhY2tfc2l6ZSk7CiAgICBzdHViTXNnLlN0YWNrVG9wID0gYXJnczsgLyogdXNlZCBieSBjb25mb3JtYW5jZSBvZiB0b3AtbGV2ZWwgb2JqZWN0cyAqLwoKICAgIC8qIGFkZCB0aGUgaW1wbGljaXQgVGhpcyBwb2ludGVyIGFzIHRoZSBmaXJzdCBhcmcgdG8gdGhlIGZ1bmN0aW9uIGlmIHdlCiAgICAgKiBhcmUgY2FsbGluZyBhbiBvYmplY3QgbWV0aG9kICovCiAgICBpZiAocFRoaXMpCiAgICAgICAgKih2b2lkICoqKWFyZ3MgPSAoKENTdGRTdHViQnVmZmVyICopcFRoaXMpLT5wdlNlcnZlck9iamVjdDsKCiAgICAvKiBvcmRlciBvZiBwaGFzZXM6CiAgICAgKiAxLiBTVFVCTEVTU19VTk1BUkhTQUwgLSB1bm1hcnNoYWwgW2luXSBwYXJhbXMgZnJvbSBidWZmZXIKICAgICAqIDIuIFNUVUJMRVNTX0NBTExTRVJWRVIgLSBzZW5kL3JlY2VpdmUgYnVmZmVyCiAgICAgKiAzLiBTVFVCTEVTU19DQUxDU0laRSAtIGdldCBbb3V0XSBidWZmZXIgc2l6ZQogICAgICogNC4gU1RVQkxFU1NfR0VUQlVGRkVSIC0gYWxsb2NhdGUgW291dF0gYnVmZmVyCiAgICAgKiA1LiBTVFVCTEVTU19NQVJIU0FMIC0gbWFyc2hhbCBbb3V0XSBwYXJhbXMgdG8gYnVmZmVyCiAgICAgKi8KICAgIGZvciAocGhhc2UgPSBTVFVCTEVTU19VTk1BUlNIQUw7IHBoYXNlIDw9IFNUVUJMRVNTX01BUlNIQUw7IHBoYXNlKyspCiAgICB7CiAgICAgICAgVFJBQ0UoInBoYXNlID0gJWRcbiIsIHBoYXNlKTsKICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgIHsKICAgICAgICBjYXNlIFNUVUJMRVNTX0NBTExTRVJWRVI6CiAgICAgICAgICAgIC8qIGNhbGwgdGhlIHNlcnZlciBmdW5jdGlvbiAqLwogICAgICAgICAgICBpZiAocFNlcnZlckluZm8tPlRodW5rVGFibGUgJiYgcFNlcnZlckluZm8tPlRodW5rVGFibGVbcFJwY01zZy0+UHJvY051bV0pCiAgICAgICAgICAgICAgICBwU2VydmVySW5mby0+VGh1bmtUYWJsZVtwUnBjTXNnLT5Qcm9jTnVtXSgmc3R1Yk1zZyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgU0VSVkVSX1JPVVRJTkUgZnVuYzsKICAgICAgICAgICAgICAgIExPTkdfUFRSIHJldHZhbDsKCiAgICAgICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX09CSkVDVCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBTRVJWRVJfUk9VVElORSAqdnRibCA9ICooU0VSVkVSX1JPVVRJTkUgKiopKChDU3RkU3R1YkJ1ZmZlciAqKXBUaGlzKS0+cHZTZXJ2ZXJPYmplY3Q7CiAgICAgICAgICAgICAgICAgICAgZnVuYyA9IHZ0YmxbcFJwY01zZy0+UHJvY051bV07CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgZnVuYyA9IHBTZXJ2ZXJJbmZvLT5EaXNwYXRjaFRhYmxlW3BScGNNc2ctPlByb2NOdW1dOwoKICAgICAgICAgICAgICAgIC8qIEZJWE1FOiB3aGF0IGhhcHBlbnMgd2l0aCByZXR1cm4gdmFsdWVzIHRoYXQgZG9uJ3QgZml0IGludG8gYSBzaW5nbGUgcmVnaXN0ZXIgb24geDg2PyAqLwogICAgICAgICAgICAgICAgcmV0dmFsID0gY2FsbF9zZXJ2ZXJfZnVuYyhmdW5jLCBhcmdzLCBzdGFja19zaXplKTsKCiAgICAgICAgICAgICAgICBpZiAocmV0dmFsX3B0cikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgic3R1YiBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCAweCVseFxuIiwgcmV0dmFsKTsKICAgICAgICAgICAgICAgICAgICAqcmV0dmFsX3B0ciA9IHJldHZhbDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBUUkFDRSgidm9pZCBzdHViIGltcGxlbWVudGF0aW9uXG4iKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3R1Yk1zZy5CdWZmZXIgPSBOVUxMOwogICAgICAgICAgICBzdHViTXNnLkJ1ZmZlckxlbmd0aCA9IDA7CgogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFNUVUJMRVNTX0dFVEJVRkZFUjoKICAgICAgICAgICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpCiAgICAgICAgICAgICAgICBOZHJTdHViR2V0QnVmZmVyKHBUaGlzLCBwQ2hhbm5lbCwgJnN0dWJNc2cpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFJQQ19TVEFUVVMgU3RhdHVzOwoKICAgICAgICAgICAgICAgIHBScGNNc2ctPkJ1ZmZlckxlbmd0aCA9IHN0dWJNc2cuQnVmZmVyTGVuZ3RoOwogICAgICAgICAgICAgICAgLyogYWxsb2NhdGUgYnVmZmVyIGZvciBbb3V0XSBhbmQgW3JldF0gcGFyYW1zICovCiAgICAgICAgICAgICAgICBTdGF0dXMgPSBJX1JwY0dldEJ1ZmZlcihwUnBjTXNnKTsgCiAgICAgICAgICAgICAgICBpZiAoU3RhdHVzKQogICAgICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFN0YXR1cyk7CiAgICAgICAgICAgICAgICBzdHViTXNnLkJ1ZmZlclN0YXJ0ID0gcFJwY01zZy0+QnVmZmVyOwogICAgICAgICAgICAgICAgc3R1Yk1zZy5CdWZmZXJFbmQgPSBzdHViTXNnLkJ1ZmZlclN0YXJ0ICsgc3R1Yk1zZy5CdWZmZXJMZW5ndGg7CiAgICAgICAgICAgICAgICBzdHViTXNnLkJ1ZmZlciA9IHN0dWJNc2cuQnVmZmVyU3RhcnQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBTVFVCTEVTU19NQVJTSEFMOgogICAgICAgIGNhc2UgU1RVQkxFU1NfVU5NQVJTSEFMOgogICAgICAgIGNhc2UgU1RVQkxFU1NfQ0FMQ1NJWkU6CiAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ID0gcGFyYW1ldGVyX3N0YXJ0X29mZnNldDsKICAgICAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgPSAwOwoKICAgICAgICAgICAgLyogTk9URTogVjEgc3R5bGUgZm9ybWF0IGRvZXMndCB0ZXJtaW5hdGUgb24gdGhlIG51bWJlcl9vZl9wYXJhbXMKICAgICAgICAgICAgICogY29uZGl0aW9uIGFzIGl0IGRvZXNuJ3QgaGF2ZSB0aGlzIGF0dHJpYnV0ZS4gSW5zdGVhZCBpdAogICAgICAgICAgICAgKiB0ZXJtaW5hdGVzIHdoZW4gdGhlIHN0YWNrIHNpemUgZ2l2ZW4gaW4gdGhlIGhlYWRlciBpcyBleGNlZWRlZC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBudW1iZXJfb2ZfcGFyYW1zOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChiVjJGb3JtYXQpIC8qIG5ldyBwYXJhbWV0ZXIgZm9ybWF0ICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgTkRSX1BBUkFNX09JRl9CQVNFVFlQRSAqcFBhcmFtID0KICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IE5EUl9QQVJBTV9PSUZfQkFTRVRZUEUgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CiAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcEFyZzsKCiAgICAgICAgICAgICAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgPSBwUGFyYW0tPnN0YWNrX29mZnNldDsKICAgICAgICAgICAgICAgICAgICBwQXJnID0gKHVuc2lnbmVkIGNoYXIgKikoYXJncytjdXJyZW50X3N0YWNrX29mZnNldCk7CgogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJwYXJhbVslZF06IG5ldyBmb3JtYXRcbiIsIGkpOwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdHBhcmFtX2F0dHJpYnV0ZXM6Iik7IGR1bXBfUlBDX0ZDX1BST0NfUEYocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzKTsgVFJBQ0UoIlxuIik7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0c3RhY2tfb2Zmc2V0OiAweCV4XG4iLCBjdXJyZW50X3N0YWNrX29mZnNldCk7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0bWVtb3J5IGFkZHIgKGJlZm9yZSk6ICVwIC0+ICVwXG4iLCBwQXJnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZyk7CgogICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuU2VydmVyQWxsb2NTaXplKQogICAgICAgICAgICAgICAgICAgICAgICBGSVhNRSgiU2VydmVyQWxsb2NTaXplIG9mICVkIGlnbm9yZWQgZm9yIHBhcmFtZXRlciAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5TZXJ2ZXJBbGxvY1NpemUgKiA4LCBpKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0Jhc2V0eXBlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqcFR5cGVGb3JtYXQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBQYXJhbS0+dHlwZV9mb3JtYXRfY2hhcjsKCiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdGJhc2UgdHlwZTogMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX01BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzT3V0IHx8IHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzU2ltcGxlUmVmKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBjYWxsIGNhbGxfZnJlZXIgaGVyZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfVU5NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0luKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBtYWtlIGEgbm90ZSBvZiB0aGUgYWRkcmVzcyBvZiB0aGUgcmV0dXJuIHZhbHVlIHBhcmFtZXRlciBmb3IgbGF0ZXIgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dmFsX3B0ciA9IChMT05HX1BUUiAqKXBBcmc7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzT3V0IHx8IHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzU2ltcGxlUmVmKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSUZfQkFTRVRZUEUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBORFJfUEFSQU1fT0lGX09USEVSICpwUGFyYW1PdGhlciA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgTkRSX1BBUkFNX09JRl9PVEhFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKHBTdHViRGVzYy0+cEZvcm1hdFR5cGVzW3BQYXJhbU90aGVyLT50eXBlX29mZnNldF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0Y29tcGxleCB0eXBlIDB4JTAyeFxuIiwgKnBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocGhhc2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCB8fCBwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R1Yk1zZy5wZm5GcmVlKCoodm9pZCAqKilwQXJnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBGSVhNRTogY2FsbCBjYWxsX2ZyZWVyIGhlcmUgZm9yIElOIHR5cGVzICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAmcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICh1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgc2l6ZSA9IGNhbGNfYXJnX3NpemUoJnN0dWJNc2csIHBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoc2l6ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoodm9pZCAqKilwQXJnID0gTmRyQWxsb2NhdGUoJnN0dWJNc2csIHNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1zZXQoKih2b2lkICoqKXBBcmcsIDAsIHNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX0NBTENTSVpFOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCB8fCBwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JRl9PVEhFUik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdG1lbW9yeSBhZGRyIChhZnRlcik6ICVwIC0+ICVwXG4iLCBwQXJnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIC8qIG9sZCBwYXJhbWV0ZXIgZm9ybWF0ICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgY29uc3QgTkRSX1BBUkFNX09JX0JBU0VUWVBFICpwUGFyYW0gPQogICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgTkRSX1BBUkFNX09JX0JBU0VUWVBFICopJnBGb3JtYXRbY3VycmVudF9vZmZzZXRdOwogICAgICAgICAgICAgICAgICAgIC8qIG5vdGU6IGN1cnJlbnRfc3RhY2tfb2Zmc2V0IHN0YXJ0cyBhZnRlciB0aGUgVGhpcyBwb2ludGVyCiAgICAgICAgICAgICAgICAgICAgICogaWYgcHJlc2VudCwgc28gYWRqdXN0IHRoaXMgKi8KICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCA9IGN1cnJlbnRfc3RhY2tfb2Zmc2V0ICsKICAgICAgICAgICAgICAgICAgICAgICAgKChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKSA/IHNpemVvZih2b2lkICopIDogMCk7CiAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcEFyZyA9ICh1bnNpZ25lZCBjaGFyICopKGFyZ3MrY3VycmVudF9zdGFja19vZmZzZXRfYWRqdXN0ZWQpOwoKICAgICAgICAgICAgICAgICAgICAvKiBubyBtb3JlIHBhcmFtZXRlcnM7IGV4aXQgbG9vcCAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCA+PSBzdGFja19zaXplKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInBhcmFtWyVkXTogb2xkIGZvcm1hdFxuIiwgaSk7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0cGFyYW1fZGlyZWN0aW9uOiAweCV4XG4iLCBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbik7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0c3RhY2tfb2Zmc2V0OiAweCV4XG4iLCBjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU1fQkFTRVRZUEUgfHwKICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwUGFyYW0tPnR5cGVfZm9ybWF0X2NoYXI7CgogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRiYXNlIHR5cGUgMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX01BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX1VOTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICZwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHZhbF9wdHIgPSAoTE9OR19QVFIgKilwQXJnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfU19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfc3RhY2tfb2Zmc2V0ICs9IGNhbGxfbWVtb3J5X3NpemVyKCZzdHViTXNnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUEFSQU1fT0lfQkFTRVRZUEUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBORFJfUEFSQU1fT0lfT1RIRVIgKnBQYXJhbU90aGVyID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgTkRSX1BBUkFNX09JX09USEVSICopJnBGb3JtYXRbY3VycmVudF9vZmZzZXRdOwoKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqIHBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwU3R1YkRlc2MtPnBGb3JtYXRUeXBlc1twUGFyYW1PdGhlci0+dHlwZV9vZmZzZXRdOwoKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0Y29tcGxleCB0eXBlIDB4JTAyeFxuIiwgKnBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocGhhc2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19PVVRfUEFSQU0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fT1VUX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX09VVF9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR2YWxfcHRyID0gKExPTkdfUFRSICopcEFyZzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19PVVRfUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgc2l6ZSA9IGNhbGNfYXJnX3NpemUoJnN0dWJNc2csIHBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoc2l6ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoodm9pZCAqKilwQXJnID0gTmRyQWxsb2NhdGUoJnN0dWJNc2csIHNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1zZXQoKih2b2lkICoqKXBBcmcsIDAsIHNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX0NBTENTSVpFOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19PVVRfUEFSQU0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fT1VUX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCArPSBwUGFyYW1PdGhlci0+c3RhY2tfc2l6ZSAqIHNpemVvZihJTlQpOwogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JX09USEVSKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigic2hvdWxkbid0IHJlYWNoIGhlcmUuIHBoYXNlICVkXG4iLCBwaGFzZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBwUnBjTXNnLT5CdWZmZXJMZW5ndGggPSAodW5zaWduZWQgaW50KShzdHViTXNnLkJ1ZmZlciAtICh1bnNpZ25lZCBjaGFyICopcFJwY01zZy0+QnVmZmVyKTsKCiAgICBpZiAoZXh0X2ZsYWdzLkhhc05ld0NvcnJEZXNjKQogICAgewogICAgICAgIC8qIGZyZWUgZXh0cmEgY29ycmVsYXRpb24gcGFja2FnZSAqLwogICAgICAgIC8qIE5kckNvcnJlbGF0aW9uRnJlZSgmc3R1Yk1zZyk7ICovCiAgICB9CgogICAgaWYgKE9pZl9mbGFncy5IYXNQaXBlcykKICAgIHsKICAgICAgICAvKiBOZHJQaXBlc0RvbmUoLi4uKSAqLwogICAgfQoKICAgIC8qIGZyZWUgdGhlIGZ1bGwgcG9pbnRlciB0cmFuc2xhdGlvbiB0YWJsZXMgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfRlVMTFBUUikKICAgICAgICBOZHJGdWxsUG9pbnRlclhsYXRGcmVlKHN0dWJNc2cuRnVsbFB0clhsYXRUYWJsZXMpOwoKICAgIC8qIGZyZWUgc2VydmVyIGZ1bmN0aW9uIHN0YWNrICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBhcmdzKTsKCiAgICByZXR1cm4gU19PSzsKfQoKdm9pZCBXSU5BUEkgTmRyU2VydmVyQ2FsbDIoUFJQQ19NRVNTQUdFIHBScGNNc2cpCnsKICAgIERXT1JEIGR3UGhhc2U7CiAgICBOZHJTdHViQ2FsbDIoTlVMTCwgTlVMTCwgcFJwY01zZywgJmR3UGhhc2UpOwp9Cg==