LyoKICpDb3B5cmlnaHQoYykyMDA0LENpc2NvIFVSUCBpbWJ1cnNlcyBhbmQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIgaW4gQmVpamluZyBVbml2ZXJzaXR5IG9mIFBvc3RzIGFuZCBUZWxlY29tbXVuaWNhdGlvbnMgcmVzZWFyY2hlcy4KICoKICpBbGwgcmlnaHQgcmVzZXJ2ZWQKICoKICpGaWxlIE5hbWU6bG9va3VwQ3RsVGFibGUuYwogKkZpbGUgRGVzY3JpcHRpb246Um93cyBvZiB0aGUgbG9va3VwQ3RsVGFibGUgTUlCIGFkZCAsIGRlbGV0ZSBhbmQgcmVhZC5Sb3dzIG9mIGxvb2t1cFJlc3VsdHNUYWJsZQogKiAgICAgICAgICAgICAgTUlCIGFkZCBhbmQgZGVsZXRlLgogKgogKkN1cnJlbnQgVmVyc2lvbjoxLjAKICpBdXRob3I6Q2hlbkppbmcKICpEYXRlOjIwMDQuOC4yMAogKi8KCi8qCiAqIFRoaXMgc2hvdWxkIGFsd2F5cyBiZSBpbmNsdWRlZCBmaXJzdCBiZWZvcmUgYW55dGhpbmcgZWxzZSAKICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgPGFycGEvaW5ldC5oPgojaW5jbHVkZSA8bmV0ZGIuaD4KCiNpbmNsdWRlICJsb29rdXBDdGxUYWJsZS5oIgojaW5jbHVkZSAibG9va3VwUmVzdWx0c1RhYmxlLmgiCiNpbmNsdWRlICJoZWFkZXJfY29tcGxleC5oIgoKI2lmbmRlZiBJTkVUQUREUkVTU1RZUEVfRU5VTVMKI2RlZmluZSBJTkVUQUREUkVTU1RZUEVfRU5VTVMKCiNkZWZpbmUgSU5FVEFERFJFU1NUWVBFX1VOS05PV04gIDAKI2RlZmluZSBJTkVUQUREUkVTU1RZUEVfSVBWNCAgICAgMQojZGVmaW5lIElORVRBRERSRVNTVFlQRV9JUFY2ICAgICAyCiNkZWZpbmUgSU5FVEFERFJFU1NUWVBFX0lQVjRaICAgIDMKI2RlZmluZSBJTkVUQUREUkVTU1RZUEVfSVBWNlogICAgNAojZGVmaW5lIElORVRBRERSRVNTVFlQRV9ETlMgICAgIDE2CgojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIElORVRBRERSRVNTVFlQRV9FTlVNUyAqLwoKLyoKICpGb3IgZGlzY29udGludWl0eSBjaGVja2luZy4KICovCgpvaWQgICAgICAgICAgICAgbG9va3VwQ3RsVGFibGVfdmFyaWFibGVzX29pZFtdID0KICAgIHsgMSwgMywgNiwgMSwgMiwgMSwgODIsIDEsIDMgfTsKCgpzdHJ1Y3QgdmFyaWFibGUyIGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc1tdID0gewogICAgLyoKICAgICAqIG1hZ2ljIG51bWJlciAgICAgICAgLCB2YXJpYWJsZSB0eXBlICwgcm8vcncgLCBjYWxsYmFjayBmbiAgLCBMLCBvaWRzdWZmaXgKICAgICAqLwogICAge0NPTFVNTl9MT09LVVBDVExUQVJHRVRBRERSRVNTVFlQRSwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JXUklURSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCAzfX0sCiAgICB7Q09MVU1OX0xPT0tVUENUTFRBUkdFVEFERFJFU1MsICAgQVNOX09DVEVUX1NUUiwgTkVUU05NUF9PTERBUElfUldSSVRFLAogICAgIHZhcl9sb29rdXBDdGxUYWJsZSwgMiwgezEsIDR9fSwKICAgIHtDT0xVTU5fTE9PS1VQQ1RMT1BFUlNUQVRVUywgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgIHZhcl9sb29rdXBDdGxUYWJsZSwgMiwgezEsIDV9fSwKICAgIHtDT0xVTU5fTE9PS1VQQ1RMVElNRSwgICAgICBBU05fVU5TSUdORUQsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgIHZhcl9sb29rdXBDdGxUYWJsZSwgMiwgezEsIDZ9fSwKICAgIHtDT0xVTU5fTE9PS1VQQ1RMUkMsICAgICAgICAgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgIHZhcl9sb29rdXBDdGxUYWJsZSwgMiwgezEsIDd9fSwKICAgIHtDT0xVTU5fTE9PS1VQQ1RMUk9XU1RBVFVTLCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUldSSVRFLAogICAgIHZhcl9sb29rdXBDdGxUYWJsZSwgMiwgezEsIDh9fQp9OwoKCi8qCiAqIGdsb2JhbCBzdG9yYWdlIG9mIG91ciBkYXRhLCBzYXZlZCBpbiBhbmQgY29uZmlndXJlZCBieSBoZWFkZXJfY29tcGxleCgpIAogKi8KCnN0cnVjdCBoZWFkZXJfY29tcGxleF9pbmRleCAqbG9va3VwQ3RsVGFibGVTdG9yYWdlID0gTlVMTDsKc3RydWN0IGhlYWRlcl9jb21wbGV4X2luZGV4ICpsb29rdXBSZXN1bHRzVGFibGVTdG9yYWdlID0gTlVMTDsKCmludCBtb2RpZnlfbG9va3VwQ3RsVGltZShzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqdGhlZGF0YSwgdW5zaWduZWQgbG9uZyB2YWwpOwppbnQgbW9kaWZ5X2xvb2t1cEN0bE9wZXJTdGF0dXMoc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKnRoZWRhdGEsIGxvbmcgdmFsKTsKaW50IG1vZGlmeV9sb29rdXBDdGxSYyhzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqdGhlZGF0YSwgbG9uZyB2YWwpOwoKdm9pZAppbml0X2xvb2t1cEN0bFRhYmxlKHZvaWQpCnsKICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsICJpbml0aWFsaXppbmcuLi4gICIpKTsKICAgIC8qCiAgICAgKiByZWdpc3RlciBvdXJzZWx2ZXMgd2l0aCB0aGUgYWdlbnQgdG8gaGFuZGxlIG91ciBtaWIgdHJlZSAKICAgICAqLwogICAgUkVHSVNURVJfTUlCKCJsb29rdXBDdGxUYWJsZSIsIGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlcywgdmFyaWFibGUyLAogICAgICAgICAgICAgICAgIGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc19vaWQpOwoKCiAgICAvKgogICAgICogcmVnaXN0ZXIgb3VyIGNvbmZpZyBoYW5kbGVyKHMpIHRvIGRlYWwgd2l0aCByZWdpc3RyYXRpb25zIAogICAgICovCiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigibG9va3VwQ3RsVGFibGUiLCBwYXJzZV9sb29rdXBDdGxUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwoKICAgIC8qCiAgICAgKiB3ZSBuZWVkIHRvIGJlIGNhbGxlZCBiYWNrIGxhdGVyIHRvIHN0b3JlIG91ciBkYXRhIAogICAgICovCiAgICBzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwgU05NUF9DQUxMQkFDS19TVE9SRV9EQVRBLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZV9sb29rdXBDdGxUYWJsZSwgTlVMTCk7CgogICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgImRvbmUuXG4iKSk7Cn0KCnN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICoKY3JlYXRlX2xvb2t1cFRhYmxlX2RhdGEodm9pZCkKewogICAgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VOZXcgPSBOVUxMOwogICAgU3RvcmFnZU5ldyA9IFNOTVBfTUFMTE9DX1NUUlVDVChsb29rdXBUYWJsZV9kYXRhKTsKICAgIGlmIChTdG9yYWdlTmV3ID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiT3V0IGluIG1lbW9yeSBpbiBuc2xvb2t1cC1taWIvY3JlYXRlX2xvb2t1cFRhYmxlX2RhdGVcbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CiAgICBTdG9yYWdlTmV3LT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzID0gc3RyZHVwKCIiKTsKICAgIFN0b3JhZ2VOZXctPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NMZW4gPSAwOwogICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsT3BlclN0YXR1cyA9IDJMOwogICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsVGltZSA9IDA7CiAgICBTdG9yYWdlTmV3LT5zdG9yYWdldHlwZSA9IFNUX05PTlZPTEFUSUxFOwogICAgcmV0dXJuIFN0b3JhZ2VOZXc7Cn0KCi8qCiAqIGxvb2t1cEN0bFRhYmxlX2FkZCgpOiBhZGRzIGEgc3RydWN0dXJlIG5vZGUgdG8gb3VyIGRhdGEgc2V0IAogKi8KaW50Cmxvb2t1cEN0bFRhYmxlX2FkZChzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqdGhlZGF0YSkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJzID0gTlVMTDsKCiAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLCAiYWRkaW5nIGRhdGEuLi4gICIpKTsKICAgIC8qCiAgICAgKiBhZGQgdGhlIGluZGV4IHZhcmlhYmxlcyB0byB0aGUgdmFyYmluZCBsaXN0LCB3aGljaCBpcyAKICAgICAqIHVzZWQgYnkgaGVhZGVyX2NvbXBsZXggdG8gaW5kZXggdGhlIGRhdGEgCiAgICAgKi8KICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleCwKICAgICAgICB0aGVkYXRhLT5sb29rdXBDdGxPd25lckluZGV4TGVuKTsKICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSwKICAgICAgICB0aGVkYXRhLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuKTsKCgogICAgaWYgKGhlYWRlcl9jb21wbGV4X2FkZF9kYXRhKCZsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIHZhcnMsIHRoZWRhdGEpID09CiAgICAgICAgTlVMTCkgewogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsICJyZWdpc3RlcmVkIGFuIGVudHJ5XG4iKSk7CiAgICB2YXJzID0gTlVMTDsKCiAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLCAiZG9uZS5cbiIpKTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCmludApsb29rdXBSZXN1bHRzVGFibGVfYWRkKHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICp0aGVkYXRhKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnNfbGlzdCA9IE5VTEw7CiAgICBzdHJ1Y3QgbG9va3VwUmVzdWx0c1RhYmxlX2RhdGEgKnAgPSBOVUxMOwogICAgcCA9IHRoZWRhdGEtPlJlc3VsdHNUYWJsZTsKICAgIGlmICh0aGVkYXRhLT5SZXN1bHRzVGFibGUgIT0gTlVMTCkKICAgICAgICBkbyB7CiAgICAgICAgICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnNfbGlzdCwgTlVMTCwgMCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgIChjaGFyICopIHAtPmxvb2t1cEN0bE93bmVySW5kZXgsCiAgICAgICAgICAgICAgICBwLT5sb29rdXBDdGxPd25lckluZGV4TGVuKTsKICAgICAgICAgICAgc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSgmdmFyc19saXN0LCBOVUxMLCAwLCBBU05fT0NURVRfU1RSLAogICAgICAgICAgICAgICAgKGNoYXIgKikgcC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSwKICAgICAgICAgICAgICAgIHAtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWVMZW4pOwogICAgICAgICAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZ2YXJzX2xpc3QsIE5VTEwsIDAsIEFTTl9VTlNJR05FRCwKICAgICAgICAgICAgICAgIChjaGFyICopICZwLT5sb29rdXBSZXN1bHRzSW5kZXgsCiAgICAgICAgICAgICAgICBzaXplb2YocC0+bG9va3VwUmVzdWx0c0luZGV4KSk7CgogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwUmVzdWx0c1RhYmxlIiwgImFkZGluZyBkYXRhLi4uICAiKSk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFkZCB0aGUgaW5kZXggdmFyaWFibGVzIHRvIHRoZSB2YXJiaW5kIGxpc3QsIHdoaWNoIGlzIAogICAgICAgICAgICAgKiB1c2VkIGJ5IGhlYWRlcl9jb21wbGV4IHRvIGluZGV4IHRoZSBkYXRhIAogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmIChoZWFkZXJfY29tcGxleF9hZGRfZGF0YQogICAgICAgICAgICAgICAgKCZsb29rdXBSZXN1bHRzVGFibGVTdG9yYWdlLCB2YXJzX2xpc3QsIHApID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cFJlc3VsdHNUYWJsZSIsICJvdXQgZmluaXNoZWRcbiIpKTsKICAgICAgICAgICAgdmFyc19saXN0ID0gTlVMTDsKICAgICAgICAgICAgcCA9IHAtPm5leHQ7CiAgICAgICAgfSB3aGlsZSAocCAhPSBOVUxMKTsKCiAgICBERUJVR01TR1RMKCgibG9va3VwUmVzdWx0c1RhYmxlIiwgImRvbmUuXG4iKSk7CiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9Cgp2b2lkCmxvb2t1cEN0bFRhYmxlX2NsZWFuZXIoc3RydWN0IGhlYWRlcl9jb21wbGV4X2luZGV4ICp0aGVzdHVmZikKewogICAgc3RydWN0IGhlYWRlcl9jb21wbGV4X2luZGV4ICpoY2lwdHIgPSBOVUxMOwogICAgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VEZWwgPSBOVUxMOwogICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgImNsZWFuZXJvdXQgICIpKTsKICAgIGZvciAoaGNpcHRyID0gdGhlc3R1ZmY7IGhjaXB0ciAhPSBOVUxMOyBoY2lwdHIgPSBoY2lwdHItPm5leHQpIHsKICAgICAgICBTdG9yYWdlRGVsID0KICAgICAgICAgICAgaGVhZGVyX2NvbXBsZXhfZXh0cmFjdF9lbnRyeSgmbG9va3VwQ3RsVGFibGVTdG9yYWdlLCBoY2lwdHIpOwogICAgICAgIGlmIChTdG9yYWdlRGVsICE9IE5VTEwpIHsKICAgICAgICAgICAgZnJlZShTdG9yYWdlRGVsLT5sb29rdXBDdGxPd25lckluZGV4KTsKICAgICAgICAgICAgU3RvcmFnZURlbC0+bG9va3VwQ3RsT3duZXJJbmRleCA9IE5VTEw7CiAgICAgICAgICAgIGZyZWUoU3RvcmFnZURlbC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSk7CiAgICAgICAgICAgIFN0b3JhZ2VEZWwtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUgPSBOVUxMOwogICAgICAgICAgICBmcmVlKFN0b3JhZ2VEZWwtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MpOwogICAgICAgICAgICBTdG9yYWdlRGVsLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzID0gTlVMTDsKICAgICAgICAgICAgZnJlZShTdG9yYWdlRGVsKTsKICAgICAgICAgICAgU3RvcmFnZURlbCA9IE5VTEw7CgogICAgICAgIH0KICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLCAiY2xlYW5lciAgIikpOwogICAgfQp9CgovKgogKiBwYXJzZV9sb29rdXBDdGxUYWJsZSgpOgogKiAgIHBhcnNlcyAuY29uZiBmaWxlIGVudHJpZXMgbmVlZGVkIHRvIGNvbmZpZ3VyZSB0aGUgbWliLgogKi8Kdm9pZApwYXJzZV9sb29rdXBDdGxUYWJsZShjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqbGluZSkKewogICAgc2l6ZV90ICAgICAgICAgIHRtcGludDsKICAgIHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICpTdG9yYWdlVG1wID0gU05NUF9NQUxMT0NfU1RSVUNUKGxvb2t1cFRhYmxlX2RhdGEpOwoKICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsICJwYXJzaW5nIGNvbmZpZy4uLiAgIikpOwoKCiAgICBpZiAoU3RvcmFnZVRtcCA9PSBOVUxMKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigibWFsbG9jIGZhaWx1cmUiKTsKICAgICAgICByZXR1cm47CiAgICB9CgoKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfZGF0YShBU05fT0NURVRfU1RSLCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsT3duZXJJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bE93bmVySW5kZXhMZW4pOwogICAgaWYgKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bE93bmVySW5kZXggPT0gTlVMTCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoImludmFsaWQgc3BlY2lmaWNhdGlvbiBmb3IgbG9va3VwQ3RsT3duZXJJbmRleCIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsaW5lID0KICAgICAgICByZWFkX2NvbmZpZ19yZWFkX2RhdGEoQVNOX09DVEVUX1NUUiwgbGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdG9yYWdlVG1wLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuKTsKICAgIGlmIChTdG9yYWdlVG1wLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lID09IE5VTEwpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJpbnZhbGlkIHNwZWNpZmljYXRpb24gZm9yIGxvb2t1cEN0bE9wZXJhdGlvbk5hbWUiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgbGluZSA9CiAgICAgICAgcmVhZF9jb25maWdfcmVhZF9kYXRhKEFTTl9JTlRFR0VSLCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0bXBpbnQpOwoKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfZGF0YShBU05fT0NURVRfU1RSLCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NMZW4pOwogICAgaWYgKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MgPT0gTlVMTCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoImludmFsaWQgc3BlY2lmaWNhdGlvbiBmb3IgbG9va3VwQ3RsVGFyZ2V0QWRkcmVzcyIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsaW5lID0KICAgICAgICByZWFkX2NvbmZpZ19yZWFkX2RhdGEoQVNOX0lOVEVHRVIsIGxpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdG9yYWdlVG1wLT5sb29rdXBDdGxPcGVyU3RhdHVzLCAmdG1waW50KTsKCiAgICBsaW5lID0KICAgICAgICByZWFkX2NvbmZpZ19yZWFkX2RhdGEoQVNOX1VOU0lHTkVELCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGltZSwgJnRtcGludCk7CgogICAgbGluZSA9CiAgICAgICAgcmVhZF9jb25maWdfcmVhZF9kYXRhKEFTTl9JTlRFR0VSLCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsUmMsICZ0bXBpbnQpOwoKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfZGF0YShBU05fSU5URUdFUiwgbGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJvd1N0YXR1cywgJnRtcGludCk7CgoKICAgIFN0b3JhZ2VUbXAtPnN0b3JhZ2V0eXBlID0gU1RfTk9OVk9MQVRJTEU7CiAgICBsb29rdXBDdGxUYWJsZV9hZGQoU3RvcmFnZVRtcCk7CiAgICAvKiBsb29rdXBDdGxUYWJsZV9jbGVhbmVyKGxvb2t1cEN0bFRhYmxlU3RvcmFnZSk7ICovCgogICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgImRvbmUuXG4iKSk7Cn0KCgoKLyoKICogc3RvcmVfbG9va3VwQ3RsVGFibGUoKToKICogICBzdG9yZXMgLmNvbmYgZmlsZSBlbnRyaWVzIG5lZWRlZCB0byBjb25maWd1cmUgdGhlIG1pYi4KICovCmludApzdG9yZV9sb29rdXBDdGxUYWJsZShpbnQgbWFqb3JJRCwgaW50IG1pbm9ySUQsIHZvaWQgKnNlcnZlcmFyZywKICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xpZW50YXJnKQp7CiAgICBjaGFyICAgICAgICAgICAgbGluZVtTTk1QX01BWEJVRl07CiAgICBjaGFyICAgICAgICAgICAqY3B0cjsKICAgIHNpemVfdCAgICAgICAgICB0bXBpbnQ7CiAgICBzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqU3RvcmFnZVRtcDsKICAgIHN0cnVjdCBoZWFkZXJfY29tcGxleF9pbmRleCAqaGNpbmRleDsKCiAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLCAic3RvcmluZyBkYXRhLi4uICAiKSk7CgogICAgZm9yIChoY2luZGV4ID0gbG9va3VwQ3RsVGFibGVTdG9yYWdlOyBoY2luZGV4ICE9IE5VTEw7CiAgICAgICAgIGhjaW5kZXggPSBoY2luZGV4LT5uZXh0KSB7CiAgICAgICAgU3RvcmFnZVRtcCA9IChzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqKSBoY2luZGV4LT5kYXRhOwoKICAgICAgICBpZiAoU3RvcmFnZVRtcC0+c3RvcmFnZXR5cGUgIT0gU1RfUkVBRE9OTFkpIHsKICAgICAgICAgICAgbWVtc2V0KGxpbmUsIDAsIHNpemVvZihsaW5lKSk7CiAgICAgICAgICAgIHN0cmNhdChsaW5lLCAibG9va3VwQ3RsVGFibGUgIik7CiAgICAgICAgICAgIGNwdHIgPSBsaW5lICsgc3RybGVuKGxpbmUpOwoKICAgICAgICAgICAgY3B0ciA9CiAgICAgICAgICAgICAgICByZWFkX2NvbmZpZ19zdG9yZV9kYXRhKEFTTl9PQ1RFVF9TVFIsIGNwdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdG9yYWdlVG1wLT5sb29rdXBDdGxPd25lckluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb2t1cEN0bE93bmVySW5kZXhMZW4pOwogICAgICAgICAgICBjcHRyID0KICAgICAgICAgICAgICAgIHJlYWRfY29uZmlnX3N0b3JlX2RhdGEoQVNOX09DVEVUX1NUUiwgY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdG9yYWdlVG1wLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbik7CiAgICAgICAgICAgIGNwdHIgPQogICAgICAgICAgICAgICAgcmVhZF9jb25maWdfc3RvcmVfZGF0YShBU05fSU5URUdFUiwgY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29rdXBDdGxUYXJnZXRBZGRyZXNzVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRtcGludCk7CiAgICAgICAgICAgIGNwdHIgPQogICAgICAgICAgICAgICAgcmVhZF9jb25maWdfc3RvcmVfZGF0YShBU05fT0NURVRfU1RSLCBjcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29rdXBDdGxUYXJnZXRBZGRyZXNzTGVuKTsKCiAgICAgICAgICAgIGNwdHIgPQogICAgICAgICAgICAgICAgcmVhZF9jb25maWdfc3RvcmVfZGF0YShBU05fSU5URUdFUiwgY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bE9wZXJTdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0bXBpbnQpOwogICAgICAgICAgICBjcHRyID0KICAgICAgICAgICAgICAgIHJlYWRfY29uZmlnX3N0b3JlX2RhdGEoQVNOX1VOU0lHTkVELCBjcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRtcGludCk7CiAgICAgICAgICAgIGNwdHIgPQogICAgICAgICAgICAgICAgcmVhZF9jb25maWdfc3RvcmVfZGF0YShBU05fSU5URUdFUiwgY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJjLCAmdG1waW50KTsKICAgICAgICAgICAgY3B0ciA9CiAgICAgICAgICAgICAgICByZWFkX2NvbmZpZ19zdG9yZV9kYXRhKEFTTl9JTlRFR0VSLCBjcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdG1waW50KTsKICAgICAgICAgICAgc25tcGRfc3RvcmVfY29uZmlnKGxpbmUpOwogICAgICAgIH0KICAgIH0KICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsICJkb25lLlxuIikpOwogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKCgoKLyoKICogdmFyX2xvb2t1cEN0bFRhYmxlKCk6CiAqICAgSGFuZGxlIHRoaXMgdGFibGUgc2VwYXJhdGVseSBmcm9tIHRoZSBzY2FsYXIgdmFsdWUgY2FzZS4KICogICBUaGUgd29ya2luZ3Mgb2YgdGhpcyBhcmUgYmFzaWNhbGx5IHRoZSBzYW1lIGFzIGZvciB2YXJfbXRlT2JqZWN0c1RhYmxlIGFib3ZlLgogKi8KdW5zaWduZWQgY2hhciAgKgp2YXJfbG9va3VwQ3RsVGFibGUoc3RydWN0IHZhcmlhYmxlICp2cCwKICAgICAgICAgICAgICAgICAgIG9pZCAqIG5hbWUsCiAgICAgICAgICAgICAgICAgICBzaXplX3QgKmxlbmd0aCwKICAgICAgICAgICAgICAgICAgIGludCBleGFjdCwgc2l6ZV90ICp2YXJfbGVuLCBXcml0ZU1ldGhvZCAqKiB3cml0ZV9tZXRob2QpCnsKICAgIHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICpTdG9yYWdlVG1wID0gTlVMTDsKCiAgICAvKgogICAgICogdGhpcyBhc3N1bWVzIHlvdSBoYXZlIHJlZ2lzdGVyZWQgYWxsIHlvdXIgZGF0YSBwcm9wZXJseQogICAgICovCiAgICBpZiAoKFN0b3JhZ2VUbXAgPQogICAgICAgICBoZWFkZXJfY29tcGxleChsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIHZwLCBuYW1lLCBsZW5ndGgsIGV4YWN0LAogICAgICAgICAgICAgICAgICAgICAgICB2YXJfbGVuLCB3cml0ZV9tZXRob2QpKSA9PSBOVUxMKSB7CiAgICAgICAgaWYgKHZwLT5tYWdpYyA9PSBDT0xVTU5fTE9PS1VQQ1RMUk9XU1RBVFVTKQogICAgICAgICAgICAqd3JpdGVfbWV0aG9kID0gd3JpdGVfbG9va3VwQ3RsUm93U3RhdHVzOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qCiAgICAgKiB0aGlzIGlzIHdoZXJlIHdlIGRvIHRoZSB2YWx1ZSBhc3NpZ25tZW50cyBmb3IgdGhlIG1pYiByZXN1bHRzLgogICAgICovCiAgICBzd2l0Y2ggKHZwLT5tYWdpYykgewogICAgY2FzZSBDT0xVTU5fTE9PS1VQQ1RMVEFSR0VUQUREUkVTU1RZUEU6CiAgICAgICAgKndyaXRlX21ldGhvZCA9IHdyaXRlX2xvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlOwogICAgICAgICp2YXJfbGVuID0gc2l6ZW9mKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlKTsKICAgICAgICByZXR1cm4gKHVfY2hhciAqKSAmIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlOwoKICAgIGNhc2UgQ09MVU1OX0xPT0tVUENUTFRBUkdFVEFERFJFU1M6CiAgICAgICAgKndyaXRlX21ldGhvZCA9IHdyaXRlX2xvb2t1cEN0bFRhcmdldEFkZHJlc3M7CiAgICAgICAgKnZhcl9sZW4gPSAoU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc0xlbik7CiAgICAgICAgcmV0dXJuICh1X2NoYXIgKikgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzczsKCiAgICBjYXNlIENPTFVNTl9MT09LVVBDVExPUEVSU1RBVFVTOgogICAgICAgICp2YXJfbGVuID0gc2l6ZW9mKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bE9wZXJTdGF0dXMpOwogICAgICAgIHJldHVybiAodV9jaGFyICopICYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsT3BlclN0YXR1czsKCiAgICBjYXNlIENPTFVNTl9MT09LVVBDVExUSU1FOgogICAgICAgICp2YXJfbGVuID0gc2l6ZW9mKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRpbWUpOwogICAgICAgIHJldHVybiAodV9jaGFyICopICYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGltZTsKCiAgICBjYXNlIENPTFVNTl9MT09LVVBDVExSQzoKICAgICAgICAqdmFyX2xlbiA9IHNpemVvZihTdG9yYWdlVG1wLT5sb29rdXBDdGxSYyk7CiAgICAgICAgcmV0dXJuICh1X2NoYXIgKikgJiBTdG9yYWdlVG1wLT5sb29rdXBDdGxSYzsKCiAgICBjYXNlIENPTFVNTl9MT09LVVBDVExST1dTVEFUVVM6CiAgICAgICAgKndyaXRlX21ldGhvZCA9IHdyaXRlX2xvb2t1cEN0bFJvd1N0YXR1czsKICAgICAgICAqdmFyX2xlbiA9IHNpemVvZihTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXMpOwogICAgICAgIHJldHVybiAodV9jaGFyICopICYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgRVJST1JfTVNHKCIiKTsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgoKc3RhdGljIHN0cnVjdCBsb29rdXBSZXN1bHRzVGFibGVfZGF0YSAqCmFkZF9yZXN1bHQoc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKml0ZW0sIGludCBpbmRleCwKICAgICAgICBpbnQgaWF0eXBlLCBjb25zdCB2b2lkICpkYXRhLCBzaXplX3QgZGF0YV9sZW4pCnsKICAgIHN0cnVjdCBsb29rdXBSZXN1bHRzVGFibGVfZGF0YSAqdGVtcDsKICAgIHRlbXAgPSBTTk1QX01BTExPQ19TVFJVQ1QobG9va3VwUmVzdWx0c1RhYmxlX2RhdGEpOwogICAgaWYgKHRlbXAgPT0gTlVMTCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJPdXQgb2YgbWVtb3J5IGluIG5zbG9va3VwLW1pYi9ydW5fbG9va3VwXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHRlbXAtPmxvb2t1cFJlc3VsdHNJbmRleCA9IGluZGV4OwogICAgdGVtcC0+bmV4dCA9IE5VTEw7CgogICAgdGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleCA9IG1hbGxvYyhpdGVtLT5sb29rdXBDdGxPd25lckluZGV4TGVuICsgMSk7CiAgICBpZiAodGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleCA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIk91dCBvZiBtZW1vcnkgaW4gbnNsb29rdXAtbWliL3J1bl9sb29rdXBcbiIpOwogICAgICAgIGZyZWUodGVtcCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBtZW1jcHkodGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleCwKICAgICAgICAgICBpdGVtLT5sb29rdXBDdGxPd25lckluZGV4LAogICAgICAgICAgIGl0ZW0tPmxvb2t1cEN0bE93bmVySW5kZXhMZW4gKyAxKTsKICAgIHRlbXAtPmxvb2t1cEN0bE93bmVySW5kZXhbaXRlbS0+bG9va3VwQ3RsT3duZXJJbmRleExlbl0gPSAnXDAnOwogICAgdGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleExlbiA9IGl0ZW0tPmxvb2t1cEN0bE93bmVySW5kZXhMZW47CgogICAgdGVtcC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSA9IG1hbGxvYyhpdGVtLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuICsgMSk7CiAgICBpZiAodGVtcC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIk91dCBvZiBtZW1vcnkgaW4gbnNsb29rdXAtbWliL3J1bl9sb29rdXBcbiIpOwogICAgICAgIGZyZWUodGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleCk7CiAgICAgICAgZnJlZSh0ZW1wKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIG1lbWNweSh0ZW1wLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lLAogICAgICAgICAgIGl0ZW0tPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgICAgaXRlbS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbiArIDEpOwogICAgdGVtcC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZVtpdGVtLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuXSA9ICdcMCc7CiAgICB0ZW1wLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuID0gaXRlbS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbjsKCiAgICB0ZW1wLT5sb29rdXBSZXN1bHRzQWRkcmVzc1R5cGUgPSBpYXR5cGU7CiAgICB0ZW1wLT5sb29rdXBSZXN1bHRzQWRkcmVzcyA9IG1hbGxvYyhkYXRhX2xlbiArIDEpOwogICAgbWVtY3B5KHRlbXAtPmxvb2t1cFJlc3VsdHNBZGRyZXNzLCBkYXRhLCBkYXRhX2xlbik7CiAgICB0ZW1wLT5sb29rdXBSZXN1bHRzQWRkcmVzc1tkYXRhX2xlbl0gPSAnXDAnOwogICAgdGVtcC0+bG9va3VwUmVzdWx0c0FkZHJlc3NMZW4gPSBkYXRhX2xlbjsKICAgIGlmICghaXRlbS0+UmVzdWx0c1RhYmxlKQogICAgICAgIGl0ZW0tPlJlc3VsdHNUYWJsZSA9IHRlbXA7CgogICAgcmV0dXJuIHRlbXA7Cn0KCnZvaWQKcnVuX2xvb2t1cChzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqaXRlbSkKewogICAgbG9uZyAgICAgICAgICAgIGFkZHJlc3NUeXBlOwogICAgY2hhciAgICAgICAgICAgKmFkZHJlc3MgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIGFkZHJlc3NsZW47CiAgICBzdHJ1Y3QgbG9va3VwUmVzdWx0c1RhYmxlX2RhdGEgKmN1cnJlbnQgPSBOVUxMOwogICAgc3RydWN0IGxvb2t1cFJlc3VsdHNUYWJsZV9kYXRhICp0ZW1wID0gTlVMTDsKICAgIGludCAgICAgICAgICAgICBpID0gMCwgbiA9IDE7CgogICAgc3RydWN0IHRpbWV2YWwgIHRwc3RhcnQsIHRwZW5kOwogICAgdW5zaWduZWQgbG9uZyAgIHRpbWV1c2UsIHRpbWV1c2U0ID0gMCwgdGltZXVzZTYgPSAwOwoKICAgIGlmIChpdGVtID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGFkZHJlc3NUeXBlID0gKGxvbmcpIGl0ZW0tPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlOwogICAgYWRkcmVzc2xlbiA9IChzaXplX3QpIGl0ZW0tPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NMZW47CiAgICBhZGRyZXNzID0gKGNoYXIgKikgbWFsbG9jKGFkZHJlc3NsZW4gKyAxKTsKICAgIG1lbWNweShhZGRyZXNzLCBpdGVtLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzLCBhZGRyZXNzbGVuICsgMSk7CiAgICBhZGRyZXNzW2FkZHJlc3NsZW5dID0gJ1wwJzsKCiAgICBpZiAoYWRkcmVzc1R5cGUgPT0gSU5FVEFERFJFU1NUWVBFX0lQVjQpIHsKICAgICAgICBzdHJ1Y3QgaW5fYWRkciBhZGRyX2luOwogICAgICAgIHN0cnVjdCBob3N0ZW50ICpsb29rdXA7CgogICAgICAgIGlmIChpbmV0X3B0b24oQUZfSU5FVCwgYWRkcmVzcywgJmFkZHJfaW4pICE9IDEpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cFJlc3VsdHNUYWJsZSIsICJJbnZhbGlkIGFyZ3VtZW50OiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcykpOwogICAgICAgICAgICBtb2RpZnlfbG9va3VwQ3RsUmMoaXRlbSwgOTkpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBnZXR0aW1lb2ZkYXkoJnRwc3RhcnQsIE5VTEwpOwogICAgICAgIGxvb2t1cCA9IGdldGhvc3RieWFkZHIoJmFkZHJfaW4sIHNpemVvZihhZGRyX2luKSwgQUZfSU5FVCk7CiAgICAgICAgZ2V0dGltZW9mZGF5KCZ0cGVuZCwgTlVMTCk7CiAgICAgICAgdGltZXVzZSA9IDEwMDAwMDAgKiAodHBlbmQudHZfc2VjIC0gdHBzdGFydC50dl9zZWMpICsKICAgICAgICAgICAgdHBlbmQudHZfdXNlYyAtIHRwc3RhcnQudHZfdXNlYzsKICAgICAgICB0aW1ldXNlIC89IDEwMDA7CiAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFRpbWUoaXRlbSwgdGltZXVzZSk7CiAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bE9wZXJTdGF0dXMoaXRlbSwgM0wpOwoKICAgICAgICBpZiAobG9va3VwID09IE5VTEwpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIkNhbid0IGdldCBhIG5ldHdvcmsgaG9zdCBlbnRyeSBmb3IgaXB2NCBhZGRyZXNzOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcykpOwogICAgICAgICAgICBtb2RpZnlfbG9va3VwQ3RsUmMoaXRlbSwgaF9lcnJubyk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBtb2RpZnlfbG9va3VwQ3RsUmMoaXRlbSwgMEwpOwogICAgICAgICAgICBpZiAobG9va3VwLT5oX25hbWUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgY3VycmVudCA9IHRlbXAgPSBhZGRfcmVzdWx0KGl0ZW0sIG4sIElORVRBRERSRVNTVFlQRV9ETlMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29rdXAtPmhfbmFtZSwgc3RybGVuKGxvb2t1cC0+aF9uYW1lKSk7CiAgICAgICAgICAgICAgICBuID0gbiArIDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGkgPSAwOwogICAgICAgICAgICB3aGlsZSAobG9va3VwLT5oX2FsaWFzZXNbaV0pIHsKICAgICAgICAgICAgICAgIHRlbXAgPSBhZGRfcmVzdWx0KGl0ZW0sIG4sIElORVRBRERSRVNTVFlQRV9ETlMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29rdXAtPmhfYWxpYXNlc1tpXSwgc3RybGVuKGxvb2t1cC0+aF9hbGlhc2VzW2ldKSk7CiAgICAgICAgICAgICAgICBjdXJyZW50LT5uZXh0ID0gdGVtcDsKICAgICAgICAgICAgICAgIGN1cnJlbnQgPSB0ZW1wOwogICAgICAgICAgICAgICAgaSA9IGkgKyAxOwogICAgICAgICAgICAgICAgbiA9IG4gKyAxOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAoaXRlbS0+UmVzdWx0c1RhYmxlICE9IE5VTEwpCiAgICAgICAgICAgIGlmIChsb29rdXBSZXN1bHRzVGFibGVfYWRkKGl0ZW0pICE9IFNOTVBFUlJfU1VDQ0VTUykKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJsb29rdXBSZXN1bHRzVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlZ2lzdGVyZWQgYW4gZW50cnkgZXJyb3JcbiIpKTsKICAgICAgICBTTk1QX0ZSRUUoYWRkcmVzcyk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGVsc2UgaWYgKGFkZHJlc3NUeXBlID09IElORVRBRERSRVNTVFlQRV9ETlMpIHsKICAgICAgICBzdHJ1Y3QgaG9zdGVudCAqbG9va3VwOwojaWYgSEFWRV9HRVRBRERSSU5GTwogICAgICAgIGludCAgICAgICAgICAgICByZXM7CiAgICAgICAgc3RydWN0IGFkZHJpbmZvICphaXM7CiAgICAgICAgc3RydWN0IGFkZHJpbmZvIGhpbnRzID0geyAwLCBBRl9JTkVUNiwgU09DS19ER1JBTSB9OwojZW5kaWYKCiAgICAgICAgZ2V0dGltZW9mZGF5KCZ0cHN0YXJ0LCBOVUxMKTsKICAgICAgICBsb29rdXAgPSBnZXRob3N0YnluYW1lKGFkZHJlc3MpOwogICAgICAgIGdldHRpbWVvZmRheSgmdHBlbmQsIE5VTEwpOwogICAgICAgIHRpbWV1c2U0ID0gMTAwMDAwMCAqICh0cGVuZC50dl9zZWMgLSB0cHN0YXJ0LnR2X3NlYykgKwogICAgICAgICAgICB0cGVuZC50dl91c2VjIC0gdHBzdGFydC50dl91c2VjOwogICAgICAgIGlmIChsb29rdXAgPT0gTlVMTCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IGEgbmV0d29yayBob3N0IGVudHJ5IGZvciAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcykpOwogICAgICAgICAgICBtb2RpZnlfbG9va3VwQ3RsUmMoaXRlbSwgaF9lcnJubyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgd2hpbGUgKGxvb2t1cC0+aF9hZGRyX2xpc3RbaV0pIHsKICAgICAgICAgICAgICAgIGNoYXIgYnVmWzY0XTsKICAgICAgICAgICAgICAgIGludCBidWZsZW47CgogICAgICAgICAgICAgICAgaW5ldF9udG9wKGxvb2t1cC0+aF9hZGRydHlwZSwgbG9va3VwLT5oX2FkZHJfbGlzdFtpXSwgYnVmLCBzaXplb2YoYnVmKSk7CiAgICAgICAgICAgICAgICBidWZsZW4gPSBzdHJsZW4oYnVmKTsKICAgICAgICAgICAgICAgIHN3aXRjaCAobG9va3VwLT5oX2FkZHJ0eXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlIEFGX0lORVQ6CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0lQVjQsIGJ1ZiwgYnVmbGVuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQUZfSU5FVDY6CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0lQVjYsIGJ1ZiwgYnVmbGVuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5zbG9va3VwLW1pYi9ydW5fbG9va3VwOiBVbmtub3duIGFkZHJlc3MgdHlwZSAlZFxuIiwgbG9va3VwLT5oX2FkZHJ0eXBlKTsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfVU5LTk9XTiwgIiIsIDApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmIChuID09IDEpCiAgICAgICAgICAgICAgICAgICAgaXRlbS0+UmVzdWx0c1RhYmxlID0gdGVtcDsKICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBjdXJyZW50LT5uZXh0ID0gdGVtcDsKICAgICAgICAgICAgICAgIGN1cnJlbnQgPSB0ZW1wOwogICAgICAgICAgICAgICAgbiA9IG4gKyAxOwogICAgICAgICAgICAgICAgaSA9IGkgKyAxOwogICAgICAgICAgICB9CiAgICAgICAgfQoKI2lmIEhBVkVfR0VUQUREUklORk8KICAgICAgICBnZXR0aW1lb2ZkYXkoJnRwc3RhcnQsIE5VTEwpOwogICAgICAgIHJlcyA9IGdldGFkZHJpbmZvKGFkZHJlc3MsIE5VTEwsICZoaW50cywgJmFpcyk7CiAgICAgICAgZ2V0dGltZW9mZGF5KCZ0cGVuZCwgTlVMTCk7CiAgICAgICAgdGltZXVzZTYgPSAxMDAwMDAwICogKHRwZW5kLnR2X3NlYyAtIHRwc3RhcnQudHZfc2VjKSArCiAgICAgICAgICAgIHRwZW5kLnR2X3VzZWMgLSB0cHN0YXJ0LnR2X3VzZWM7CgogICAgICAgIGlmIChyZXMgIT0gMCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IGEgaXB2NiBuZXR3b3JrIGhvc3QgZW50cnkgZm9yICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzKSk7CiAgICAgICAgICAgIG1vZGlmeV9sb29rdXBDdGxSYyhpdGVtLCByZXMpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHN0cnVjdCBhZGRyaW5mbyAqYWlwID0gYWlzOwogICAgICAgICAgICB3aGlsZSAoYWlwKSB7CiAgICAgICAgICAgICAgICBjaGFyIGJ1Zls2NF07CiAgICAgICAgICAgICAgICBpbnQgYnVmbGVuOwoKICAgICAgICAgICAgICAgIHN3aXRjaCAoYWlwLT5haV9mYW1pbHkpIHsKICAgICAgICAgICAgICAgIGNhc2UgQUZfSU5FVDoKICAgICAgICAgICAgICAgICAgICBpbmV0X250b3AoYWlwLT5haV9mYW1pbHksCiAgICAgICAgICAgICAgICAgICAgICAgICYoKHN0cnVjdCBzb2NrYWRkcl9pbiAqKWFpcC0+YWlfYWRkciktPnNpbl9hZGRyLAogICAgICAgICAgICAgICAgICAgICAgICBidWYsIHNpemVvZihidWYpKTsKICAgICAgICAgICAgICAgICAgICBidWZsZW4gPSBzdHJsZW4oYnVmKTsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfSVBWNCwgYnVmLCBidWZsZW4pOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBBRl9JTkVUNjoKICAgICAgICAgICAgICAgICAgICBpbmV0X250b3AoYWlwLT5haV9mYW1pbHksCiAgICAgICAgICAgICAgICAgICAgICAgICYoKHN0cnVjdCBzb2NrYWRkcl9pbjYgKilhaXAtPmFpX2FkZHIpLT5zaW42X2FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Ziwgc2l6ZW9mKGJ1ZikpOwogICAgICAgICAgICAgICAgICAgIGJ1ZmxlbiA9IHN0cmxlbihidWYpOwogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBhZGRfcmVzdWx0KGl0ZW0sIG4sIElORVRBRERSRVNTVFlQRV9JUFY2LCBidWYsIGJ1Zmxlbik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJuc2xvb2t1cC1taWIvcnVuX2xvb2t1cDogVW5rbm93biBhZGRyZXNzIHR5cGUgJWRcbiIsIGFpcC0+YWlfZmFtaWx5KTsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfVU5LTk9XTiwgIiIsIDApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgIkFkZGluZyAlZCAlc1xuIiwgbiwgYnVmKSk7CgogICAgICAgICAgICAgICAgaWYgKG4gPT0gMSkKICAgICAgICAgICAgICAgICAgICBpdGVtLT5SZXN1bHRzVGFibGUgPSB0ZW1wOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQtPm5leHQgPSB0ZW1wOwogICAgICAgICAgICAgICAgY3VycmVudCA9IHRlbXA7CiAgICAgICAgICAgICAgICBuID0gbiArIDE7CiAgICAgICAgICAgICAgICBhaXAgPSBhaXAtPmFpX25leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZnJlZWFkZHJpbmZvKGFpcyk7CiAgICAgICAgfQojZWxpZiBIQVZFX0dFVEhPU1RCWU5BTUUyCiAgICAgICAgZ2V0dGltZW9mZGF5KCZ0cHN0YXJ0LCBOVUxMKTsKICAgICAgICBsb29rdXAgPSBnZXRob3N0YnluYW1lMihhZGRyZXNzLCBBRl9JTkVUNik7CiAgICAgICAgZ2V0dGltZW9mZGF5KCZ0cGVuZCwgTlVMTCk7CiAgICAgICAgdGltZXVzZTYgPSAxMDAwMDAwICogKHRwZW5kLnR2X3NlYyAtIHRwc3RhcnQudHZfc2VjKSArCiAgICAgICAgICAgIHRwZW5kLnR2X3VzZWMgLSB0cHN0YXJ0LnR2X3VzZWM7CgogICAgICAgIGlmIChsb29rdXAgPT0gTlVMTCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IGEgaXB2NiBuZXR3b3JrIGhvc3QgZW50cnkgZm9yICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzKSk7CiAgICAgICAgICAgIG1vZGlmeV9sb29rdXBDdGxSYyhpdGVtLCBoX2Vycm5vKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgd2hpbGUgKGxvb2t1cC0+aF9hZGRyX2xpc3RbaV0pIHsKICAgICAgICAgICAgICAgIGNoYXIgYnVmWzY0XTsKICAgICAgICAgICAgICAgIGludCBidWZsZW47CgogICAgICAgICAgICAgICAgaW5ldF9udG9wKGxvb2t1cC0+aF9hZGRydHlwZSwgbG9va3VwLT5oX2FkZHJfbGlzdFtpXSwKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLCBzaXplb2YoYnVmKSk7CiAgICAgICAgICAgICAgICBidWZsZW4gPSBzdHJsZW4oYnVmKTsKICAgICAgICAgICAgICAgIHN3aXRjaCAobG9va3VwLT5oX2FkZHJ0eXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlIEFGX0lORVQ6CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0lQVjQsIGJ1ZiwgYnVmbGVuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQUZfSU5FVDY6CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0lQVjYsIGJ1ZiwgYnVmbGVuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5zbG9va3VwLW1pYi9ydW5fbG9va3VwOiBVbmtub3duIGFkZHJlc3MgdHlwZSAlZFxuIiwgbG9va3VwLT5oX2FkZHJ0eXBlKTsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfVU5LTk9XTiwgIiIsIDApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgIkFkZGluZyAlZCAlc1xuIiwgbiwgYnVmKSk7CgogICAgICAgICAgICAgICAgaWYgKG4gPT0gMSkKICAgICAgICAgICAgICAgICAgICBpdGVtLT5SZXN1bHRzVGFibGUgPSB0ZW1wOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQtPm5leHQgPSB0ZW1wOwogICAgICAgICAgICAgICAgY3VycmVudCA9IHRlbXA7CiAgICAgICAgICAgICAgICBuID0gbiArIDE7CiAgICAgICAgICAgICAgICBpID0gaSArIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZgoKICAgICAgICB0aW1ldXNlID0gdGltZXVzZTQgKyB0aW1ldXNlNjsKICAgICAgICB0aW1ldXNlIC89IDEwMDA7CiAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFRpbWUoaXRlbSwgdGltZXVzZSk7CiAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bE9wZXJTdGF0dXMoaXRlbSwgM0wpOwoKICAgICAgICBpZiAoaXRlbS0+UmVzdWx0c1RhYmxlICE9IE5VTEwpIHsKICAgICAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFJjKGl0ZW0sIDBMKTsKICAgICAgICAgICAgaWYgKGxvb2t1cFJlc3VsdHNUYWJsZV9hZGQoaXRlbSkgIT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cFJlc3VsdHNUYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVnaXN0ZXJlZCBhbiBlbnRyeSBlcnJvclxuIikpOwogICAgICAgIH0KICAgICAgICBTTk1QX0ZSRUUoYWRkcmVzcyk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGVsc2UgaWYgKGFkZHJlc3NUeXBlID09IElORVRBRERSRVNTVFlQRV9JUFY2KSB7CiAgICAgICAgc3RydWN0IGluNl9hZGRyIGFkZHJfaW42OwogICAgICAgIHN0cnVjdCBob3N0ZW50ICpsb29rdXA7CgogICAgICAgIGlmIChpbmV0X3B0b24oQUZfSU5FVDYsIGFkZHJlc3MsICZhZGRyX2luNikgPT0gMSkKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgInN1Y2Nlc3MhIFxuIikpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgImVycm9yISBcbiIpKTsKCiAgICAgICAgZ2V0dGltZW9mZGF5KCZ0cHN0YXJ0LCBOVUxMKTsKICAgICAgICBsb29rdXAgPSBnZXRob3N0YnlhZGRyKCZhZGRyX2luNiwgc2l6ZW9mKGFkZHJfaW42KSwgQUZfSU5FVDYpOwogICAgICAgIGdldHRpbWVvZmRheSgmdHBlbmQsIE5VTEwpOwogICAgICAgIHRpbWV1c2UgPSAxMDAwMDAwICogKHRwZW5kLnR2X3NlYyAtIHRwc3RhcnQudHZfc2VjKSArCiAgICAgICAgICAgIHRwZW5kLnR2X3VzZWMgLSB0cHN0YXJ0LnR2X3VzZWM7CiAgICAgICAgdGltZXVzZSAvPSAxMDAwOwogICAgICAgIG1vZGlmeV9sb29rdXBDdGxUaW1lKGl0ZW0sIHRpbWV1c2UpOwogICAgICAgIG1vZGlmeV9sb29rdXBDdGxPcGVyU3RhdHVzKGl0ZW0sIDNMKTsKCiAgICAgICAgaWYgKGxvb2t1cCA9PSBOVUxMKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJDYW4ndCBnZXQgYSBuZXR3b3JrIGhvc3QgZW50cnkgZm9yICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzKSk7CiAgICAgICAgICAgIG1vZGlmeV9sb29rdXBDdGxSYyhpdGVtLCBoX2Vycm5vKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG1vZGlmeV9sb29rdXBDdGxSYyhpdGVtLCAwTCk7CiAgICAgICAgICAgIGlmIChsb29rdXAtPmhfbmFtZSAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBjdXJyZW50ID0gdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0ROUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb2t1cC0+aF9uYW1lLCBzdHJsZW4obG9va3VwLT5oX25hbWUpKTsKICAgICAgICAgICAgICAgIG4gPSBuICsgMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaSA9IDA7CiAgICAgICAgICAgIHdoaWxlIChsb29rdXAtPmhfYWxpYXNlc1tpXSkgewogICAgICAgICAgICAgICAgY3VycmVudCA9IHRlbXAgPSBhZGRfcmVzdWx0KGl0ZW0sIG4sIElORVRBRERSRVNTVFlQRV9ETlMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29rdXAtPmhfYWxpYXNlc1tpXSwgc3RybGVuKGxvb2t1cC0+aF9hbGlhc2VzW2ldKSk7CiAgICAgICAgICAgICAgICBjdXJyZW50LT5uZXh0ID0gdGVtcDsKICAgICAgICAgICAgICAgIGN1cnJlbnQgPSB0ZW1wOwogICAgICAgICAgICAgICAgaSA9IGkgKyAxOwogICAgICAgICAgICAgICAgbiA9IG4gKyAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoaXRlbS0+UmVzdWx0c1RhYmxlICE9IE5VTEwpCiAgICAgICAgICAgICAgICBjdXJyZW50LT5uZXh0ID0gTlVMTDsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgY3VycmVudCA9IE5VTEw7CiAgICAgICAgfQoKICAgICAgICBpZiAoaXRlbS0+UmVzdWx0c1RhYmxlICE9IE5VTEwpCiAgICAgICAgICAgIGlmIChsb29rdXBSZXN1bHRzVGFibGVfYWRkKGl0ZW0pICE9IFNOTVBFUlJfU1VDQ0VTUykKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJsb29rdXBSZXN1bHRzVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlZ2lzdGVyZWQgYW4gZW50cnkgZXJyb3JcbiIpKTsKICAgICAgICBTTk1QX0ZSRUUoYWRkcmVzcyk7CiAgICAgICAgcmV0dXJuOwogICAgfSBlbHNlIHsKICAgICAgICBTTk1QX0ZSRUUoYWRkcmVzcyk7CiAgICAgICAgcmV0dXJuOwogICAgfQp9CgoKaW50Cm1vZGlmeV9sb29rdXBDdGxPcGVyU3RhdHVzKHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICp0aGVkYXRhLCBsb25nIHZhbCkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJzID0gTlVMTDsKICAgIHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICpTdG9yYWdlVG1wID0gTlVMTDsKCiAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZ2YXJzLCBOVUxMLCAwLCBBU05fT0NURVRfU1RSLAogICAgICAgIChjaGFyICopIHRoZWRhdGEtPmxvb2t1cEN0bE93bmVySW5kZXgsIHRoZWRhdGEtPmxvb2t1cEN0bE93bmVySW5kZXhMZW4pOwogICAgc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSgmdmFycywgTlVMTCwgMCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAoY2hhciAqKSB0aGVkYXRhLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lLAogICAgICAgIHRoZWRhdGEtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWVMZW4pOwoKCiAgICBpZiAoKFN0b3JhZ2VUbXAgPQogICAgICAgICBoZWFkZXJfY29tcGxleF9nZXQobG9va3VwQ3RsVGFibGVTdG9yYWdlLCB2YXJzKSkgPT0gTlVMTCkgewogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHZhcnMpOwogICAgICAgIHZhcnMgPSBOVUxMOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1NVQ0hOQU1FOwogICAgfQogICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsT3BlclN0YXR1cyA9IHZhbDsKCiAgICBzbm1wX2ZyZWVfdmFyYmluZCh2YXJzKTsKICAgIHZhcnMgPSBOVUxMOwoKICAgIERFQlVHTVNHVEwoKCJsb29rdXBPcGVyU3RhdHVzIiwgImRvbmUuXG4iKSk7CiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgppbnQKbW9kaWZ5X2xvb2t1cEN0bFRpbWUoc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKnRoZWRhdGEsIHVuc2lnbmVkIGxvbmcgdmFsKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMgPSBOVUxMOwogICAgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VUbXAgPSBOVUxMOwoKICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleCwgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleExlbik7CiAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZ2YXJzLCBOVUxMLCAwLCBBU05fT0NURVRfU1RSLAogICAgICAgIChjaGFyICopIHRoZWRhdGEtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgdGhlZGF0YS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbik7CgoKICAgIGlmICgoU3RvcmFnZVRtcCA9CiAgICAgICAgIGhlYWRlcl9jb21wbGV4X2dldChsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIHZhcnMpKSA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmFycyk7CiAgICAgICAgdmFycyA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PU1VDSE5BTUU7CiAgICB9CiAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxUaW1lID0gdmFsOwoKICAgIHNubXBfZnJlZV92YXJiaW5kKHZhcnMpOwogICAgdmFycyA9IE5VTEw7CgogICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRpbWUiLCAiZG9uZS5cbiIpKTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCmludAptb2RpZnlfbG9va3VwQ3RsUmMoc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKnRoZWRhdGEsIGxvbmcgdmFsKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMgPSBOVUxMOwogICAgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VUbXAgPSBOVUxMOwoKICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleCwgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleExlbik7CiAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZ2YXJzLCBOVUxMLCAwLCBBU05fT0NURVRfU1RSLAogICAgICAgIChjaGFyICopIHRoZWRhdGEtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgdGhlZGF0YS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbik7CgoKICAgIGlmICgoU3RvcmFnZVRtcCA9CiAgICAgICAgIGhlYWRlcl9jb21wbGV4X2dldChsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIHZhcnMpKSA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmFycyk7CiAgICAgICAgdmFycyA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PU1VDSE5BTUU7CiAgICB9CiAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxSYyA9IHZhbDsKCiAgICBzbm1wX2ZyZWVfdmFyYmluZCh2YXJzKTsKICAgIHZhcnMgPSBOVUxMOwogICAgREVCVUdNU0dUTCgoImxvb2t1cE9wZXJTdGF0dXMiLCAiZG9uZS5cbiIpKTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCgppbnQKbG9va3VwUmVzdWx0c1RhYmxlX2RlbChzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqdGhlZGF0YSkKewogICAgc3RydWN0IGhlYWRlcl9jb21wbGV4X2luZGV4ICpoY2lwdHIyID0gTlVMTDsKICAgIHN0cnVjdCBsb29rdXBSZXN1bHRzVGFibGVfZGF0YSAqU3RvcmFnZURlbCA9IE5VTEw7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMgPSBOVUxMOwogICAgb2lkICAgICAgICAgICAgIG5ld29pZFtNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgICAgICAgICAgbmV3b2lkX2xlbjsKCiAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZ2YXJzLCBOVUxMLCAwLCBBU05fT0NURVRfU1RSLAogICAgICAgIChjaGFyICopIHRoZWRhdGEtPmxvb2t1cEN0bE93bmVySW5kZXgsIHRoZWRhdGEtPmxvb2t1cEN0bE93bmVySW5kZXhMZW4pOwogICAgc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSgmdmFycywgTlVMTCwgMCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAoY2hhciAqKSB0aGVkYXRhLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lLAogICAgICAgIHRoZWRhdGEtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWVMZW4pOwogICAgbWVtc2V0KG5ld29pZCwgJ1wwJywgTUFYX09JRF9MRU4gKiBzaXplb2Yob2lkKSk7CiAgICBoZWFkZXJfY29tcGxleF9nZW5lcmF0ZV9vaWQobmV3b2lkLCAmbmV3b2lkX2xlbiwgTlVMTCwgMCwgdmFycyk7CgoKICAgIHNubXBfZnJlZV92YXJiaW5kKHZhcnMpOwogICAgdmFycyA9IE5VTEw7CiAgICBmb3IgKGhjaXB0cjIgPSBsb29rdXBSZXN1bHRzVGFibGVTdG9yYWdlOyBoY2lwdHIyICE9IE5VTEw7CiAgICAgICAgIGhjaXB0cjIgPSBoY2lwdHIyLT5uZXh0KSB7CiAgICAgICAgaWYgKHNubXBfb2lkX2NvbXBhcmUobmV3b2lkLCBuZXdvaWRfbGVuLCBoY2lwdHIyLT5uYW1lLCBuZXdvaWRfbGVuKQogICAgICAgICAgICA9PSAwKSB7CiAgICAgICAgICAgIFN0b3JhZ2VEZWwgPQogICAgICAgICAgICAgICAgaGVhZGVyX2NvbXBsZXhfZXh0cmFjdF9lbnRyeSgmbG9va3VwUmVzdWx0c1RhYmxlU3RvcmFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGNpcHRyMik7CiAgICAgICAgICAgIGlmIChTdG9yYWdlRGVsICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIFNOTVBfRlJFRShTdG9yYWdlRGVsLT5sb29rdXBDdGxPd25lckluZGV4KTsKICAgICAgICAgICAgICAgIFNOTVBfRlJFRShTdG9yYWdlRGVsLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lKTsKICAgICAgICAgICAgICAgIFNOTVBfRlJFRShTdG9yYWdlRGVsLT5sb29rdXBSZXN1bHRzQWRkcmVzcyk7CiAgICAgICAgICAgICAgICBTTk1QX0ZSRUUoU3RvcmFnZURlbCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cFJlc3VsdHNUYWJsZSIsICJkZWxldGUgIHN1Y2Nlc3MhXG4iKSk7CgogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCgppbnQKd3JpdGVfbG9va3VwQ3RsVGFyZ2V0QWRkcmVzc1R5cGUoaW50IGFjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyICogdmFyX3ZhbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyIHZhcl92YWxfdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHZhcl92YWxfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiBzdGF0UCwgb2lkICogbmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG5hbWVfbGVuKQp7CiAgICBzdGF0aWMgc2l6ZV90ICAgdG1wdmFyOwogICAgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VUbXAgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIG5ld2xlbiA9CiAgICAgICAgbmFtZV9sZW4gLSAoc2l6ZW9mKGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc19vaWQpIC8gc2l6ZW9mKG9pZCkgKwogICAgICAgICAgICAgICAgICAgIDMgLSAxKTsKCiAgICBpZiAoKFN0b3JhZ2VUbXAgPQogICAgICAgICBoZWFkZXJfY29tcGxleChsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICZuYW1lW3NpemVvZihsb29rdXBDdGxUYWJsZV92YXJpYWJsZXNfb2lkKSAvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihvaWQpICsgMyAtIDFdLCAmbmV3bGVuLCAxLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICBOVUxMKSkgPT0gTlVMTCkKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9TVUNITkFNRTsgICAgIC8qIHJlbW92ZSBpZiB5b3Ugc3VwcG9ydCBjcmVhdGlvbiBoZXJlICovCgogICAgaWYgKFN0b3JhZ2VUbXAgJiYgU3RvcmFnZVRtcC0+c3RvcmFnZXR5cGUgPT0gU1RfUkVBRE9OTFkpIHsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9UV1JJVEFCTEU7CiAgICB9CgogICAgaWYgKFN0b3JhZ2VUbXAgJiYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzID09IFJTX0FDVElWRSkgewogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1RXUklUQUJMRTsKICAgIH0KICAgIHN3aXRjaCAoYWN0aW9uKSB7CiAgICBjYXNlIFJFU0VSVkUxOgogICAgICAgIGlmICh2YXJfdmFsX3R5cGUgIT0gQVNOX0lOVEVHRVIpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgIndyaXRlIHRvIGxvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlIG5vdCBBU05fSU5URUdFUlxuIik7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1RZUEU7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgUkVTRVJWRTI6CiAgICAgICAgLyoKICAgICAgICAgKiBtZW1vcnkgcmVzZXZlcmF0aW9uLCBmaW5hbCBwcmVwYXJhdGlvbi4uLiAKICAgICAgICAgKi8KICAgICAgICBicmVhazsKCiAgICBjYXNlIEZSRUU6CiAgICAgICAgLyoKICAgICAgICAgKiBSZWxlYXNlIGFueSByZXNvdXJjZXMgdGhhdCBoYXZlIGJlZW4gYWxsb2NhdGVkIAogICAgICAgICAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQUNUSU9OOgogICAgICAgIC8qCiAgICAgICAgICogVGhlIHZhcmlhYmxlIGhhcyBiZWVuIHN0b3JlZCBpbiBvYmppZCBmb3IKICAgICAgICAgKiB5b3UgdG8gdXNlLCBhbmQgeW91IGhhdmUganVzdCBiZWVuIGFza2VkIHRvIGRvIHNvbWV0aGluZyB3aXRoCiAgICAgICAgICogaXQuICBOb3RlIHRoYXQgYW55dGhpbmcgZG9uZSBoZXJlIG11c3QgYmUgcmV2ZXJzYWJsZSBpbiB0aGUgVU5ETyBjYXNlCiAgICAgICAgICovCiAgICAgICAgdG1wdmFyID0gU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc1R5cGU7CiAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc1R5cGUgPSAqKChsb25nICopIHZhcl92YWwpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgVU5ETzoKICAgICAgICAvKgogICAgICAgICAqIEJhY2sgb3V0IGFueSBjaGFuZ2VzIG1hZGUgaW4gdGhlIEFDVElPTiBjYXNlIAogICAgICAgICAqLwogICAgICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlID0gdG1wdmFyOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQ09NTUlUOgogICAgICAgIC8qCiAgICAgICAgICogVGhpbmdzIGFyZSB3b3JraW5nIHdlbGwsIHNvIGl0J3Mgbm93IHNhZmUgdG8gbWFrZSB0aGUgY2hhbmdlCiAgICAgICAgICogcGVybWFuZW50bHkuICBNYWtlIHN1cmUgdGhhdCBhbnl0aGluZyBkb25lIGhlcmUgY2FuJ3QgZmFpbCEgCiAgICAgICAgICovCgogICAgICAgIC8qKiBzZXQgdXAgdG8gc2F2ZSBwZXJzaXN0ZW50IHN0b3JlICovCiAgICAgICAgc25tcF9zdG9yZV9uZWVkZWQoTlVMTCk7CgogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCgoKaW50CndyaXRlX2xvb2t1cEN0bFRhcmdldEFkZHJlc3MoaW50IGFjdGlvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiB2YXJfdmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciB2YXJfdmFsX3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IHZhcl92YWxfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqIHN0YXRQLCBvaWQgKiBuYW1lLCBzaXplX3QgbmFtZV9sZW4pCnsKICAgIHN0YXRpYyBjaGFyICAgICp0bXB2YXIgPSBOVUxMOwogICAgc3RhdGljIHNpemVfdCAgIHRtcGxlbjsKICAgIHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICpTdG9yYWdlVG1wID0gTlVMTDsKICAgIHNpemVfdCAgICAgICAgICBuZXdsZW4gPQogICAgICAgIG5hbWVfbGVuIC0gKHNpemVvZihsb29rdXBDdGxUYWJsZV92YXJpYWJsZXNfb2lkKSAvIHNpemVvZihvaWQpICsKICAgICAgICAgICAgICAgICAgICAzIC0gMSk7CiAgICBpZiAoKFN0b3JhZ2VUbXAgPQogICAgICAgICBoZWFkZXJfY29tcGxleChsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICZuYW1lW3NpemVvZihsb29rdXBDdGxUYWJsZV92YXJpYWJsZXNfb2lkKSAvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihvaWQpICsgMyAtIDFdLCAmbmV3bGVuLCAxLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICBOVUxMKSkgPT0gTlVMTCkKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9TVUNITkFNRTsgICAgIC8qIHJlbW92ZSBpZiB5b3Ugc3VwcG9ydCBjcmVhdGlvbiBoZXJlICovCgogICAgaWYgKFN0b3JhZ2VUbXAgJiYgU3RvcmFnZVRtcC0+c3RvcmFnZXR5cGUgPT0gU1RfUkVBRE9OTFkpIHsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9UV1JJVEFCTEU7CiAgICB9CgogICAgaWYgKFN0b3JhZ2VUbXAgJiYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzID09IFJTX0FDVElWRSkgewogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1RXUklUQUJMRTsKICAgIH0KCiAgICBzd2l0Y2ggKGFjdGlvbikgewogICAgY2FzZSBSRVNFUlZFMToKICAgICAgICBpZiAodmFyX3ZhbF90eXBlICE9IEFTTl9PQ1RFVF9TVFIpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgIndyaXRlIHRvIGxvb2t1cEN0bFRhcmdldEFkZHJlc3Mgbm90IEFTTl9PQ1RFVF9TVFJcbiIpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfV1JPTkdUWVBFOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFJFU0VSVkUyOgogICAgICAgIC8qCiAgICAgICAgICogbWVtb3J5IHJlc2V2ZXJhdGlvbiwgZmluYWwgcHJlcGFyYXRpb24uLi4gCiAgICAgICAgICovCiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBGUkVFOgogICAgICAgIC8qCiAgICAgICAgICogUmVsZWFzZSBhbnkgcmVzb3VyY2VzIHRoYXQgaGF2ZSBiZWVuIGFsbG9jYXRlZCAKICAgICAgICAgKi8KICAgICAgICBicmVhazsKCiAgICBjYXNlIEFDVElPTjoKICAgICAgICAvKgogICAgICAgICAqIFRoZSB2YXJpYWJsZSBoYXMgYmVlbiBzdG9yZWQgaW4gbG9uZ19yZXQgZm9yCiAgICAgICAgICogeW91IHRvIHVzZSwgYW5kIHlvdSBoYXZlIGp1c3QgYmVlbiBhc2tlZCB0byBkbyBzb21ldGhpbmcgd2l0aAogICAgICAgICAqIGl0LiAgTm90ZSB0aGF0IGFueXRoaW5nIGRvbmUgaGVyZSBtdXN0IGJlIHJldmVyc2FibGUgaW4gdGhlIFVORE8gY2FzZQogICAgICAgICAqLwogICAgICAgIHRtcHZhciA9IFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3M7CiAgICAgICAgdG1wbGVuID0gU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc0xlbjsKCiAgICAgICAgaWYgKChTdG9yYWdlVG1wLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzID0KICAgICAgICAgICAgIChjaGFyICopIG1hbGxvYyh2YXJfdmFsX2xlbiArIDEpKSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJPdXQgb2YgbWVtb3J5IGluIG5zbG9va3VwLW1pYi93cml0ZV9sb29rdXBDdGxUYXJnZXRBZGRyZXNzXG4iKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CiAgICAgICAgbWVtY3B5KFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MsIHZhcl92YWwsIHZhcl92YWxfbGVuKTsKICAgICAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzW3Zhcl92YWxfbGVuXSA9ICdcMCc7CiAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc0xlbiA9IHZhcl92YWxfbGVuOwoKICAgICAgICBicmVhazsKCiAgICBjYXNlIFVORE86CiAgICAgICAgLyoKICAgICAgICAgKiBCYWNrIG91dCBhbnkgY2hhbmdlcyBtYWRlIGluIHRoZSBBQ1RJT04gY2FzZSAKICAgICAgICAgKi8KICAgICAgICBmcmVlKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MpOwogICAgICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MgPSBOVUxMOwogICAgICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MgPSB0bXB2YXI7CiAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc0xlbiA9IHRtcGxlbjsKCiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBDT01NSVQ6CiAgICAgICAgLyoKICAgICAgICAgKiBUaGluZ3MgYXJlIHdvcmtpbmcgd2VsbCwgc28gaXQncyBub3cgc2FmZSB0byBtYWtlIHRoZSBjaGFuZ2UKICAgICAgICAgKiBwZXJtYW5lbnRseS4gIE1ha2Ugc3VyZSB0aGF0IGFueXRoaW5nIGRvbmUgaGVyZSBjYW4ndCBmYWlsISAKICAgICAgICAgKi8KCiAgICAgICAgZnJlZSh0bXB2YXIpOwogICAgICAgIHRtcHZhciA9IE5VTEw7CgogICAgICAgIC8qKiBzZXQgdXAgdG8gc2F2ZSBwZXJzaXN0ZW50IHN0b3JlICovCiAgICAgICAgc25tcF9zdG9yZV9uZWVkZWQoTlVMTCk7CgogICAgICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCgoKaW50CndyaXRlX2xvb2t1cEN0bFJvd1N0YXR1cyhpbnQgYWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyICogdmFyX3ZhbCwKICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciB2YXJfdmFsX3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgdmFyX3ZhbF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiBzdGF0UCwgb2lkICogbmFtZSwgc2l6ZV90IG5hbWVfbGVuKQp7CiAgICBzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqU3RvcmFnZVRtcCA9IE5VTEw7CiAgICBzdGF0aWMgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VOZXcgPSBOVUxMLCAqU3RvcmFnZURlbCA9IE5VTEw7CiAgICBzaXplX3QgICAgICAgICAgbmV3bGVuID0KICAgICAgICBuYW1lX2xlbiAtIChzaXplb2YobG9va3VwQ3RsVGFibGVfdmFyaWFibGVzX29pZCkgLyBzaXplb2Yob2lkKSArCiAgICAgICAgICAgICAgICAgICAgMyAtIDEpOwogICAgc3RhdGljIGludCAgICAgIG9sZF92YWx1ZTsKICAgIGludCAgICAgICAgICAgICBzZXRfdmFsdWU7CiAgICBzdGF0aWMgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJzLCAqdnA7CiAgICBzdHJ1Y3QgaGVhZGVyX2NvbXBsZXhfaW5kZXggKmhjaXB0ciA9IE5VTEw7CgogICAgU3RvcmFnZVRtcCA9CiAgICAgICAgaGVhZGVyX2NvbXBsZXgobG9va3VwQ3RsVGFibGVTdG9yYWdlLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICZuYW1lW3NpemVvZihsb29rdXBDdGxUYWJsZV92YXJpYWJsZXNfb2lkKSAvCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG9pZCkgKyAzIC0gMV0sICZuZXdsZW4sIDEsIE5VTEwsIE5VTEwpOwoKICAgIGlmICh2YXJfdmFsX3R5cGUgIT0gQVNOX0lOVEVHRVIgfHwgdmFyX3ZhbCA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIndyaXRlIHRvIGxvb2t1cEN0bFJvd1N0YXR1cyBub3QgQVNOX0lOVEVHRVJcbiIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1RZUEU7CiAgICB9CiAgICBpZiAoU3RvcmFnZVRtcCAmJiBTdG9yYWdlVG1wLT5zdG9yYWdldHlwZSA9PSBTVF9SRUFET05MWSkgewogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1RXUklUQUJMRTsKICAgIH0KCiAgICBzZXRfdmFsdWUgPSAqKChsb25nICopIHZhcl92YWwpOwoKCiAgICAvKgogICAgICogY2hlY2sgbGVnYWwgcmFuZ2UsIGFuZCBub3RSZWFkeSBpcyByZXNlcnZlZCBmb3IgdXMsIG5vdCBhIHVzZXIgCiAgICAgKi8KICAgIGlmIChzZXRfdmFsdWUgPCAxIHx8IHNldF92YWx1ZSA+IDYgfHwgc2V0X3ZhbHVlID09IFJTX05PVFJFQURZKQogICAgICAgIHJldHVybiBTTk1QX0VSUl9JTkNPTlNJU1RFTlRWQUxVRTsKCgogICAgc3dpdGNoIChhY3Rpb24pIHsKICAgIGNhc2UgUkVTRVJWRTE6CiAgICAgICAgLyoKICAgICAgICAgKiBzdGFnZSBvbmU6IHRlc3QgdmFsaWRpdHkgCiAgICAgICAgICovCiAgICAgICAgaWYgKFN0b3JhZ2VUbXAgPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBjcmVhdGUgdGhlIHJvdyBub3c/IAogICAgICAgICAgICAgKi8KCgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBkaXRjaCBpbGxlZ2FsIHZhbHVlcyBub3cgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoc2V0X3ZhbHVlID09IFJTX0FDVElWRSB8fCBzZXRfdmFsdWUgPT0gUlNfTk9USU5TRVJWSUNFKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfSU5DT05TSVNURU5UVkFMVUU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGRlc3Ryb3lpbmcgYSBub24tZXhpc3RlbnQgcm93IGlzIGFjdHVhbGx5IGxlZ2FsIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHNldF92YWx1ZSA9PSBSU19ERVNUUk9ZKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICAgICAgfQoKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGlsbGVnYWwgY3JlYXRpb24gdmFsdWVzIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHNldF92YWx1ZSA9PSBSU19BQ1RJVkUgfHwgc2V0X3ZhbHVlID09IFJTX05PVElOU0VSVklDRSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0lOQ09OU0lTVEVOVFZBTFVFOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcm93IGV4aXN0cy4gIENoZWNrIGZvciBhIHZhbGlkIHN0YXRlIGNoYW5nZSAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChzZXRfdmFsdWUgPT0gUlNfQ1JFQVRFQU5ER08KICAgICAgICAgICAgICAgIHx8IHNldF92YWx1ZSA9PSBSU19DUkVBVEVBTkRXQUlUKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogY2FuJ3QgY3JlYXRlIGEgcm93IHRoYXQgZXhpc3RzIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfSU5DT05TSVNURU5UVkFMVUU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFhYWDogaW50ZXJhY3Rpb24gd2l0aCByb3cgc3RvcmFnZSB0eXBlIG5lZWRlZCAKICAgICAgICAgICAgICovCgogICAgICAgICAgICBpZiAoU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzID09IFJTX0FDVElWRSAmJgogICAgICAgICAgICAgICAgc2V0X3ZhbHVlICE9IFJTX0RFU1RST1kpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiAiT25jZSBtYWRlIGFjdGl2ZSBhbiBlbnRyeSBtYXkgbm90IGJlIG1vZGlmaWVkIGV4Y2VwdCB0byAKICAgICAgICAgICAgICAgICAqIGRlbGV0ZSBpdC4iICBYWFg6IGRvZXNuJ3QgdGhpcyBpbiBmYWN0IGFwcGx5IHRvIEFMTAogICAgICAgICAgICAgICAgICogY29sdW1ucyBvZiB0aGUgdGFibGUgYW5kIG5vdCBqdXN0IHRoaXMgb25lPyAgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9JTkNPTlNJU1RFTlRWQUxVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoU3RvcmFnZVRtcC0+c3RvcmFnZXR5cGUgIT0gU1RfTk9OVk9MQVRJTEUpCiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9UV1JJVEFCTEU7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKCgoKICAgIGNhc2UgUkVTRVJWRTI6CiAgICAgICAgLyoKICAgICAgICAgKiBtZW1vcnkgcmVzZXZlcmF0aW9uLCBmaW5hbCBwcmVwYXJhdGlvbi4uLiAKICAgICAgICAgKi8KICAgICAgICBpZiAoU3RvcmFnZVRtcCA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNyZWF0aW9uIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHNldF92YWx1ZSA9PSBSU19ERVNUUk9ZKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICAgICAgfQogICAgICAgICAgICB2YXJzID0gTlVMTDsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIL2rbmFtZc6qv9W1xMj9uPbL99L919a2zrzTtb12YXKx5MG/wdCx7bXExKnOsiAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsIE5VTEwsIDApOyAgLyogbG9va3VwQ3RsT3duZXJJbmRleCAqLwogICAgICAgICAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZ2YXJzLCBOVUxMLCAwLCBBU05fT0NURVRfU1RSLCBOVUxMLCAwKTsgIC8qIGxvb2t1cEN0bE9wZXJhdGlvbk5hbWUgKi8KCiAgICAgICAgICAgIGlmIChoZWFkZXJfY29tcGxleF9wYXJzZV9vaWQKICAgICAgICAgICAgICAgICgmCiAgICAgICAgICAgICAgICAgKG5hbWUKICAgICAgICAgICAgICAgICAgW3NpemVvZihsb29rdXBDdGxUYWJsZV92YXJpYWJsZXNfb2lkKSAvIHNpemVvZihvaWQpICsKICAgICAgICAgICAgICAgICAgIDJdKSwgbmV3bGVuLCB2YXJzKSAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBYWFg6IGZyZWUsIHplcm8gdmFycyAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmFycyk7CiAgICAgICAgICAgICAgICB2YXJzID0gTlVMTDsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9JTkNPTlNJU1RFTlROQU1FOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZwID0gdmFyczsKICAgICAgICAgICAgU3RvcmFnZU5ldyA9IGNyZWF0ZV9sb29rdXBUYWJsZV9kYXRhKCk7CiAgICAgICAgICAgIFN0b3JhZ2VOZXctPmxvb2t1cEN0bE93bmVySW5kZXggPSBtYWxsb2ModnAtPnZhbF9sZW4gKyAxKTsKICAgICAgICAgICAgbWVtY3B5KFN0b3JhZ2VOZXctPmxvb2t1cEN0bE93bmVySW5kZXgsIHZwLT52YWwuc3RyaW5nLAogICAgICAgICAgICAgICAgICAgdnAtPnZhbF9sZW4pOwogICAgICAgICAgICBTdG9yYWdlTmV3LT5sb29rdXBDdGxPd25lckluZGV4W3ZwLT52YWxfbGVuXSA9ICdcMCc7CiAgICAgICAgICAgIFN0b3JhZ2VOZXctPmxvb2t1cEN0bE93bmVySW5kZXhMZW4gPSB2cC0+dmFsX2xlbjsKICAgICAgICAgICAgdnAgPSB2cC0+bmV4dF92YXJpYWJsZTsKCiAgICAgICAgICAgIFN0b3JhZ2VOZXctPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUgPSBtYWxsb2ModnAtPnZhbF9sZW4gKyAxKTsKICAgICAgICAgICAgbWVtY3B5KFN0b3JhZ2VOZXctPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsIHZwLT52YWwuc3RyaW5nLAogICAgICAgICAgICAgICAgICAgdnAtPnZhbF9sZW4pOwogICAgICAgICAgICBTdG9yYWdlTmV3LT5sb29rdXBDdGxPcGVyYXRpb25OYW1lW3ZwLT52YWxfbGVuXSA9ICdcMCc7CiAgICAgICAgICAgIFN0b3JhZ2VOZXctPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWVMZW4gPSB2cC0+dmFsX2xlbjsKICAgICAgICAgICAgdnAgPSB2cC0+bmV4dF92YXJpYWJsZTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFhYWDogZmlsbCBpbiBkZWZhdWx0IHJvdyB2YWx1ZXMgaGVyZSBpbnRvIFN0b3JhZ2VOZXcgCiAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc1R5cGUgPSBJTkVUQUREUkVTU1RZUEVfSVBWNDsKCiAgICAgICAgICAgIFN0b3JhZ2VOZXctPmxvb2t1cEN0bFJvd1N0YXR1cyA9IHNldF92YWx1ZTsKCiAgICAgICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHZhcnMpOwogICAgICAgICAgICB2YXJzID0gTlVMTDsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFhYWDogZnJlZSwgemVybyB2YXJzLCBubyBsb25nZXIgbmVlZGVkPyAKICAgICAgICAgICAgICovCiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgRlJFRToKICAgICAgICAvKgogICAgICAgICAqIFhYWDogZnJlZSwgemVybyB2YXJzIAogICAgICAgICAqLwogICAgICAgIC8qCiAgICAgICAgICogUmVsZWFzZSBhbnkgcmVzb3VyY2VzIHRoYXQgaGF2ZSBiZWVuIGFsbG9jYXRlZCAKICAgICAgICAgKi8KICAgICAgICBicmVhazsKCiAgICBjYXNlIEFDVElPTjoKICAgICAgICAvKgogICAgICAgICAqIFRoZSB2YXJpYWJsZSBoYXMgYmVlbiBzdG9yZWQgaW4gc2V0X3ZhbHVlIGZvciB5b3UgdG8KICAgICAgICAgKiB1c2UsIGFuZCB5b3UgaGF2ZSBqdXN0IGJlZW4gYXNrZWQgdG8gZG8gc29tZXRoaW5nIHdpdGgKICAgICAgICAgKiBpdC4gIE5vdGUgdGhhdCBhbnl0aGluZyBkb25lIGhlcmUgbXVzdCBiZSByZXZlcnNhYmxlIGluCiAgICAgICAgICogdGhlIFVORE8gY2FzZSAKICAgICAgICAgKi8KICAgICAgICBpZiAoU3RvcmFnZVRtcCA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHJvdyBjcmVhdGlvbiwgc28gYWRkIGl0IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHNldF92YWx1ZSA9PSBSU19ERVNUUk9ZKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoU3RvcmFnZU5ldyAhPSBOVUxMKQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3cml0ZV9sb29rdXBDdGxSb3dTdGF0dXMgZW50ZXJpbmcgbmV3PSVkLi4uICBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3Rpb24pKTsKICAgICAgICAgICAgbG9va3VwQ3RsVGFibGVfYWRkKFN0b3JhZ2VOZXcpOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBYWFg6IGFjaywgYW5kIGlmIGl0IGlzIE5VTEw/IAogICAgICAgICAgICAgKi8KICAgICAgICB9IGVsc2UgaWYgKHNldF92YWx1ZSAhPSBSU19ERVNUUk9ZKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHNldCB0aGUgZmxhZz8gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBvbGRfdmFsdWUgPSBTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXM7CiAgICAgICAgICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJvd1N0YXR1cyA9ICooKGxvbmcgKikgdmFyX3ZhbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZGVzdHJveS4uLiAgZXh0cmFjdCBpdCBmb3Igbm93IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIndyaXRlX2xvb2t1cEN0bFRhYmxlX2RlbGV0ZSAxIFxuIikpOwogICAgICAgICAgICBoY2lwdHIgPQogICAgICAgICAgICAgICAgaGVhZGVyX2NvbXBsZXhfZmluZF9lbnRyeShsb29rdXBDdGxUYWJsZVN0b3JhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0b3JhZ2VUbXApOwoKICAgICAgICAgICAgU3RvcmFnZURlbCA9CiAgICAgICAgICAgICAgICBoZWFkZXJfY29tcGxleF9leHRyYWN0X2VudHJ5KCZsb29rdXBDdGxUYWJsZVN0b3JhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhjaXB0cik7CiAgICAgICAgICAgIGxvb2t1cFJlc3VsdHNUYWJsZV9kZWwoU3RvcmFnZVRtcCk7CgogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAid3JpdGVfbG9va3VwQ3RsVGFibGVfZGVsZXRlICBcbiIpKTsKCiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgVU5ETzoKICAgICAgICAvKgogICAgICAgICAqIEJhY2sgb3V0IGFueSBjaGFuZ2VzIG1hZGUgaW4gdGhlIEFDVElPTiBjYXNlIAogICAgICAgICAqLwogICAgICAgIGlmIChTdG9yYWdlVG1wID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcm93IGNyZWF0aW9uLCBzbyByZW1vdmUgaXQgYWdhaW4gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBoY2lwdHIgPQogICAgICAgICAgICAgICAgaGVhZGVyX2NvbXBsZXhfZmluZF9lbnRyeShsb29rdXBDdGxUYWJsZVN0b3JhZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0b3JhZ2VUbXApOwogICAgICAgICAgICBTdG9yYWdlRGVsID0KICAgICAgICAgICAgICAgIGhlYWRlcl9jb21wbGV4X2V4dHJhY3RfZW50cnkoJmxvb2t1cEN0bFRhYmxlU3RvcmFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGNpcHRyKTsKCiAgICAgICAgICAgIGxvb2t1cFJlc3VsdHNUYWJsZV9kZWwoU3RvcmFnZVRtcCk7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBYWFg6IGZyZWUgaXQgCiAgICAgICAgICAgICAqLwogICAgICAgIH0gZWxzZSBpZiAoU3RvcmFnZURlbCAhPSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHJvdyBkZWxldGlvbiwgc28gYWRkIGl0IGFnYWluIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgbG9va3VwQ3RsVGFibGVfYWRkKFN0b3JhZ2VEZWwpOwogICAgICAgICAgICBsb29rdXBSZXN1bHRzVGFibGVfYWRkKFN0b3JhZ2VEZWwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJvd1N0YXR1cyA9IG9sZF92YWx1ZTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBDT01NSVQ6CiAgICAgICAgLyoKICAgICAgICAgKiBUaGluZ3MgYXJlIHdvcmtpbmcgd2VsbCwgc28gaXQncyBub3cgc2FmZSB0byBtYWtlIHRoZSBjaGFuZ2UKICAgICAgICAgKiBwZXJtYW5lbnRseS4gIE1ha2Ugc3VyZSB0aGF0IGFueXRoaW5nIGRvbmUgaGVyZSBjYW4ndCBmYWlsISAKICAgICAgICAgKi8KICAgICAgICBpZiAoU3RvcmFnZVRtcCA9PSBOVUxMKSB7CiAgICAgICAgICAgIGlmIChzZXRfdmFsdWUgPT0gUlNfREVTVFJPWSkgewogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChTdG9yYWdlRGVsICE9IE5VTEwpIHsKICAgICAgICAgICAgU05NUF9GUkVFKFN0b3JhZ2VEZWwtPmxvb2t1cEN0bE93bmVySW5kZXgpOwogICAgICAgICAgICBTTk1QX0ZSRUUoU3RvcmFnZURlbC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSk7CiAgICAgICAgICAgIFNOTVBfRlJFRShTdG9yYWdlRGVsLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzKTsKICAgICAgICAgICAgU05NUF9GUkVFKFN0b3JhZ2VEZWwpOwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBYWFg6IGZyZWUgaXQsIGl0cyBkZWFkIAogICAgICAgICAgICAgKi8KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpZiAoU3RvcmFnZVRtcAogICAgICAgICAgICAgICAgJiYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzID09IFJTX0NSRUFURUFOREdPKSB7CiAgICAgICAgICAgICAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXMgPSBSU19BQ1RJVkU7CiAgICAgICAgICAgIH0gZWxzZSBpZiAoU3RvcmFnZVRtcCAmJgogICAgICAgICAgICAgICAgICAgICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJvd1N0YXR1cyA9PQogICAgICAgICAgICAgICAgICAgICAgIFJTX0NSRUFURUFORFdBSVQpIHsKCiAgICAgICAgICAgICAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXMgPSBSU19OT1RJTlNFUlZJQ0U7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKFN0b3JhZ2VUbXAgJiYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzID09IFJTX0FDVElWRSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAid3JpdGVfbG9va3VwQ3RsUm93U3RhdHVzIGVudGVyaW5nIHJ1bmJlZm9yZT0lbGQuLi4gIFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc1R5cGUpKTsKCiAgICAgICAgICAgIG1vZGlmeV9sb29rdXBDdGxPcGVyU3RhdHVzKFN0b3JhZ2VUbXAsIDJMKTsKICAgICAgICAgICAgcnVuX2xvb2t1cCgoc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKikgU3RvcmFnZVRtcCk7CgogICAgICAgIH0KCiAgICAgICAgLyoqIHNldCB1cCB0byBzYXZlIHBlcnNpc3RlbnQgc3RvcmUgKi8KICAgICAgICBzbm1wX3N0b3JlX25lZWRlZChOVUxMKTsKCiAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQo=