LyoKICogTkRSIC1PaSwtT2lmLC1PaWNmIEludGVycHJldGVyCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzLTUgUm9iZXJ0IFNoZWFybWFuIChmb3IgQ29kZVdlYXZlcnMpCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBUT0RPOgogKiAgLSBQaXBlcwogKiAgLSBTb21lIHR5cGVzIG9mIGJpbmRpbmcgaGFuZGxlcwogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbnJlZy5oIgoKI2luY2x1ZGUgIm9iamJhc2UuaCIKI2luY2x1ZGUgInJwYy5oIgojaW5jbHVkZSAicnBjcHJveHkuaCIKI2luY2x1ZGUgIm5kcnR5cGVzLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAid2luZS9ycGNmYy5oIgoKI2luY2x1ZGUgIm5kcl9taXNjLmgiCiNpbmNsdWRlICJjcHNmLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChycGMpOwoKI2RlZmluZSBORFJfVEFCTEVfTUFTSyAxMjcKCnN0YXRpYyBpbmxpbmUgdm9pZCBjYWxsX2J1ZmZlcl9zaXplcihQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIHVuc2lnbmVkIGNoYXIgKnBNZW1vcnksIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICAgIE5EUl9CVUZGRVJTSVpFIG0gPSBOZHJCdWZmZXJTaXplcltwRm9ybWF0WzBdICYgTkRSX1RBQkxFX01BU0tdOwogICAgaWYgKG0pIG0ocFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogICAgZWxzZQogICAgewogICAgICAgIEZJWE1FKCJmb3JtYXQgdHlwZSAweCV4IG5vdCBpbXBsZW1lbnRlZFxuIiwgcEZvcm1hdFswXSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgY2hhciAqY2FsbF9tYXJzaGFsbGVyKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogICAgTkRSX01BUlNIQUxMIG0gPSBOZHJNYXJzaGFsbGVyW3BGb3JtYXRbMF0gJiBORFJfVEFCTEVfTUFTS107CiAgICBpZiAobSkgcmV0dXJuIG0ocFN0dWJNc2csIHBNZW1vcnksIHBGb3JtYXQpOwogICAgZWxzZQogICAgewogICAgICAgIEZJWE1FKCJmb3JtYXQgdHlwZSAweCV4IG5vdCBpbXBsZW1lbnRlZFxuIiwgcEZvcm1hdFswXSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgY2hhciAqY2FsbF91bm1hcnNoYWxsZXIoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCB1bnNpZ25lZCBjaGFyICoqcHBNZW1vcnksIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQsIHVuc2lnbmVkIGNoYXIgZk11c3RBbGxvYykKewogICAgTkRSX1VOTUFSU0hBTEwgbSA9IE5kclVubWFyc2hhbGxlcltwRm9ybWF0WzBdICYgTkRSX1RBQkxFX01BU0tdOwogICAgaWYgKG0pIHJldHVybiBtKHBTdHViTXNnLCBwcE1lbW9yeSwgcEZvcm1hdCwgZk11c3RBbGxvYyk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgRklYTUUoImZvcm1hdCB0eXBlIDB4JXggbm90IGltcGxlbWVudGVkXG4iLCBwRm9ybWF0WzBdKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KfQoKc3RhdGljIGlubGluZSB2b2lkIGNhbGxfZnJlZXIoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LCBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgICBORFJfRlJFRSBtID0gTmRyRnJlZXJbcEZvcm1hdFswXSAmIE5EUl9UQUJMRV9NQVNLXTsKICAgIGlmIChtKSBtKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKfQoKc3RhdGljIGlubGluZSB1bnNpZ25lZCBsb25nIGNhbGxfbWVtb3J5X3NpemVyKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogICAgTkRSX01FTU9SWVNJWkUgbSA9IE5kck1lbW9yeVNpemVyW3BGb3JtYXRbMF0gJiBORFJfVEFCTEVfTUFTS107CiAgICBpZiAobSkKICAgIHsKICAgICAgICB1bnNpZ25lZCBjaGFyICpzYXZlZF9idWZmZXIgPSBwU3R1Yk1zZy0+QnVmZmVyOwogICAgICAgIHVuc2lnbmVkIGxvbmcgcmV0OwogICAgICAgIGludCBzYXZlZF9pZ25vcmVfZW1iZWRkZWRfcG9pbnRlcnMgPSBwU3R1Yk1zZy0+SWdub3JlRW1iZWRkZWRQb2ludGVyczsKICAgICAgICBwU3R1Yk1zZy0+TWVtb3J5U2l6ZSA9IDA7CiAgICAgICAgcFN0dWJNc2ctPklnbm9yZUVtYmVkZGVkUG9pbnRlcnMgPSAxOwogICAgICAgIHJldCA9IG0ocFN0dWJNc2csIHBGb3JtYXQpOwogICAgICAgIHBTdHViTXNnLT5JZ25vcmVFbWJlZGRlZFBvaW50ZXJzID0gc2F2ZWRfaWdub3JlX2VtYmVkZGVkX3BvaW50ZXJzOwogICAgICAgIHBTdHViTXNnLT5CdWZmZXIgPSBzYXZlZF9idWZmZXI7CiAgICAgICAgcmV0dXJuIHJldDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBGSVhNRSgiZm9ybWF0IHR5cGUgMHgleCBub3QgaW1wbGVtZW50ZWRcbiIsIHBGb3JtYXRbMF0pOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgICAgIHJldHVybiAwOwogICAgfQp9CgovKiB0aGVyZSBjYW4ndCBiZSBhbnkgYWxpZ25tZW50IHdpdGggdGhlIHN0cnVjdHVyZXMgaW4gdGhpcyBmaWxlICovCiNpbmNsdWRlICJwc2hwYWNrMS5oIgoKI2RlZmluZSBTVFVCTEVTU19VTk1BUlNIQUwgIDEKI2RlZmluZSBTVFVCTEVTU19DQUxMU0VSVkVSIDIKI2RlZmluZSBTVFVCTEVTU19DQUxDU0laRSAgIDMKI2RlZmluZSBTVFVCTEVTU19HRVRCVUZGRVIgIDQKI2RlZmluZSBTVFVCTEVTU19NQVJTSEFMICAgIDUKCi8qIEZyb20gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9saWJyYXJ5L2RlZmF1bHQuYXNwP3VybD0vbGlicmFyeS9lbi11cy9ycGMvcnBjL3BhcmFtZXRlcl9kZXNjcmlwdG9ycy5hc3AgKi8KdHlwZWRlZiBzdHJ1Y3QgX05EUl9QUk9DX0hFQURFUgp7CiAgICAvKiB0eXBlIG9mIGhhbmRsZSB0byB1c2U6CiAgICAgKiBSUENfRkNfQklORF9FWFBMSUNJVCA9IDAgLSBFeHBsaWNpdCBoYW5kbGUuCiAgICAgKiAgIEhhbmRsZSBpcyBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIgdG8gdGhlIGZ1bmN0aW9uLgogICAgICogICBJbmRpY2F0ZXMgdGhhdCBleHBsaWNpdCBoYW5kbGUgaW5mb3JtYXRpb24gZm9sbG93cyB0aGUgaGVhZGVyLAogICAgICogICB3aGljaCBhY3R1YWxseSBkZXNjcmliZXMgdGhlIGhhbmRsZS4KICAgICAqIFJQQ19GQ19CSU5EX0dFTkVSSUMgPSAzMSAtIEltcGxpY2l0IGhhbmRsZSB3aXRoIGN1c3RvbSBiaW5kaW5nIHJvdXRpbmVzCiAgICAgKiAgIChNSURMX1NUVUJfREVTQzo6SU1QTElDSVRfSEFORExFX0lORk86OnBHZW5lcmljQmluZGluZ0luZm8pCiAgICAgKiBSUENfRkNfQklORF9QUklNSVRJVkUgPSAzMiAtIEltcGxpY2l0IGhhbmRsZSB1c2luZyBoYW5kbGVfdCBjcmVhdGVkIGJ5CiAgICAgKiAgIGNhbGxpbmcgYXBwbGljYXRpb24KICAgICAqIFJQQ19GQ19BVVRPX0hBTkRMRSA9IDMzIC0gQXV0b21hdGljIGhhbmRsZQogICAgICogUlBDX0ZDX0NBTExCQUNLX0hBTkRMRSA9IDM0IC0gdW5kb2NtZW50ZWQKICAgICAqLwogICAgdW5zaWduZWQgY2hhciBoYW5kbGVfdHlwZTsKCiAgICAvKiBwcm9jZWR1cmUgZmxhZ3M6CiAgICAgKiBPaV9GVUxMX1BUUl9VU0VEID0gMHgwMSAtIEEgZnVsbCBwb2ludGVyIGNhbiBoYXZlIHRoZSB2YWx1ZSBOVUxMIGFuZCBjYW4KICAgICAqICAgY2hhbmdlIGR1cmluZyB0aGUgY2FsbCBmcm9tIE5VTEwgdG8gbm9uLU5VTEwgYW5kIHN1cHBvcnRzIGFsaWFzaW5nCiAgICAgKiAgIGFuZCBjeWNsZXMuIEluZGljYXRlcyB0aGF0IHRoZSBOZHJGdWxsUG9pbnRlclhsYXRJbml0IGZ1bmN0aW9uCiAgICAgKiAgIHNob3VsZCBiZSBjYWxsZWQuCiAgICAgKiBPaV9SUENTU19BTExPQ19VU0VEID0gMHgwMiAtIFVzZSBScGNTUyBhbGxvY2F0ZS9mcmVlIHJvdXRpbmVzIGluc3RlYWQgb2YKICAgICAqICAgbm9ybWFsIGFsbG9jYXRlL2ZyZWUgcm91dGluZXMKICAgICAqIE9pX09CSkVDVF9QUk9DID0gMHgwNCAtIEluZGljYXRlcyBhIHByb2NlZHVyZSB0aGF0IGlzIHBhcnQgb2YgYW4gT0xFCiAgICAgKiAgIGludGVyZmFjZSwgcmF0aGVyIHRoYW4gYSBEQ0UgUlBDIGludGVyZmFjZS4KICAgICAqIE9pX0hBU19SUENGTEFHUyA9IDB4MDggLSBJbmRpY2F0ZXMgdGhhdCB0aGUgcnBjX2ZsYWdzIGVsZW1lbnQgaXMgCiAgICAgKiAgIHByZXNlbnQgaW4gdGhlIGhlYWRlci4KICAgICAqIE9pX0hBU19DT01NX09SX0ZBVUxUID0gMHgyMCAtIElmIE9pX09CSkVDVF9QUk9DIG5vdCBwcmVzZW50IG9ubHkgdGhlbgogICAgICogICBpbmRpY2F0ZXMgdGhhdCB0aGUgcHJvY2VkdXJlIGhhcyB0aGUgY29tbV9zdGF0dXMgb3IgZmF1bHRfc3RhdHVzCiAgICAgKiAgIE1JREwgYXR0cmlidXRlLgogICAgICogT2lfT0JKX1VTRV9WMl9JTlRFUlBSRVRFUiA9IDB4MjAgLSBJZiBPaV9PQkpFQ1RfUFJPQyBwcmVzZW50IG9ubHkKICAgICAqICAgdGhlbiBpbmRpY2F0ZXMgdGhhdCB0aGUgZm9ybWF0IHN0cmluZyBpcyBpbiAtT2lmIG9yIC1PaWNmIGZvcm1hdAogICAgICogT2lfVVNFX05FV19JTklUX1JPVVRJTkVTID0gMHg0MCAtIFVzZSBOZHJYSW5pdGlhbGl6ZU5ldyBpbnN0ZWFkIG9mCiAgICAgKiAgIE5kclhJbml0aWFsaXplPwogICAgICovCiAgICB1bnNpZ25lZCBjaGFyIE9pX2ZsYWdzOwoKICAgIC8qIHRoZSB6ZXJvLWJhc2VkIGluZGV4IG9mIHRoZSBwcm9jZWR1cmUgKi8KICAgIHVuc2lnbmVkIHNob3J0IHByb2NfbnVtOwoKICAgIC8qIHRvdGFsIHNpemUgb2YgYWxsIHBhcmFtZXRlcnMgb24gdGhlIHN0YWNrLCBpbmNsdWRpbmcgYW55ICJ0aGlzIgogICAgICogcG9pbnRlciBhbmQvb3IgcmV0dXJuIHZhbHVlICovCiAgICB1bnNpZ25lZCBzaG9ydCBzdGFja19zaXplOwp9IE5EUl9QUk9DX0hFQURFUjsKCi8qIHNhbWUgYXMgYWJvdmUgc3RydWN0IGV4Y2VwdCBhZGRpdGlvbmFsIGVsZW1lbnQgcnBjX2ZsYWdzICovCnR5cGVkZWYgc3RydWN0IF9ORFJfUFJPQ19IRUFERVJfUlBDCnsKICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CiAgICB1bnNpZ25lZCBjaGFyIE9pX2ZsYWdzOwoKICAgIC8qCiAgICAgKiBSUENGX0lkZW1wb3RlbnQgPSAweDAwMDEgLSBbaWRlbXBvdGVudF0gTUlETCBhdHRyaWJ1dGUKICAgICAqIFJQQ0ZfQnJvYWRjYXN0ID0gMHgwMDAyIC0gW2Jyb2FkY2FzdF0gTUlETCBhdHRyaWJ1dGUKICAgICAqIFJQQ0ZfTWF5YmUgPSAweDAwMDQgLSBbbWF5YmVdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSZXNlcnZlZCA9IDB4MDAwOCAtIDB4MDA4MAogICAgICogUlBDRl9NZXNzYWdlID0gMHgwMTAwIC0gW21lc3NhZ2VdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSZXNlcnZlZCA9IDB4MDIwMCAtIDB4MTAwMAogICAgICogUlBDRl9JbnB1dFN5bmNocm9ub3VzID0gMHgyMDAwIC0gdW5rbm93bgogICAgICogUlBDRl9Bc3luY2hyb25vdXMgPSAweDQwMDAgLSBbYXN5bmNdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSZXNlcnZlZCA9IDB4ODAwMAogICAgICovCiAgICB1bnNpZ25lZCBsb25nIHJwY19mbGFnczsKICAgIHVuc2lnbmVkIHNob3J0IHByb2NfbnVtOwogICAgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZTsKCn0gTkRSX1BST0NfSEVBREVSX1JQQzsKCnR5cGVkZWYgc3RydWN0IF9ORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIKewogICAgLyogdGhlIHByZS1jb21wdXRlZCBjbGllbnQgYnVmZmVyIHNpemUgc28gdGhhdCBpbnRlcnByZXRlciBjYW4gc2tpcCBhbGwKICAgICAqIG9yIHNvbWUgKGlmIHRoZSBmbGFnIFJQQ19GQ19QUk9DX09JMkZfQ0xUTVVTVFNJWkUgaXMgc3BlY2lmaWVkKSBvZiB0aGUKICAgICAqIHNpemluZyBwYXNzICovCiAgICB1bnNpZ25lZCBzaG9ydCBjb25zdGFudF9jbGllbnRfYnVmZmVyX3NpemU7CgogICAgLyogdGhlIHByZS1jb21wdXRlZCBzZXJ2ZXIgYnVmZmVyIHNpemUgc28gdGhhdCBpbnRlcnByZXRlciBjYW4gc2tpcCBhbGwKICAgICAqIG9yIHNvbWUgKGlmIHRoZSBmbGFnIFJQQ19GQ19QUk9DX09JMkZfU1JWTVVTVFNJWkUgaXMgc3BlY2lmaWVkKSBvZiB0aGUKICAgICAqIHNpemluZyBwYXNzICovCiAgICB1bnNpZ25lZCBzaG9ydCBjb25zdGFudF9zZXJ2ZXJfYnVmZmVyX3NpemU7CgogICAgSU5URVJQUkVURVJfT1BUX0ZMQUdTIE9pMkZsYWdzOwoKICAgIC8qIG51bWJlciBvZiBwYXJhbXMgKi8KICAgIHVuc2lnbmVkIGNoYXIgbnVtYmVyX29mX3BhcmFtczsKfSBORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVI7Cgp0eXBlZGVmIHN0cnVjdCBfTkRSX1BBUkFNX09JX0JBU0VUWVBFCnsKICAgIC8qIHBhcmFtZXRlciBkaXJlY3Rpb24uIE9uZSBvZjoKICAgICAqIEZDX0lOX1BBUkFNX0JBU0VUWVBFID0gMHg0ZSAtIGFuIGluIHBhcmFtCiAgICAgKiBGQ19SRVRVUk5fUEFSQU1fQkFTRVRZUEUgPSAweDUzIC0gYSByZXR1cm4gcGFyYW0KICAgICAqLwogICAgdW5zaWduZWQgY2hhciBwYXJhbV9kaXJlY3Rpb247CgogICAgLyogT25lIG9mOiBGQ19CWVRFLEZDX0NIQVIsRkNfU01BTEwsRkNfVVNNQUxMLEZDX1dDSEFSLEZDX1NIT1JULEZDX1VTSE9SVCwKICAgICAqIEZDX0xPTkcsRkNfVUxPTkcsRkNfRkxPQVQsRkNfSFlQRVIsRkNfRE9VQkxFLEZDX0VOVU0xNixGQ19FTlVNMzIsCiAgICAgKiBGQ19FUlJPUl9TVEFUVVNfVCxGQ19JTlQzMjY0LEZDX1VJTlQzMjY0ICovCiAgICB1bnNpZ25lZCBjaGFyIHR5cGVfZm9ybWF0X2NoYXI7Cn0gTkRSX1BBUkFNX09JX0JBU0VUWVBFOwoKdHlwZWRlZiBzdHJ1Y3QgX05EUl9QQVJBTV9PSV9PVEhFUgp7CiAgICAvKiBPbmUgb2Y6CiAgICAgKiBGQ19JTl9QQVJBTSA9IDB4NGQgLSBBbiBpbiBwYXJhbQogICAgICogRkNfSU5fT1VUX1BBUkFNID0gMHg1MCAtIEFuIGluL291dCBwYXJhbQogICAgICogRkNfT1VUX1BBUkFNID0gMHg1MSAtIEFuIG91dCBwYXJhbQogICAgICogRkNfUkVUVVJOX1BBUkFNID0gMHg1MiAtIEEgcmV0dXJuIHZhbHVlCiAgICAgKiBGQ19JTl9QQVJBTV9OT19GUkVFX0lOU1QgPSAweDRmIC0gQSBwYXJhbSBmb3Igd2hpY2ggbm8gZnJlZWluZyBpcyBkb25lCiAgICAgKi8KICAgIHVuc2lnbmVkIGNoYXIgcGFyYW1fZGlyZWN0aW9uOwoKICAgIC8qIFNpemUgb2YgcGFyYW0gb24gc3RhY2sgaW4gTlVNQkVSUyBPRiBJTlRTICovCiAgICB1bnNpZ25lZCBjaGFyIHN0YWNrX3NpemU7CgogICAgLyogb2Zmc2V0IGluIHRoZSB0eXBlIGZvcm1hdCBzdHJpbmcgdGFibGUgKi8KICAgIHVuc2lnbmVkIHNob3J0IHR5cGVfb2Zmc2V0Owp9IE5EUl9QQVJBTV9PSV9PVEhFUjsKCnR5cGVkZWYgc3RydWN0IF9ORFJfUEFSQU1fT0lGX0JBU0VUWVBFCnsKICAgIFBBUkFNX0FUVFJJQlVURVMgcGFyYW1fYXR0cmlidXRlczsKCiAgICAvKiB0aGUgb2Zmc2V0IG9uIHRoZSBjYWxsaW5nIHN0YWNrIHdoZXJlIHRoZSBwYXJhbWV0ZXIgaXMgbG9jYXRlZCAqLwogICAgdW5zaWduZWQgc2hvcnQgc3RhY2tfb2Zmc2V0OwoKICAgIC8qIHNlZSBORFJfUEFSQU1fT0lfQkFTRVRZUEU6OnR5cGVfZm9ybWF0X2NoYXIgKi8KICAgIHVuc2lnbmVkIGNoYXIgdHlwZV9mb3JtYXRfY2hhcjsKCiAgICAvKiBhbHdheXMgRkNfUEFEICovCiAgICB1bnNpZ25lZCBjaGFyIHVudXNlZDsKfSBORFJfUEFSQU1fT0lGX0JBU0VUWVBFOwoKdHlwZWRlZiBzdHJ1Y3QgX05EUl9QQVJBTV9PSUZfT1RIRVIKewogICAgUEFSQU1fQVRUUklCVVRFUyBwYXJhbV9hdHRyaWJ1dGVzOwoKICAgIC8qIHNlZSBORFJfUEFSQU1fT0lGX0JBU0VUWVBFOjpzdGFja19vZmZzZXQgKi8KICAgIHVuc2lnbmVkIHNob3J0IHN0YWNrX29mZnNldDsKCiAgICAvKiBvZmZzZXQgaW50byB0aGUgcHJvdmlkZWQgdHlwZSBmb3JtYXQgc3RyaW5nIHdoZXJlIHRoZSB0eXBlIGZvciB0aGlzCiAgICAgKiBwYXJhbWV0ZXIgc3RhcnRzICovCiAgICB1bnNpZ25lZCBzaG9ydCB0eXBlX29mZnNldDsKfSBORFJfUEFSQU1fT0lGX09USEVSOwoKLyogZXhwbGljaXQgaGFuZGxlIGRlc2NyaXB0aW9uIGZvciBGQ19CSU5EX1BSSU1JVElWRSB0eXBlICovCnR5cGVkZWYgc3RydWN0IF9ORFJfRUhEX1BSSU1JVElWRQp7CiAgICAvKiBGQ19CSU5EX1BSSU1JVElWRSAqLwogICAgdW5zaWduZWQgY2hhciBoYW5kbGVfdHlwZTsKCiAgICAvKiBpcyB0aGUgaGFuZGxlIHBhc3NlZCBpbiB2aWEgYSBwb2ludGVyPyAqLwogICAgdW5zaWduZWQgY2hhciBmbGFnOwoKICAgIC8qIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0YWNrIHRvIHRoZSBoYW5kbGUgaW4gYnl0ZXMgKi8KICAgIHVuc2lnbmVkIHNob3J0IG9mZnNldDsKfSBORFJfRUhEX1BSSU1JVElWRTsKCi8qIGV4cGxpY2l0IGhhbmRsZSBkZXNjcmlwdGlvbiBmb3IgRkNfQklORF9HRU5FUklDIHR5cGUgKi8KdHlwZWRlZiBzdHJ1Y3QgX05EUl9FSERfR0VORVJJQwp7CiAgICAvKiBGQ19CSU5EX0dFTkVSSUMgKi8KICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CgogICAgLyogdXBwZXIgNGJpdHMgaXMgYSBmbGFnIGluZGljYXRpbmcgd2hldGhlciB0aGUgaGFuZGxlIGlzIHBhc3NlZCBpbgogICAgICogdmlhIGEgcG9pbnRlci4gbG93ZXIgNGJpdHMgaXMgdGhlIHNpemUgb2YgdGhlIHVzZXIgZGVmaW5lZCBnZW5lcmljCiAgICAgKiBoYW5kbGUgdHlwZS4gdGhlIHNpemUgbXVzdCBiZSBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gdGhlIG1hY2hpbmUKICAgICAqIHJlZ2lzdGVyIHNpemUgKi8KICAgIHVuc2lnbmVkIGNoYXIgZmxhZ19hbmRfc2l6ZTsKCiAgICAvKiBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdGFjayB0byB0aGUgaGFuZGxlIGluIGJ5dGVzICovCiAgICB1bnNpZ25lZCBzaG9ydCBvZmZzZXQ7CgogICAgLyogdGhlIGluZGV4IGludG8gdGhlIGFHZW5lcmljQmluZGluZ1JvdXRpbmVzUGFpcnMgZmllbGQgb2YgTUlETF9TVFVCX0RFU0MKICAgICAqIGdpdmluZyB0aGUgYmluZCBhbmQgdW5iaW5kIHJvdXRpbmVzIGZvciB0aGUgaGFuZGxlICovCiAgICB1bnNpZ25lZCBjaGFyIGJpbmRpbmdfcm91dGluZV9wYWlyX2luZGV4OwoKICAgIC8qIEZDX1BBRCAqLwogICAgdW5zaWduZWQgY2hhciB1bnVzZWQ7Cn0gTkRSX0VIRF9HRU5FUklDOwoKLyogZXhwbGljaXQgaGFuZGxlIGRlc2NyaXB0aW9uIGZvciBGQ19CSU5EX0NPTlRFWFQgdHlwZSAqLwp0eXBlZGVmIHN0cnVjdCBfTkRSX0VIRF9DT05URVhUCnsKICAgIC8qIEZDX0JJTkRfQ09OVEVYVCAqLwogICAgdW5zaWduZWQgY2hhciBoYW5kbGVfdHlwZTsKCiAgICAvKiBBbnkgb2YgdGhlIGZvbGxvd2luZyBmbGFnczoKICAgICAqIE5EUl9DT05URVhUX0hBTkRMRV9DQU5OT1RfQkVfTlVMTCA9IDB4MDEKICAgICAqIE5EUl9DT05URVhUX0hBTkRMRV9TRVJJQUxJWkUgPSAweDAyCiAgICAgKiBORFJfQ09OVEVYVF9IQU5ETEVfTk9fU0VSSUFMSVpFID0gMHgwNAogICAgICogTkRSX1NUUklDVF9DT05URVhUX0hBTkRMRSA9IDB4MDgKICAgICAqIEhBTkRMRV9QQVJBTV9JU19PVVQgPSAweDIwCiAgICAgKiBIQU5ETEVfUEFSQU1fSVNfUkVUVVJOID0gMHgyMQogICAgICogSEFORExFX1BBUkFNX0lTX0lOID0gMHg0MAogICAgICogSEFORExFX1BBUkFNX0lTX1ZJQV9QVFIgPSAweDgwCiAgICAgKi8KICAgIHVuc2lnbmVkIGNoYXIgZmxhZ3M7CgogICAgLyogb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RhY2sgdG8gdGhlIGhhbmRsZSBpbiBieXRlcyAqLwogICAgdW5zaWduZWQgc2hvcnQgb2Zmc2V0OwoKICAgIC8qIHplcm8tYmFzZWQgaW5kZXggb24gcnVuZG93biByb3V0aW5lIGluIGFwZm5OZHJSdW5kb3duUm91dGluZXMgZmllbGQKICAgICAqIG9mIE1JRExfU1RVQl9ERVNDICovCiAgICB1bnNpZ25lZCBjaGFyIGNvbnRleHRfcnVuZG93bl9yb3V0aW5lX2luZGV4OwoKICAgIC8qIHZhcmllcyBkZXBlbmRpbmcgb24gTkRSIHZlcnNpb24gdXNlZC4KICAgICAqIFYxOiB6ZXJvLWJhc2VkIGluZGV4IGludG8gcGFyYW1ldGVycyAKICAgICAqIFYyOiB6ZXJvLWJhc2VkIGluZGV4IGludG8gaGFuZGxlcyB0aGF0IGFyZSBwYXJhbWV0ZXJzICovCiAgICB1bnNpZ25lZCBjaGFyIHBhcmFtX251bTsKfSBORFJfRUhEX0NPTlRFWFQ7CgojaW5jbHVkZSAicG9wcGFjay5oIgoKdm9pZCBXSU5BUEkgTmRyUnBjU21TZXRDbGllbnRUb09zZihQTUlETF9TVFVCX01FU1NBR0UgcE1lc3NhZ2UpCnsKI2lmIDAgLyogdGhlc2UgZnVuY3Rpb25zIGFyZSBub3QgZGVmaW5lZCB5ZXQgKi8KICAgIHBNZXNzYWdlLT5wZm5BbGxvY2F0ZSA9IE5kclJwY1NtQ2xpZW50QWxsb2NhdGU7CiAgICBwTWVzc2FnZS0+cGZuRnJlZSA9IE5kclJwY1NtQ2xpZW50RnJlZTsKI2VuZGlmCn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBkdW1wX1JQQ19GQ19QUk9DX1BGKFBBUkFNX0FUVFJJQlVURVMgcGFyYW1fYXR0cmlidXRlcykKewogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuTXVzdFNpemUpIFRSQUNFKCIgTXVzdFNpemUiKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLk11c3RGcmVlKSBUUkFDRSgiIE11c3RGcmVlIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc1BpcGUpIFRSQUNFKCIgSXNQaXBlIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc0luKSBUUkFDRSgiIElzSW4iKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLklzT3V0KSBUUkFDRSgiIElzT3V0Iik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikgVFJBQ0UoIiBJc1JldHVybiIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNCYXNldHlwZSkgVFJBQ0UoIiBJc0Jhc2V0eXBlIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpIFRSQUNFKCIgSXNCeVZhbHVlIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc1NpbXBsZVJlZikgVFJBQ0UoIiBJc1NpbXBsZVJlZiIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNEb250Q2FsbEZyZWVJbnN0KSBUUkFDRSgiIElzRG9udENhbGxGcmVlSW5zdCIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuU2F2ZUZvckFzeW5jRmluaXNoKSBUUkFDRSgiIFNhdmVGb3JBc3luY0ZpbmlzaCIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuU2VydmVyQWxsb2NTaXplKSBUUkFDRSgiIFNlcnZlckFsbG9jU2l6ZSA9ICVkIiwgcGFyYW1fYXR0cmlidXRlcy5TZXJ2ZXJBbGxvY1NpemUgKiA4KTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIGR1bXBfSU5URVJQUkVURVJfT1BUX0ZMQUdTKElOVEVSUFJFVEVSX09QVF9GTEFHUyBPaTJGbGFncykKewogICAgaWYgKE9pMkZsYWdzLlNlcnZlck11c3RTaXplKSBUUkFDRSgiIFNlcnZlck11c3RTaXplIik7CiAgICBpZiAoT2kyRmxhZ3MuQ2xpZW50TXVzdFNpemUpIFRSQUNFKCIgQ2xpZW50TXVzdFNpemUiKTsKICAgIGlmIChPaTJGbGFncy5IYXNSZXR1cm4pIFRSQUNFKCIgSGFzUmV0dXJuIik7CiAgICBpZiAoT2kyRmxhZ3MuSGFzUGlwZXMpIFRSQUNFKCIgSGFzUGlwZXMiKTsKICAgIGlmIChPaTJGbGFncy5VbnVzZWQpIFRSQUNFKCIgVW51c2VkIik7CiAgICBpZiAoT2kyRmxhZ3MuSGFzQXN5bmNVdWlkKSBUUkFDRSgiIEhhc0FzeW5jVXVpZCIpOwogICAgaWYgKE9pMkZsYWdzLkhhc0V4dGVuc2lvbnMpIFRSQUNFKCIgSGFzRXh0ZW5zaW9ucyIpOwogICAgaWYgKE9pMkZsYWdzLkhhc0FzeW5jSGFuZGxlKSBUUkFDRSgiIEhhc0FzeW5jSGFuZGxlIik7CiAgICBUUkFDRSgiXG4iKTsKfQoKI2RlZmluZSBBUkdfRlJPTV9PRkZTRVQoc3R1Yk1zZywgb2Zmc2V0KSAoKHN0dWJNc2cpLlN0YWNrVG9wICsgKG9mZnNldCkpCgpzdGF0aWMgUEZPUk1BVF9TVFJJTkcgY2xpZW50X2dldF9oYW5kbGUoCiAgICBQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIGNvbnN0IE5EUl9QUk9DX0hFQURFUiAqcFByb2NIZWFkZXIsCiAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0LCBoYW5kbGVfdCAqcGhCaW5kaW5nKQp7CiAgICAvKiBiaW5kaW5nICovCiAgICBzd2l0Y2ggKHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSkKICAgIHsKICAgIC8qIGV4cGxpY2l0IGJpbmRpbmc6IHBhcnNlIGFkZGl0aW9uYWwgc2VjdGlvbiAqLwogICAgY2FzZSBSUENfRkNfQklORF9FWFBMSUNJVDoKICAgICAgICBzd2l0Y2ggKCpwRm9ybWF0KSAvKiBoYW5kbGVfdHlwZSAqLwogICAgICAgIHsKICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX1BSSU1JVElWRTogLyogZXhwbGljaXQgcHJpbWl0aXZlICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5EUl9FSERfUFJJTUlUSVZFICogcERlc2MgPSAoTkRSX0VIRF9QUklNSVRJVkUgKilwRm9ybWF0OwoKICAgICAgICAgICAgICAgIFRSQUNFKCJFeHBsaWNpdCBwcmltaXRpdmUgaGFuZGxlIEAgJWRcbiIsIHBEZXNjLT5vZmZzZXQpOwoKICAgICAgICAgICAgICAgIGlmIChwRGVzYy0+ZmxhZykgLyogcG9pbnRlciB0byBiaW5kaW5nICovCiAgICAgICAgICAgICAgICAgICAgKnBoQmluZGluZyA9ICoqKGhhbmRsZV90ICoqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICpwaEJpbmRpbmcgPSAqKGhhbmRsZV90ICopQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgcERlc2MtPm9mZnNldCk7CiAgICAgICAgICAgICAgICByZXR1cm4gcEZvcm1hdCArIHNpemVvZihORFJfRUhEX1BSSU1JVElWRSk7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0dFTkVSSUM6IC8qIGV4cGxpY2l0IGdlbmVyaWMgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTkRSX0VIRF9HRU5FUklDICogcERlc2MgPSAoTkRSX0VIRF9HRU5FUklDICopcEZvcm1hdDsKICAgICAgICAgICAgICAgIHZvaWQgKnBPYmplY3QgPSBOVUxMOwogICAgICAgICAgICAgICAgdm9pZCAqcEFyZzsKICAgICAgICAgICAgICAgIGNvbnN0IEdFTkVSSUNfQklORElOR19ST1VUSU5FX1BBSVIgKnBHZW5QYWlyOwoKICAgICAgICAgICAgICAgIFRSQUNFKCJFeHBsaWNpdCBnZW5lcmljIGJpbmRpbmcgaGFuZGxlICMlZFxuIiwgcERlc2MtPmJpbmRpbmdfcm91dGluZV9wYWlyX2luZGV4KTsKCiAgICAgICAgICAgICAgICBpZiAocERlc2MtPmZsYWdfYW5kX3NpemUgJiBIQU5ETEVfUEFSQU1fSVNfVklBX1BUUikKICAgICAgICAgICAgICAgICAgICBwQXJnID0gKih2b2lkICoqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHBBcmcgPSAodm9pZCAqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgbWVtY3B5KCZwT2JqZWN0LCBwQXJnLCBwRGVzYy0+ZmxhZ19hbmRfc2l6ZSAmIDB4Zik7CiAgICAgICAgICAgICAgICBwR2VuUGFpciA9ICZwU3R1Yk1zZy0+U3R1YkRlc2MtPmFHZW5lcmljQmluZGluZ1JvdXRpbmVQYWlyc1twRGVzYy0+YmluZGluZ19yb3V0aW5lX3BhaXJfaW5kZXhdOwogICAgICAgICAgICAgICAgKnBoQmluZGluZyA9IHBHZW5QYWlyLT5wZm5CaW5kKHBPYmplY3QpOwogICAgICAgICAgICAgICAgcmV0dXJuIHBGb3JtYXQgKyBzaXplb2YoTkRSX0VIRF9HRU5FUklDKTsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfQ09OVEVYVDogLyogZXhwbGljaXQgY29udGV4dCAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBORFJfRUhEX0NPTlRFWFQgKiBwRGVzYyA9IChORFJfRUhEX0NPTlRFWFQgKilwRm9ybWF0OwogICAgICAgICAgICAgICAgTkRSX0NDT05URVhUIGNvbnRleHRfaGFuZGxlOwogICAgICAgICAgICAgICAgVFJBQ0UoIkV4cGxpY2l0IGJpbmQgY29udGV4dFxuIik7CiAgICAgICAgICAgICAgICBpZiAocERlc2MtPmZsYWdzICYgSEFORExFX1BBUkFNX0lTX1ZJQV9QVFIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0SEFORExFX1BBUkFNX0lTX1ZJQV9QVFJcbiIpOwogICAgICAgICAgICAgICAgICAgIGNvbnRleHRfaGFuZGxlID0gKiooTkRSX0NDT05URVhUICoqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGNvbnRleHRfaGFuZGxlID0gKihORFJfQ0NPTlRFWFQgKilBUkdfRlJPTV9PRkZTRVQoKnBTdHViTXNnLCBwRGVzYy0+b2Zmc2V0KTsKICAgICAgICAgICAgICAgIGlmICgocERlc2MtPmZsYWdzICYgTkRSX0NPTlRFWFRfSEFORExFX0NBTk5PVF9CRV9OVUxMKSAmJgogICAgICAgICAgICAgICAgICAgICFjb250ZXh0X2hhbmRsZSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBFUlIoIm51bGwgY29udGV4dCBoYW5kbGUgaXNuJ3QgYWxsb3dlZFxuIik7CiAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfU1NfSU5fTlVMTF9DT05URVhUKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICpwaEJpbmRpbmcgPSBORFJDQ29udGV4dEJpbmRpbmcoY29udGV4dF9oYW5kbGUpOwogICAgICAgICAgICAgICAgLyogRklYTUU6IHNob3VsZCB3ZSBzdG9yZSB0aGlzIHN0cnVjdHVyZSBpbiBzdHViTXNnLnBDb250ZXh0PyAqLwogICAgICAgICAgICAgICAgcmV0dXJuIHBGb3JtYXQgKyBzaXplb2YoTkRSX0VIRF9DT05URVhUKTsKICAgICAgICAgICAgfQogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiYmFkIGV4cGxpY2l0IGJpbmRpbmcgaGFuZGxlIHR5cGUgKDB4JTAyeClcbiIsIHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSk7CiAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0JJTkRfR0VORVJJQzogLyogaW1wbGljaXQgZ2VuZXJpYyAqLwogICAgICAgIEZJWE1FKCJSUENfRkNfQklORF9HRU5FUklDXG4iKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsgLyogRklYTUU6IHJlbW92ZSB3aGVuIGltcGxlbWVudGVkICovCiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFJQQ19GQ19CSU5EX1BSSU1JVElWRTogLyogaW1wbGljaXQgcHJpbWl0aXZlICovCiAgICAgICAgVFJBQ0UoIkltcGxpY2l0IHByaW1pdGl2ZSBoYW5kbGVcbiIpOwogICAgICAgICpwaEJpbmRpbmcgPSAqcFN0dWJNc2ctPlN0dWJEZXNjLT5JTVBMSUNJVF9IQU5ETEVfSU5GTy5wUHJpbWl0aXZlSGFuZGxlOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfQ0FMTEJBQ0tfSEFORExFOiAvKiBpbXBsaWNpdCBjYWxsYmFjayAqLwogICAgICAgIEZJWE1FKCJSUENfRkNfQ0FMTEJBQ0tfSEFORExFXG4iKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0FVVE9fSEFORExFOiAvKiBpbXBsaWNpdCBhdXRvIGhhbmRsZSAqLwogICAgICAgIC8qIHN0cmljdGx5IHNwZWFraW5nLCBpdCBpc24ndCBuZWNlc3NhcnkgdG8gc2V0IGhCaW5kaW5nIGhlcmUKICAgICAgICAgKiBzaW5jZSBpdCBpc24ndCBhY3R1YWxseSB1c2VkIChoZW5jZSB0aGUgYXV0b21hdGljIGluIGl0cyBuYW1lKSwKICAgICAgICAgKiBidXQgdGhlbiB3aHkgZG9lcyBNSURMIGdlbmVyYXRlIGEgdmFsaWQgZW50cnkgaW4gdGhlCiAgICAgICAgICogTUlETF9TVFVCX0RFU0MgZm9yIGl0PyAqLwogICAgICAgIFRSQUNFKCJJbXBsaWNpdCBhdXRvIGhhbmRsZVxuIik7CiAgICAgICAgKnBoQmluZGluZyA9ICpwU3R1Yk1zZy0+U3R1YkRlc2MtPklNUExJQ0lUX0hBTkRMRV9JTkZPLnBBdXRvSGFuZGxlOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBFUlIoImJhZCBpbXBsaWNpdCBiaW5kaW5nIGhhbmRsZSB0eXBlICgweCUwMngpXG4iLCBwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgfQogICAgcmV0dXJuIHBGb3JtYXQ7Cn0KCnN0YXRpYyB2b2lkIGNsaWVudF9mcmVlX2hhbmRsZSgKICAgIFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgY29uc3QgTkRSX1BST0NfSEVBREVSICpwUHJvY0hlYWRlciwKICAgIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQsIGhhbmRsZV90IGhCaW5kaW5nKQp7CiAgICAvKiBiaW5kaW5nICovCiAgICBzd2l0Y2ggKHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSkKICAgIHsKICAgIC8qIGV4cGxpY2l0IGJpbmRpbmc6IHBhcnNlIGFkZGl0aW9uYWwgc2VjdGlvbiAqLwogICAgY2FzZSBSUENfRkNfQklORF9FWFBMSUNJVDoKICAgICAgICBzd2l0Y2ggKCpwRm9ybWF0KSAvKiBoYW5kbGVfdHlwZSAqLwogICAgICAgIHsKICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0dFTkVSSUM6IC8qIGV4cGxpY2l0IGdlbmVyaWMgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTkRSX0VIRF9HRU5FUklDICogcERlc2MgPSAoTkRSX0VIRF9HRU5FUklDICopcEZvcm1hdDsKICAgICAgICAgICAgICAgIHZvaWQgKnBPYmplY3QgPSBOVUxMOwogICAgICAgICAgICAgICAgdm9pZCAqcEFyZzsKICAgICAgICAgICAgICAgIGNvbnN0IEdFTkVSSUNfQklORElOR19ST1VUSU5FX1BBSVIgKnBHZW5QYWlyOwoKICAgICAgICAgICAgICAgIFRSQUNFKCJFeHBsaWNpdCBnZW5lcmljIGJpbmRpbmcgaGFuZGxlICMlZFxuIiwgcERlc2MtPmJpbmRpbmdfcm91dGluZV9wYWlyX2luZGV4KTsKCiAgICAgICAgICAgICAgICBpZiAocERlc2MtPmZsYWdfYW5kX3NpemUgJiBIQU5ETEVfUEFSQU1fSVNfVklBX1BUUikKICAgICAgICAgICAgICAgICAgICBwQXJnID0gKih2b2lkICoqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHBBcmcgPSAodm9pZCAqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgbWVtY3B5KCZwT2JqZWN0LCBwQXJnLCBwRGVzYy0+ZmxhZ19hbmRfc2l6ZSAmIDB4Zik7CiAgICAgICAgICAgICAgICBwR2VuUGFpciA9ICZwU3R1Yk1zZy0+U3R1YkRlc2MtPmFHZW5lcmljQmluZGluZ1JvdXRpbmVQYWlyc1twRGVzYy0+YmluZGluZ19yb3V0aW5lX3BhaXJfaW5kZXhdOwogICAgICAgICAgICAgICAgcEdlblBhaXItPnBmblVuYmluZChwT2JqZWN0LCBoQmluZGluZyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfQ09OVEVYVDogLyogZXhwbGljaXQgY29udGV4dCAqLwogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfUFJJTUlUSVZFOiAvKiBleHBsaWNpdCBwcmltaXRpdmUgKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJiYWQgZXhwbGljaXQgYmluZGluZyBoYW5kbGUgdHlwZSAoMHglMDJ4KVxuIiwgcFByb2NIZWFkZXItPmhhbmRsZV90eXBlKTsKICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfQklORF9HRU5FUklDOiAvKiBpbXBsaWNpdCBnZW5lcmljICovCiAgICAgICAgRklYTUUoIlJQQ19GQ19CSU5EX0dFTkVSSUNcbiIpOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOyAvKiBGSVhNRTogcmVtb3ZlIHdoZW4gaW1wbGVtZW50ZWQgKi8KICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0NBTExCQUNLX0hBTkRMRTogLyogaW1wbGljaXQgY2FsbGJhY2sgKi8KICAgIGNhc2UgUlBDX0ZDX0JJTkRfUFJJTUlUSVZFOiAvKiBpbXBsaWNpdCBwcmltaXRpdmUgKi8KICAgIGNhc2UgUlBDX0ZDX0FVVE9fSEFORExFOiAvKiBpbXBsaWNpdCBhdXRvIGhhbmRsZSAqLwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBFUlIoImJhZCBpbXBsaWNpdCBiaW5kaW5nIGhhbmRsZSB0eXBlICgweCUwMngpXG4iLCBwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBjbGllbnRfZG9fYXJncyhQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQsCiAgICBpbnQgcGhhc2UsIHVuc2lnbmVkIHNob3J0IG51bWJlcl9vZl9wYXJhbXMsIHVuc2lnbmVkIGNoYXIgKnBSZXRWYWwpCnsKICAgIC8qIGN1cnJlbnQgZm9ybWF0IHN0cmluZyBvZmZzZXQgKi8KICAgIGludCBjdXJyZW50X29mZnNldCA9IDA7CiAgICAvKiBjdXJyZW50IHN0YWNrIG9mZnNldCAqLwogICAgdW5zaWduZWQgc2hvcnQgY3VycmVudF9zdGFja19vZmZzZXQgPSAwOwogICAgLyogY291bnRlciAqLwogICAgdW5zaWduZWQgc2hvcnQgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtYmVyX29mX3BhcmFtczsgaSsrKQogICAgewogICAgICAgIE5EUl9QQVJBTV9PSUZfQkFTRVRZUEUgKiBwUGFyYW0gPQogICAgICAgICAgICAoTkRSX1BBUkFNX09JRl9CQVNFVFlQRSAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKICAgICAgICB1bnNpZ25lZCBjaGFyICogcEFyZzsKCiAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgPSBwUGFyYW0tPnN0YWNrX29mZnNldDsKICAgICAgICBwQXJnID0gQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgY3VycmVudF9zdGFja19vZmZzZXQpOwoKICAgICAgICBUUkFDRSgicGFyYW1bJWRdOiBuZXcgZm9ybWF0XG4iLCBpKTsKICAgICAgICBUUkFDRSgiXHRwYXJhbV9hdHRyaWJ1dGVzOiIpOyBkdW1wX1JQQ19GQ19QUk9DX1BGKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcyk7IFRSQUNFKCJcbiIpOwogICAgICAgIFRSQUNFKCJcdHN0YWNrX29mZnNldDogMHgleFxuIiwgY3VycmVudF9zdGFja19vZmZzZXQpOwogICAgICAgIFRSQUNFKCJcdG1lbW9yeSBhZGRyIChiZWZvcmUpOiAlcFxuIiwgcEFyZyk7CgogICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCYXNldHlwZSkKICAgICAgICB7CiAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAmcFBhcmFtLT50eXBlX2Zvcm1hdF9jaGFyOwoKICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1NpbXBsZVJlZikKICAgICAgICAgICAgICAgIHBBcmcgPSAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZzsKCiAgICAgICAgICAgIFRSQUNFKCJcdGJhc2UgdHlwZTogMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIFBST1hZX0NBTENTSVpFOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0luKQogICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKHBTdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQUk9YWV9NQVJTSEFMOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0luKQogICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcihwU3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfVU5NQVJTSEFMOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzUmV0dXJuKQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgJnBSZXRWYWwsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKHBTdHViTXNnLCAmcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJwUmV0VmFsID0gJXBcbiIsIHBSZXRWYWwpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfU19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUEFSQU1fT0lGX0JBU0VUWVBFKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgTkRSX1BBUkFNX09JRl9PVEhFUiAqIHBQYXJhbU90aGVyID0KICAgICAgICAgICAgICAgIChORFJfUEFSQU1fT0lGX09USEVSICopJnBGb3JtYXRbY3VycmVudF9vZmZzZXRdOwoKICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqIHBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICYocFN0dWJNc2ctPlN0dWJEZXNjLT5wRm9ybWF0VHlwZXNbcFBhcmFtT3RoZXItPnR5cGVfb2Zmc2V0XSk7CgogICAgICAgICAgICAvKiBpZiBhIHNpbXBsZSByZWYgcG9pbnRlciB0aGVuIHdlIGhhdmUgdG8gZG8gdGhlCiAgICAgICAgICAgICAqIGNoZWNrIGZvciB0aGUgcG9pbnRlciBiZWluZyBub24tTlVMTC4gKi8KICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1NpbXBsZVJlZikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKCEqKHVuc2lnbmVkIGNoYXIgKiopcEFyZykKICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9OVUxMX1JFRl9QT0lOVEVSKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgVFJBQ0UoIlx0Y29tcGxleCB0eXBlOiAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKHBTdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcihwU3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBST1hZX01BUlNIQUw6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcihwU3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKHBTdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfVU5NQVJTSEFMOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzUmV0dXJuKQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgJnBSZXRWYWwsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKHBTdHViTXNnLCAodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSUZfT1RIRVIpOwogICAgICAgIH0KICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYWZ0ZXIpOiAlcFxuIiwgcEFyZyk7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIGNsaWVudF9kb19hcmdzX29sZF9mb3JtYXQoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLAogICAgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCwgaW50IHBoYXNlLCB1bnNpZ25lZCBzaG9ydCBzdGFja19zaXplLAogICAgdW5zaWduZWQgY2hhciAqcFJldFZhbCwgQk9PTCBvYmplY3RfcHJvYykKewogICAgLyogY3VycmVudCBmb3JtYXQgc3RyaW5nIG9mZnNldCAqLwogICAgaW50IGN1cnJlbnRfb2Zmc2V0ID0gMDsKICAgIC8qIGN1cnJlbnQgc3RhY2sgb2Zmc2V0ICovCiAgICB1bnNpZ25lZCBzaG9ydCBjdXJyZW50X3N0YWNrX29mZnNldCA9IDA7CiAgICAvKiBjb3VudGVyICovCiAgICB1bnNpZ25lZCBzaG9ydCBpOwoKICAgIC8qIE5PVEU6IFYxIHN0eWxlIGZvcm1hdCBkb2VzJ3QgdGVybWluYXRlIG9uIHRoZSBudW1iZXJfb2ZfcGFyYW1zCiAgICAgKiBjb25kaXRpb24gYXMgaXQgZG9lc24ndCBoYXZlIHRoaXMgYXR0cmlidXRlLiBJbnN0ZWFkIGl0CiAgICAgKiB0ZXJtaW5hdGVzIHdoZW4gdGhlIHN0YWNrIHNpemUgZ2l2ZW4gaW4gdGhlIGhlYWRlciBpcyBleGNlZWRlZC4KICAgICAqLwogICAgZm9yIChpID0gMDsgVFJVRTsgaSsrKQogICAgewogICAgICAgIE5EUl9QQVJBTV9PSV9CQVNFVFlQRSAqIHBQYXJhbSA9CiAgICAgICAgICAgIChORFJfUEFSQU1fT0lfQkFTRVRZUEUgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CiAgICAgICAgLyogbm90ZTogY3VycmVudF9zdGFja19vZmZzZXQgc3RhcnRzIGFmdGVyIHRoZSBUaGlzIHBvaW50ZXIKICAgICAgICAgKiBpZiBwcmVzZW50LCBzbyBhZGp1c3QgdGhpcyAqLwogICAgICAgIHVuc2lnbmVkIHNob3J0IGN1cnJlbnRfc3RhY2tfb2Zmc2V0X2FkanVzdGVkID0gY3VycmVudF9zdGFja19vZmZzZXQgKwogICAgICAgICAgICAob2JqZWN0X3Byb2MgPyBzaXplb2Yodm9pZCAqKSA6IDApOwogICAgICAgIHVuc2lnbmVkIGNoYXIgKiBwQXJnID0gQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgY3VycmVudF9zdGFja19vZmZzZXRfYWRqdXN0ZWQpOwoKICAgICAgICAvKiBubyBtb3JlIHBhcmFtZXRlcnM7IGV4aXQgbG9vcCAqLwogICAgICAgIGlmIChjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCA+PSBzdGFja19zaXplKQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgVFJBQ0UoInBhcmFtWyVkXTogb2xkIGZvcm1hdFxuIiwgaSk7CiAgICAgICAgVFJBQ0UoIlx0cGFyYW1fZGlyZWN0aW9uOiAweCV4XG4iLCBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbik7CiAgICAgICAgVFJBQ0UoIlx0c3RhY2tfb2Zmc2V0OiAweCV4XG4iLCBjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCk7CiAgICAgICAgVFJBQ0UoIlx0bWVtb3J5IGFkZHIgKGJlZm9yZSk6ICVwXG4iLCBwQXJnKTsKCiAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTV9CQVNFVFlQRSB8fAogICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqIHBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICZwUGFyYW0tPnR5cGVfZm9ybWF0X2NoYXI7CgogICAgICAgICAgICBUUkFDRSgiXHRiYXNlIHR5cGUgMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIFBST1hZX0NBTENTSVpFOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcihwU3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfTUFSU0hBTDoKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKHBTdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQUk9YWV9VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gJiBSUENfRkNfUkVUVVJOX1BBUkFNKQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgKHVuc2lnbmVkIGNoYXIgKiopcFJldFZhbCwgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIocFN0dWJNc2csICZwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgKz0gY2FsbF9tZW1vcnlfc2l6ZXIocFN0dWJNc2csIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSV9CQVNFVFlQRSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIE5EUl9QQVJBTV9PSV9PVEhFUiAqIHBQYXJhbU90aGVyID0gCiAgICAgICAgICAgICAgICAoTkRSX1BBUkFNX09JX09USEVSICopJnBGb3JtYXRbY3VycmVudF9vZmZzZXRdOwoKICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqcFR5cGVGb3JtYXQgPQogICAgICAgICAgICAgICAgJnBTdHViTXNnLT5TdHViRGVzYy0+cEZvcm1hdFR5cGVzW3BQYXJhbU90aGVyLT50eXBlX29mZnNldF07CgogICAgICAgICAgICBUUkFDRSgiXHRjb21wbGV4IHR5cGUgMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIFBST1hZX0NBTENTSVpFOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uICYgUlBDX0ZDX0lOX09VVF9QQVJBTSkKICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcihwU3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBST1hZX01BUlNIQUw6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gJiBSUENfRkNfSU5fT1VUX1BBUkFNKQogICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcihwU3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fT1VUX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX09VVF9QQVJBTSkKICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgZWxzZSBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTSkKICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgKHVuc2lnbmVkIGNoYXIgKiopcFJldFZhbCwgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfU19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGN1cnJlbnRfc3RhY2tfb2Zmc2V0ICs9IHBQYXJhbU90aGVyLT5zdGFja19zaXplICogc2l6ZW9mKElOVCk7CiAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUEFSQU1fT0lfT1RIRVIpOwogICAgICAgIH0KICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYWZ0ZXIpOiAlcFxuIiwgcEFyZyk7CiAgICB9Cn0KCi8qIHRoZSByZXR1cm4gdHlwZSBzaG91bGQgYmUgQ0xJRU5UX0NBTExfUkVUVVJOLCBidXQgdGhpcyBpcyBpbmNvbXBhdGlibGUKICogd2l0aCB0aGUgd2F5IGdjYyByZXR1cm5zIHN0cnVjdHVyZXMuICJ2b2lkICoiIHNob3VsZCBiZSB0aGUgbGFyZ2VzdCB0eXBlCiAqIHRoYXQgTUlETCBzaG91bGQgYWxsb3cgeW91IHRvIHJldHVybiBhbnl3YXkgKi8KTE9OR19QVFIgV0lOQVBJViBOZHJDbGllbnRDYWxsMihQTUlETF9TVFVCX0RFU0MgcFN0dWJEZXNjLCBQRk9STUFUX1NUUklORyBwRm9ybWF0LCAuLi4pCnsKICAgIC8qIHBvaW50ZXIgdG8gc3RhcnQgb2Ygc3RhY2sgd2hlcmUgYXJndW1lbnRzIHN0YXJ0ICovCiAgICBSUENfTUVTU0FHRSBycGNNc2c7CiAgICBNSURMX1NUVUJfTUVTU0FHRSBzdHViTXNnOwogICAgaGFuZGxlX3QgaEJpbmRpbmcgPSBOVUxMOwogICAgLyogcHJvY2VkdXJlIG51bWJlciAqLwogICAgdW5zaWduZWQgc2hvcnQgcHJvY2VkdXJlX251bWJlcjsKICAgIC8qIHNpemUgb2Ygc3RhY2sgKi8KICAgIHVuc2lnbmVkIHNob3J0IHN0YWNrX3NpemU7CiAgICAvKiBudW1iZXIgb2YgcGFyYW1ldGVycy4gb3B0aW9uYWwgZm9yIGNsaWVudCB0byBnaXZlIGl0IHRvIHVzICovCiAgICB1bnNpZ25lZCBjaGFyIG51bWJlcl9vZl9wYXJhbXMgPSB+MDsKICAgIC8qIGNhY2hlIG9mIE9pZl9mbGFncyBmcm9tIHYyIHByb2NlZHVyZSBoZWFkZXIgKi8KICAgIElOVEVSUFJFVEVSX09QVF9GTEFHUyBPaWZfZmxhZ3MgPSB7IDAgfTsKICAgIC8qIGNhY2hlIG9mIGV4dGVuc2lvbiBmbGFncyBmcm9tIE5EUl9QUk9DX0hFQURFUl9FWFRTICovCiAgICBJTlRFUlBSRVRFUl9PUFRfRkxBR1MyIGV4dF9mbGFncyA9IHsgMCB9OwogICAgLyogdGhlIHR5cGUgb2YgcGFzcyB3ZSBhcmUgY3VycmVudGx5IGRvaW5nICovCiAgICBpbnQgcGhhc2U7CiAgICAvKiBoZWFkZXIgZm9yIHByb2NlZHVyZSBzdHJpbmcgKi8KICAgIGNvbnN0IE5EUl9QUk9DX0hFQURFUiAqIHBQcm9jSGVhZGVyID0gKGNvbnN0IE5EUl9QUk9DX0hFQURFUiAqKSZwRm9ybWF0WzBdOwogICAgLyogLU9pZiBvciAtT2ljZiBnZW5lcmF0ZWQgZm9ybWF0ICovCiAgICBCT09MIGJWMkZvcm1hdCA9IEZBTFNFOwogICAgLyogdGhlIHZhbHVlIHRvIHJldHVybiB0byB0aGUgY2xpZW50IGZyb20gdGhlIHJlbW90ZSBwcm9jZWR1cmUgKi8KICAgIExPTkdfUFRSIFJldFZhbCA9IDA7CiAgICAvKiB0aGUgcG9pbnRlciB0byB0aGUgb2JqZWN0IHdoZW4gaW4gT0xFIG1vZGUgKi8KICAgIHZvaWQgKiBUaGlzID0gTlVMTDsKICAgIFBGT1JNQVRfU1RSSU5HIHBIYW5kbGVGb3JtYXQ7CgogICAgVFJBQ0UoInBTdHViRGVzYyAlcCwgcEZvcm1hdCAlcCwgLi4uXG4iLCBwU3R1YkRlc2MsIHBGb3JtYXQpOwoKICAgIC8qIExhdGVyIE5EUiBsYW5ndWFnZSB2ZXJzaW9ucyBwcm9iYWJseSB3b24ndCBiZSBiYWNrd2FyZHMgY29tcGF0aWJsZSAqLwogICAgaWYgKHBTdHViRGVzYy0+VmVyc2lvbiA+IDB4NTAwMDIpCiAgICB7CiAgICAgICAgRklYTUUoIkluY29tcGF0aWJsZSBzdHViIGRlc2NyaXB0aW9uIHZlcnNpb246IDB4JWx4XG4iLCBwU3R1YkRlc2MtPlZlcnNpb24pOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX1dST05HX1NUVUJfVkVSU0lPTik7CiAgICB9CgogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENGTEFHUykKICAgIHsKICAgICAgICBORFJfUFJPQ19IRUFERVJfUlBDICogcFByb2NIZWFkZXIgPSAoTkRSX1BST0NfSEVBREVSX1JQQyAqKSZwRm9ybWF0WzBdOwogICAgICAgIHN0YWNrX3NpemUgPSBwUHJvY0hlYWRlci0+c3RhY2tfc2l6ZTsKICAgICAgICBwcm9jZWR1cmVfbnVtYmVyID0gcFByb2NIZWFkZXItPnByb2NfbnVtOwogICAgICAgIHBGb3JtYXQgKz0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUl9SUEMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN0YWNrX3NpemUgPSBwUHJvY0hlYWRlci0+c3RhY2tfc2l6ZTsKICAgICAgICBwcm9jZWR1cmVfbnVtYmVyID0gcFByb2NIZWFkZXItPnByb2NfbnVtOwogICAgICAgIHBGb3JtYXQgKz0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUik7CiAgICB9CiAgICBUUkFDRSgic3RhY2sgc2l6ZTogMHgleFxuIiwgc3RhY2tfc2l6ZSk7CiAgICBUUkFDRSgicHJvYyBudW06ICVkXG4iLCBwcm9jZWR1cmVfbnVtYmVyKTsKCiAgICAvKiBjcmVhdGUgdGhlIGZ1bGwgcG9pbnRlciB0cmFuc2xhdGlvbiB0YWJsZXMsIGlmIHJlcXVlc3RlZCAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9GVUxMUFRSKQogICAgICAgIHN0dWJNc2cuRnVsbFB0clhsYXRUYWJsZXMgPSBOZHJGdWxsUG9pbnRlclhsYXRJbml0KDAsWExBVF9DTElFTlQpOwoKICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgewogICAgICAgIC8qIG9iamVjdCBpcyBhbHdheXMgdGhlIGZpcnN0IGFyZ3VtZW50ICovCiAgICAgICAgVGhpcyA9ICoqKHZvaWQgKioqKSgmcEZvcm1hdCsxKTsKICAgICAgICBOZHJQcm94eUluaXRpYWxpemUoVGhpcywgJnJwY01zZywgJnN0dWJNc2csIHBTdHViRGVzYywgcHJvY2VkdXJlX251bWJlcik7CiAgICB9CiAgICBlbHNlCiAgICAgICAgTmRyQ2xpZW50SW5pdGlhbGl6ZU5ldygmcnBjTXNnLCAmc3R1Yk1zZywgcFN0dWJEZXNjLCBwcm9jZWR1cmVfbnVtYmVyKTsKCiAgICBUUkFDRSgiT2lfZmxhZ3MgPSAweCUwMnhcbiIsIHBQcm9jSGVhZGVyLT5PaV9mbGFncyk7CiAgICBUUkFDRSgiTUlETCBzdHViIHZlcnNpb24gPSAweCVseFxuIiwgcFN0dWJEZXNjLT5NSURMVmVyc2lvbik7CgogICAgLyogbmVlZGVkIGZvciBjb25mb3JtYW5jZSBvZiB0b3AtbGV2ZWwgb2JqZWN0cyAqLwojaWZkZWYgX19pMzg2X18KICAgIHN0dWJNc2cuU3RhY2tUb3AgPSAqKHVuc2lnbmVkIGNoYXIgKiopKCZwRm9ybWF0KzEpOwojZWxzZQojIHdhcm5pbmcgU3RhY2sgbm90IHJldHJpZXZlZCBmb3IgeW91ciBDUFUgYXJjaGl0ZWN0dXJlCiNlbmRpZgoKICAgIHBIYW5kbGVGb3JtYXQgPSBwRm9ybWF0OwoKICAgIC8qIHdlIG9ubHkgbmVlZCBhIGhhbmRsZSBpZiB0aGlzIGlzbid0IGFuIG9iamVjdCBtZXRob2QgKi8KICAgIGlmICghKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpKQogICAgewogICAgICAgIHBGb3JtYXQgPSBjbGllbnRfZ2V0X2hhbmRsZSgmc3R1Yk1zZywgcFByb2NIZWFkZXIsIHBIYW5kbGVGb3JtYXQsICZoQmluZGluZyk7CiAgICAgICAgaWYgKCFwRm9ybWF0KSByZXR1cm4gMDsKICAgIH0KCiAgICBiVjJGb3JtYXQgPSAocFN0dWJEZXNjLT5WZXJzaW9uID49IDB4MjAwMDApOwoKICAgIGlmIChiVjJGb3JtYXQpCiAgICB7CiAgICAgICAgTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSICogcE9JRkhlYWRlciA9CiAgICAgICAgICAgIChORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIqKXBGb3JtYXQ7CgogICAgICAgIE9pZl9mbGFncyA9IHBPSUZIZWFkZXItPk9pMkZsYWdzOwogICAgICAgIG51bWJlcl9vZl9wYXJhbXMgPSBwT0lGSGVhZGVyLT5udW1iZXJfb2ZfcGFyYW1zOwoKICAgICAgICBwRm9ybWF0ICs9IHNpemVvZihORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIpOwogICAgfQoKICAgIFRSQUNFKCJPaWZfZmxhZ3MgPSAiKTsgZHVtcF9JTlRFUlBSRVRFUl9PUFRfRkxBR1MoT2lmX2ZsYWdzKTsKCiAgICBpZiAoT2lmX2ZsYWdzLkhhc0V4dGVuc2lvbnMpCiAgICB7CiAgICAgICAgTkRSX1BST0NfSEVBREVSX0VYVFMgKiBwRXh0ZW5zaW9ucyA9CiAgICAgICAgICAgIChORFJfUFJPQ19IRUFERVJfRVhUUyAqKXBGb3JtYXQ7CiAgICAgICAgZXh0X2ZsYWdzID0gcEV4dGVuc2lvbnMtPkZsYWdzMjsKICAgICAgICBwRm9ybWF0ICs9IHBFeHRlbnNpb25zLT5TaXplOwogICAgfQoKICAgIHN0dWJNc2cuQnVmZmVyTGVuZ3RoID0gMDsKCiAgICAvKiBzdG9yZSB0aGUgUlBDIGZsYWdzIGF3YXkgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfUlBDRkxBR1MpCiAgICAgICAgcnBjTXNnLlJwY0ZsYWdzID0gKChORFJfUFJPQ19IRUFERVJfUlBDICopcFByb2NIZWFkZXIpLT5ycGNfZmxhZ3M7CgogICAgLyogdXNlIGFsdGVybmF0ZSBtZW1vcnkgYWxsb2NhdGlvbiByb3V0aW5lcyAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENTU0FMTE9DKQogICAgICAgIE5kclJwY1NtU2V0Q2xpZW50VG9Pc2YoJnN0dWJNc2cpOwoKICAgIGlmIChPaWZfZmxhZ3MuSGFzUGlwZXMpCiAgICB7CiAgICAgICAgRklYTUUoInBpcGVzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9XUk9OR19TVFVCX1ZFUlNJT04pOyAvKiBGSVhNRTogcmVtb3ZlIHdoZW4gaW1wbGVtZW50ZWQgKi8KICAgICAgICAvKiBpbml0IHBpcGVzIHBhY2thZ2UgKi8KICAgICAgICAvKiBOZHJQaXBlc0luaXRpYWxpemUoLi4uKSAqLwogICAgfQogICAgaWYgKGV4dF9mbGFncy5IYXNOZXdDb3JyRGVzYykKICAgIHsKICAgICAgICAvKiBpbml0aWFsaXplIGV4dHJhIGNvcnJlbGF0aW9uIHBhY2thZ2UgKi8KICAgICAgICBGSVhNRSgibmV3IGNvcnJlbGF0aW9uIGRlc2NyaXB0aW9uIG5vdCBpbXBsZW1lbnRlZFxuIik7CiAgICAgICAgc3R1Yk1zZy5mSGFzTmV3Q29yckRlc2MgPSBUUlVFOwogICAgfQoKICAgIC8qIG9yZGVyIG9mIHBoYXNlczoKICAgICAqIDEuIFBST1hZX0NBTENTSVpFIC0gY2FsY3VsYXRlIHRoZSBidWZmZXIgc2l6ZQogICAgICogMi4gUFJPWFlfR0VUQlVGRkVSIC0gYWxsb2NhdGUgdGhlIGJ1ZmZlcgogICAgICogMy4gUFJPWFlfTUFSSFNBTCAtIG1hcnNoYWwgW2luXSBwYXJhbXMgaW50byB0aGUgYnVmZmVyCiAgICAgKiA0LiBQUk9YWV9TRU5EUkVDRUlWRSAtIHNlbmQvcmVjZWl2ZSBidWZmZXIKICAgICAqIDUuIFBST1hZX1VOTUFSSFNBTCAtIHVubWFyc2hhbCBbb3V0XSBwYXJhbXMgZnJvbSBidWZmZXIKICAgICAqLwogICAgZm9yIChwaGFzZSA9IFBST1hZX0NBTENTSVpFOyBwaGFzZSA8PSBQUk9YWV9VTk1BUlNIQUw7IHBoYXNlKyspCiAgICB7CiAgICAgICAgVFJBQ0UoInBoYXNlID0gJWRcbiIsIHBoYXNlKTsKICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgIHsKICAgICAgICBjYXNlIFBST1hZX0dFVEJVRkZFUjoKICAgICAgICAgICAgLyogYWxsb2NhdGUgdGhlIGJ1ZmZlciAqLwogICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX09CSkVDVCkKICAgICAgICAgICAgICAgIE5kclByb3h5R2V0QnVmZmVyKFRoaXMsICZzdHViTXNnKTsKICAgICAgICAgICAgZWxzZSBpZiAoT2lmX2ZsYWdzLkhhc1BpcGVzKQogICAgICAgICAgICAgICAgLyogTmRyR2V0UGlwZUJ1ZmZlciguLi4pICovCiAgICAgICAgICAgICAgICBGSVhNRSgicGlwZXMgbm90IHN1cHBvcnRlZCB5ZXRcbiIpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmIChwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUgPT0gUlBDX0ZDX0FVVE9fSEFORExFKQojaWYgMAogICAgICAgICAgICAgICAgICAgIE5kck5zR2V0QnVmZmVyKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlckxlbmd0aCwgaEJpbmRpbmcpOwojZWxzZQogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJ1c2luZyBhdXRvIGhhbmRsZSAtIGNhbGwgTmRyTnNHZXRCdWZmZXIgd2hlbiBpdCBnZXRzIGltcGxlbWVudGVkXG4iKTsKI2VuZGlmCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgTmRyR2V0QnVmZmVyKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlckxlbmd0aCwgaEJpbmRpbmcpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgUFJPWFlfU0VORFJFQ0VJVkU6CiAgICAgICAgICAgIC8qIHNlbmQgdGhlIFtpbl0gcGFyYW1zIGFuZCByZWNlaXZlIHRoZSBbb3V0XSBhbmQgW3JldHZhbF0KICAgICAgICAgICAgICogcGFyYW1zICovCiAgICAgICAgICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgICAgICAgICAgTmRyUHJveHlTZW5kUmVjZWl2ZShUaGlzLCAmc3R1Yk1zZyk7CiAgICAgICAgICAgIGVsc2UgaWYgKE9pZl9mbGFncy5IYXNQaXBlcykKICAgICAgICAgICAgICAgIC8qIE5kclBpcGVzU2VuZFJlY2VpdmUoLi4uKSAqLwogICAgICAgICAgICAgICAgRklYTUUoInBpcGVzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPmhhbmRsZV90eXBlID09IFJQQ19GQ19BVVRPX0hBTkRMRSkKI2lmIDAKICAgICAgICAgICAgICAgICAgICBOZHJOc1NlbmRSZWNlaXZlKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlciwgcFN0dWJEZXNjLT5JTVBMSUNJVF9IQU5ETEVfSU5GTy5wQXV0b0hhbmRsZSk7CiNlbHNlCiAgICAgICAgICAgICAgICAgICAgRklYTUUoInVzaW5nIGF1dG8gaGFuZGxlIC0gY2FsbCBOZHJOc1NlbmRSZWNlaXZlIHdoZW4gaXQgZ2V0cyBpbXBsZW1lbnRlZFxuIik7CiNlbmRpZgogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIE5kclNlbmRSZWNlaXZlKCZzdHViTXNnLCBzdHViTXNnLkJ1ZmZlcik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGNvbnZlcnQgc3RyaW5ncywgZmxvYXRpbmcgcG9pbnQgdmFsdWVzIGFuZCBlbmRpYW5lc3MgaW50byBvdXIKICAgICAgICAgICAgICogcHJlZmVycmVkIGZvcm1hdCAqLwogICAgICAgICAgICBpZiAoKHJwY01zZy5EYXRhUmVwcmVzZW50YXRpb24gJiAweDAwMDBGRkZGVUwpICE9IE5EUl9MT0NBTF9EQVRBX1JFUFJFU0VOVEFUSU9OKQogICAgICAgICAgICAgICAgTmRyQ29udmVydCgmc3R1Yk1zZywgcEZvcm1hdCk7CgogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFBST1hZX0NBTENTSVpFOgogICAgICAgIGNhc2UgUFJPWFlfTUFSU0hBTDoKICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgaWYgKGJWMkZvcm1hdCkKICAgICAgICAgICAgICAgIGNsaWVudF9kb19hcmdzKCZzdHViTXNnLCBwRm9ybWF0LCBwaGFzZSwgbnVtYmVyX29mX3BhcmFtcywKICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgY2hhciAqKSZSZXRWYWwpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBjbGllbnRfZG9fYXJnc19vbGRfZm9ybWF0KCZzdHViTXNnLCBwRm9ybWF0LCBwaGFzZSwgc3RhY2tfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgY2hhciAqKSZSZXRWYWwsCiAgICAgICAgICAgICAgICAgICAgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJzaG91bGRuJ3QgcmVhY2ggaGVyZS4gcGhhc2UgJWRcbiIsIHBoYXNlKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmIChleHRfZmxhZ3MuSGFzTmV3Q29yckRlc2MpCiAgICB7CiAgICAgICAgLyogZnJlZSBleHRyYSBjb3JyZWxhdGlvbiBwYWNrYWdlICovCiAgICAgICAgLyogTmRyQ29ycmVsYXRpb25GcmVlKCZzdHViTXNnKTsgKi8KICAgIH0KCiAgICBpZiAoT2lmX2ZsYWdzLkhhc1BpcGVzKQogICAgewogICAgICAgIC8qIE5kclBpcGVzRG9uZSguLi4pICovCiAgICB9CgogICAgLyogZnJlZSB0aGUgZnVsbCBwb2ludGVyIHRyYW5zbGF0aW9uIHRhYmxlcyAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9GVUxMUFRSKQogICAgICAgIE5kckZ1bGxQb2ludGVyWGxhdEZyZWUoc3R1Yk1zZy5GdWxsUHRyWGxhdFRhYmxlcyk7CgogICAgLyogZnJlZSBtYXJzaGFsbGluZyBidWZmZXIgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgIE5kclByb3h5RnJlZUJ1ZmZlcihUaGlzLCAmc3R1Yk1zZyk7CiAgICBlbHNlCiAgICB7CiAgICAgICAgTmRyRnJlZUJ1ZmZlcigmc3R1Yk1zZyk7CiAgICAgICAgY2xpZW50X2ZyZWVfaGFuZGxlKCZzdHViTXNnLCBwUHJvY0hlYWRlciwgcEhhbmRsZUZvcm1hdCwgaEJpbmRpbmcpOwogICAgfQoKICAgIFRSQUNFKCJSZXRWYWwgPSAweCVseFxuIiwgUmV0VmFsKTsKCiAgICByZXR1cm4gUmV0VmFsOwp9CgovKiBjYWxscyBhIGZ1bmN0aW9uIHdpdGggdGhlIHNwZWNpZmljZWQgYXJndW1lbnRzLCByZXN0b3JpbmcgdGhlIHN0YWNrCiAqIHByb3Blcmx5IGFmdGVyd2FyZHMgYXMgd2UgZG9uJ3Qga25vdyB0aGUgY2FsbGluZyBjb252ZW50aW9uIG9mIHRoZQogKiBmdW5jdGlvbiAqLwojaWYgZGVmaW5lZCBfX2kzODZfXyAmJiBkZWZpbmVkIF9NU0NfVkVSCl9fZGVjbHNwZWMobmFrZWQpIExPTkdfUFRSIF9fY2RlY2wgY2FsbF9zZXJ2ZXJfZnVuYyhTRVJWRVJfUk9VVElORSBmdW5jLCB1bnNpZ25lZCBjaGFyICogYXJncywgdW5zaWduZWQgaW50IHN0YWNrX3NpemUpCnsKICAgIF9fYXNtCiAgICB7CiAgICAgICAgcHVzaCBlYnAKICAgICAgICBwdXNoIGVkaSAgICAgICAgICAgIDsgU2F2ZSByZWdpc3RlcnMKICAgICAgICBwdXNoIGVzaQogICAgICAgIG1vdiBlYnAsIGVzcAogICAgICAgIG1vdiBlYXgsIFtlYnArMTZdICAgOyBHZXQgc3RhY2sgc2l6ZQogICAgICAgIHN1YiBlc3AsIGVheCAgICAgICAgOyBNYWtlIHJvb20gaW4gc3RhY2sgZm9yIGFyZ3VtZW50cwogICAgICAgIG1vdiBlZGksIGVzcAogICAgICAgIG1vdiBlY3gsIGVheAogICAgICAgIG1vdiBlc2ksIFtlYnArMTJdCiAgICAgICAgc2hyIGVjeCwgMgogICAgICAgIGNsZAogICAgICAgIHJlcCBtb3ZzZCAgICAgICAgICAgOyBDb3B5IGR3b3JkIGJsb2NrcwogICAgICAgIGNhbGwgW2VicCs4XSAgICAgICAgOyBDYWxsIGZ1bmN0aW9uCiAgICAgICAgbGVhIGVzcCwgW2VicC04XSAgICA7IFJlc3RvcmUgc3RhY2sKICAgICAgICBwb3AgZXNpICAgICAgICAgICAgIDsgUmVzdG9yZSByZWdpc3RlcnMKICAgICAgICBwb3AgZWRpCiAgICAgICAgcG9wIGVicAogICAgICAgIHJldAogICAgfQp9CiNlbGlmIGRlZmluZWQgX19pMzg2X18gJiYgZGVmaW5lZCBfX0dOVUNfXwpMT05HX1BUUiBfX2NkZWNsIGNhbGxfc2VydmVyX2Z1bmMoU0VSVkVSX1JPVVRJTkUgZnVuYywgdW5zaWduZWQgY2hhciAqIGFyZ3MsIHVuc2lnbmVkIGludCBzdGFja19zaXplKTsKX19BU01fR0xPQkFMX0ZVTkMoY2FsbF9zZXJ2ZXJfZnVuYywKICAgICJwdXNobCAlZWJwXG5cdCIKICAgICJtb3ZsICVlc3AsICVlYnBcblx0IgogICAgInB1c2hsICVlZGlcblx0IiAgICAgICAgICAgIC8qIFNhdmUgcmVnaXN0ZXJzICovCiAgICAicHVzaGwgJWVzaVxuXHQiCiAgICAibW92bCAxNiglZWJwKSwgJWVheFxuXHQiICAgLyogR2V0IHN0YWNrIHNpemUgKi8KICAgICJzdWJsICVlYXgsICVlc3Bcblx0IiAgICAgICAvKiBNYWtlIHJvb20gaW4gc3RhY2sgZm9yIGFyZ3VtZW50cyAqLwogICAgImFuZGwgJH4xNSwgJWVzcFxuXHQiCS8qIE1ha2Ugc3VyZSBzdGFjayBoYXMgMTYtYnl0ZSBhbGlnbm1lbnQgZm9yIE1hY09TIFggKi8KICAgICJtb3ZsICVlc3AsICVlZGlcblx0IgogICAgIm1vdmwgJWVheCwgJWVjeFxuXHQiCiAgICAibW92bCAxMiglZWJwKSwgJWVzaVxuXHQiCiAgICAic2hybCAkMiwgJWVjeFxuXHQiICAgICAgICAgLyogZGl2aWRlIGJ5IDQgKi8KICAgICJjbGRcblx0IgogICAgInJlcDsgbW92c2xcblx0IiAgICAgICAgICAgIC8qIENvcHkgZHdvcmQgYmxvY2tzICovCiAgICAiY2FsbCAqOCglZWJwKVxuXHQiICAgICAgICAgLyogQ2FsbCBmdW5jdGlvbiAqLwogICAgImxlYWwgLTgoJWVicCksICVlc3Bcblx0IiAgIC8qIFJlc3RvcmUgc3RhY2sgKi8KICAgICJwb3BsICVlc2lcblx0IiAgICAgICAgICAgICAvKiBSZXN0b3JlIHJlZ2lzdGVycyAqLwogICAgInBvcGwgJWVkaVxuXHQiCiAgICAicG9wbCAlZWJwXG5cdCIKICAgICJyZXRcbiIgKTsKI2Vsc2UKI3dhcm5pbmcgY2FsbF9zZXJ2ZXJfZnVuYyBub3QgaW1wbGVtZW50ZWQgZm9yIHlvdXIgYXJjaGl0ZWN0dXJlCkxPTkdfUFRSIF9fY2RlY2wgY2FsbF9zZXJ2ZXJfZnVuYyhTRVJWRVJfUk9VVElORSBmdW5jLCB1bnNpZ25lZCBjaGFyICogYXJncywgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZSkKewogICAgRklYTUUoIk5vdCBpbXBsZW1lbnRlZCBmb3IgeW91ciBhcmNoaXRlY3R1cmVcbiIpOwogICAgcmV0dXJuIDA7Cn0KI2VuZGlmCgpzdGF0aWMgRFdPUkQgY2FsY19hcmdfc2l6ZShNSURMX1NUVUJfTUVTU0FHRSAqcFN0dWJNc2csIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICAgIERXT1JEIHNpemU7CiAgICBzd2l0Y2goKnBGb3JtYXQpCiAgICB7CiAgICBjYXNlIFJQQ19GQ19TVFJVQ1Q6CiAgICAgICAgc2l6ZSA9ICooY29uc3QgV09SRCopKHBGb3JtYXQgKyAyKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0NBUlJBWToKICAgICAgICBzaXplID0gKihjb25zdCBXT1JEKikocEZvcm1hdCArIDIpOwogICAgICAgIENvbXB1dGVDb25mb3JtYW5jZShwU3R1Yk1zZywgTlVMTCwgcEZvcm1hdCArIDQsIDApOwogICAgICAgIHNpemUgKj0gcFN0dWJNc2ctPk1heENvdW50OwogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfU01GQVJSQVk6CiAgICAgICAgc2l6ZSA9ICooY29uc3QgV09SRCopKHBGb3JtYXQgKyAyKTsKICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0xHRkFSUkFZOgogICAgICAgIHNpemUgPSAqKGNvbnN0IERXT1JEKikocEZvcm1hdCArIDIpOwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBGSVhNRSgiVW5oYW5kbGVkIHR5cGUgJTAyeFxuIiwgKnBGb3JtYXQpOwogICAgICAgIC8qIGZhbGx0aHJvdWdoICovCiAgICBjYXNlIFJQQ19GQ19SUDoKICAgICAgICBzaXplID0gc2l6ZW9mKHZvaWQgKik7CiAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gc2l6ZTsKfQoKLyogRklYTUU6IG5lZWQgdG8gZnJlZSBzb21lIHN0dWZmIGluIGhlcmUgdG9vICovCmxvbmcgV0lOQVBJIE5kclN0dWJDYWxsMigKICAgIHN0cnVjdCBJUnBjU3R1YkJ1ZmZlciAqIHBUaGlzLAogICAgc3RydWN0IElScGNDaGFubmVsQnVmZmVyICogcENoYW5uZWwsCiAgICBQUlBDX01FU1NBR0UgcFJwY01zZywKICAgIHVuc2lnbmVkIGxvbmcgKiBwZHdTdHViUGhhc2UpCnsKICAgIGNvbnN0IE1JRExfU0VSVkVSX0lORk8gKnBTZXJ2ZXJJbmZvOwogICAgY29uc3QgTUlETF9TVFVCX0RFU0MgKnBTdHViRGVzYzsKICAgIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQ7CiAgICBNSURMX1NUVUJfTUVTU0FHRSBzdHViTXNnOwogICAgLyogcG9pbnRlciB0byBzdGFydCBvZiBzdGFjayB0byBwYXNzIGludG8gc3R1YiBpbXBsZW1lbnRhdGlvbiAqLwogICAgdW5zaWduZWQgY2hhciAqIGFyZ3M7CiAgICAvKiBzaXplIG9mIHN0YWNrICovCiAgICB1bnNpZ25lZCBzaG9ydCBzdGFja19zaXplOwogICAgLyogY3VycmVudCBzdGFjayBvZmZzZXQgKi8KICAgIHVuc2lnbmVkIHNob3J0IGN1cnJlbnRfc3RhY2tfb2Zmc2V0OwogICAgLyogbnVtYmVyIG9mIHBhcmFtZXRlcnMuIG9wdGlvbmFsIGZvciBjbGllbnQgdG8gZ2l2ZSBpdCB0byB1cyAqLwogICAgdW5zaWduZWQgY2hhciBudW1iZXJfb2ZfcGFyYW1zID0gfjA7CiAgICAvKiBjb3VudGVyICovCiAgICB1bnNpZ25lZCBzaG9ydCBpOwogICAgLyogY2FjaGUgb2YgT2lmX2ZsYWdzIGZyb20gdjIgcHJvY2VkdXJlIGhlYWRlciAqLwogICAgSU5URVJQUkVURVJfT1BUX0ZMQUdTIE9pZl9mbGFncyA9IHsgMCB9OwogICAgLyogY2FjaGUgb2YgZXh0ZW5zaW9uIGZsYWdzIGZyb20gTkRSX1BST0NfSEVBREVSX0VYVFMgKi8KICAgIElOVEVSUFJFVEVSX09QVF9GTEFHUzIgZXh0X2ZsYWdzID0geyAwIH07CiAgICAvKiB0aGUgdHlwZSBvZiBwYXNzIHdlIGFyZSBjdXJyZW50bHkgZG9pbmcgKi8KICAgIGludCBwaGFzZTsKICAgIC8qIGhlYWRlciBmb3IgcHJvY2VkdXJlIHN0cmluZyAqLwogICAgY29uc3QgTkRSX1BST0NfSEVBREVSICpwUHJvY0hlYWRlcjsKICAgIC8qIG9mZnNldCBpbiBmb3JtYXQgc3RyaW5nIGZvciBzdGFydCBvZiBwYXJhbXMgKi8KICAgIGludCBwYXJhbWV0ZXJfc3RhcnRfb2Zmc2V0OwogICAgLyogY3VycmVudCBmb3JtYXQgc3RyaW5nIG9mZnNldCAqLwogICAgaW50IGN1cnJlbnRfb2Zmc2V0OwogICAgLyogLU9pZiBvciAtT2ljZiBnZW5lcmF0ZWQgZm9ybWF0ICovCiAgICBCT09MIGJWMkZvcm1hdCA9IEZBTFNFOwogICAgLyogbG9jYXRpb24gdG8gcHV0IHJldHZhbCBpbnRvICovCiAgICBMT05HX1BUUiAqcmV0dmFsX3B0ciA9IE5VTEw7CgogICAgVFJBQ0UoInBUaGlzICVwLCBwQ2hhbm5lbCAlcCwgcFJwY01zZyAlcCwgcGR3U3R1YlBoYXNlICVwXG4iLCBwVGhpcywgcENoYW5uZWwsIHBScGNNc2csIHBkd1N0dWJQaGFzZSk7CgogICAgaWYgKHBUaGlzKQogICAgICAgIHBTZXJ2ZXJJbmZvID0gQ1N0ZFN0dWJCdWZmZXJfR2V0U2VydmVySW5mbyhwVGhpcyk7CiAgICBlbHNlCiAgICAgICAgcFNlcnZlckluZm8gPSAoKFJQQ19TRVJWRVJfSU5URVJGQUNFICopcFJwY01zZy0+UnBjSW50ZXJmYWNlSW5mb3JtYXRpb24pLT5JbnRlcnByZXRlckluZm87CgogICAgcFN0dWJEZXNjID0gcFNlcnZlckluZm8tPnBTdHViRGVzYzsKICAgIHBGb3JtYXQgPSBwU2VydmVySW5mby0+UHJvY1N0cmluZyArIHBTZXJ2ZXJJbmZvLT5GbXRTdHJpbmdPZmZzZXRbcFJwY01zZy0+UHJvY051bV07CiAgICBwUHJvY0hlYWRlciA9IChjb25zdCBORFJfUFJPQ19IRUFERVIgKikmcEZvcm1hdFswXTsKCiAgICAvKiBMYXRlciBORFIgbGFuZ3VhZ2UgdmVyc2lvbnMgcHJvYmFibHkgd29uJ3QgYmUgYmFja3dhcmRzIGNvbXBhdGlibGUgKi8KICAgIGlmIChwU3R1YkRlc2MtPlZlcnNpb24gPiAweDUwMDAyKQogICAgewogICAgICAgIEZJWE1FKCJJbmNvbXBhdGlibGUgc3R1YiBkZXNjcmlwdGlvbiB2ZXJzaW9uOiAweCVseFxuIiwgcFN0dWJEZXNjLT5WZXJzaW9uKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9XUk9OR19TVFVCX1ZFUlNJT04pOwogICAgfQoKICAgIC8qIGNyZWF0ZSB0aGUgZnVsbCBwb2ludGVyIHRyYW5zbGF0aW9uIHRhYmxlcywgaWYgcmVxdWVzdGVkICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX0ZVTExQVFIpCiAgICAgICAgc3R1Yk1zZy5GdWxsUHRyWGxhdFRhYmxlcyA9IE5kckZ1bGxQb2ludGVyWGxhdEluaXQoMCxYTEFUX1NFUlZFUik7CgogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENGTEFHUykKICAgIHsKICAgICAgICBORFJfUFJPQ19IRUFERVJfUlBDICogcFByb2NIZWFkZXIgPSAoTkRSX1BST0NfSEVBREVSX1JQQyAqKSZwRm9ybWF0WzBdOwogICAgICAgIHN0YWNrX3NpemUgPSBwUHJvY0hlYWRlci0+c3RhY2tfc2l6ZTsKICAgICAgICBjdXJyZW50X29mZnNldCA9IHNpemVvZihORFJfUFJPQ19IRUFERVJfUlBDKTsKCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc3RhY2tfc2l6ZSA9IHBQcm9jSGVhZGVyLT5zdGFja19zaXplOwogICAgICAgIGN1cnJlbnRfb2Zmc2V0ID0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUik7CiAgICB9CgogICAgVFJBQ0UoIk9pX2ZsYWdzID0gMHglMDJ4XG4iLCBwUHJvY0hlYWRlci0+T2lfZmxhZ3MpOwoKICAgIC8qIGJpbmRpbmcgKi8KICAgIHN3aXRjaCAocFByb2NIZWFkZXItPmhhbmRsZV90eXBlKQogICAgewogICAgLyogZXhwbGljaXQgYmluZGluZzogcGFyc2UgYWRkaXRpb25hbCBzZWN0aW9uICovCiAgICBjYXNlIFJQQ19GQ19CSU5EX0VYUExJQ0lUOgogICAgICAgIHN3aXRjaCAocEZvcm1hdFtjdXJyZW50X29mZnNldF0pIC8qIGhhbmRsZV90eXBlICovCiAgICAgICAgewogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfUFJJTUlUSVZFOiAvKiBleHBsaWNpdCBwcmltaXRpdmUgKi8KICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9FSERfUFJJTUlUSVZFKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSUENfRkNfQklORF9HRU5FUklDOiAvKiBleHBsaWNpdCBnZW5lcmljICovCiAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfRUhEX0dFTkVSSUMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0NPTlRFWFQ6IC8qIGV4cGxpY2l0IGNvbnRleHQgKi8KICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9FSERfQ09OVEVYVCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiYmFkIGV4cGxpY2l0IGJpbmRpbmcgaGFuZGxlIHR5cGUgKDB4JTAyeClcbiIsIHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSk7CiAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0JJTkRfR0VORVJJQzogLyogaW1wbGljaXQgZ2VuZXJpYyAqLwogICAgY2FzZSBSUENfRkNfQklORF9QUklNSVRJVkU6IC8qIGltcGxpY2l0IHByaW1pdGl2ZSAqLwogICAgY2FzZSBSUENfRkNfQ0FMTEJBQ0tfSEFORExFOiAvKiBpbXBsaWNpdCBjYWxsYmFjayAqLwogICAgY2FzZSBSUENfRkNfQVVUT19IQU5ETEU6IC8qIGltcGxpY2l0IGF1dG8gaGFuZGxlICovCiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIEVSUigiYmFkIGltcGxpY2l0IGJpbmRpbmcgaGFuZGxlIHR5cGUgKDB4JTAyeClcbiIsIHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICB9CgogICAgYlYyRm9ybWF0ID0gKHBTdHViRGVzYy0+VmVyc2lvbiA+PSAweDIwMDAwKTsKCiAgICBpZiAoYlYyRm9ybWF0KQogICAgewogICAgICAgIE5EUl9QUk9DX1BBUlRJQUxfT0lGX0hFQURFUiAqIHBPSUZIZWFkZXIgPQogICAgICAgICAgICAoTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CgogICAgICAgIE9pZl9mbGFncyA9IHBPSUZIZWFkZXItPk9pMkZsYWdzOwogICAgICAgIG51bWJlcl9vZl9wYXJhbXMgPSBwT0lGSGVhZGVyLT5udW1iZXJfb2ZfcGFyYW1zOwoKICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSKTsKICAgIH0KCiAgICBUUkFDRSgiT2lmX2ZsYWdzID0gIik7IGR1bXBfSU5URVJQUkVURVJfT1BUX0ZMQUdTKE9pZl9mbGFncyk7CgogICAgaWYgKE9pZl9mbGFncy5IYXNFeHRlbnNpb25zKQogICAgewogICAgICAgIE5EUl9QUk9DX0hFQURFUl9FWFRTICogcEV4dGVuc2lvbnMgPQogICAgICAgICAgICAoTkRSX1BST0NfSEVBREVSX0VYVFMgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CiAgICAgICAgZXh0X2ZsYWdzID0gcEV4dGVuc2lvbnMtPkZsYWdzMjsKICAgICAgICBjdXJyZW50X29mZnNldCArPSBwRXh0ZW5zaW9ucy0+U2l6ZTsKICAgIH0KCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX09CSkVDVCkKICAgICAgICBOZHJTdHViSW5pdGlhbGl6ZShwUnBjTXNnLCAmc3R1Yk1zZywgcFN0dWJEZXNjLCBwQ2hhbm5lbCk7CiAgICBlbHNlCiAgICAgICAgTmRyU2VydmVySW5pdGlhbGl6ZU5ldyhwUnBjTXNnLCAmc3R1Yk1zZywgcFN0dWJEZXNjKTsKCiAgICAvKiBzdG9yZSB0aGUgUlBDIGZsYWdzIGF3YXkgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfUlBDRkxBR1MpCiAgICAgICAgcFJwY01zZy0+UnBjRmxhZ3MgPSAoKE5EUl9QUk9DX0hFQURFUl9SUEMgKilwUHJvY0hlYWRlciktPnJwY19mbGFnczsKCiAgICAvKiB1c2UgYWx0ZXJuYXRlIG1lbW9yeSBhbGxvY2F0aW9uIHJvdXRpbmVzICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX1JQQ1NTQUxMT0MpCiNpZiAwCiAgICAgICAgICBOZHJScGNTc0VuYWJsZUFsbG9jYXRlKCZzdHViTXNnKTsKI2Vsc2UKICAgICAgICAgIEZJWE1FKCJTZXQgUlBDU1MgbWVtb3J5IGFsbG9jYXRpb24gcm91dGluZXNcbiIpOwojZW5kaWYKCiAgICBpZiAoT2lmX2ZsYWdzLkhhc1BpcGVzKQogICAgewogICAgICAgIEZJWE1FKCJwaXBlcyBub3Qgc3VwcG9ydGVkIHlldFxuIik7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfV1JPTkdfU1RVQl9WRVJTSU9OKTsgLyogRklYTUU6IHJlbW92ZSB3aGVuIGltcGxlbWVudGVkICovCiAgICAgICAgLyogaW5pdCBwaXBlcyBwYWNrYWdlICovCiAgICAgICAgLyogTmRyUGlwZXNJbml0aWFsaXplKC4uLikgKi8KICAgIH0KICAgIGlmIChleHRfZmxhZ3MuSGFzTmV3Q29yckRlc2MpCiAgICB7CiAgICAgICAgLyogaW5pdGlhbGl6ZSBleHRyYSBjb3JyZWxhdGlvbiBwYWNrYWdlICovCiAgICAgICAgRklYTUUoIm5ldyBjb3JyZWxhdGlvbiBkZXNjcmlwdGlvbiBub3QgaW1wbGVtZW50ZWRcbiIpOwogICAgICAgIHN0dWJNc2cuZkhhc05ld0NvcnJEZXNjID0gVFJVRTsKICAgIH0KCiAgICAvKiBjb252ZXJ0IHN0cmluZ3MsIGZsb2F0aW5nIHBvaW50IHZhbHVlcyBhbmQgZW5kaWFuZXNzIGludG8gb3VyCiAgICAgKiBwcmVmZXJyZWQgZm9ybWF0ICovCiAgICBpZiAoKHBScGNNc2ctPkRhdGFSZXByZXNlbnRhdGlvbiAmIDB4MDAwMEZGRkZVTCkgIT0gTkRSX0xPQ0FMX0RBVEFfUkVQUkVTRU5UQVRJT04pCiAgICAgICAgTmRyQ29udmVydCgmc3R1Yk1zZywgcEZvcm1hdCk7CgogICAgcGFyYW1ldGVyX3N0YXJ0X29mZnNldCA9IGN1cnJlbnRfb2Zmc2V0OwoKICAgIFRSQUNFKCJhbGxvY2F0aW5nIG1lbW9yeSBmb3Igc3RhY2sgb2Ygc2l6ZSAleFxuIiwgc3RhY2tfc2l6ZSk7CgogICAgYXJncyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzdGFja19zaXplKTsKICAgIHN0dWJNc2cuU3RhY2tUb3AgPSBhcmdzOyAvKiB1c2VkIGJ5IGNvbmZvcm1hbmNlIG9mIHRvcC1sZXZlbCBvYmplY3RzICovCgogICAgLyogYWRkIHRoZSBpbXBsaWNpdCBUaGlzIHBvaW50ZXIgYXMgdGhlIGZpcnN0IGFyZyB0byB0aGUgZnVuY3Rpb24gaWYgd2UKICAgICAqIGFyZSBjYWxsaW5nIGFuIG9iamVjdCBtZXRob2QgKi8KICAgIGlmIChwVGhpcykKICAgICAgICAqKHZvaWQgKiopYXJncyA9ICgoQ1N0ZFN0dWJCdWZmZXIgKilwVGhpcyktPnB2U2VydmVyT2JqZWN0OwoKICAgIC8qIG9yZGVyIG9mIHBoYXNlczoKICAgICAqIDEuIFNUVUJMRVNTX1VOTUFSSFNBTCAtIHVubWFyc2hhbCBbaW5dIHBhcmFtcyBmcm9tIGJ1ZmZlcgogICAgICogMi4gU1RVQkxFU1NfQ0FMTFNFUlZFUiAtIHNlbmQvcmVjZWl2ZSBidWZmZXIKICAgICAqIDMuIFNUVUJMRVNTX0NBTENTSVpFIC0gZ2V0IFtvdXRdIGJ1ZmZlciBzaXplCiAgICAgKiA0LiBTVFVCTEVTU19HRVRCVUZGRVIgLSBhbGxvY2F0ZSBbb3V0XSBidWZmZXIKICAgICAqIDUuIFNUVUJMRVNTX01BUkhTQUwgLSBtYXJzaGFsIFtvdXRdIHBhcmFtcyB0byBidWZmZXIKICAgICAqLwogICAgZm9yIChwaGFzZSA9IFNUVUJMRVNTX1VOTUFSU0hBTDsgcGhhc2UgPD0gU1RVQkxFU1NfTUFSU0hBTDsgcGhhc2UrKykKICAgIHsKICAgICAgICBUUkFDRSgicGhhc2UgPSAlZFxuIiwgcGhhc2UpOwogICAgICAgIHN3aXRjaCAocGhhc2UpCiAgICAgICAgewogICAgICAgIGNhc2UgU1RVQkxFU1NfQ0FMTFNFUlZFUjoKICAgICAgICAgICAgLyogY2FsbCB0aGUgc2VydmVyIGZ1bmN0aW9uICovCiAgICAgICAgICAgIGlmIChwU2VydmVySW5mby0+VGh1bmtUYWJsZSAmJiBwU2VydmVySW5mby0+VGh1bmtUYWJsZVtwUnBjTXNnLT5Qcm9jTnVtXSkKICAgICAgICAgICAgICAgIHBTZXJ2ZXJJbmZvLT5UaHVua1RhYmxlW3BScGNNc2ctPlByb2NOdW1dKCZzdHViTXNnKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBTRVJWRVJfUk9VVElORSBmdW5jOwogICAgICAgICAgICAgICAgTE9OR19QVFIgcmV0dmFsOwoKICAgICAgICAgICAgICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFNFUlZFUl9ST1VUSU5FICp2dGJsID0gKihTRVJWRVJfUk9VVElORSAqKikoKENTdGRTdHViQnVmZmVyICopcFRoaXMpLT5wdlNlcnZlck9iamVjdDsKICAgICAgICAgICAgICAgICAgICBmdW5jID0gdnRibFtwUnBjTXNnLT5Qcm9jTnVtXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBmdW5jID0gcFNlcnZlckluZm8tPkRpc3BhdGNoVGFibGVbcFJwY01zZy0+UHJvY051bV07CgogICAgICAgICAgICAgICAgLyogRklYTUU6IHdoYXQgaGFwcGVucyB3aXRoIHJldHVybiB2YWx1ZXMgdGhhdCBkb24ndCBmaXQgaW50byBhIHNpbmdsZSByZWdpc3RlciBvbiB4ODY/ICovCiAgICAgICAgICAgICAgICByZXR2YWwgPSBjYWxsX3NlcnZlcl9mdW5jKGZ1bmMsIGFyZ3MsIHN0YWNrX3NpemUpOwoKICAgICAgICAgICAgICAgIGlmIChyZXR2YWxfcHRyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJzdHViIGltcGxlbWVudGF0aW9uIHJldHVybmVkIDB4JWx4XG4iLCByZXR2YWwpOwogICAgICAgICAgICAgICAgICAgICpyZXR2YWxfcHRyID0gcmV0dmFsOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJ2b2lkIHN0dWIgaW1wbGVtZW50YXRpb25cbiIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICBzdHViTXNnLkJ1ZmZlciA9IE5VTEw7CiAgICAgICAgICAgIHN0dWJNc2cuQnVmZmVyTGVuZ3RoID0gMDsKCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgU1RVQkxFU1NfR0VUQlVGRkVSOgogICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX09CSkVDVCkKICAgICAgICAgICAgICAgIE5kclN0dWJHZXRCdWZmZXIocFRoaXMsIHBDaGFubmVsLCAmc3R1Yk1zZyk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgUlBDX1NUQVRVUyBTdGF0dXM7CgogICAgICAgICAgICAgICAgcFJwY01zZy0+QnVmZmVyTGVuZ3RoID0gc3R1Yk1zZy5CdWZmZXJMZW5ndGg7CiAgICAgICAgICAgICAgICAvKiBhbGxvY2F0ZSBidWZmZXIgZm9yIFtvdXRdIGFuZCBbcmV0XSBwYXJhbXMgKi8KICAgICAgICAgICAgICAgIFN0YXR1cyA9IElfUnBjR2V0QnVmZmVyKHBScGNNc2cpOyAKICAgICAgICAgICAgICAgIGlmIChTdGF0dXMpCiAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oU3RhdHVzKTsKICAgICAgICAgICAgICAgIHN0dWJNc2cuQnVmZmVyU3RhcnQgPSBwUnBjTXNnLT5CdWZmZXI7CiAgICAgICAgICAgICAgICBzdHViTXNnLkJ1ZmZlckVuZCA9IHN0dWJNc2cuQnVmZmVyU3RhcnQgKyBzdHViTXNnLkJ1ZmZlckxlbmd0aDsKICAgICAgICAgICAgICAgIHN0dWJNc2cuQnVmZmVyID0gc3R1Yk1zZy5CdWZmZXJTdGFydDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFNUVUJMRVNTX01BUlNIQUw6CiAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgY2FzZSBTVFVCTEVTU19DQUxDU0laRToKICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgPSBwYXJhbWV0ZXJfc3RhcnRfb2Zmc2V0OwogICAgICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCA9IDA7CgogICAgICAgICAgICAvKiBOT1RFOiBWMSBzdHlsZSBmb3JtYXQgZG9lcyd0IHRlcm1pbmF0ZSBvbiB0aGUgbnVtYmVyX29mX3BhcmFtcwogICAgICAgICAgICAgKiBjb25kaXRpb24gYXMgaXQgZG9lc24ndCBoYXZlIHRoaXMgYXR0cmlidXRlLiBJbnN0ZWFkIGl0CiAgICAgICAgICAgICAqIHRlcm1pbmF0ZXMgd2hlbiB0aGUgc3RhY2sgc2l6ZSBnaXZlbiBpbiB0aGUgaGVhZGVyIGlzIGV4Y2VlZGVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bWJlcl9vZl9wYXJhbXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGJWMkZvcm1hdCkgLyogbmV3IHBhcmFtZXRlciBmb3JtYXQgKi8KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBORFJfUEFSQU1fT0lGX0JBU0VUWVBFICpwUGFyYW0gPQogICAgICAgICAgICAgICAgICAgICAgICAoTkRSX1BBUkFNX09JRl9CQVNFVFlQRSAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpwQXJnOwoKICAgICAgICAgICAgICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCA9IHBQYXJhbS0+c3RhY2tfb2Zmc2V0OwogICAgICAgICAgICAgICAgICAgIHBBcmcgPSAodW5zaWduZWQgY2hhciAqKShhcmdzK2N1cnJlbnRfc3RhY2tfb2Zmc2V0KTsKCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInBhcmFtWyVkXTogbmV3IGZvcm1hdFxuIiwgaSk7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0cGFyYW1fYXR0cmlidXRlczoiKTsgZHVtcF9SUENfRkNfUFJPQ19QRihwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMpOyBUUkFDRSgiXG4iKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRzdGFja19vZmZzZXQ6IDB4JXhcbiIsIGN1cnJlbnRfc3RhY2tfb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYmVmb3JlKTogJXAgLT4gJXBcbiIsIHBBcmcsICoodW5zaWduZWQgY2hhciAqKilwQXJnKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5TZXJ2ZXJBbGxvY1NpemUpCiAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJTZXJ2ZXJBbGxvY1NpemUgb2YgJWQgaWdub3JlZCBmb3IgcGFyYW1ldGVyICVkXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLlNlcnZlckFsbG9jU2l6ZSAqIDgsIGkpOwoKICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzQmFzZXR5cGUpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyICpwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFBhcmFtLT50eXBlX2Zvcm1hdF9jaGFyOwoKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0YmFzZSB0eXBlOiAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNPdXQgfHwgcFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzUmV0dXJuKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogRklYTUU6IGNhbGwgY2FsbF9mcmVlciBoZXJlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1NpbXBsZVJlZikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICh1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAmcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1ha2UgYSBub3RlIG9mIHRoZSBhZGRyZXNzIG9mIHRoZSByZXR1cm4gdmFsdWUgcGFyYW1ldGVyIGZvciBsYXRlciAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR2YWxfcHRyID0gKExPTkdfUFRSICopcEFyZzsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19DQUxDU0laRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNPdXQgfHwgcFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzUmV0dXJuKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JRl9CQVNFVFlQRSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIE5EUl9QQVJBTV9PSUZfT1RIRVIgKiBwUGFyYW1PdGhlciA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTkRSX1BBUkFNX09JRl9PVEhFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKHBTdHViRGVzYy0+cEZvcm1hdFR5cGVzW3BQYXJhbU90aGVyLT50eXBlX29mZnNldF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0Y29tcGxleCB0eXBlIDB4JTAyeFxuIiwgKnBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocGhhc2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCB8fCBwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R1Yk1zZy5wZm5GcmVlKCoodm9pZCAqKilwQXJnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBGSVhNRTogY2FsbCBjYWxsX2ZyZWVyIGhlcmUgZm9yIElOIHR5cGVzICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAmcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICh1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgc2l6ZSA9IGNhbGNfYXJnX3NpemUoJnN0dWJNc2csIHBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoc2l6ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoodm9pZCAqKilwQXJnID0gTmRyQWxsb2NhdGUoJnN0dWJNc2csIHNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1zZXQoKih2b2lkICoqKXBBcmcsIDAsIHNpemUpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX0NBTENTSVpFOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCB8fCBwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1NfSU5URVJOQUxfRVJST1IpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BBUkFNX09JRl9PVEhFUik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdG1lbW9yeSBhZGRyIChhZnRlcik6ICVwIC0+ICVwXG4iLCBwQXJnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIC8qIG9sZCBwYXJhbWV0ZXIgZm9ybWF0ICovCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTkRSX1BBUkFNX09JX0JBU0VUWVBFICpwUGFyYW0gPQogICAgICAgICAgICAgICAgICAgICAgICAoTkRSX1BBUkFNX09JX0JBU0VUWVBFICopJnBGb3JtYXRbY3VycmVudF9vZmZzZXRdOwogICAgICAgICAgICAgICAgICAgIC8qIG5vdGU6IGN1cnJlbnRfc3RhY2tfb2Zmc2V0IHN0YXJ0cyBhZnRlciB0aGUgVGhpcyBwb2ludGVyCiAgICAgICAgICAgICAgICAgICAgICogaWYgcHJlc2VudCwgc28gYWRqdXN0IHRoaXMgKi8KICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBzaG9ydCBjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCA9IGN1cnJlbnRfc3RhY2tfb2Zmc2V0ICsKICAgICAgICAgICAgICAgICAgICAgICAgKChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKSA/IHNpemVvZih2b2lkICopIDogMCk7CiAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgY2hhciAqcEFyZyA9ICh1bnNpZ25lZCBjaGFyICopKGFyZ3MrY3VycmVudF9zdGFja19vZmZzZXRfYWRqdXN0ZWQpOwoKICAgICAgICAgICAgICAgICAgICAvKiBubyBtb3JlIHBhcmFtZXRlcnM7IGV4aXQgbG9vcCAqLwogICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCA+PSBzdGFja19zaXplKQogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInBhcmFtWyVkXTogb2xkIGZvcm1hdFxuIiwgaSk7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0cGFyYW1fZGlyZWN0aW9uOiAweCV4XG4iLCBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbik7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0c3RhY2tfb2Zmc2V0OiAweCV4XG4iLCBjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCk7CgogICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU1fQkFTRVRZUEUgfHwKICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwUGFyYW0tPnR5cGVfZm9ybWF0X2NoYXI7CgogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRiYXNlIHR5cGUgMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX01BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX1VOTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICZwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHZhbF9wdHIgPSAoTE9OR19QVFIgKilwQXJnOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfU19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfc3RhY2tfb2Zmc2V0ICs9IGNhbGxfbWVtb3J5X3NpemVyKCZzdHViTXNnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUEFSQU1fT0lfQkFTRVRZUEUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBORFJfUEFSQU1fT0lfT1RIRVIgKiBwUGFyYW1PdGhlciA9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5EUl9QQVJBTV9PSV9PVEhFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcFN0dWJEZXNjLT5wRm9ybWF0VHlwZXNbcFBhcmFtT3RoZXItPnR5cGVfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdGNvbXBsZXggdHlwZSAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfT1VUX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX09VVF9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKCZzdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfVU5NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9PVVRfUEFSQU0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICh1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dmFsX3B0ciA9IChMT05HX1BUUiAqKXBBcmc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfT1VUX1BBUkFNKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHNpemUgPSBjYWxjX2FyZ19zaXplKCZzdHViTXNnLCBwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHNpemUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHZvaWQgKiopcEFyZyA9IE5kckFsbG9jYXRlKCZzdHViTXNnLCBzaXplKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtc2V0KCoodm9pZCAqKilwQXJnLCAwLCBzaXplKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19DQUxDU0laRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfT1VUX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX09VVF9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIoJnN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgKz0gcFBhcmFtT3RoZXItPnN0YWNrX3NpemUgKiBzaXplb2YoSU5UKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSV9PVEhFUik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoInNob3VsZG4ndCByZWFjaCBoZXJlLiBwaGFzZSAlZFxuIiwgcGhhc2UpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcFJwY01zZy0+QnVmZmVyTGVuZ3RoID0gKHVuc2lnbmVkIGludCkoc3R1Yk1zZy5CdWZmZXIgLSAodW5zaWduZWQgY2hhciAqKXBScGNNc2ctPkJ1ZmZlcik7CgogICAgaWYgKGV4dF9mbGFncy5IYXNOZXdDb3JyRGVzYykKICAgIHsKICAgICAgICAvKiBmcmVlIGV4dHJhIGNvcnJlbGF0aW9uIHBhY2thZ2UgKi8KICAgICAgICAvKiBOZHJDb3JyZWxhdGlvbkZyZWUoJnN0dWJNc2cpOyAqLwogICAgfQoKICAgIGlmIChPaWZfZmxhZ3MuSGFzUGlwZXMpCiAgICB7CiAgICAgICAgLyogTmRyUGlwZXNEb25lKC4uLikgKi8KICAgIH0KCiAgICAvKiBmcmVlIHRoZSBmdWxsIHBvaW50ZXIgdHJhbnNsYXRpb24gdGFibGVzICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX0ZVTExQVFIpCiAgICAgICAgTmRyRnVsbFBvaW50ZXJYbGF0RnJlZShzdHViTXNnLkZ1bGxQdHJYbGF0VGFibGVzKTsKCiAgICAvKiBmcmVlIHNlcnZlciBmdW5jdGlvbiBzdGFjayAqLwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYXJncyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCnZvaWQgV0lOQVBJIE5kclNlcnZlckNhbGwyKFBSUENfTUVTU0FHRSBwUnBjTXNnKQp7CiAgICBEV09SRCBkd1BoYXNlOwogICAgTmRyU3R1YkNhbGwyKE5VTEwsIE5VTEwsIHBScGNNc2csICZkd1BoYXNlKTsKfQo=