LyoKICogTkRSIC1PaSwtT2lmLC1PaWNmIEludGVycHJldGVyCiAqCiAqIENvcHlyaWdodCAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzCiAqIENvcHlyaWdodCAyMDAzLTUgUm9iZXJ0IFNoZWFybWFuIChmb3IgQ29kZVdlYXZlcnMpCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLCBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQQogKgogKiBUT0RPOgogKiAgLSBQaXBlcwogKiAgLSBTb21lIHR5cGVzIG9mIGJpbmRpbmcgaGFuZGxlcwogKi8KCiNpbmNsdWRlICJjb25maWcuaCIKI2luY2x1ZGUgIndpbmUvcG9ydC5oIgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKCiNpbmNsdWRlICJvYmpiYXNlLmgiCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgInJwY3Byb3h5LmgiCiNpbmNsdWRlICJuZHJ0eXBlcy5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgIndpbmUvcnBjZmMuaCIKCiNpbmNsdWRlICJuZHJfbWlzYy5oIgojaW5jbHVkZSAiY3BzZi5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwocnBjKTsKCiNkZWZpbmUgTkRSX1RBQkxFX01BU0sgMTI3CgpzdGF0aWMgaW5saW5lIHZvaWQgY2FsbF9idWZmZXJfc2l6ZXIoUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCB1bnNpZ25lZCBjaGFyICpwTWVtb3J5LCBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgICBORFJfQlVGRkVSU0laRSBtID0gTmRyQnVmZmVyU2l6ZXJbcEZvcm1hdFswXSAmIE5EUl9UQUJMRV9NQVNLXTsKICAgIGlmIChtKSBtKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICAgIGVsc2UKICAgIHsKICAgICAgICBGSVhNRSgiZm9ybWF0IHR5cGUgMHgleCBub3QgaW1wbGVtZW50ZWRcbiIsIHBGb3JtYXRbMF0pOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgfQp9CgpzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGNoYXIgKmNhbGxfbWFyc2hhbGxlcihQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIHVuc2lnbmVkIGNoYXIgKnBNZW1vcnksIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICAgIE5EUl9NQVJTSEFMTCBtID0gTmRyTWFyc2hhbGxlcltwRm9ybWF0WzBdICYgTkRSX1RBQkxFX01BU0tdOwogICAgaWYgKG0pIHJldHVybiBtKHBTdHViTXNnLCBwTWVtb3J5LCBwRm9ybWF0KTsKICAgIGVsc2UKICAgIHsKICAgICAgICBGSVhNRSgiZm9ybWF0IHR5cGUgMHgleCBub3QgaW1wbGVtZW50ZWRcbiIsIHBGb3JtYXRbMF0pOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQp9CgpzdGF0aWMgaW5saW5lIHVuc2lnbmVkIGNoYXIgKmNhbGxfdW5tYXJzaGFsbGVyKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgdW5zaWduZWQgY2hhciAqKnBwTWVtb3J5LCBQRk9STUFUX1NUUklORyBwRm9ybWF0LCB1bnNpZ25lZCBjaGFyIGZNdXN0QWxsb2MpCnsKICAgIE5EUl9VTk1BUlNIQUxMIG0gPSBOZHJVbm1hcnNoYWxsZXJbcEZvcm1hdFswXSAmIE5EUl9UQUJMRV9NQVNLXTsKICAgIGlmIChtKSByZXR1cm4gbShwU3R1Yk1zZywgcHBNZW1vcnksIHBGb3JtYXQsIGZNdXN0QWxsb2MpOwogICAgZWxzZQogICAgewogICAgICAgIEZJWE1FKCJmb3JtYXQgdHlwZSAweCV4IG5vdCBpbXBsZW1lbnRlZFxuIiwgcEZvcm1hdFswXSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBjYWxsX2ZyZWVyKFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywgdW5zaWduZWQgY2hhciAqcE1lbW9yeSwgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCkKewogICAgTkRSX0ZSRUUgbSA9IE5kckZyZWVyW3BGb3JtYXRbMF0gJiBORFJfVEFCTEVfTUFTS107CiAgICBpZiAobSkgbShwU3R1Yk1zZywgcE1lbW9yeSwgcEZvcm1hdCk7Cn0KCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgbG9uZyBjYWxsX21lbW9yeV9zaXplcihQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQpCnsKICAgIE5EUl9NRU1PUllTSVpFIG0gPSBOZHJNZW1vcnlTaXplcltwRm9ybWF0WzBdICYgTkRSX1RBQkxFX01BU0tdOwogICAgaWYgKG0pCiAgICB7CiAgICAgICAgdW5zaWduZWQgY2hhciAqc2F2ZWRfYnVmZmVyID0gcFN0dWJNc2ctPkJ1ZmZlcjsKICAgICAgICB1bnNpZ25lZCBsb25nIHJldDsKICAgICAgICBpbnQgc2F2ZWRfaWdub3JlX2VtYmVkZGVkX3BvaW50ZXJzID0gcFN0dWJNc2ctPklnbm9yZUVtYmVkZGVkUG9pbnRlcnM7CiAgICAgICAgcFN0dWJNc2ctPk1lbW9yeVNpemUgPSAwOwogICAgICAgIHBTdHViTXNnLT5JZ25vcmVFbWJlZGRlZFBvaW50ZXJzID0gMTsKICAgICAgICByZXQgPSBtKHBTdHViTXNnLCBwRm9ybWF0KTsKICAgICAgICBwU3R1Yk1zZy0+SWdub3JlRW1iZWRkZWRQb2ludGVycyA9IHNhdmVkX2lnbm9yZV9lbWJlZGRlZF9wb2ludGVyczsKICAgICAgICBwU3R1Yk1zZy0+QnVmZmVyID0gc2F2ZWRfYnVmZmVyOwogICAgICAgIHJldHVybiByZXQ7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRklYTUUoImZvcm1hdCB0eXBlIDB4JXggbm90IGltcGxlbWVudGVkXG4iLCBwRm9ybWF0WzBdKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQoKLyogdGhlcmUgY2FuJ3QgYmUgYW55IGFsaWdubWVudCB3aXRoIHRoZSBzdHJ1Y3R1cmVzIGluIHRoaXMgZmlsZSAqLwojaW5jbHVkZSAicHNocGFjazEuaCIKCiNkZWZpbmUgU1RVQkxFU1NfVU5NQVJTSEFMICAxCiNkZWZpbmUgU1RVQkxFU1NfQ0FMTFNFUlZFUiAyCiNkZWZpbmUgU1RVQkxFU1NfQ0FMQ1NJWkUgICAzCiNkZWZpbmUgU1RVQkxFU1NfR0VUQlVGRkVSICA0CiNkZWZpbmUgU1RVQkxFU1NfTUFSU0hBTCAgICA1CiNkZWZpbmUgU1RVQkxFU1NfRlJFRSAgICAgICA2CgovKiBGcm9tIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vbGlicmFyeS9kZWZhdWx0LmFzcD91cmw9L2xpYnJhcnkvZW4tdXMvcnBjL3JwYy9wYXJhbWV0ZXJfZGVzY3JpcHRvcnMuYXNwICovCnR5cGVkZWYgc3RydWN0IF9ORFJfUFJPQ19IRUFERVIKewogICAgLyogdHlwZSBvZiBoYW5kbGUgdG8gdXNlOgogICAgICogUlBDX0ZDX0JJTkRfRVhQTElDSVQgPSAwIC0gRXhwbGljaXQgaGFuZGxlLgogICAgICogICBIYW5kbGUgaXMgcGFzc2VkIGFzIGEgcGFyYW1ldGVyIHRvIHRoZSBmdW5jdGlvbi4KICAgICAqICAgSW5kaWNhdGVzIHRoYXQgZXhwbGljaXQgaGFuZGxlIGluZm9ybWF0aW9uIGZvbGxvd3MgdGhlIGhlYWRlciwKICAgICAqICAgd2hpY2ggYWN0dWFsbHkgZGVzY3JpYmVzIHRoZSBoYW5kbGUuCiAgICAgKiBSUENfRkNfQklORF9HRU5FUklDID0gMzEgLSBJbXBsaWNpdCBoYW5kbGUgd2l0aCBjdXN0b20gYmluZGluZyByb3V0aW5lcwogICAgICogICAoTUlETF9TVFVCX0RFU0M6OklNUExJQ0lUX0hBTkRMRV9JTkZPOjpwR2VuZXJpY0JpbmRpbmdJbmZvKQogICAgICogUlBDX0ZDX0JJTkRfUFJJTUlUSVZFID0gMzIgLSBJbXBsaWNpdCBoYW5kbGUgdXNpbmcgaGFuZGxlX3QgY3JlYXRlZCBieQogICAgICogICBjYWxsaW5nIGFwcGxpY2F0aW9uCiAgICAgKiBSUENfRkNfQVVUT19IQU5ETEUgPSAzMyAtIEF1dG9tYXRpYyBoYW5kbGUKICAgICAqIFJQQ19GQ19DQUxMQkFDS19IQU5ETEUgPSAzNCAtIHVuZG9jbWVudGVkCiAgICAgKi8KICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CgogICAgLyogcHJvY2VkdXJlIGZsYWdzOgogICAgICogT2lfRlVMTF9QVFJfVVNFRCA9IDB4MDEgLSBBIGZ1bGwgcG9pbnRlciBjYW4gaGF2ZSB0aGUgdmFsdWUgTlVMTCBhbmQgY2FuCiAgICAgKiAgIGNoYW5nZSBkdXJpbmcgdGhlIGNhbGwgZnJvbSBOVUxMIHRvIG5vbi1OVUxMIGFuZCBzdXBwb3J0cyBhbGlhc2luZwogICAgICogICBhbmQgY3ljbGVzLiBJbmRpY2F0ZXMgdGhhdCB0aGUgTmRyRnVsbFBvaW50ZXJYbGF0SW5pdCBmdW5jdGlvbgogICAgICogICBzaG91bGQgYmUgY2FsbGVkLgogICAgICogT2lfUlBDU1NfQUxMT0NfVVNFRCA9IDB4MDIgLSBVc2UgUnBjU1MgYWxsb2NhdGUvZnJlZSByb3V0aW5lcyBpbnN0ZWFkIG9mCiAgICAgKiAgIG5vcm1hbCBhbGxvY2F0ZS9mcmVlIHJvdXRpbmVzCiAgICAgKiBPaV9PQkpFQ1RfUFJPQyA9IDB4MDQgLSBJbmRpY2F0ZXMgYSBwcm9jZWR1cmUgdGhhdCBpcyBwYXJ0IG9mIGFuIE9MRQogICAgICogICBpbnRlcmZhY2UsIHJhdGhlciB0aGFuIGEgRENFIFJQQyBpbnRlcmZhY2UuCiAgICAgKiBPaV9IQVNfUlBDRkxBR1MgPSAweDA4IC0gSW5kaWNhdGVzIHRoYXQgdGhlIHJwY19mbGFncyBlbGVtZW50IGlzIAogICAgICogICBwcmVzZW50IGluIHRoZSBoZWFkZXIuCiAgICAgKiBPaV9IQVNfQ09NTV9PUl9GQVVMVCA9IDB4MjAgLSBJZiBPaV9PQkpFQ1RfUFJPQyBub3QgcHJlc2VudCBvbmx5IHRoZW4KICAgICAqICAgaW5kaWNhdGVzIHRoYXQgdGhlIHByb2NlZHVyZSBoYXMgdGhlIGNvbW1fc3RhdHVzIG9yIGZhdWx0X3N0YXR1cwogICAgICogICBNSURMIGF0dHJpYnV0ZS4KICAgICAqIE9pX09CSl9VU0VfVjJfSU5URVJQUkVURVIgPSAweDIwIC0gSWYgT2lfT0JKRUNUX1BST0MgcHJlc2VudCBvbmx5CiAgICAgKiAgIHRoZW4gaW5kaWNhdGVzIHRoYXQgdGhlIGZvcm1hdCBzdHJpbmcgaXMgaW4gLU9pZiBvciAtT2ljZiBmb3JtYXQKICAgICAqIE9pX1VTRV9ORVdfSU5JVF9ST1VUSU5FUyA9IDB4NDAgLSBVc2UgTmRyWEluaXRpYWxpemVOZXcgaW5zdGVhZCBvZgogICAgICogICBOZHJYSW5pdGlhbGl6ZT8KICAgICAqLwogICAgdW5zaWduZWQgY2hhciBPaV9mbGFnczsKCiAgICAvKiB0aGUgemVyby1iYXNlZCBpbmRleCBvZiB0aGUgcHJvY2VkdXJlICovCiAgICB1bnNpZ25lZCBzaG9ydCBwcm9jX251bTsKCiAgICAvKiB0b3RhbCBzaXplIG9mIGFsbCBwYXJhbWV0ZXJzIG9uIHRoZSBzdGFjaywgaW5jbHVkaW5nIGFueSAidGhpcyIKICAgICAqIHBvaW50ZXIgYW5kL29yIHJldHVybiB2YWx1ZSAqLwogICAgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZTsKfSBORFJfUFJPQ19IRUFERVI7CgovKiBzYW1lIGFzIGFib3ZlIHN0cnVjdCBleGNlcHQgYWRkaXRpb25hbCBlbGVtZW50IHJwY19mbGFncyAqLwp0eXBlZGVmIHN0cnVjdCBfTkRSX1BST0NfSEVBREVSX1JQQwp7CiAgICB1bnNpZ25lZCBjaGFyIGhhbmRsZV90eXBlOwogICAgdW5zaWduZWQgY2hhciBPaV9mbGFnczsKCiAgICAvKgogICAgICogUlBDRl9JZGVtcG90ZW50ID0gMHgwMDAxIC0gW2lkZW1wb3RlbnRdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSUENGX0Jyb2FkY2FzdCA9IDB4MDAwMiAtIFticm9hZGNhc3RdIE1JREwgYXR0cmlidXRlCiAgICAgKiBSUENGX01heWJlID0gMHgwMDA0IC0gW21heWJlXSBNSURMIGF0dHJpYnV0ZQogICAgICogUmVzZXJ2ZWQgPSAweDAwMDggLSAweDAwODAKICAgICAqIFJQQ0ZfTWVzc2FnZSA9IDB4MDEwMCAtIFttZXNzYWdlXSBNSURMIGF0dHJpYnV0ZQogICAgICogUmVzZXJ2ZWQgPSAweDAyMDAgLSAweDEwMDAKICAgICAqIFJQQ0ZfSW5wdXRTeW5jaHJvbm91cyA9IDB4MjAwMCAtIHVua25vd24KICAgICAqIFJQQ0ZfQXN5bmNocm9ub3VzID0gMHg0MDAwIC0gW2FzeW5jXSBNSURMIGF0dHJpYnV0ZQogICAgICogUmVzZXJ2ZWQgPSAweDgwMDAKICAgICAqLwogICAgdW5zaWduZWQgbG9uZyBycGNfZmxhZ3M7CiAgICB1bnNpZ25lZCBzaG9ydCBwcm9jX251bTsKICAgIHVuc2lnbmVkIHNob3J0IHN0YWNrX3NpemU7Cgp9IE5EUl9QUk9DX0hFQURFUl9SUEM7Cgp0eXBlZGVmIHN0cnVjdCBfTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSCnsKICAgIC8qIHRoZSBwcmUtY29tcHV0ZWQgY2xpZW50IGJ1ZmZlciBzaXplIHNvIHRoYXQgaW50ZXJwcmV0ZXIgY2FuIHNraXAgYWxsCiAgICAgKiBvciBzb21lIChpZiB0aGUgZmxhZyBSUENfRkNfUFJPQ19PSTJGX0NMVE1VU1RTSVpFIGlzIHNwZWNpZmllZCkgb2YgdGhlCiAgICAgKiBzaXppbmcgcGFzcyAqLwogICAgdW5zaWduZWQgc2hvcnQgY29uc3RhbnRfY2xpZW50X2J1ZmZlcl9zaXplOwoKICAgIC8qIHRoZSBwcmUtY29tcHV0ZWQgc2VydmVyIGJ1ZmZlciBzaXplIHNvIHRoYXQgaW50ZXJwcmV0ZXIgY2FuIHNraXAgYWxsCiAgICAgKiBvciBzb21lIChpZiB0aGUgZmxhZyBSUENfRkNfUFJPQ19PSTJGX1NSVk1VU1RTSVpFIGlzIHNwZWNpZmllZCkgb2YgdGhlCiAgICAgKiBzaXppbmcgcGFzcyAqLwogICAgdW5zaWduZWQgc2hvcnQgY29uc3RhbnRfc2VydmVyX2J1ZmZlcl9zaXplOwoKICAgIElOVEVSUFJFVEVSX09QVF9GTEFHUyBPaTJGbGFnczsKCiAgICAvKiBudW1iZXIgb2YgcGFyYW1zICovCiAgICB1bnNpZ25lZCBjaGFyIG51bWJlcl9vZl9wYXJhbXM7Cn0gTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSOwoKdHlwZWRlZiBzdHJ1Y3QgX05EUl9QQVJBTV9PSV9CQVNFVFlQRQp7CiAgICAvKiBwYXJhbWV0ZXIgZGlyZWN0aW9uLiBPbmUgb2Y6CiAgICAgKiBGQ19JTl9QQVJBTV9CQVNFVFlQRSA9IDB4NGUgLSBhbiBpbiBwYXJhbQogICAgICogRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFID0gMHg1MyAtIGEgcmV0dXJuIHBhcmFtCiAgICAgKi8KICAgIHVuc2lnbmVkIGNoYXIgcGFyYW1fZGlyZWN0aW9uOwoKICAgIC8qIE9uZSBvZjogRkNfQllURSxGQ19DSEFSLEZDX1NNQUxMLEZDX1VTTUFMTCxGQ19XQ0hBUixGQ19TSE9SVCxGQ19VU0hPUlQsCiAgICAgKiBGQ19MT05HLEZDX1VMT05HLEZDX0ZMT0FULEZDX0hZUEVSLEZDX0RPVUJMRSxGQ19FTlVNMTYsRkNfRU5VTTMyLAogICAgICogRkNfRVJST1JfU1RBVFVTX1QsRkNfSU5UMzI2NCxGQ19VSU5UMzI2NCAqLwogICAgdW5zaWduZWQgY2hhciB0eXBlX2Zvcm1hdF9jaGFyOwp9IE5EUl9QQVJBTV9PSV9CQVNFVFlQRTsKCnR5cGVkZWYgc3RydWN0IF9ORFJfUEFSQU1fT0lfT1RIRVIKewogICAgLyogT25lIG9mOgogICAgICogRkNfSU5fUEFSQU0gPSAweDRkIC0gQW4gaW4gcGFyYW0KICAgICAqIEZDX0lOX09VVF9QQVJBTSA9IDB4NTAgLSBBbiBpbi9vdXQgcGFyYW0KICAgICAqIEZDX09VVF9QQVJBTSA9IDB4NTEgLSBBbiBvdXQgcGFyYW0KICAgICAqIEZDX1JFVFVSTl9QQVJBTSA9IDB4NTIgLSBBIHJldHVybiB2YWx1ZQogICAgICogRkNfSU5fUEFSQU1fTk9fRlJFRV9JTlNUID0gMHg0ZiAtIEEgcGFyYW0gZm9yIHdoaWNoIG5vIGZyZWVpbmcgaXMgZG9uZQogICAgICovCiAgICB1bnNpZ25lZCBjaGFyIHBhcmFtX2RpcmVjdGlvbjsKCiAgICAvKiBTaXplIG9mIHBhcmFtIG9uIHN0YWNrIGluIE5VTUJFUlMgT0YgSU5UUyAqLwogICAgdW5zaWduZWQgY2hhciBzdGFja19zaXplOwoKICAgIC8qIG9mZnNldCBpbiB0aGUgdHlwZSBmb3JtYXQgc3RyaW5nIHRhYmxlICovCiAgICB1bnNpZ25lZCBzaG9ydCB0eXBlX29mZnNldDsKfSBORFJfUEFSQU1fT0lfT1RIRVI7Cgp0eXBlZGVmIHN0cnVjdCBfTkRSX1BBUkFNX09JRl9CQVNFVFlQRQp7CiAgICBQQVJBTV9BVFRSSUJVVEVTIHBhcmFtX2F0dHJpYnV0ZXM7CgogICAgLyogdGhlIG9mZnNldCBvbiB0aGUgY2FsbGluZyBzdGFjayB3aGVyZSB0aGUgcGFyYW1ldGVyIGlzIGxvY2F0ZWQgKi8KICAgIHVuc2lnbmVkIHNob3J0IHN0YWNrX29mZnNldDsKCiAgICAvKiBzZWUgTkRSX1BBUkFNX09JX0JBU0VUWVBFOjp0eXBlX2Zvcm1hdF9jaGFyICovCiAgICB1bnNpZ25lZCBjaGFyIHR5cGVfZm9ybWF0X2NoYXI7CgogICAgLyogYWx3YXlzIEZDX1BBRCAqLwogICAgdW5zaWduZWQgY2hhciB1bnVzZWQ7Cn0gTkRSX1BBUkFNX09JRl9CQVNFVFlQRTsKCnR5cGVkZWYgc3RydWN0IF9ORFJfUEFSQU1fT0lGX09USEVSCnsKICAgIFBBUkFNX0FUVFJJQlVURVMgcGFyYW1fYXR0cmlidXRlczsKCiAgICAvKiBzZWUgTkRSX1BBUkFNX09JRl9CQVNFVFlQRTo6c3RhY2tfb2Zmc2V0ICovCiAgICB1bnNpZ25lZCBzaG9ydCBzdGFja19vZmZzZXQ7CgogICAgLyogb2Zmc2V0IGludG8gdGhlIHByb3ZpZGVkIHR5cGUgZm9ybWF0IHN0cmluZyB3aGVyZSB0aGUgdHlwZSBmb3IgdGhpcwogICAgICogcGFyYW1ldGVyIHN0YXJ0cyAqLwogICAgdW5zaWduZWQgc2hvcnQgdHlwZV9vZmZzZXQ7Cn0gTkRSX1BBUkFNX09JRl9PVEhFUjsKCi8qIGV4cGxpY2l0IGhhbmRsZSBkZXNjcmlwdGlvbiBmb3IgRkNfQklORF9QUklNSVRJVkUgdHlwZSAqLwp0eXBlZGVmIHN0cnVjdCBfTkRSX0VIRF9QUklNSVRJVkUKewogICAgLyogRkNfQklORF9QUklNSVRJVkUgKi8KICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CgogICAgLyogaXMgdGhlIGhhbmRsZSBwYXNzZWQgaW4gdmlhIGEgcG9pbnRlcj8gKi8KICAgIHVuc2lnbmVkIGNoYXIgZmxhZzsKCiAgICAvKiBvZmZzZXQgZnJvbSB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzdGFjayB0byB0aGUgaGFuZGxlIGluIGJ5dGVzICovCiAgICB1bnNpZ25lZCBzaG9ydCBvZmZzZXQ7Cn0gTkRSX0VIRF9QUklNSVRJVkU7CgovKiBleHBsaWNpdCBoYW5kbGUgZGVzY3JpcHRpb24gZm9yIEZDX0JJTkRfR0VORVJJQyB0eXBlICovCnR5cGVkZWYgc3RydWN0IF9ORFJfRUhEX0dFTkVSSUMKewogICAgLyogRkNfQklORF9HRU5FUklDICovCiAgICB1bnNpZ25lZCBjaGFyIGhhbmRsZV90eXBlOwoKICAgIC8qIHVwcGVyIDRiaXRzIGlzIGEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdGhlIGhhbmRsZSBpcyBwYXNzZWQgaW4KICAgICAqIHZpYSBhIHBvaW50ZXIuIGxvd2VyIDRiaXRzIGlzIHRoZSBzaXplIG9mIHRoZSB1c2VyIGRlZmluZWQgZ2VuZXJpYwogICAgICogaGFuZGxlIHR5cGUuIHRoZSBzaXplIG11c3QgYmUgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIHRoZSBtYWNoaW5lCiAgICAgKiByZWdpc3RlciBzaXplICovCiAgICB1bnNpZ25lZCBjaGFyIGZsYWdfYW5kX3NpemU7CgogICAgLyogb2Zmc2V0IGZyb20gdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RhY2sgdG8gdGhlIGhhbmRsZSBpbiBieXRlcyAqLwogICAgdW5zaWduZWQgc2hvcnQgb2Zmc2V0OwoKICAgIC8qIHRoZSBpbmRleCBpbnRvIHRoZSBhR2VuZXJpY0JpbmRpbmdSb3V0aW5lc1BhaXJzIGZpZWxkIG9mIE1JRExfU1RVQl9ERVNDCiAgICAgKiBnaXZpbmcgdGhlIGJpbmQgYW5kIHVuYmluZCByb3V0aW5lcyBmb3IgdGhlIGhhbmRsZSAqLwogICAgdW5zaWduZWQgY2hhciBiaW5kaW5nX3JvdXRpbmVfcGFpcl9pbmRleDsKCiAgICAvKiBGQ19QQUQgKi8KICAgIHVuc2lnbmVkIGNoYXIgdW51c2VkOwp9IE5EUl9FSERfR0VORVJJQzsKCi8qIGV4cGxpY2l0IGhhbmRsZSBkZXNjcmlwdGlvbiBmb3IgRkNfQklORF9DT05URVhUIHR5cGUgKi8KdHlwZWRlZiBzdHJ1Y3QgX05EUl9FSERfQ09OVEVYVAp7CiAgICAvKiBGQ19CSU5EX0NPTlRFWFQgKi8KICAgIHVuc2lnbmVkIGNoYXIgaGFuZGxlX3R5cGU7CgogICAgLyogQW55IG9mIHRoZSBmb2xsb3dpbmcgZmxhZ3M6CiAgICAgKiBORFJfQ09OVEVYVF9IQU5ETEVfQ0FOTk9UX0JFX05VTEwgPSAweDAxCiAgICAgKiBORFJfQ09OVEVYVF9IQU5ETEVfU0VSSUFMSVpFID0gMHgwMgogICAgICogTkRSX0NPTlRFWFRfSEFORExFX05PX1NFUklBTElaRSA9IDB4MDQKICAgICAqIE5EUl9TVFJJQ1RfQ09OVEVYVF9IQU5ETEUgPSAweDA4CiAgICAgKiBIQU5ETEVfUEFSQU1fSVNfT1VUID0gMHgyMAogICAgICogSEFORExFX1BBUkFNX0lTX1JFVFVSTiA9IDB4MjEKICAgICAqIEhBTkRMRV9QQVJBTV9JU19JTiA9IDB4NDAKICAgICAqIEhBTkRMRV9QQVJBTV9JU19WSUFfUFRSID0gMHg4MAogICAgICovCiAgICB1bnNpZ25lZCBjaGFyIGZsYWdzOwoKICAgIC8qIG9mZnNldCBmcm9tIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHN0YWNrIHRvIHRoZSBoYW5kbGUgaW4gYnl0ZXMgKi8KICAgIHVuc2lnbmVkIHNob3J0IG9mZnNldDsKCiAgICAvKiB6ZXJvLWJhc2VkIGluZGV4IG9uIHJ1bmRvd24gcm91dGluZSBpbiBhcGZuTmRyUnVuZG93blJvdXRpbmVzIGZpZWxkCiAgICAgKiBvZiBNSURMX1NUVUJfREVTQyAqLwogICAgdW5zaWduZWQgY2hhciBjb250ZXh0X3J1bmRvd25fcm91dGluZV9pbmRleDsKCiAgICAvKiB2YXJpZXMgZGVwZW5kaW5nIG9uIE5EUiB2ZXJzaW9uIHVzZWQuCiAgICAgKiBWMTogemVyby1iYXNlZCBpbmRleCBpbnRvIHBhcmFtZXRlcnMgCiAgICAgKiBWMjogemVyby1iYXNlZCBpbmRleCBpbnRvIGhhbmRsZXMgdGhhdCBhcmUgcGFyYW1ldGVycyAqLwogICAgdW5zaWduZWQgY2hhciBwYXJhbV9udW07Cn0gTkRSX0VIRF9DT05URVhUOwoKI2luY2x1ZGUgInBvcHBhY2suaCIKCnZvaWQgV0lOQVBJIE5kclJwY1NtU2V0Q2xpZW50VG9Pc2YoUE1JRExfU1RVQl9NRVNTQUdFIHBNZXNzYWdlKQp7CiNpZiAwIC8qIHRoZXNlIGZ1bmN0aW9ucyBhcmUgbm90IGRlZmluZWQgeWV0ICovCiAgICBwTWVzc2FnZS0+cGZuQWxsb2NhdGUgPSBOZHJScGNTbUNsaWVudEFsbG9jYXRlOwogICAgcE1lc3NhZ2UtPnBmbkZyZWUgPSBOZHJScGNTbUNsaWVudEZyZWU7CiNlbmRpZgp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgZHVtcF9SUENfRkNfUFJPQ19QRihQQVJBTV9BVFRSSUJVVEVTIHBhcmFtX2F0dHJpYnV0ZXMpCnsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLk11c3RTaXplKSBUUkFDRSgiIE11c3RTaXplIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5NdXN0RnJlZSkgVFJBQ0UoIiBNdXN0RnJlZSIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNQaXBlKSBUUkFDRSgiIElzUGlwZSIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNJbikgVFJBQ0UoIiBJc0luIik7CiAgICBpZiAocGFyYW1fYXR0cmlidXRlcy5Jc091dCkgVFJBQ0UoIiBJc091dCIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pIFRSQUNFKCIgSXNSZXR1cm4iKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLklzQmFzZXR5cGUpIFRSQUNFKCIgSXNCYXNldHlwZSIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKSBUUkFDRSgiIElzQnlWYWx1ZSIpOwogICAgaWYgKHBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpIFRSQUNFKCIgSXNTaW1wbGVSZWYiKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLklzRG9udENhbGxGcmVlSW5zdCkgVFJBQ0UoIiBJc0RvbnRDYWxsRnJlZUluc3QiKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLlNhdmVGb3JBc3luY0ZpbmlzaCkgVFJBQ0UoIiBTYXZlRm9yQXN5bmNGaW5pc2giKTsKICAgIGlmIChwYXJhbV9hdHRyaWJ1dGVzLlNlcnZlckFsbG9jU2l6ZSkgVFJBQ0UoIiBTZXJ2ZXJBbGxvY1NpemUgPSAlZCIsIHBhcmFtX2F0dHJpYnV0ZXMuU2VydmVyQWxsb2NTaXplICogOCk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBkdW1wX0lOVEVSUFJFVEVSX09QVF9GTEFHUyhJTlRFUlBSRVRFUl9PUFRfRkxBR1MgT2kyRmxhZ3MpCnsKICAgIGlmIChPaTJGbGFncy5TZXJ2ZXJNdXN0U2l6ZSkgVFJBQ0UoIiBTZXJ2ZXJNdXN0U2l6ZSIpOwogICAgaWYgKE9pMkZsYWdzLkNsaWVudE11c3RTaXplKSBUUkFDRSgiIENsaWVudE11c3RTaXplIik7CiAgICBpZiAoT2kyRmxhZ3MuSGFzUmV0dXJuKSBUUkFDRSgiIEhhc1JldHVybiIpOwogICAgaWYgKE9pMkZsYWdzLkhhc1BpcGVzKSBUUkFDRSgiIEhhc1BpcGVzIik7CiAgICBpZiAoT2kyRmxhZ3MuVW51c2VkKSBUUkFDRSgiIFVudXNlZCIpOwogICAgaWYgKE9pMkZsYWdzLkhhc0FzeW5jVXVpZCkgVFJBQ0UoIiBIYXNBc3luY1V1aWQiKTsKICAgIGlmIChPaTJGbGFncy5IYXNFeHRlbnNpb25zKSBUUkFDRSgiIEhhc0V4dGVuc2lvbnMiKTsKICAgIGlmIChPaTJGbGFncy5IYXNBc3luY0hhbmRsZSkgVFJBQ0UoIiBIYXNBc3luY0hhbmRsZSIpOwogICAgVFJBQ0UoIlxuIik7Cn0KCiNkZWZpbmUgQVJHX0ZST01fT0ZGU0VUKHN0dWJNc2csIG9mZnNldCkgKChzdHViTXNnKS5TdGFja1RvcCArIChvZmZzZXQpKQoKc3RhdGljIFBGT1JNQVRfU1RSSU5HIGNsaWVudF9nZXRfaGFuZGxlKAogICAgUE1JRExfU1RVQl9NRVNTQUdFIHBTdHViTXNnLCBjb25zdCBORFJfUFJPQ19IRUFERVIgKnBQcm9jSGVhZGVyLAogICAgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdCwgaGFuZGxlX3QgKnBoQmluZGluZykKewogICAgLyogYmluZGluZyAqLwogICAgc3dpdGNoIChwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpCiAgICB7CiAgICAvKiBleHBsaWNpdCBiaW5kaW5nOiBwYXJzZSBhZGRpdGlvbmFsIHNlY3Rpb24gKi8KICAgIGNhc2UgUlBDX0ZDX0JJTkRfRVhQTElDSVQ6CiAgICAgICAgc3dpdGNoICgqcEZvcm1hdCkgLyogaGFuZGxlX3R5cGUgKi8KICAgICAgICB7CiAgICAgICAgY2FzZSBSUENfRkNfQklORF9QUklNSVRJVkU6IC8qIGV4cGxpY2l0IHByaW1pdGl2ZSAqLwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb25zdCBORFJfRUhEX1BSSU1JVElWRSAqcERlc2MgPSAoY29uc3QgTkRSX0VIRF9QUklNSVRJVkUgKilwRm9ybWF0OwoKICAgICAgICAgICAgICAgIFRSQUNFKCJFeHBsaWNpdCBwcmltaXRpdmUgaGFuZGxlIEAgJWRcbiIsIHBEZXNjLT5vZmZzZXQpOwoKICAgICAgICAgICAgICAgIGlmIChwRGVzYy0+ZmxhZykgLyogcG9pbnRlciB0byBiaW5kaW5nICovCiAgICAgICAgICAgICAgICAgICAgKnBoQmluZGluZyA9ICoqKGhhbmRsZV90ICoqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICpwaEJpbmRpbmcgPSAqKGhhbmRsZV90ICopQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgcERlc2MtPm9mZnNldCk7CiAgICAgICAgICAgICAgICByZXR1cm4gcEZvcm1hdCArIHNpemVvZihORFJfRUhEX1BSSU1JVElWRSk7CiAgICAgICAgICAgIH0KICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0dFTkVSSUM6IC8qIGV4cGxpY2l0IGdlbmVyaWMgKi8KICAgICAgICAgICAgewogICAgICAgICAgICAgICAgY29uc3QgTkRSX0VIRF9HRU5FUklDICpwRGVzYyA9IChjb25zdCBORFJfRUhEX0dFTkVSSUMgKilwRm9ybWF0OwogICAgICAgICAgICAgICAgdm9pZCAqcE9iamVjdCA9IE5VTEw7CiAgICAgICAgICAgICAgICB2b2lkICpwQXJnOwogICAgICAgICAgICAgICAgY29uc3QgR0VORVJJQ19CSU5ESU5HX1JPVVRJTkVfUEFJUiAqcEdlblBhaXI7CgogICAgICAgICAgICAgICAgVFJBQ0UoIkV4cGxpY2l0IGdlbmVyaWMgYmluZGluZyBoYW5kbGUgIyVkXG4iLCBwRGVzYy0+YmluZGluZ19yb3V0aW5lX3BhaXJfaW5kZXgpOwoKICAgICAgICAgICAgICAgIGlmIChwRGVzYy0+ZmxhZ19hbmRfc2l6ZSAmIEhBTkRMRV9QQVJBTV9JU19WSUFfUFRSKQogICAgICAgICAgICAgICAgICAgIHBBcmcgPSAqKHZvaWQgKiopQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgcERlc2MtPm9mZnNldCk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgcEFyZyA9ICh2b2lkICopQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgcERlc2MtPm9mZnNldCk7CiAgICAgICAgICAgICAgICBtZW1jcHkoJnBPYmplY3QsIHBBcmcsIHBEZXNjLT5mbGFnX2FuZF9zaXplICYgMHhmKTsKICAgICAgICAgICAgICAgIHBHZW5QYWlyID0gJnBTdHViTXNnLT5TdHViRGVzYy0+YUdlbmVyaWNCaW5kaW5nUm91dGluZVBhaXJzW3BEZXNjLT5iaW5kaW5nX3JvdXRpbmVfcGFpcl9pbmRleF07CiAgICAgICAgICAgICAgICAqcGhCaW5kaW5nID0gcEdlblBhaXItPnBmbkJpbmQocE9iamVjdCk7CiAgICAgICAgICAgICAgICByZXR1cm4gcEZvcm1hdCArIHNpemVvZihORFJfRUhEX0dFTkVSSUMpOwogICAgICAgICAgICB9CiAgICAgICAgY2FzZSBSUENfRkNfQklORF9DT05URVhUOiAvKiBleHBsaWNpdCBjb250ZXh0ICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IE5EUl9FSERfQ09OVEVYVCAqcERlc2MgPSAoY29uc3QgTkRSX0VIRF9DT05URVhUICopcEZvcm1hdDsKICAgICAgICAgICAgICAgIE5EUl9DQ09OVEVYVCBjb250ZXh0X2hhbmRsZTsKICAgICAgICAgICAgICAgIFRSQUNFKCJFeHBsaWNpdCBiaW5kIGNvbnRleHRcbiIpOwogICAgICAgICAgICAgICAgaWYgKHBEZXNjLT5mbGFncyAmIEhBTkRMRV9QQVJBTV9JU19WSUFfUFRSKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdEhBTkRMRV9QQVJBTV9JU19WSUFfUFRSXG4iKTsKICAgICAgICAgICAgICAgICAgICBjb250ZXh0X2hhbmRsZSA9ICoqKE5EUl9DQ09OVEVYVCAqKilBUkdfRlJPTV9PRkZTRVQoKnBTdHViTXNnLCBwRGVzYy0+b2Zmc2V0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBjb250ZXh0X2hhbmRsZSA9ICooTkRSX0NDT05URVhUICopQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgcERlc2MtPm9mZnNldCk7CiAgICAgICAgICAgICAgICBpZiAoKHBEZXNjLT5mbGFncyAmIE5EUl9DT05URVhUX0hBTkRMRV9DQU5OT1RfQkVfTlVMTCkgJiYKICAgICAgICAgICAgICAgICAgICAhY29udGV4dF9oYW5kbGUpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgRVJSKCJudWxsIGNvbnRleHQgaGFuZGxlIGlzbid0IGFsbG93ZWRcbiIpOwogICAgICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX1NTX0lOX05VTExfQ09OVEVYVCk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAqcGhCaW5kaW5nID0gTkRSQ0NvbnRleHRCaW5kaW5nKGNvbnRleHRfaGFuZGxlKTsKICAgICAgICAgICAgICAgIC8qIEZJWE1FOiBzaG91bGQgd2Ugc3RvcmUgdGhpcyBzdHJ1Y3R1cmUgaW4gc3R1Yk1zZy5wQ29udGV4dD8gKi8KICAgICAgICAgICAgICAgIHJldHVybiBwRm9ybWF0ICsgc2l6ZW9mKE5EUl9FSERfQ09OVEVYVCk7CiAgICAgICAgICAgIH0KICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoImJhZCBleHBsaWNpdCBiaW5kaW5nIGhhbmRsZSB0eXBlICgweCUwMngpXG4iLCBwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpOwogICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFJQQ19GQ19CSU5EX0dFTkVSSUM6IC8qIGltcGxpY2l0IGdlbmVyaWMgKi8KICAgICAgICBGSVhNRSgiUlBDX0ZDX0JJTkRfR0VORVJJQ1xuIik7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7IC8qIEZJWE1FOiByZW1vdmUgd2hlbiBpbXBsZW1lbnRlZCAqLwogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfQklORF9QUklNSVRJVkU6IC8qIGltcGxpY2l0IHByaW1pdGl2ZSAqLwogICAgICAgIFRSQUNFKCJJbXBsaWNpdCBwcmltaXRpdmUgaGFuZGxlXG4iKTsKICAgICAgICAqcGhCaW5kaW5nID0gKnBTdHViTXNnLT5TdHViRGVzYy0+SU1QTElDSVRfSEFORExFX0lORk8ucFByaW1pdGl2ZUhhbmRsZTsKICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0NBTExCQUNLX0hBTkRMRTogLyogaW1wbGljaXQgY2FsbGJhY2sgKi8KICAgICAgICBGSVhNRSgiUlBDX0ZDX0NBTExCQUNLX0hBTkRMRVxuIik7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFJQQ19GQ19BVVRPX0hBTkRMRTogLyogaW1wbGljaXQgYXV0byBoYW5kbGUgKi8KICAgICAgICAvKiBzdHJpY3RseSBzcGVha2luZywgaXQgaXNuJ3QgbmVjZXNzYXJ5IHRvIHNldCBoQmluZGluZyBoZXJlCiAgICAgICAgICogc2luY2UgaXQgaXNuJ3QgYWN0dWFsbHkgdXNlZCAoaGVuY2UgdGhlIGF1dG9tYXRpYyBpbiBpdHMgbmFtZSksCiAgICAgICAgICogYnV0IHRoZW4gd2h5IGRvZXMgTUlETCBnZW5lcmF0ZSBhIHZhbGlkIGVudHJ5IGluIHRoZQogICAgICAgICAqIE1JRExfU1RVQl9ERVNDIGZvciBpdD8gKi8KICAgICAgICBUUkFDRSgiSW1wbGljaXQgYXV0byBoYW5kbGVcbiIpOwogICAgICAgICpwaEJpbmRpbmcgPSAqcFN0dWJNc2ctPlN0dWJEZXNjLT5JTVBMSUNJVF9IQU5ETEVfSU5GTy5wQXV0b0hhbmRsZTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgRVJSKCJiYWQgaW1wbGljaXQgYmluZGluZyBoYW5kbGUgdHlwZSAoMHglMDJ4KVxuIiwgcFByb2NIZWFkZXItPmhhbmRsZV90eXBlKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9CQURfU1RVQl9EQVRBKTsKICAgIH0KICAgIHJldHVybiBwRm9ybWF0Owp9CgpzdGF0aWMgdm9pZCBjbGllbnRfZnJlZV9oYW5kbGUoCiAgICBQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIGNvbnN0IE5EUl9QUk9DX0hFQURFUiAqcFByb2NIZWFkZXIsCiAgICBQRk9STUFUX1NUUklORyBwRm9ybWF0LCBoYW5kbGVfdCBoQmluZGluZykKewogICAgLyogYmluZGluZyAqLwogICAgc3dpdGNoIChwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpCiAgICB7CiAgICAvKiBleHBsaWNpdCBiaW5kaW5nOiBwYXJzZSBhZGRpdGlvbmFsIHNlY3Rpb24gKi8KICAgIGNhc2UgUlBDX0ZDX0JJTkRfRVhQTElDSVQ6CiAgICAgICAgc3dpdGNoICgqcEZvcm1hdCkgLyogaGFuZGxlX3R5cGUgKi8KICAgICAgICB7CiAgICAgICAgY2FzZSBSUENfRkNfQklORF9HRU5FUklDOiAvKiBleHBsaWNpdCBnZW5lcmljICovCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNvbnN0IE5EUl9FSERfR0VORVJJQyAqcERlc2MgPSAoY29uc3QgTkRSX0VIRF9HRU5FUklDICopcEZvcm1hdDsKICAgICAgICAgICAgICAgIHZvaWQgKnBPYmplY3QgPSBOVUxMOwogICAgICAgICAgICAgICAgdm9pZCAqcEFyZzsKICAgICAgICAgICAgICAgIGNvbnN0IEdFTkVSSUNfQklORElOR19ST1VUSU5FX1BBSVIgKnBHZW5QYWlyOwoKICAgICAgICAgICAgICAgIFRSQUNFKCJFeHBsaWNpdCBnZW5lcmljIGJpbmRpbmcgaGFuZGxlICMlZFxuIiwgcERlc2MtPmJpbmRpbmdfcm91dGluZV9wYWlyX2luZGV4KTsKCiAgICAgICAgICAgICAgICBpZiAocERlc2MtPmZsYWdfYW5kX3NpemUgJiBIQU5ETEVfUEFSQU1fSVNfVklBX1BUUikKICAgICAgICAgICAgICAgICAgICBwQXJnID0gKih2b2lkICoqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHBBcmcgPSAodm9pZCAqKUFSR19GUk9NX09GRlNFVCgqcFN0dWJNc2csIHBEZXNjLT5vZmZzZXQpOwogICAgICAgICAgICAgICAgbWVtY3B5KCZwT2JqZWN0LCBwQXJnLCBwRGVzYy0+ZmxhZ19hbmRfc2l6ZSAmIDB4Zik7CiAgICAgICAgICAgICAgICBwR2VuUGFpciA9ICZwU3R1Yk1zZy0+U3R1YkRlc2MtPmFHZW5lcmljQmluZGluZ1JvdXRpbmVQYWlyc1twRGVzYy0+YmluZGluZ19yb3V0aW5lX3BhaXJfaW5kZXhdOwogICAgICAgICAgICAgICAgcEdlblBhaXItPnBmblVuYmluZChwT2JqZWN0LCBoQmluZGluZyk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfQ09OVEVYVDogLyogZXhwbGljaXQgY29udGV4dCAqLwogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfUFJJTUlUSVZFOiAvKiBleHBsaWNpdCBwcmltaXRpdmUgKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRVJSKCJiYWQgZXhwbGljaXQgYmluZGluZyBoYW5kbGUgdHlwZSAoMHglMDJ4KVxuIiwgcFByb2NIZWFkZXItPmhhbmRsZV90eXBlKTsKICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgY2FzZSBSUENfRkNfQklORF9HRU5FUklDOiAvKiBpbXBsaWNpdCBnZW5lcmljICovCiAgICAgICAgRklYTUUoIlJQQ19GQ19CSU5EX0dFTkVSSUNcbiIpOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOyAvKiBGSVhNRTogcmVtb3ZlIHdoZW4gaW1wbGVtZW50ZWQgKi8KICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0NBTExCQUNLX0hBTkRMRTogLyogaW1wbGljaXQgY2FsbGJhY2sgKi8KICAgIGNhc2UgUlBDX0ZDX0JJTkRfUFJJTUlUSVZFOiAvKiBpbXBsaWNpdCBwcmltaXRpdmUgKi8KICAgIGNhc2UgUlBDX0ZDX0FVVE9fSEFORExFOiAvKiBpbXBsaWNpdCBhdXRvIGhhbmRsZSAqLwogICAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgICBFUlIoImJhZCBpbXBsaWNpdCBiaW5kaW5nIGhhbmRsZSB0eXBlICgweCUwMngpXG4iLCBwUHJvY0hlYWRlci0+aGFuZGxlX3R5cGUpOwogICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBjbGllbnRfZG9fYXJncyhQTUlETF9TVFVCX01FU1NBR0UgcFN0dWJNc2csIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQsCiAgICBpbnQgcGhhc2UsIHVuc2lnbmVkIHNob3J0IG51bWJlcl9vZl9wYXJhbXMsIHVuc2lnbmVkIGNoYXIgKnBSZXRWYWwpCnsKICAgIC8qIGN1cnJlbnQgZm9ybWF0IHN0cmluZyBvZmZzZXQgKi8KICAgIGludCBjdXJyZW50X29mZnNldCA9IDA7CiAgICAvKiBjdXJyZW50IHN0YWNrIG9mZnNldCAqLwogICAgdW5zaWduZWQgc2hvcnQgY3VycmVudF9zdGFja19vZmZzZXQgPSAwOwogICAgLyogY291bnRlciAqLwogICAgdW5zaWduZWQgc2hvcnQgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgbnVtYmVyX29mX3BhcmFtczsgaSsrKQogICAgewogICAgICAgIGNvbnN0IE5EUl9QQVJBTV9PSUZfQkFTRVRZUEUgKnBQYXJhbSA9CiAgICAgICAgICAgIChjb25zdCBORFJfUEFSQU1fT0lGX0JBU0VUWVBFICopJnBGb3JtYXRbY3VycmVudF9vZmZzZXRdOwogICAgICAgIHVuc2lnbmVkIGNoYXIgKiBwQXJnOwoKICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCA9IHBQYXJhbS0+c3RhY2tfb2Zmc2V0OwogICAgICAgIHBBcmcgPSBBUkdfRlJPTV9PRkZTRVQoKnBTdHViTXNnLCBjdXJyZW50X3N0YWNrX29mZnNldCk7CgogICAgICAgIFRSQUNFKCJwYXJhbVslZF06IG5ldyBmb3JtYXRcbiIsIGkpOwogICAgICAgIFRSQUNFKCJcdHBhcmFtX2F0dHJpYnV0ZXM6Iik7IGR1bXBfUlBDX0ZDX1BST0NfUEYocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzKTsgVFJBQ0UoIlxuIik7CiAgICAgICAgVFJBQ0UoIlx0c3RhY2tfb2Zmc2V0OiAweCV4XG4iLCBjdXJyZW50X3N0YWNrX29mZnNldCk7CiAgICAgICAgVFJBQ0UoIlx0bWVtb3J5IGFkZHIgKGJlZm9yZSk6ICVwXG4iLCBwQXJnKTsKCiAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0Jhc2V0eXBlKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqIHBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICZwUGFyYW0tPnR5cGVfZm9ybWF0X2NoYXI7CgogICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzU2ltcGxlUmVmKQogICAgICAgICAgICAgICAgcEFyZyA9ICoodW5zaWduZWQgY2hhciAqKilwQXJnOwoKICAgICAgICAgICAgVFJBQ0UoIlx0YmFzZSB0eXBlOiAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIocFN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBST1hZX01BUlNIQUw6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzSW4pCiAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKHBTdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQUk9YWV9VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzT3V0KQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKHBTdHViTXNnLCAmcFJldFZhbCwgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIocFN0dWJNc2csICZwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInBSZXRWYWwgPSAlcFxuIiwgcFJldFZhbCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSUZfQkFTRVRZUEUpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBjb25zdCBORFJfUEFSQU1fT0lGX09USEVSICpwUGFyYW1PdGhlciA9CiAgICAgICAgICAgICAgICAoY29uc3QgTkRSX1BBUkFNX09JRl9PVEhFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAmKHBTdHViTXNnLT5TdHViRGVzYy0+cEZvcm1hdFR5cGVzW3BQYXJhbU90aGVyLT50eXBlX29mZnNldF0pOwoKICAgICAgICAgICAgLyogaWYgYSBzaW1wbGUgcmVmIHBvaW50ZXIgdGhlbiB3ZSBoYXZlIHRvIGRvIHRoZQogICAgICAgICAgICAgKiBjaGVjayBmb3IgdGhlIHBvaW50ZXIgYmVpbmcgbm9uLU5VTEwuICovCiAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICghKih1bnNpZ25lZCBjaGFyICoqKXBBcmcpCiAgICAgICAgICAgICAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfTlVMTF9SRUZfUE9JTlRFUik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIFRSQUNFKCJcdGNvbXBsZXggdHlwZTogMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIFBST1hZX0NBTENTSVpFOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0luKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcihwU3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIocFN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQUk9YWV9NQVJTSEFMOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0luKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIocFN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcihwU3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBST1hZX1VOTUFSU0hBTDoKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNPdXQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIocFN0dWJNc2csICZwUmV0VmFsLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzQnlWYWx1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIocFN0dWJNc2csICZwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfU19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUEFSQU1fT0lGX09USEVSKTsKICAgICAgICB9CiAgICAgICAgVFJBQ0UoIlx0bWVtb3J5IGFkZHIgKGFmdGVyKTogJXBcbiIsIHBBcmcpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBjbGllbnRfZG9fYXJnc19vbGRfZm9ybWF0KFBNSURMX1NUVUJfTUVTU0FHRSBwU3R1Yk1zZywKICAgIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQsIGludCBwaGFzZSwgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZSwKICAgIHVuc2lnbmVkIGNoYXIgKnBSZXRWYWwsIEJPT0wgb2JqZWN0X3Byb2MpCnsKICAgIC8qIGN1cnJlbnQgZm9ybWF0IHN0cmluZyBvZmZzZXQgKi8KICAgIGludCBjdXJyZW50X29mZnNldCA9IDA7CiAgICAvKiBjdXJyZW50IHN0YWNrIG9mZnNldCAqLwogICAgdW5zaWduZWQgc2hvcnQgY3VycmVudF9zdGFja19vZmZzZXQgPSAwOwogICAgLyogY291bnRlciAqLwogICAgdW5zaWduZWQgc2hvcnQgaTsKCiAgICAvKiBOT1RFOiBWMSBzdHlsZSBmb3JtYXQgZG9lcyd0IHRlcm1pbmF0ZSBvbiB0aGUgbnVtYmVyX29mX3BhcmFtcwogICAgICogY29uZGl0aW9uIGFzIGl0IGRvZXNuJ3QgaGF2ZSB0aGlzIGF0dHJpYnV0ZS4gSW5zdGVhZCBpdAogICAgICogdGVybWluYXRlcyB3aGVuIHRoZSBzdGFjayBzaXplIGdpdmVuIGluIHRoZSBoZWFkZXIgaXMgZXhjZWVkZWQuCiAgICAgKi8KICAgIGZvciAoaSA9IDA7IFRSVUU7IGkrKykKICAgIHsKICAgICAgICBjb25zdCBORFJfUEFSQU1fT0lfQkFTRVRZUEUgKnBQYXJhbSA9CiAgICAgICAgICAgIChjb25zdCBORFJfUEFSQU1fT0lfQkFTRVRZUEUgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CiAgICAgICAgLyogbm90ZTogY3VycmVudF9zdGFja19vZmZzZXQgc3RhcnRzIGFmdGVyIHRoZSBUaGlzIHBvaW50ZXIKICAgICAgICAgKiBpZiBwcmVzZW50LCBzbyBhZGp1c3QgdGhpcyAqLwogICAgICAgIHVuc2lnbmVkIHNob3J0IGN1cnJlbnRfc3RhY2tfb2Zmc2V0X2FkanVzdGVkID0gY3VycmVudF9zdGFja19vZmZzZXQgKwogICAgICAgICAgICAob2JqZWN0X3Byb2MgPyBzaXplb2Yodm9pZCAqKSA6IDApOwogICAgICAgIHVuc2lnbmVkIGNoYXIgKiBwQXJnID0gQVJHX0ZST01fT0ZGU0VUKCpwU3R1Yk1zZywgY3VycmVudF9zdGFja19vZmZzZXRfYWRqdXN0ZWQpOwoKICAgICAgICAvKiBubyBtb3JlIHBhcmFtZXRlcnM7IGV4aXQgbG9vcCAqLwogICAgICAgIGlmIChjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCA+PSBzdGFja19zaXplKQogICAgICAgICAgICBicmVhazsKCiAgICAgICAgVFJBQ0UoInBhcmFtWyVkXTogb2xkIGZvcm1hdFxuIiwgaSk7CiAgICAgICAgVFJBQ0UoIlx0cGFyYW1fZGlyZWN0aW9uOiAweCV4XG4iLCBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbik7CiAgICAgICAgVFJBQ0UoIlx0c3RhY2tfb2Zmc2V0OiAweCV4XG4iLCBjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCk7CiAgICAgICAgVFJBQ0UoIlx0bWVtb3J5IGFkZHIgKGJlZm9yZSk6ICVwXG4iLCBwQXJnKTsKCiAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTV9CQVNFVFlQRSB8fAogICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgIHsKICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqIHBUeXBlRm9ybWF0ID0KICAgICAgICAgICAgICAgICZwUGFyYW0tPnR5cGVfZm9ybWF0X2NoYXI7CgogICAgICAgICAgICBUUkFDRSgiXHRiYXNlIHR5cGUgMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgewogICAgICAgICAgICBjYXNlIFBST1hZX0NBTENTSVpFOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcihwU3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfTUFSU0hBTDoKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKHBTdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQUk9YWV9VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX1JFVFVSTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gJiBSUENfRkNfUkVUVVJOX1BBUkFNKQogICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcihwU3R1Yk1zZywgKHVuc2lnbmVkIGNoYXIgKiopcFJldFZhbCwgcFR5cGVGb3JtYXQsIDApOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIocFN0dWJNc2csICZwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgKz0gY2FsbF9tZW1vcnlfc2l6ZXIocFN0dWJNc2csIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSV9CQVNFVFlQRSk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGNvbnN0IE5EUl9QQVJBTV9PSV9PVEhFUiAqcFBhcmFtT3RoZXIgPSAKICAgICAgICAgICAgICAgIChjb25zdCBORFJfUEFSQU1fT0lfT1RIRVIgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CgogICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyICpwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAmcFN0dWJNc2ctPlN0dWJEZXNjLT5wRm9ybWF0VHlwZXNbcFBhcmFtT3RoZXItPnR5cGVfb2Zmc2V0XTsKCiAgICAgICAgICAgIFRSQUNFKCJcdGNvbXBsZXggdHlwZSAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICB7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gJiBSUENfRkNfSU5fT1VUX1BBUkFNKQogICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKHBTdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfTUFSU0hBTDoKICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU0gfHwKICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiAmIFJQQ19GQ19JTl9PVVRfUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKHBTdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUFJPWFlfVU5NQVJTSEFMOgogICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9PVVRfUEFSQU0gfHwKICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfT1VUX1BBUkFNKQogICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKHBTdHViTXNnLCAodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNKQogICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKHBTdHViTXNnLCAodW5zaWduZWQgY2hhciAqKilwUmV0VmFsLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgKz0gcFBhcmFtT3RoZXItPnN0YWNrX3NpemUgKiBzaXplb2YoSU5UKTsKICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSV9PVEhFUik7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJcdG1lbW9yeSBhZGRyIChhZnRlcik6ICVwXG4iLCBwQXJnKTsKICAgIH0KfQoKLyogdGhlIHJldHVybiB0eXBlIHNob3VsZCBiZSBDTElFTlRfQ0FMTF9SRVRVUk4sIGJ1dCB0aGlzIGlzIGluY29tcGF0aWJsZQogKiB3aXRoIHRoZSB3YXkgZ2NjIHJldHVybnMgc3RydWN0dXJlcy4gInZvaWQgKiIgc2hvdWxkIGJlIHRoZSBsYXJnZXN0IHR5cGUKICogdGhhdCBNSURMIHNob3VsZCBhbGxvdyB5b3UgdG8gcmV0dXJuIGFueXdheSAqLwpMT05HX1BUUiBXSU5BUElWIE5kckNsaWVudENhbGwyKFBNSURMX1NUVUJfREVTQyBwU3R1YkRlc2MsIFBGT1JNQVRfU1RSSU5HIHBGb3JtYXQsIC4uLikKewogICAgLyogcG9pbnRlciB0byBzdGFydCBvZiBzdGFjayB3aGVyZSBhcmd1bWVudHMgc3RhcnQgKi8KICAgIFJQQ19NRVNTQUdFIHJwY01zZzsKICAgIE1JRExfU1RVQl9NRVNTQUdFIHN0dWJNc2c7CiAgICBoYW5kbGVfdCBoQmluZGluZyA9IE5VTEw7CiAgICAvKiBwcm9jZWR1cmUgbnVtYmVyICovCiAgICB1bnNpZ25lZCBzaG9ydCBwcm9jZWR1cmVfbnVtYmVyOwogICAgLyogc2l6ZSBvZiBzdGFjayAqLwogICAgdW5zaWduZWQgc2hvcnQgc3RhY2tfc2l6ZTsKICAgIC8qIG51bWJlciBvZiBwYXJhbWV0ZXJzLiBvcHRpb25hbCBmb3IgY2xpZW50IHRvIGdpdmUgaXQgdG8gdXMgKi8KICAgIHVuc2lnbmVkIGNoYXIgbnVtYmVyX29mX3BhcmFtcyA9IH4wOwogICAgLyogY2FjaGUgb2YgT2lmX2ZsYWdzIGZyb20gdjIgcHJvY2VkdXJlIGhlYWRlciAqLwogICAgSU5URVJQUkVURVJfT1BUX0ZMQUdTIE9pZl9mbGFncyA9IHsgMCB9OwogICAgLyogY2FjaGUgb2YgZXh0ZW5zaW9uIGZsYWdzIGZyb20gTkRSX1BST0NfSEVBREVSX0VYVFMgKi8KICAgIElOVEVSUFJFVEVSX09QVF9GTEFHUzIgZXh0X2ZsYWdzID0geyAwIH07CiAgICAvKiB0aGUgdHlwZSBvZiBwYXNzIHdlIGFyZSBjdXJyZW50bHkgZG9pbmcgKi8KICAgIGludCBwaGFzZTsKICAgIC8qIGhlYWRlciBmb3IgcHJvY2VkdXJlIHN0cmluZyAqLwogICAgY29uc3QgTkRSX1BST0NfSEVBREVSICogcFByb2NIZWFkZXIgPSAoY29uc3QgTkRSX1BST0NfSEVBREVSICopJnBGb3JtYXRbMF07CiAgICAvKiAtT2lmIG9yIC1PaWNmIGdlbmVyYXRlZCBmb3JtYXQgKi8KICAgIEJPT0wgYlYyRm9ybWF0ID0gRkFMU0U7CiAgICAvKiB0aGUgdmFsdWUgdG8gcmV0dXJuIHRvIHRoZSBjbGllbnQgZnJvbSB0aGUgcmVtb3RlIHByb2NlZHVyZSAqLwogICAgTE9OR19QVFIgUmV0VmFsID0gMDsKICAgIC8qIHRoZSBwb2ludGVyIHRvIHRoZSBvYmplY3Qgd2hlbiBpbiBPTEUgbW9kZSAqLwogICAgdm9pZCAqIFRoaXMgPSBOVUxMOwogICAgUEZPUk1BVF9TVFJJTkcgcEhhbmRsZUZvcm1hdDsKCiAgICBUUkFDRSgicFN0dWJEZXNjICVwLCBwRm9ybWF0ICVwLCAuLi5cbiIsIHBTdHViRGVzYywgcEZvcm1hdCk7CgogICAgLyogTGF0ZXIgTkRSIGxhbmd1YWdlIHZlcnNpb25zIHByb2JhYmx5IHdvbid0IGJlIGJhY2t3YXJkcyBjb21wYXRpYmxlICovCiAgICBpZiAocFN0dWJEZXNjLT5WZXJzaW9uID4gMHg1MDAwMikKICAgIHsKICAgICAgICBGSVhNRSgiSW5jb21wYXRpYmxlIHN0dWIgZGVzY3JpcHRpb24gdmVyc2lvbjogMHgleFxuIiwgcFN0dWJEZXNjLT5WZXJzaW9uKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9XUk9OR19TVFVCX1ZFUlNJT04pOwogICAgfQoKICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfUlBDRkxBR1MpCiAgICB7CiAgICAgICAgY29uc3QgTkRSX1BST0NfSEVBREVSX1JQQyAqcFByb2NIZWFkZXIgPSAoY29uc3QgTkRSX1BST0NfSEVBREVSX1JQQyAqKSZwRm9ybWF0WzBdOwogICAgICAgIHN0YWNrX3NpemUgPSBwUHJvY0hlYWRlci0+c3RhY2tfc2l6ZTsKICAgICAgICBwcm9jZWR1cmVfbnVtYmVyID0gcFByb2NIZWFkZXItPnByb2NfbnVtOwogICAgICAgIHBGb3JtYXQgKz0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUl9SUEMpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN0YWNrX3NpemUgPSBwUHJvY0hlYWRlci0+c3RhY2tfc2l6ZTsKICAgICAgICBwcm9jZWR1cmVfbnVtYmVyID0gcFByb2NIZWFkZXItPnByb2NfbnVtOwogICAgICAgIHBGb3JtYXQgKz0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUik7CiAgICB9CiAgICBUUkFDRSgic3RhY2sgc2l6ZTogMHgleFxuIiwgc3RhY2tfc2l6ZSk7CiAgICBUUkFDRSgicHJvYyBudW06ICVkXG4iLCBwcm9jZWR1cmVfbnVtYmVyKTsKCiAgICAvKiBjcmVhdGUgdGhlIGZ1bGwgcG9pbnRlciB0cmFuc2xhdGlvbiB0YWJsZXMsIGlmIHJlcXVlc3RlZCAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9GVUxMUFRSKQogICAgICAgIHN0dWJNc2cuRnVsbFB0clhsYXRUYWJsZXMgPSBOZHJGdWxsUG9pbnRlclhsYXRJbml0KDAsWExBVF9DTElFTlQpOwoKICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgewogICAgICAgIC8qIG9iamVjdCBpcyBhbHdheXMgdGhlIGZpcnN0IGFyZ3VtZW50ICovCiAgICAgICAgVGhpcyA9ICoqKHZvaWQgKmNvbnN0ICoqKSgmcEZvcm1hdCsxKTsKICAgICAgICBOZHJQcm94eUluaXRpYWxpemUoVGhpcywgJnJwY01zZywgJnN0dWJNc2csIHBTdHViRGVzYywgcHJvY2VkdXJlX251bWJlcik7CiAgICB9CiAgICBlbHNlCiAgICAgICAgTmRyQ2xpZW50SW5pdGlhbGl6ZU5ldygmcnBjTXNnLCAmc3R1Yk1zZywgcFN0dWJEZXNjLCBwcm9jZWR1cmVfbnVtYmVyKTsKCiAgICBUUkFDRSgiT2lfZmxhZ3MgPSAweCUwMnhcbiIsIHBQcm9jSGVhZGVyLT5PaV9mbGFncyk7CiAgICBUUkFDRSgiTUlETCBzdHViIHZlcnNpb24gPSAweCV4XG4iLCBwU3R1YkRlc2MtPk1JRExWZXJzaW9uKTsKCiAgICAvKiBuZWVkZWQgZm9yIGNvbmZvcm1hbmNlIG9mIHRvcC1sZXZlbCBvYmplY3RzICovCiNpZmRlZiBfX2kzODZfXwogICAgc3R1Yk1zZy5TdGFja1RvcCA9ICoodW5zaWduZWQgY2hhciAqKikoJnBGb3JtYXQrMSk7CiNlbHNlCiMgd2FybmluZyBTdGFjayBub3QgcmV0cmlldmVkIGZvciB5b3VyIENQVSBhcmNoaXRlY3R1cmUKI2VuZGlmCgogICAgcEhhbmRsZUZvcm1hdCA9IHBGb3JtYXQ7CgogICAgLyogd2Ugb25seSBuZWVkIGEgaGFuZGxlIGlmIHRoaXMgaXNuJ3QgYW4gb2JqZWN0IG1ldGhvZCAqLwogICAgaWYgKCEocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX09CSkVDVCkpCiAgICB7CiAgICAgICAgcEZvcm1hdCA9IGNsaWVudF9nZXRfaGFuZGxlKCZzdHViTXNnLCBwUHJvY0hlYWRlciwgcEhhbmRsZUZvcm1hdCwgJmhCaW5kaW5nKTsKICAgICAgICBpZiAoIXBGb3JtYXQpIHJldHVybiAwOwogICAgfQoKICAgIGJWMkZvcm1hdCA9IChwU3R1YkRlc2MtPlZlcnNpb24gPj0gMHgyMDAwMCk7CgogICAgaWYgKGJWMkZvcm1hdCkKICAgIHsKICAgICAgICBjb25zdCBORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIgKnBPSUZIZWFkZXIgPQogICAgICAgICAgICAoY29uc3QgTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSICopcEZvcm1hdDsKCiAgICAgICAgT2lmX2ZsYWdzID0gcE9JRkhlYWRlci0+T2kyRmxhZ3M7CiAgICAgICAgbnVtYmVyX29mX3BhcmFtcyA9IHBPSUZIZWFkZXItPm51bWJlcl9vZl9wYXJhbXM7CgogICAgICAgIHBGb3JtYXQgKz0gc2l6ZW9mKE5EUl9QUk9DX1BBUlRJQUxfT0lGX0hFQURFUik7CiAgICB9CgogICAgVFJBQ0UoIk9pZl9mbGFncyA9ICIpOyBkdW1wX0lOVEVSUFJFVEVSX09QVF9GTEFHUyhPaWZfZmxhZ3MpOwoKICAgIGlmIChPaWZfZmxhZ3MuSGFzRXh0ZW5zaW9ucykKICAgIHsKICAgICAgICBjb25zdCBORFJfUFJPQ19IRUFERVJfRVhUUyAqcEV4dGVuc2lvbnMgPQogICAgICAgICAgICAoY29uc3QgTkRSX1BST0NfSEVBREVSX0VYVFMgKilwRm9ybWF0OwogICAgICAgIGV4dF9mbGFncyA9IHBFeHRlbnNpb25zLT5GbGFnczI7CiAgICAgICAgcEZvcm1hdCArPSBwRXh0ZW5zaW9ucy0+U2l6ZTsKICAgIH0KCiAgICBzdHViTXNnLkJ1ZmZlckxlbmd0aCA9IDA7CgogICAgLyogc3RvcmUgdGhlIFJQQyBmbGFncyBhd2F5ICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX1JQQ0ZMQUdTKQogICAgICAgIHJwY01zZy5ScGNGbGFncyA9ICgoY29uc3QgTkRSX1BST0NfSEVBREVSX1JQQyAqKXBQcm9jSGVhZGVyKS0+cnBjX2ZsYWdzOwoKICAgIC8qIHVzZSBhbHRlcm5hdGUgbWVtb3J5IGFsbG9jYXRpb24gcm91dGluZXMgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfUlBDU1NBTExPQykKICAgICAgICBOZHJScGNTbVNldENsaWVudFRvT3NmKCZzdHViTXNnKTsKCiAgICBpZiAoT2lmX2ZsYWdzLkhhc1BpcGVzKQogICAgewogICAgICAgIEZJWE1FKCJwaXBlcyBub3Qgc3VwcG9ydGVkIHlldFxuIik7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfV1JPTkdfU1RVQl9WRVJTSU9OKTsgLyogRklYTUU6IHJlbW92ZSB3aGVuIGltcGxlbWVudGVkICovCiAgICAgICAgLyogaW5pdCBwaXBlcyBwYWNrYWdlICovCiAgICAgICAgLyogTmRyUGlwZXNJbml0aWFsaXplKC4uLikgKi8KICAgIH0KICAgIGlmIChleHRfZmxhZ3MuSGFzTmV3Q29yckRlc2MpCiAgICB7CiAgICAgICAgLyogaW5pdGlhbGl6ZSBleHRyYSBjb3JyZWxhdGlvbiBwYWNrYWdlICovCiAgICAgICAgRklYTUUoIm5ldyBjb3JyZWxhdGlvbiBkZXNjcmlwdGlvbiBub3QgaW1wbGVtZW50ZWRcbiIpOwogICAgICAgIHN0dWJNc2cuZkhhc05ld0NvcnJEZXNjID0gVFJVRTsKICAgIH0KCiAgICAvKiBvcmRlciBvZiBwaGFzZXM6CiAgICAgKiAxLiBQUk9YWV9DQUxDU0laRSAtIGNhbGN1bGF0ZSB0aGUgYnVmZmVyIHNpemUKICAgICAqIDIuIFBST1hZX0dFVEJVRkZFUiAtIGFsbG9jYXRlIHRoZSBidWZmZXIKICAgICAqIDMuIFBST1hZX01BUkhTQUwgLSBtYXJzaGFsIFtpbl0gcGFyYW1zIGludG8gdGhlIGJ1ZmZlcgogICAgICogNC4gUFJPWFlfU0VORFJFQ0VJVkUgLSBzZW5kL3JlY2VpdmUgYnVmZmVyCiAgICAgKiA1LiBQUk9YWV9VTk1BUkhTQUwgLSB1bm1hcnNoYWwgW291dF0gcGFyYW1zIGZyb20gYnVmZmVyCiAgICAgKi8KICAgIGZvciAocGhhc2UgPSBQUk9YWV9DQUxDU0laRTsgcGhhc2UgPD0gUFJPWFlfVU5NQVJTSEFMOyBwaGFzZSsrKQogICAgewogICAgICAgIFRSQUNFKCJwaGFzZSA9ICVkXG4iLCBwaGFzZSk7CiAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBQUk9YWV9HRVRCVUZGRVI6CiAgICAgICAgICAgIC8qIGFsbG9jYXRlIHRoZSBidWZmZXIgKi8KICAgICAgICAgICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpCiAgICAgICAgICAgICAgICBOZHJQcm94eUdldEJ1ZmZlcihUaGlzLCAmc3R1Yk1zZyk7CiAgICAgICAgICAgIGVsc2UgaWYgKE9pZl9mbGFncy5IYXNQaXBlcykKICAgICAgICAgICAgICAgIC8qIE5kckdldFBpcGVCdWZmZXIoLi4uKSAqLwogICAgICAgICAgICAgICAgRklYTUUoInBpcGVzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPmhhbmRsZV90eXBlID09IFJQQ19GQ19BVVRPX0hBTkRMRSkKI2lmIDAKICAgICAgICAgICAgICAgICAgICBOZHJOc0dldEJ1ZmZlcigmc3R1Yk1zZywgc3R1Yk1zZy5CdWZmZXJMZW5ndGgsIGhCaW5kaW5nKTsKI2Vsc2UKICAgICAgICAgICAgICAgICAgICBGSVhNRSgidXNpbmcgYXV0byBoYW5kbGUgLSBjYWxsIE5kck5zR2V0QnVmZmVyIHdoZW4gaXQgZ2V0cyBpbXBsZW1lbnRlZFxuIik7CiNlbmRpZgogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIE5kckdldEJ1ZmZlcigmc3R1Yk1zZywgc3R1Yk1zZy5CdWZmZXJMZW5ndGgsIGhCaW5kaW5nKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFBST1hZX1NFTkRSRUNFSVZFOgogICAgICAgICAgICAvKiBzZW5kIHRoZSBbaW5dIHBhcmFtcyBhbmQgcmVjZWl2ZSB0aGUgW291dF0gYW5kIFtyZXR2YWxdCiAgICAgICAgICAgICAqIHBhcmFtcyAqLwogICAgICAgICAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX09CSkVDVCkKICAgICAgICAgICAgICAgIE5kclByb3h5U2VuZFJlY2VpdmUoVGhpcywgJnN0dWJNc2cpOwogICAgICAgICAgICBlbHNlIGlmIChPaWZfZmxhZ3MuSGFzUGlwZXMpCiAgICAgICAgICAgICAgICAvKiBOZHJQaXBlc1NlbmRSZWNlaXZlKC4uLikgKi8KICAgICAgICAgICAgICAgIEZJWE1FKCJwaXBlcyBub3Qgc3VwcG9ydGVkIHlldFxuIik7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSA9PSBSUENfRkNfQVVUT19IQU5ETEUpCiNpZiAwCiAgICAgICAgICAgICAgICAgICAgTmRyTnNTZW5kUmVjZWl2ZSgmc3R1Yk1zZywgc3R1Yk1zZy5CdWZmZXIsIHBTdHViRGVzYy0+SU1QTElDSVRfSEFORExFX0lORk8ucEF1dG9IYW5kbGUpOwojZWxzZQogICAgICAgICAgICAgICAgICAgIEZJWE1FKCJ1c2luZyBhdXRvIGhhbmRsZSAtIGNhbGwgTmRyTnNTZW5kUmVjZWl2ZSB3aGVuIGl0IGdldHMgaW1wbGVtZW50ZWRcbiIpOwojZW5kaWYKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBOZHJTZW5kUmVjZWl2ZSgmc3R1Yk1zZywgc3R1Yk1zZy5CdWZmZXIpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBjb252ZXJ0IHN0cmluZ3MsIGZsb2F0aW5nIHBvaW50IHZhbHVlcyBhbmQgZW5kaWFuZXNzIGludG8gb3VyCiAgICAgICAgICAgICAqIHByZWZlcnJlZCBmb3JtYXQgKi8KICAgICAgICAgICAgaWYgKChycGNNc2cuRGF0YVJlcHJlc2VudGF0aW9uICYgMHgwMDAwRkZGRlVMKSAhPSBORFJfTE9DQUxfREFUQV9SRVBSRVNFTlRBVElPTikKICAgICAgICAgICAgICAgIE5kckNvbnZlcnQoJnN0dWJNc2csIHBGb3JtYXQpOwoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBQUk9YWV9DQUxDU0laRToKICAgICAgICBjYXNlIFBST1hZX01BUlNIQUw6CiAgICAgICAgY2FzZSBQUk9YWV9VTk1BUlNIQUw6CiAgICAgICAgICAgIGlmIChiVjJGb3JtYXQpCiAgICAgICAgICAgICAgICBjbGllbnRfZG9fYXJncygmc3R1Yk1zZywgcEZvcm1hdCwgcGhhc2UsIG51bWJlcl9vZl9wYXJhbXMsCiAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIgKikmUmV0VmFsKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgY2xpZW50X2RvX2FyZ3Nfb2xkX2Zvcm1hdCgmc3R1Yk1zZywgcEZvcm1hdCwgcGhhc2UsIHN0YWNrX3NpemUsCiAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIgKikmUmV0VmFsLAogICAgICAgICAgICAgICAgICAgIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigic2hvdWxkbid0IHJlYWNoIGhlcmUuIHBoYXNlICVkXG4iLCBwaGFzZSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoZXh0X2ZsYWdzLkhhc05ld0NvcnJEZXNjKQogICAgewogICAgICAgIC8qIGZyZWUgZXh0cmEgY29ycmVsYXRpb24gcGFja2FnZSAqLwogICAgICAgIC8qIE5kckNvcnJlbGF0aW9uRnJlZSgmc3R1Yk1zZyk7ICovCiAgICB9CgogICAgaWYgKE9pZl9mbGFncy5IYXNQaXBlcykKICAgIHsKICAgICAgICAvKiBOZHJQaXBlc0RvbmUoLi4uKSAqLwogICAgfQoKICAgIC8qIGZyZWUgdGhlIGZ1bGwgcG9pbnRlciB0cmFuc2xhdGlvbiB0YWJsZXMgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfRlVMTFBUUikKICAgICAgICBOZHJGdWxsUG9pbnRlclhsYXRGcmVlKHN0dWJNc2cuRnVsbFB0clhsYXRUYWJsZXMpOwoKICAgIC8qIGZyZWUgbWFyc2hhbGxpbmcgYnVmZmVyICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX09CSkVDVCkKICAgICAgICBOZHJQcm94eUZyZWVCdWZmZXIoVGhpcywgJnN0dWJNc2cpOwogICAgZWxzZQogICAgewogICAgICAgIE5kckZyZWVCdWZmZXIoJnN0dWJNc2cpOwogICAgICAgIGNsaWVudF9mcmVlX2hhbmRsZSgmc3R1Yk1zZywgcFByb2NIZWFkZXIsIHBIYW5kbGVGb3JtYXQsIGhCaW5kaW5nKTsKICAgIH0KCiAgICBUUkFDRSgiUmV0VmFsID0gMHglbHhcbiIsIFJldFZhbCk7CgogICAgcmV0dXJuIFJldFZhbDsKfQoKLyogY2FsbHMgYSBmdW5jdGlvbiB3aXRoIHRoZSBzcGVjaWZpY2VkIGFyZ3VtZW50cywgcmVzdG9yaW5nIHRoZSBzdGFjawogKiBwcm9wZXJseSBhZnRlcndhcmRzIGFzIHdlIGRvbid0IGtub3cgdGhlIGNhbGxpbmcgY29udmVudGlvbiBvZiB0aGUKICogZnVuY3Rpb24gKi8KI2lmIGRlZmluZWQgX19pMzg2X18gJiYgZGVmaW5lZCBfTVNDX1ZFUgpfX2RlY2xzcGVjKG5ha2VkKSBMT05HX1BUUiBfX2NkZWNsIGNhbGxfc2VydmVyX2Z1bmMoU0VSVkVSX1JPVVRJTkUgZnVuYywgdW5zaWduZWQgY2hhciAqIGFyZ3MsIHVuc2lnbmVkIGludCBzdGFja19zaXplKQp7CiAgICBfX2FzbQogICAgewogICAgICAgIHB1c2ggZWJwCiAgICAgICAgcHVzaCBlZGkgICAgICAgICAgICA7IFNhdmUgcmVnaXN0ZXJzCiAgICAgICAgcHVzaCBlc2kKICAgICAgICBtb3YgZWJwLCBlc3AKICAgICAgICBtb3YgZWF4LCBbZWJwKzE2XSAgIDsgR2V0IHN0YWNrIHNpemUKICAgICAgICBzdWIgZXNwLCBlYXggICAgICAgIDsgTWFrZSByb29tIGluIHN0YWNrIGZvciBhcmd1bWVudHMKICAgICAgICBtb3YgZWRpLCBlc3AKICAgICAgICBtb3YgZWN4LCBlYXgKICAgICAgICBtb3YgZXNpLCBbZWJwKzEyXQogICAgICAgIHNociBlY3gsIDIKICAgICAgICBjbGQKICAgICAgICByZXAgbW92c2QgICAgICAgICAgIDsgQ29weSBkd29yZCBibG9ja3MKICAgICAgICBjYWxsIFtlYnArOF0gICAgICAgIDsgQ2FsbCBmdW5jdGlvbgogICAgICAgIGxlYSBlc3AsIFtlYnAtOF0gICAgOyBSZXN0b3JlIHN0YWNrCiAgICAgICAgcG9wIGVzaSAgICAgICAgICAgICA7IFJlc3RvcmUgcmVnaXN0ZXJzCiAgICAgICAgcG9wIGVkaQogICAgICAgIHBvcCBlYnAKICAgICAgICByZXQKICAgIH0KfQojZWxpZiBkZWZpbmVkIF9faTM4Nl9fICYmIGRlZmluZWQgX19HTlVDX18KTE9OR19QVFIgX19jZGVjbCBjYWxsX3NlcnZlcl9mdW5jKFNFUlZFUl9ST1VUSU5FIGZ1bmMsIHVuc2lnbmVkIGNoYXIgKiBhcmdzLCB1bnNpZ25lZCBpbnQgc3RhY2tfc2l6ZSk7Cl9fQVNNX0dMT0JBTF9GVU5DKGNhbGxfc2VydmVyX2Z1bmMsCiAgICAicHVzaGwgJWVicFxuXHQiCiAgICAibW92bCAlZXNwLCAlZWJwXG5cdCIKICAgICJwdXNobCAlZWRpXG5cdCIgICAgICAgICAgICAvKiBTYXZlIHJlZ2lzdGVycyAqLwogICAgInB1c2hsICVlc2lcblx0IgogICAgIm1vdmwgMTYoJWVicCksICVlYXhcblx0IiAgIC8qIEdldCBzdGFjayBzaXplICovCiAgICAic3VibCAlZWF4LCAlZXNwXG5cdCIgICAgICAgLyogTWFrZSByb29tIGluIHN0YWNrIGZvciBhcmd1bWVudHMgKi8KICAgICJhbmRsICR+MTUsICVlc3Bcblx0IgkvKiBNYWtlIHN1cmUgc3RhY2sgaGFzIDE2LWJ5dGUgYWxpZ25tZW50IGZvciBNYWMgT1MgWCAqLwogICAgIm1vdmwgJWVzcCwgJWVkaVxuXHQiCiAgICAibW92bCAlZWF4LCAlZWN4XG5cdCIKICAgICJtb3ZsIDEyKCVlYnApLCAlZXNpXG5cdCIKICAgICJzaHJsICQyLCAlZWN4XG5cdCIgICAgICAgICAvKiBkaXZpZGUgYnkgNCAqLwogICAgImNsZFxuXHQiCiAgICAicmVwOyBtb3ZzbFxuXHQiICAgICAgICAgICAgLyogQ29weSBkd29yZCBibG9ja3MgKi8KICAgICJjYWxsICo4KCVlYnApXG5cdCIgICAgICAgICAvKiBDYWxsIGZ1bmN0aW9uICovCiAgICAibGVhbCAtOCglZWJwKSwgJWVzcFxuXHQiICAgLyogUmVzdG9yZSBzdGFjayAqLwogICAgInBvcGwgJWVzaVxuXHQiICAgICAgICAgICAgIC8qIFJlc3RvcmUgcmVnaXN0ZXJzICovCiAgICAicG9wbCAlZWRpXG5cdCIKICAgICJwb3BsICVlYnBcblx0IgogICAgInJldFxuIiApCiNlbHNlCiN3YXJuaW5nIGNhbGxfc2VydmVyX2Z1bmMgbm90IGltcGxlbWVudGVkIGZvciB5b3VyIGFyY2hpdGVjdHVyZQpMT05HX1BUUiBfX2NkZWNsIGNhbGxfc2VydmVyX2Z1bmMoU0VSVkVSX1JPVVRJTkUgZnVuYywgdW5zaWduZWQgY2hhciAqIGFyZ3MsIHVuc2lnbmVkIHNob3J0IHN0YWNrX3NpemUpCnsKICAgIEZJWE1FKCJOb3QgaW1wbGVtZW50ZWQgZm9yIHlvdXIgYXJjaGl0ZWN0dXJlXG4iKTsKICAgIHJldHVybiAwOwp9CiNlbmRpZgoKc3RhdGljIERXT1JEIGNhbGNfYXJnX3NpemUoTUlETF9TVFVCX01FU1NBR0UgKnBTdHViTXNnLCBQRk9STUFUX1NUUklORyBwRm9ybWF0KQp7CiAgICBEV09SRCBzaXplOwogICAgc3dpdGNoKCpwRm9ybWF0KQogICAgewogICAgY2FzZSBSUENfRkNfU1RSVUNUOgogICAgICAgIHNpemUgPSAqKGNvbnN0IFdPUkQqKShwRm9ybWF0ICsgMik7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFJQQ19GQ19DQVJSQVk6CiAgICAgICAgc2l6ZSA9ICooY29uc3QgV09SRCopKHBGb3JtYXQgKyAyKTsKICAgICAgICBDb21wdXRlQ29uZm9ybWFuY2UocFN0dWJNc2csIE5VTEwsIHBGb3JtYXQgKyA0LCAwKTsKICAgICAgICBzaXplICo9IHBTdHViTXNnLT5NYXhDb3VudDsKICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX1NNRkFSUkFZOgogICAgICAgIHNpemUgPSAqKGNvbnN0IFdPUkQqKShwRm9ybWF0ICsgMik7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFJQQ19GQ19MR0ZBUlJBWToKICAgICAgICBzaXplID0gKihjb25zdCBEV09SRCopKHBGb3JtYXQgKyAyKTsKICAgICAgICBicmVhazsKICAgIGRlZmF1bHQ6CiAgICAgICAgRklYTUUoIlVuaGFuZGxlZCB0eXBlICUwMnhcbiIsICpwRm9ybWF0KTsKICAgICAgICAvKiBmYWxsdGhyb3VnaCAqLwogICAgY2FzZSBSUENfRkNfUlA6CiAgICAgICAgc2l6ZSA9IHNpemVvZih2b2lkICopOwogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIHNpemU7Cn0KCi8qIEZJWE1FOiBuZWVkIHRvIGZyZWUgc29tZSBzdHVmZiBpbiBoZXJlIHRvbyAqLwpMT05HIFdJTkFQSSBOZHJTdHViQ2FsbDIoCiAgICBzdHJ1Y3QgSVJwY1N0dWJCdWZmZXIgKiBwVGhpcywKICAgIHN0cnVjdCBJUnBjQ2hhbm5lbEJ1ZmZlciAqIHBDaGFubmVsLAogICAgUFJQQ19NRVNTQUdFIHBScGNNc2csCiAgICBEV09SRCAqIHBkd1N0dWJQaGFzZSkKewogICAgY29uc3QgTUlETF9TRVJWRVJfSU5GTyAqcFNlcnZlckluZm87CiAgICBjb25zdCBNSURMX1NUVUJfREVTQyAqcFN0dWJEZXNjOwogICAgUEZPUk1BVF9TVFJJTkcgcEZvcm1hdDsKICAgIE1JRExfU1RVQl9NRVNTQUdFIHN0dWJNc2c7CiAgICAvKiBwb2ludGVyIHRvIHN0YXJ0IG9mIHN0YWNrIHRvIHBhc3MgaW50byBzdHViIGltcGxlbWVudGF0aW9uICovCiAgICB1bnNpZ25lZCBjaGFyICogYXJnczsKICAgIC8qIHNpemUgb2Ygc3RhY2sgKi8KICAgIHVuc2lnbmVkIHNob3J0IHN0YWNrX3NpemU7CiAgICAvKiBjdXJyZW50IHN0YWNrIG9mZnNldCAqLwogICAgdW5zaWduZWQgc2hvcnQgY3VycmVudF9zdGFja19vZmZzZXQ7CiAgICAvKiBudW1iZXIgb2YgcGFyYW1ldGVycy4gb3B0aW9uYWwgZm9yIGNsaWVudCB0byBnaXZlIGl0IHRvIHVzICovCiAgICB1bnNpZ25lZCBjaGFyIG51bWJlcl9vZl9wYXJhbXMgPSB+MDsKICAgIC8qIGNvdW50ZXIgKi8KICAgIHVuc2lnbmVkIHNob3J0IGk7CiAgICAvKiBjYWNoZSBvZiBPaWZfZmxhZ3MgZnJvbSB2MiBwcm9jZWR1cmUgaGVhZGVyICovCiAgICBJTlRFUlBSRVRFUl9PUFRfRkxBR1MgT2lmX2ZsYWdzID0geyAwIH07CiAgICAvKiBjYWNoZSBvZiBleHRlbnNpb24gZmxhZ3MgZnJvbSBORFJfUFJPQ19IRUFERVJfRVhUUyAqLwogICAgSU5URVJQUkVURVJfT1BUX0ZMQUdTMiBleHRfZmxhZ3MgPSB7IDAgfTsKICAgIC8qIHRoZSB0eXBlIG9mIHBhc3Mgd2UgYXJlIGN1cnJlbnRseSBkb2luZyAqLwogICAgaW50IHBoYXNlOwogICAgLyogaGVhZGVyIGZvciBwcm9jZWR1cmUgc3RyaW5nICovCiAgICBjb25zdCBORFJfUFJPQ19IRUFERVIgKnBQcm9jSGVhZGVyOwogICAgLyogb2Zmc2V0IGluIGZvcm1hdCBzdHJpbmcgZm9yIHN0YXJ0IG9mIHBhcmFtcyAqLwogICAgaW50IHBhcmFtZXRlcl9zdGFydF9vZmZzZXQ7CiAgICAvKiBjdXJyZW50IGZvcm1hdCBzdHJpbmcgb2Zmc2V0ICovCiAgICBpbnQgY3VycmVudF9vZmZzZXQ7CiAgICAvKiAtT2lmIG9yIC1PaWNmIGdlbmVyYXRlZCBmb3JtYXQgKi8KICAgIEJPT0wgYlYyRm9ybWF0ID0gRkFMU0U7CiAgICAvKiBsb2NhdGlvbiB0byBwdXQgcmV0dmFsIGludG8gKi8KICAgIExPTkdfUFRSICpyZXR2YWxfcHRyID0gTlVMTDsKCiAgICBUUkFDRSgicFRoaXMgJXAsIHBDaGFubmVsICVwLCBwUnBjTXNnICVwLCBwZHdTdHViUGhhc2UgJXBcbiIsIHBUaGlzLCBwQ2hhbm5lbCwgcFJwY01zZywgcGR3U3R1YlBoYXNlKTsKCiAgICBpZiAocFRoaXMpCiAgICAgICAgcFNlcnZlckluZm8gPSBDU3RkU3R1YkJ1ZmZlcl9HZXRTZXJ2ZXJJbmZvKHBUaGlzKTsKICAgIGVsc2UKICAgICAgICBwU2VydmVySW5mbyA9ICgoUlBDX1NFUlZFUl9JTlRFUkZBQ0UgKilwUnBjTXNnLT5ScGNJbnRlcmZhY2VJbmZvcm1hdGlvbiktPkludGVycHJldGVySW5mbzsKCiAgICBwU3R1YkRlc2MgPSBwU2VydmVySW5mby0+cFN0dWJEZXNjOwogICAgcEZvcm1hdCA9IHBTZXJ2ZXJJbmZvLT5Qcm9jU3RyaW5nICsgcFNlcnZlckluZm8tPkZtdFN0cmluZ09mZnNldFtwUnBjTXNnLT5Qcm9jTnVtXTsKICAgIHBQcm9jSGVhZGVyID0gKGNvbnN0IE5EUl9QUk9DX0hFQURFUiAqKSZwRm9ybWF0WzBdOwoKICAgIC8qIExhdGVyIE5EUiBsYW5ndWFnZSB2ZXJzaW9ucyBwcm9iYWJseSB3b24ndCBiZSBiYWNrd2FyZHMgY29tcGF0aWJsZSAqLwogICAgaWYgKHBTdHViRGVzYy0+VmVyc2lvbiA+IDB4NTAwMDIpCiAgICB7CiAgICAgICAgRklYTUUoIkluY29tcGF0aWJsZSBzdHViIGRlc2NyaXB0aW9uIHZlcnNpb246IDB4JXhcbiIsIHBTdHViRGVzYy0+VmVyc2lvbik7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfV1JPTkdfU1RVQl9WRVJTSU9OKTsKICAgIH0KCiAgICAvKiBjcmVhdGUgdGhlIGZ1bGwgcG9pbnRlciB0cmFuc2xhdGlvbiB0YWJsZXMsIGlmIHJlcXVlc3RlZCAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9GVUxMUFRSKQogICAgICAgIHN0dWJNc2cuRnVsbFB0clhsYXRUYWJsZXMgPSBOZHJGdWxsUG9pbnRlclhsYXRJbml0KDAsWExBVF9TRVJWRVIpOwoKICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfUlBDRkxBR1MpCiAgICB7CiAgICAgICAgY29uc3QgTkRSX1BST0NfSEVBREVSX1JQQyAqcFByb2NIZWFkZXIgPSAoY29uc3QgTkRSX1BST0NfSEVBREVSX1JQQyAqKSZwRm9ybWF0WzBdOwogICAgICAgIHN0YWNrX3NpemUgPSBwUHJvY0hlYWRlci0+c3RhY2tfc2l6ZTsKICAgICAgICBjdXJyZW50X29mZnNldCA9IHNpemVvZihORFJfUFJPQ19IRUFERVJfUlBDKTsKCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc3RhY2tfc2l6ZSA9IHBQcm9jSGVhZGVyLT5zdGFja19zaXplOwogICAgICAgIGN1cnJlbnRfb2Zmc2V0ID0gc2l6ZW9mKE5EUl9QUk9DX0hFQURFUik7CiAgICB9CgogICAgVFJBQ0UoIk9pX2ZsYWdzID0gMHglMDJ4XG4iLCBwUHJvY0hlYWRlci0+T2lfZmxhZ3MpOwoKICAgIC8qIGJpbmRpbmcgKi8KICAgIHN3aXRjaCAocFByb2NIZWFkZXItPmhhbmRsZV90eXBlKQogICAgewogICAgLyogZXhwbGljaXQgYmluZGluZzogcGFyc2UgYWRkaXRpb25hbCBzZWN0aW9uICovCiAgICBjYXNlIFJQQ19GQ19CSU5EX0VYUExJQ0lUOgogICAgICAgIHN3aXRjaCAocEZvcm1hdFtjdXJyZW50X29mZnNldF0pIC8qIGhhbmRsZV90eXBlICovCiAgICAgICAgewogICAgICAgIGNhc2UgUlBDX0ZDX0JJTkRfUFJJTUlUSVZFOiAvKiBleHBsaWNpdCBwcmltaXRpdmUgKi8KICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9FSERfUFJJTUlUSVZFKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBSUENfRkNfQklORF9HRU5FUklDOiAvKiBleHBsaWNpdCBnZW5lcmljICovCiAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfRUhEX0dFTkVSSUMpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFJQQ19GQ19CSU5EX0NPTlRFWFQ6IC8qIGV4cGxpY2l0IGNvbnRleHQgKi8KICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9FSERfQ09OVEVYVCk7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIEVSUigiYmFkIGV4cGxpY2l0IGJpbmRpbmcgaGFuZGxlIHR5cGUgKDB4JTAyeClcbiIsIHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSk7CiAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19YX0JBRF9TVFVCX0RBVEEpOwogICAgICAgIH0KICAgICAgICBicmVhazsKICAgIGNhc2UgUlBDX0ZDX0JJTkRfR0VORVJJQzogLyogaW1wbGljaXQgZ2VuZXJpYyAqLwogICAgY2FzZSBSUENfRkNfQklORF9QUklNSVRJVkU6IC8qIGltcGxpY2l0IHByaW1pdGl2ZSAqLwogICAgY2FzZSBSUENfRkNfQ0FMTEJBQ0tfSEFORExFOiAvKiBpbXBsaWNpdCBjYWxsYmFjayAqLwogICAgY2FzZSBSUENfRkNfQVVUT19IQU5ETEU6IC8qIGltcGxpY2l0IGF1dG8gaGFuZGxlICovCiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIEVSUigiYmFkIGltcGxpY2l0IGJpbmRpbmcgaGFuZGxlIHR5cGUgKDB4JTAyeClcbiIsIHBQcm9jSGVhZGVyLT5oYW5kbGVfdHlwZSk7CiAgICAgICAgUnBjUmFpc2VFeGNlcHRpb24oUlBDX1hfQkFEX1NUVUJfREFUQSk7CiAgICB9CgogICAgYlYyRm9ybWF0ID0gKHBTdHViRGVzYy0+VmVyc2lvbiA+PSAweDIwMDAwKTsKCiAgICBpZiAoYlYyRm9ybWF0KQogICAgewogICAgICAgIGNvbnN0IE5EUl9QUk9DX1BBUlRJQUxfT0lGX0hFQURFUiAqcE9JRkhlYWRlciA9CiAgICAgICAgICAgIChjb25zdCBORFJfUFJPQ19QQVJUSUFMX09JRl9IRUFERVIgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CgogICAgICAgIE9pZl9mbGFncyA9IHBPSUZIZWFkZXItPk9pMkZsYWdzOwogICAgICAgIG51bWJlcl9vZl9wYXJhbXMgPSBwT0lGSGVhZGVyLT5udW1iZXJfb2ZfcGFyYW1zOwoKICAgICAgICBjdXJyZW50X29mZnNldCArPSBzaXplb2YoTkRSX1BST0NfUEFSVElBTF9PSUZfSEVBREVSKTsKICAgIH0KCiAgICBUUkFDRSgiT2lmX2ZsYWdzID0gIik7IGR1bXBfSU5URVJQUkVURVJfT1BUX0ZMQUdTKE9pZl9mbGFncyk7CgogICAgaWYgKE9pZl9mbGFncy5IYXNFeHRlbnNpb25zKQogICAgewogICAgICAgIGNvbnN0IE5EUl9QUk9DX0hFQURFUl9FWFRTICpwRXh0ZW5zaW9ucyA9CiAgICAgICAgICAgIChjb25zdCBORFJfUFJPQ19IRUFERVJfRVhUUyAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKICAgICAgICBleHRfZmxhZ3MgPSBwRXh0ZW5zaW9ucy0+RmxhZ3MyOwogICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHBFeHRlbnNpb25zLT5TaXplOwogICAgfQoKICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgIE5kclN0dWJJbml0aWFsaXplKHBScGNNc2csICZzdHViTXNnLCBwU3R1YkRlc2MsIHBDaGFubmVsKTsKICAgIGVsc2UKICAgICAgICBOZHJTZXJ2ZXJJbml0aWFsaXplTmV3KHBScGNNc2csICZzdHViTXNnLCBwU3R1YkRlc2MpOwoKICAgIC8qIHN0b3JlIHRoZSBSUEMgZmxhZ3MgYXdheSAqLwogICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9SUENGTEFHUykKICAgICAgICBwUnBjTXNnLT5ScGNGbGFncyA9ICgoY29uc3QgTkRSX1BST0NfSEVBREVSX1JQQyAqKXBQcm9jSGVhZGVyKS0+cnBjX2ZsYWdzOwoKICAgIC8qIHVzZSBhbHRlcm5hdGUgbWVtb3J5IGFsbG9jYXRpb24gcm91dGluZXMgKi8KICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfUlBDU1NBTExPQykKI2lmIDAKICAgICAgICAgIE5kclJwY1NzRW5hYmxlQWxsb2NhdGUoJnN0dWJNc2cpOwojZWxzZQogICAgICAgICAgRklYTUUoIlNldCBSUENTUyBtZW1vcnkgYWxsb2NhdGlvbiByb3V0aW5lc1xuIik7CiNlbmRpZgoKICAgIGlmIChPaWZfZmxhZ3MuSGFzUGlwZXMpCiAgICB7CiAgICAgICAgRklYTUUoInBpcGVzIG5vdCBzdXBwb3J0ZWQgeWV0XG4iKTsKICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfWF9XUk9OR19TVFVCX1ZFUlNJT04pOyAvKiBGSVhNRTogcmVtb3ZlIHdoZW4gaW1wbGVtZW50ZWQgKi8KICAgICAgICAvKiBpbml0IHBpcGVzIHBhY2thZ2UgKi8KICAgICAgICAvKiBOZHJQaXBlc0luaXRpYWxpemUoLi4uKSAqLwogICAgfQogICAgaWYgKGV4dF9mbGFncy5IYXNOZXdDb3JyRGVzYykKICAgIHsKICAgICAgICAvKiBpbml0aWFsaXplIGV4dHJhIGNvcnJlbGF0aW9uIHBhY2thZ2UgKi8KICAgICAgICBGSVhNRSgibmV3IGNvcnJlbGF0aW9uIGRlc2NyaXB0aW9uIG5vdCBpbXBsZW1lbnRlZFxuIik7CiAgICAgICAgc3R1Yk1zZy5mSGFzTmV3Q29yckRlc2MgPSBUUlVFOwogICAgfQoKICAgIC8qIGNvbnZlcnQgc3RyaW5ncywgZmxvYXRpbmcgcG9pbnQgdmFsdWVzIGFuZCBlbmRpYW5lc3MgaW50byBvdXIKICAgICAqIHByZWZlcnJlZCBmb3JtYXQgKi8KICAgIGlmICgocFJwY01zZy0+RGF0YVJlcHJlc2VudGF0aW9uICYgMHgwMDAwRkZGRlVMKSAhPSBORFJfTE9DQUxfREFUQV9SRVBSRVNFTlRBVElPTikKICAgICAgICBOZHJDb252ZXJ0KCZzdHViTXNnLCBwRm9ybWF0KTsKCiAgICBwYXJhbWV0ZXJfc3RhcnRfb2Zmc2V0ID0gY3VycmVudF9vZmZzZXQ7CgogICAgVFJBQ0UoImFsbG9jYXRpbmcgbWVtb3J5IGZvciBzdGFjayBvZiBzaXplICV4XG4iLCBzdGFja19zaXplKTsKCiAgICBhcmdzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHN0YWNrX3NpemUpOwogICAgc3R1Yk1zZy5TdGFja1RvcCA9IGFyZ3M7IC8qIHVzZWQgYnkgY29uZm9ybWFuY2Ugb2YgdG9wLWxldmVsIG9iamVjdHMgKi8KCiAgICAvKiBhZGQgdGhlIGltcGxpY2l0IFRoaXMgcG9pbnRlciBhcyB0aGUgZmlyc3QgYXJnIHRvIHRoZSBmdW5jdGlvbiBpZiB3ZQogICAgICogYXJlIGNhbGxpbmcgYW4gb2JqZWN0IG1ldGhvZCAqLwogICAgaWYgKHBUaGlzKQogICAgICAgICoodm9pZCAqKilhcmdzID0gKChDU3RkU3R1YkJ1ZmZlciAqKXBUaGlzKS0+cHZTZXJ2ZXJPYmplY3Q7CgogICAgLyogb3JkZXIgb2YgcGhhc2VzOgogICAgICogMS4gU1RVQkxFU1NfVU5NQVJIU0FMIC0gdW5tYXJzaGFsIFtpbl0gcGFyYW1zIGZyb20gYnVmZmVyCiAgICAgKiAyLiBTVFVCTEVTU19DQUxMU0VSVkVSIC0gc2VuZC9yZWNlaXZlIGJ1ZmZlcgogICAgICogMy4gU1RVQkxFU1NfQ0FMQ1NJWkUgLSBnZXQgW291dF0gYnVmZmVyIHNpemUKICAgICAqIDQuIFNUVUJMRVNTX0dFVEJVRkZFUiAtIGFsbG9jYXRlIFtvdXRdIGJ1ZmZlcgogICAgICogNS4gU1RVQkxFU1NfTUFSSFNBTCAtIG1hcnNoYWwgW291dF0gcGFyYW1zIHRvIGJ1ZmZlcgogICAgICovCiAgICBmb3IgKHBoYXNlID0gU1RVQkxFU1NfVU5NQVJTSEFMOyBwaGFzZSA8PSBTVFVCTEVTU19GUkVFOyBwaGFzZSsrKQogICAgewogICAgICAgIFRSQUNFKCJwaGFzZSA9ICVkXG4iLCBwaGFzZSk7CiAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBTVFVCTEVTU19DQUxMU0VSVkVSOgogICAgICAgICAgICAvKiBjYWxsIHRoZSBzZXJ2ZXIgZnVuY3Rpb24gKi8KICAgICAgICAgICAgaWYgKHBTZXJ2ZXJJbmZvLT5UaHVua1RhYmxlICYmIHBTZXJ2ZXJJbmZvLT5UaHVua1RhYmxlW3BScGNNc2ctPlByb2NOdW1dKQogICAgICAgICAgICAgICAgcFNlcnZlckluZm8tPlRodW5rVGFibGVbcFJwY01zZy0+UHJvY051bV0oJnN0dWJNc2cpOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIFNFUlZFUl9ST1VUSU5FIGZ1bmM7CiAgICAgICAgICAgICAgICBMT05HX1BUUiByZXR2YWw7CgogICAgICAgICAgICAgICAgaWYgKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgU0VSVkVSX1JPVVRJTkUgKnZ0YmwgPSAqKFNFUlZFUl9ST1VUSU5FICoqKSgoQ1N0ZFN0dWJCdWZmZXIgKilwVGhpcyktPnB2U2VydmVyT2JqZWN0OwogICAgICAgICAgICAgICAgICAgIGZ1bmMgPSB2dGJsW3BScGNNc2ctPlByb2NOdW1dOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGZ1bmMgPSBwU2VydmVySW5mby0+RGlzcGF0Y2hUYWJsZVtwUnBjTXNnLT5Qcm9jTnVtXTsKCiAgICAgICAgICAgICAgICAvKiBGSVhNRTogd2hhdCBoYXBwZW5zIHdpdGggcmV0dXJuIHZhbHVlcyB0aGF0IGRvbid0IGZpdCBpbnRvIGEgc2luZ2xlIHJlZ2lzdGVyIG9uIHg4Nj8gKi8KICAgICAgICAgICAgICAgIHJldHZhbCA9IGNhbGxfc2VydmVyX2Z1bmMoZnVuYywgYXJncywgc3RhY2tfc2l6ZSk7CgogICAgICAgICAgICAgICAgaWYgKHJldHZhbF9wdHIpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInN0dWIgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgMHglbHhcbiIsIHJldHZhbCk7CiAgICAgICAgICAgICAgICAgICAgKnJldHZhbF9wdHIgPSByZXR2YWw7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInZvaWQgc3R1YiBpbXBsZW1lbnRhdGlvblxuIik7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIHN0dWJNc2cuQnVmZmVyID0gTlVMTDsKICAgICAgICAgICAgc3R1Yk1zZy5CdWZmZXJMZW5ndGggPSAwOwoKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBTVFVCTEVTU19HRVRCVUZGRVI6CiAgICAgICAgICAgIGlmIChwUHJvY0hlYWRlci0+T2lfZmxhZ3MgJiBSUENfRkNfUFJPQ19PSUZfT0JKRUNUKQogICAgICAgICAgICAgICAgTmRyU3R1YkdldEJ1ZmZlcihwVGhpcywgcENoYW5uZWwsICZzdHViTXNnKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBSUENfU1RBVFVTIFN0YXR1czsKCiAgICAgICAgICAgICAgICBwUnBjTXNnLT5CdWZmZXJMZW5ndGggPSBzdHViTXNnLkJ1ZmZlckxlbmd0aDsKICAgICAgICAgICAgICAgIC8qIGFsbG9jYXRlIGJ1ZmZlciBmb3IgW291dF0gYW5kIFtyZXRdIHBhcmFtcyAqLwogICAgICAgICAgICAgICAgU3RhdHVzID0gSV9ScGNHZXRCdWZmZXIocFJwY01zZyk7IAogICAgICAgICAgICAgICAgaWYgKFN0YXR1cykKICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihTdGF0dXMpOwogICAgICAgICAgICAgICAgc3R1Yk1zZy5CdWZmZXJTdGFydCA9IHBScGNNc2ctPkJ1ZmZlcjsKICAgICAgICAgICAgICAgIHN0dWJNc2cuQnVmZmVyRW5kID0gc3R1Yk1zZy5CdWZmZXJTdGFydCArIHN0dWJNc2cuQnVmZmVyTGVuZ3RoOwogICAgICAgICAgICAgICAgc3R1Yk1zZy5CdWZmZXIgPSBzdHViTXNnLkJ1ZmZlclN0YXJ0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgU1RVQkxFU1NfTUFSU0hBTDoKICAgICAgICBjYXNlIFNUVUJMRVNTX1VOTUFSU0hBTDoKICAgICAgICBjYXNlIFNUVUJMRVNTX0NBTENTSVpFOgogICAgICAgIGNhc2UgU1RVQkxFU1NfRlJFRToKICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgPSBwYXJhbWV0ZXJfc3RhcnRfb2Zmc2V0OwogICAgICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCA9IDA7CgogICAgICAgICAgICAvKiBOT1RFOiBWMSBzdHlsZSBmb3JtYXQgZG9lcyd0IHRlcm1pbmF0ZSBvbiB0aGUgbnVtYmVyX29mX3BhcmFtcwogICAgICAgICAgICAgKiBjb25kaXRpb24gYXMgaXQgZG9lc24ndCBoYXZlIHRoaXMgYXR0cmlidXRlLiBJbnN0ZWFkIGl0CiAgICAgICAgICAgICAqIHRlcm1pbmF0ZXMgd2hlbiB0aGUgc3RhY2sgc2l6ZSBnaXZlbiBpbiB0aGUgaGVhZGVyIGlzIGV4Y2VlZGVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bWJlcl9vZl9wYXJhbXM7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKGJWMkZvcm1hdCkgLyogbmV3IHBhcmFtZXRlciBmb3JtYXQgKi8KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBORFJfUEFSQU1fT0lGX0JBU0VUWVBFICpwUGFyYW0gPQogICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgTkRSX1BBUkFNX09JRl9CQVNFVFlQRSAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpwQXJnOwoKICAgICAgICAgICAgICAgICAgICBjdXJyZW50X3N0YWNrX29mZnNldCA9IHBQYXJhbS0+c3RhY2tfb2Zmc2V0OwogICAgICAgICAgICAgICAgICAgIHBBcmcgPSAodW5zaWduZWQgY2hhciAqKShhcmdzK2N1cnJlbnRfc3RhY2tfb2Zmc2V0KTsKCiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoInBhcmFtWyVkXTogbmV3IGZvcm1hdFxuIiwgaSk7CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0cGFyYW1fYXR0cmlidXRlczoiKTsgZHVtcF9SUENfRkNfUFJPQ19QRihwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMpOyBUUkFDRSgiXG4iKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRzdGFja19vZmZzZXQ6IDB4JXhcbiIsIGN1cnJlbnRfc3RhY2tfb2Zmc2V0KTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRtZW1vcnkgYWRkciAoYmVmb3JlKTogJXAgLT4gJXBcbiIsIHBBcmcsICoodW5zaWduZWQgY2hhciAqKilwQXJnKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0Jhc2V0eXBlKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqcFR5cGVGb3JtYXQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBQYXJhbS0+dHlwZV9mb3JtYXRfY2hhcjsKCiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdGJhc2UgdHlwZTogMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX01BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzT3V0IHx8IHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzU2ltcGxlUmVmKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX21hcnNoYWxsZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX0ZSRUU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLlNlcnZlckFsbG9jU2l6ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCAqKHZvaWQgKiopcEFyZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLlNlcnZlckFsbG9jU2l6ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHZvaWQgKiopcEFyZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuU2VydmVyQWxsb2NTaXplICogOCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0luKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNTaW1wbGVSZWYpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBtYWtlIGEgbm90ZSBvZiB0aGUgYWRkcmVzcyBvZiB0aGUgcmV0dXJuIHZhbHVlIHBhcmFtZXRlciBmb3IgbGF0ZXIgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dmFsX3B0ciA9IChMT05HX1BUUiAqKXBBcmc7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzT3V0IHx8IHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzU2ltcGxlUmVmKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2J1ZmZlcl9zaXplcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSUZfQkFTRVRZUEUpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBORFJfUEFSQU1fT0lGX09USEVSICpwUGFyYW1PdGhlciA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29uc3QgTkRSX1BBUkFNX09JRl9PVEhFUiAqKSZwRm9ybWF0W2N1cnJlbnRfb2Zmc2V0XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIgKiBwVHlwZUZvcm1hdCA9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKHBTdHViRGVzYy0+cEZvcm1hdFR5cGVzW3BQYXJhbU90aGVyLT50eXBlX29mZnNldF0pOwoKICAgICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0Y29tcGxleCB0eXBlIDB4JTAyeFxuIiwgKnBUeXBlRm9ybWF0KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHN3aXRjaCAocGhhc2UpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCB8fCBwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNSZXR1cm4pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9tYXJzaGFsbGVyKCZzdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfRlJFRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuTXVzdEZyZWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0J5VmFsdWUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfZnJlZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfZnJlZXIoJnN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc091dCAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNJbiAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5TZXJ2ZXJBbGxvY1NpemUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R1Yk1zZy5wZm5GcmVlKCoodm9pZCAqKilwQXJnKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLlNlcnZlckFsbG9jU2l6ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCAqKHZvaWQgKiopcEFyZyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBGSVhNRTogY2FsbCBjYWxsX2ZyZWVyIGhlcmUgZm9yIElOIHR5cGVzIHdpdGggTXVzdEZyZWUgc2V0ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19VTk1BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLlNlcnZlckFsbG9jU2l6ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHZvaWQgKiopcEFyZyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuU2VydmVyQWxsb2NTaXplICogOCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc0luKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNCeVZhbHVlKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfdW5tYXJzaGFsbGVyKCZzdHViTXNnLCAodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCwgMCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuSXNPdXQgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICFwUGFyYW0tPnBhcmFtX2F0dHJpYnV0ZXMuU2VydmVyQWxsb2NTaXplICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAhcFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzQnlWYWx1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBzaXplID0gY2FsY19hcmdfc2l6ZSgmc3R1Yk1zZywgcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihzaXplKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKih2b2lkICoqKXBBcmcgPSBOZHJBbGxvY2F0ZSgmc3R1Yk1zZywgc2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbXNldCgqKHZvaWQgKiopcEFyZywgMCwgc2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfQ0FMQ1NJWkU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzT3V0IHx8IHBQYXJhbS0+cGFyYW1fYXR0cmlidXRlcy5Jc1JldHVybikKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9hdHRyaWJ1dGVzLklzQnlWYWx1ZSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIoJnN0dWJNc2csIHBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBScGNSYWlzZUV4Y2VwdGlvbihSUENfU19JTlRFUk5BTF9FUlJPUik7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRfb2Zmc2V0ICs9IHNpemVvZihORFJfUEFSQU1fT0lGX09USEVSKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0bWVtb3J5IGFkZHIgKGFmdGVyKTogJXAgLT4gJXBcbiIsIHBBcmcsICoodW5zaWduZWQgY2hhciAqKilwQXJnKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgLyogb2xkIHBhcmFtZXRlciBmb3JtYXQgKi8KICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBjb25zdCBORFJfUEFSQU1fT0lfQkFTRVRZUEUgKnBQYXJhbSA9CiAgICAgICAgICAgICAgICAgICAgICAgIChjb25zdCBORFJfUEFSQU1fT0lfQkFTRVRZUEUgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CiAgICAgICAgICAgICAgICAgICAgLyogbm90ZTogY3VycmVudF9zdGFja19vZmZzZXQgc3RhcnRzIGFmdGVyIHRoZSBUaGlzIHBvaW50ZXIKICAgICAgICAgICAgICAgICAgICAgKiBpZiBwcmVzZW50LCBzbyBhZGp1c3QgdGhpcyAqLwogICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNob3J0IGN1cnJlbnRfc3RhY2tfb2Zmc2V0X2FkanVzdGVkID0gY3VycmVudF9zdGFja19vZmZzZXQgKwogICAgICAgICAgICAgICAgICAgICAgICAoKHBQcm9jSGVhZGVyLT5PaV9mbGFncyAmIFJQQ19GQ19QUk9DX09JRl9PQkpFQ1QpID8gc2l6ZW9mKHZvaWQgKikgOiAwKTsKICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyICpwQXJnID0gKHVuc2lnbmVkIGNoYXIgKikoYXJncytjdXJyZW50X3N0YWNrX29mZnNldF9hZGp1c3RlZCk7CgogICAgICAgICAgICAgICAgICAgIC8qIG5vIG1vcmUgcGFyYW1ldGVyczsgZXhpdCBsb29wICovCiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnRfc3RhY2tfb2Zmc2V0X2FkanVzdGVkID49IHN0YWNrX3NpemUpCiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgICAgICAgICBUUkFDRSgicGFyYW1bJWRdOiBvbGQgZm9ybWF0XG4iLCBpKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRwYXJhbV9kaXJlY3Rpb246IDB4JXhcbiIsIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uKTsKICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRzdGFja19vZmZzZXQ6IDB4JXhcbiIsIGN1cnJlbnRfc3RhY2tfb2Zmc2V0X2FkanVzdGVkKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTV9CQVNFVFlQRSB8fAogICAgICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqcFR5cGVGb3JtYXQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBQYXJhbS0+dHlwZV9mb3JtYXRfY2hhcjsKCiAgICAgICAgICAgICAgICAgICAgICAgIFRSQUNFKCJcdGJhc2UgdHlwZSAweCUwMnhcbiIsICpwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKHBoYXNlKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfTUFSU0hBTDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfRlJFRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9mcmVlcigmc3R1Yk1zZywgcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfVU5NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTV9CQVNFVFlQRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX3VubWFyc2hhbGxlcigmc3R1Yk1zZywgJnBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU1fQkFTRVRZUEUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dmFsX3B0ciA9IChMT05HX1BUUiAqKXBBcmc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19DQUxDU0laRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNX0JBU0VUWVBFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfYnVmZmVyX3NpemVyKCZzdHViTXNnLCBwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgKz0gY2FsbF9tZW1vcnlfc2l6ZXIoJnN0dWJNc2csIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSV9CQVNFVFlQRSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE5EUl9QQVJBTV9PSV9PVEhFUiAqcFBhcmFtT3RoZXIgPSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjb25zdCBORFJfUEFSQU1fT0lfT1RIRVIgKikmcEZvcm1hdFtjdXJyZW50X29mZnNldF07CgogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyICogcFR5cGVGb3JtYXQgPQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBTdHViRGVzYy0+cEZvcm1hdFR5cGVzW3BQYXJhbU90aGVyLT50eXBlX29mZnNldF07CgogICAgICAgICAgICAgICAgICAgICAgICBUUkFDRSgiXHRjb21wbGV4IHR5cGUgMHglMDJ4XG4iLCAqcFR5cGVGb3JtYXQpOwoKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChwaGFzZSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX01BUlNIQUw6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX09VVF9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9PVVRfUEFSQU0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfUkVUVVJOX1BBUkFNKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxfbWFyc2hhbGxlcigmc3R1Yk1zZywgKih1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgICAgICBjYXNlIFNUVUJMRVNTX0ZSRUU6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX09VVF9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsX2ZyZWVyKCZzdHViTXNnLCAqKHVuc2lnbmVkIGNoYXIgKiopcEFyZywgcFR5cGVGb3JtYXQpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAocFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX09VVF9QQVJBTSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHViTXNnLnBmbkZyZWUoKih2b2lkICoqKXBBcmcpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgU1RVQkxFU1NfVU5NQVJTSEFMOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19JTl9PVVRfUEFSQU0gfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfSU5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF91bm1hcnNoYWxsZXIoJnN0dWJNc2csICh1bnNpZ25lZCBjaGFyICoqKXBBcmcsIHBUeXBlRm9ybWF0LCAwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dmFsX3B0ciA9IChMT05HX1BUUiAqKXBBcmc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfT1VUX1BBUkFNKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHNpemUgPSBjYWxjX2FyZ19zaXplKCZzdHViTXNnLCBwVHlwZUZvcm1hdCk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKHNpemUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKHZvaWQgKiopcEFyZyA9IE5kckFsbG9jYXRlKCZzdHViTXNnLCBzaXplKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWVtc2V0KCoodm9pZCAqKilwQXJnLCAwLCBzaXplKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSBTVFVCTEVTU19DQUxDU0laRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwUGFyYW0tPnBhcmFtX2RpcmVjdGlvbiA9PSBSUENfRkNfT1VUX1BBUkFNIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcFBhcmFtLT5wYXJhbV9kaXJlY3Rpb24gPT0gUlBDX0ZDX0lOX09VVF9QQVJBTSB8fAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBQYXJhbS0+cGFyYW1fZGlyZWN0aW9uID09IFJQQ19GQ19SRVRVUk5fUEFSQU0pCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FsbF9idWZmZXJfc2l6ZXIoJnN0dWJNc2csICoodW5zaWduZWQgY2hhciAqKilwQXJnLCBwVHlwZUZvcm1hdCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJwY1JhaXNlRXhjZXB0aW9uKFJQQ19TX0lOVEVSTkFMX0VSUk9SKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9zdGFja19vZmZzZXQgKz0gcFBhcmFtT3RoZXItPnN0YWNrX3NpemUgKiBzaXplb2YoSU5UKTsKICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudF9vZmZzZXQgKz0gc2l6ZW9mKE5EUl9QQVJBTV9PSV9PVEhFUik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBFUlIoInNob3VsZG4ndCByZWFjaCBoZXJlLiBwaGFzZSAlZFxuIiwgcGhhc2UpOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgcFJwY01zZy0+QnVmZmVyTGVuZ3RoID0gKHVuc2lnbmVkIGludCkoc3R1Yk1zZy5CdWZmZXIgLSAodW5zaWduZWQgY2hhciAqKXBScGNNc2ctPkJ1ZmZlcik7CgogICAgaWYgKGV4dF9mbGFncy5IYXNOZXdDb3JyRGVzYykKICAgIHsKICAgICAgICAvKiBmcmVlIGV4dHJhIGNvcnJlbGF0aW9uIHBhY2thZ2UgKi8KICAgICAgICAvKiBOZHJDb3JyZWxhdGlvbkZyZWUoJnN0dWJNc2cpOyAqLwogICAgfQoKICAgIGlmIChPaWZfZmxhZ3MuSGFzUGlwZXMpCiAgICB7CiAgICAgICAgLyogTmRyUGlwZXNEb25lKC4uLikgKi8KICAgIH0KCiAgICAvKiBmcmVlIHRoZSBmdWxsIHBvaW50ZXIgdHJhbnNsYXRpb24gdGFibGVzICovCiAgICBpZiAocFByb2NIZWFkZXItPk9pX2ZsYWdzICYgUlBDX0ZDX1BST0NfT0lGX0ZVTExQVFIpCiAgICAgICAgTmRyRnVsbFBvaW50ZXJYbGF0RnJlZShzdHViTXNnLkZ1bGxQdHJYbGF0VGFibGVzKTsKCiAgICAvKiBmcmVlIHNlcnZlciBmdW5jdGlvbiBzdGFjayAqLwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYXJncyk7CgogICAgcmV0dXJuIFNfT0s7Cn0KCnZvaWQgV0lOQVBJIE5kclNlcnZlckNhbGwyKFBSUENfTUVTU0FHRSBwUnBjTXNnKQp7CiAgICBEV09SRCBkd1BoYXNlOwogICAgTmRyU3R1YkNhbGwyKE5VTEwsIE5VTEwsIHBScGNNc2csICZkd1BoYXNlKTsKfQo=