LyoKICpDb3B5cmlnaHQoYykyMDA0LENpc2NvIFVSUCBpbWJ1cnNlcyBhbmQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIgaW4gQmVpamluZyBVbml2ZXJzaXR5IG9mIFBvc3RzIGFuZCBUZWxlY29tbXVuaWNhdGlvbnMgcmVzZWFyY2hlcy4KICoKICpBbGwgcmlnaHQgcmVzZXJ2ZWQKICoKICpGaWxlIE5hbWU6bG9va3VwQ3RsVGFibGUuYwogKkZpbGUgRGVzY3JpcHRpb246Um93cyBvZiB0aGUgbG9va3VwQ3RsVGFibGUgTUlCIGFkZCAsIGRlbGV0ZSBhbmQgcmVhZC5Sb3dzIG9mIGxvb2t1cFJlc3VsdHNUYWJsZQogKiAgICAgICAgICAgICAgTUlCIGFkZCBhbmQgZGVsZXRlLgogKgogKkN1cnJlbnQgVmVyc2lvbjoxLjAKICpBdXRob3I6Q2hlbkppbmcKICpEYXRlOjIwMDQuOC4yMAogKi8KCi8qCiAqIFRoaXMgc2hvdWxkIGFsd2F5cyBiZSBpbmNsdWRlZCBmaXJzdCBiZWZvcmUgYW55dGhpbmcgZWxzZSAKICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWZlYXR1cmVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KCiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCm5ldHNubXBfZmVhdHVyZV9yZXF1aXJlKGhlYWRlcl9jb21wbGV4X2ZpbmRfZW50cnkpCiNlbmRpZiAvKiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQgKi8KCiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2luY2x1ZGUgPG5ldGRiLmg+CgojaW5jbHVkZSAibG9va3VwQ3RsVGFibGUuaCIKI2luY2x1ZGUgImxvb2t1cFJlc3VsdHNUYWJsZS5oIgojaW5jbHVkZSAiaGVhZGVyX2NvbXBsZXguaCIKCiNpZm5kZWYgSU5FVEFERFJFU1NUWVBFX0VOVU1TCiNkZWZpbmUgSU5FVEFERFJFU1NUWVBFX0VOVU1TCgojZGVmaW5lIElORVRBRERSRVNTVFlQRV9VTktOT1dOICAwCiNkZWZpbmUgSU5FVEFERFJFU1NUWVBFX0lQVjQgICAgIDEKI2RlZmluZSBJTkVUQUREUkVTU1RZUEVfSVBWNiAgICAgMgojZGVmaW5lIElORVRBRERSRVNTVFlQRV9JUFY0WiAgICAzCiNkZWZpbmUgSU5FVEFERFJFU1NUWVBFX0lQVjZaICAgIDQKI2RlZmluZSBJTkVUQUREUkVTU1RZUEVfRE5TICAgICAxNgoKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBJTkVUQUREUkVTU1RZUEVfRU5VTVMgKi8KCi8qCiAqRm9yIGRpc2NvbnRpbnVpdHkgY2hlY2tpbmcuCiAqLwoKb2lkICAgICAgICAgICAgIGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc19vaWRbXSA9CiAgICB7IDEsIDMsIDYsIDEsIDIsIDEsIDgyLCAxLCAzIH07CgoKI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKc3RydWN0IHZhcmlhYmxlMiBsb29rdXBDdGxUYWJsZV92YXJpYWJsZXNbXSA9IHsKICAgIC8qCiAgICAgKiBtYWdpYyBudW1iZXIgICAgICAgICwgdmFyaWFibGUgdHlwZSAsIHJvL3J3ICwgY2FsbGJhY2sgZm4gICwgTCwgb2lkc3VmZml4CiAgICAgKi8KICAgIHtDT0xVTU5fTE9PS1VQQ1RMVEFSR0VUQUREUkVTU1RZUEUsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9SV1JJVEUsCiAgICAgdmFyX2xvb2t1cEN0bFRhYmxlLCAyLCB7MSwgM319LAogICAge0NPTFVNTl9MT09LVVBDVExUQVJHRVRBRERSRVNTLCAgIEFTTl9PQ1RFVF9TVFIsIE5FVFNOTVBfT0xEQVBJX1JXUklURSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCA0fX0sCiAgICB7Q09MVU1OX0xPT0tVUENUTE9QRVJTVEFUVVMsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCA1fX0sCiAgICB7Q09MVU1OX0xPT0tVUENUTFRJTUUsICAgICAgQVNOX1VOU0lHTkVELCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCA2fX0sCiAgICB7Q09MVU1OX0xPT0tVUENUTFJDLCAgICAgICAgIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCA3fX0sCiAgICB7Q09MVU1OX0xPT0tVUENUTFJPV1NUQVRVUywgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JXUklURSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCA4fX0KfTsKI2Vsc2UgLyogIU5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVCAqLwpzdHJ1Y3QgdmFyaWFibGUyIGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc1tdID0gewogICAgLyoKICAgICAqIG1hZ2ljIG51bWJlciAgICAgICAgLCB2YXJpYWJsZSB0eXBlICwgcm8vcncgLCBjYWxsYmFjayBmbiAgLCBMLCBvaWRzdWZmaXgKICAgICAqLwogICAge0NPTFVNTl9MT09LVVBDVExUQVJHRVRBRERSRVNTVFlQRSwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgIHZhcl9sb29rdXBDdGxUYWJsZSwgMiwgezEsIDN9fSwKICAgIHtDT0xVTU5fTE9PS1VQQ1RMVEFSR0VUQUREUkVTUywgICBBU05fT0NURVRfU1RSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCA0fX0sCiAgICB7Q09MVU1OX0xPT0tVUENUTE9QRVJTVEFUVVMsIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCA1fX0sCiAgICB7Q09MVU1OX0xPT0tVUENUTFRJTUUsICAgICAgQVNOX1VOU0lHTkVELCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCA2fX0sCiAgICB7Q09MVU1OX0xPT0tVUENUTFJDLCAgICAgICAgIEFTTl9JTlRFR0VSLCBORVRTTk1QX09MREFQSV9ST05MWSwKICAgICB2YXJfbG9va3VwQ3RsVGFibGUsIDIsIHsxLCA3fX0sCiAgICB7Q09MVU1OX0xPT0tVUENUTFJPV1NUQVRVUywgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgIHZhcl9sb29rdXBDdGxUYWJsZSwgMiwgezEsIDh9fQp9OwojZW5kaWYgLyogIU5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVCAqLwoKCi8qCiAqIGdsb2JhbCBzdG9yYWdlIG9mIG91ciBkYXRhLCBzYXZlZCBpbiBhbmQgY29uZmlndXJlZCBieSBoZWFkZXJfY29tcGxleCgpIAogKi8KCnN0cnVjdCBoZWFkZXJfY29tcGxleF9pbmRleCAqbG9va3VwQ3RsVGFibGVTdG9yYWdlID0gTlVMTDsKc3RydWN0IGhlYWRlcl9jb21wbGV4X2luZGV4ICpsb29rdXBSZXN1bHRzVGFibGVTdG9yYWdlID0gTlVMTDsKCmludCBtb2RpZnlfbG9va3VwQ3RsVGltZShzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqdGhlZGF0YSwgdW5zaWduZWQgbG9uZyB2YWwpOwppbnQgbW9kaWZ5X2xvb2t1cEN0bE9wZXJTdGF0dXMoc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKnRoZWRhdGEsIGxvbmcgdmFsKTsKaW50IG1vZGlmeV9sb29rdXBDdGxSYyhzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqdGhlZGF0YSwgbG9uZyB2YWwpOwoKdm9pZAppbml0X2xvb2t1cEN0bFRhYmxlKHZvaWQpCnsKICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsICJpbml0aWFsaXppbmcuLi4gICIpKTsKICAgIC8qCiAgICAgKiByZWdpc3RlciBvdXJzZWx2ZXMgd2l0aCB0aGUgYWdlbnQgdG8gaGFuZGxlIG91ciBtaWIgdHJlZSAKICAgICAqLwogICAgUkVHSVNURVJfTUlCKCJsb29rdXBDdGxUYWJsZSIsIGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlcywgdmFyaWFibGUyLAogICAgICAgICAgICAgICAgIGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc19vaWQpOwoKCiAgICAvKgogICAgICogcmVnaXN0ZXIgb3VyIGNvbmZpZyBoYW5kbGVyKHMpIHRvIGRlYWwgd2l0aCByZWdpc3RyYXRpb25zIAogICAgICovCiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigibG9va3VwQ3RsVGFibGUiLCBwYXJzZV9sb29rdXBDdGxUYWJsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE5VTEwpOwoKICAgIC8qCiAgICAgKiB3ZSBuZWVkIHRvIGJlIGNhbGxlZCBiYWNrIGxhdGVyIHRvIHN0b3JlIG91ciBkYXRhIAogICAgICovCiAgICBzbm1wX3JlZ2lzdGVyX2NhbGxiYWNrKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwgU05NUF9DQUxMQkFDS19TVE9SRV9EQVRBLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9yZV9sb29rdXBDdGxUYWJsZSwgTlVMTCk7CgogICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgImRvbmUuXG4iKSk7Cn0KCnN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICoKY3JlYXRlX2xvb2t1cFRhYmxlX2RhdGEodm9pZCkKewogICAgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VOZXcgPSBOVUxMOwogICAgU3RvcmFnZU5ldyA9IFNOTVBfTUFMTE9DX1NUUlVDVChsb29rdXBUYWJsZV9kYXRhKTsKICAgIGlmIChTdG9yYWdlTmV3ID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiT3V0IGluIG1lbW9yeSBpbiBuc2xvb2t1cC1taWIvY3JlYXRlX2xvb2t1cFRhYmxlX2RhdGVcbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CiAgICBTdG9yYWdlTmV3LT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzID0gc3RyZHVwKCIiKTsKICAgIFN0b3JhZ2VOZXctPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NMZW4gPSAwOwogICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsT3BlclN0YXR1cyA9IDJMOwogICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsVGltZSA9IDA7CiAgICBTdG9yYWdlTmV3LT5zdG9yYWdldHlwZSA9IFNUX05PTlZPTEFUSUxFOwogICAgcmV0dXJuIFN0b3JhZ2VOZXc7Cn0KCi8qCiAqIGxvb2t1cEN0bFRhYmxlX2FkZCgpOiBhZGRzIGEgc3RydWN0dXJlIG5vZGUgdG8gb3VyIGRhdGEgc2V0IAogKi8KaW50Cmxvb2t1cEN0bFRhYmxlX2FkZChzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqdGhlZGF0YSkKewogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJzID0gTlVMTDsKCiAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLCAiYWRkaW5nIGRhdGEuLi4gICIpKTsKICAgIC8qCiAgICAgKiBhZGQgdGhlIGluZGV4IHZhcmlhYmxlcyB0byB0aGUgdmFyYmluZCBsaXN0LCB3aGljaCBpcyAKICAgICAqIHVzZWQgYnkgaGVhZGVyX2NvbXBsZXggdG8gaW5kZXggdGhlIGRhdGEgCiAgICAgKi8KICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleCwKICAgICAgICB0aGVkYXRhLT5sb29rdXBDdGxPd25lckluZGV4TGVuKTsKICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSwKICAgICAgICB0aGVkYXRhLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuKTsKCgogICAgaWYgKGhlYWRlcl9jb21wbGV4X2FkZF9kYXRhKCZsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIHZhcnMsIHRoZWRhdGEpID09CiAgICAgICAgTlVMTCkgewogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsICJyZWdpc3RlcmVkIGFuIGVudHJ5XG4iKSk7CiAgICB2YXJzID0gTlVMTDsKCiAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLCAiZG9uZS5cbiIpKTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCmludApsb29rdXBSZXN1bHRzVGFibGVfYWRkKHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICp0aGVkYXRhKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnNfbGlzdCA9IE5VTEw7CiAgICBzdHJ1Y3QgbG9va3VwUmVzdWx0c1RhYmxlX2RhdGEgKnAgPSBOVUxMOwogICAgcCA9IHRoZWRhdGEtPlJlc3VsdHNUYWJsZTsKICAgIGlmICh0aGVkYXRhLT5SZXN1bHRzVGFibGUgIT0gTlVMTCkKICAgICAgICBkbyB7CiAgICAgICAgICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnNfbGlzdCwgTlVMTCwgMCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgIChjaGFyICopIHAtPmxvb2t1cEN0bE93bmVySW5kZXgsCiAgICAgICAgICAgICAgICBwLT5sb29rdXBDdGxPd25lckluZGV4TGVuKTsKICAgICAgICAgICAgc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSgmdmFyc19saXN0LCBOVUxMLCAwLCBBU05fT0NURVRfU1RSLAogICAgICAgICAgICAgICAgKGNoYXIgKikgcC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSwKICAgICAgICAgICAgICAgIHAtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWVMZW4pOwogICAgICAgICAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZ2YXJzX2xpc3QsIE5VTEwsIDAsIEFTTl9VTlNJR05FRCwKICAgICAgICAgICAgICAgIChjaGFyICopICZwLT5sb29rdXBSZXN1bHRzSW5kZXgsCiAgICAgICAgICAgICAgICBzaXplb2YocC0+bG9va3VwUmVzdWx0c0luZGV4KSk7CgogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwUmVzdWx0c1RhYmxlIiwgImFkZGluZyBkYXRhLi4uICAiKSk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFkZCB0aGUgaW5kZXggdmFyaWFibGVzIHRvIHRoZSB2YXJiaW5kIGxpc3QsIHdoaWNoIGlzIAogICAgICAgICAgICAgKiB1c2VkIGJ5IGhlYWRlcl9jb21wbGV4IHRvIGluZGV4IHRoZSBkYXRhIAogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmIChoZWFkZXJfY29tcGxleF9hZGRfZGF0YQogICAgICAgICAgICAgICAgKCZsb29rdXBSZXN1bHRzVGFibGVTdG9yYWdlLCB2YXJzX2xpc3QsIHApID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cFJlc3VsdHNUYWJsZSIsICJvdXQgZmluaXNoZWRcbiIpKTsKICAgICAgICAgICAgdmFyc19saXN0ID0gTlVMTDsKICAgICAgICAgICAgcCA9IHAtPm5leHQ7CiAgICAgICAgfSB3aGlsZSAocCAhPSBOVUxMKTsKCiAgICBERUJVR01TR1RMKCgibG9va3VwUmVzdWx0c1RhYmxlIiwgImRvbmUuXG4iKSk7CiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9Cgp2b2lkCmxvb2t1cEN0bFRhYmxlX2NsZWFuZXIoc3RydWN0IGhlYWRlcl9jb21wbGV4X2luZGV4ICp0aGVzdHVmZikKewogICAgc3RydWN0IGhlYWRlcl9jb21wbGV4X2luZGV4ICpoY2lwdHIgPSBOVUxMOwogICAgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VEZWwgPSBOVUxMOwogICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgImNsZWFuZXJvdXQgICIpKTsKICAgIGZvciAoaGNpcHRyID0gdGhlc3R1ZmY7IGhjaXB0ciAhPSBOVUxMOyBoY2lwdHIgPSBoY2lwdHItPm5leHQpIHsKICAgICAgICBTdG9yYWdlRGVsID0KICAgICAgICAgICAgaGVhZGVyX2NvbXBsZXhfZXh0cmFjdF9lbnRyeSgmbG9va3VwQ3RsVGFibGVTdG9yYWdlLCBoY2lwdHIpOwogICAgICAgIGlmIChTdG9yYWdlRGVsICE9IE5VTEwpIHsKICAgICAgICAgICAgZnJlZShTdG9yYWdlRGVsLT5sb29rdXBDdGxPd25lckluZGV4KTsKICAgICAgICAgICAgU3RvcmFnZURlbC0+bG9va3VwQ3RsT3duZXJJbmRleCA9IE5VTEw7CiAgICAgICAgICAgIGZyZWUoU3RvcmFnZURlbC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSk7CiAgICAgICAgICAgIFN0b3JhZ2VEZWwtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUgPSBOVUxMOwogICAgICAgICAgICBmcmVlKFN0b3JhZ2VEZWwtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MpOwogICAgICAgICAgICBTdG9yYWdlRGVsLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzID0gTlVMTDsKICAgICAgICAgICAgZnJlZShTdG9yYWdlRGVsKTsKICAgICAgICAgICAgU3RvcmFnZURlbCA9IE5VTEw7CgogICAgICAgIH0KICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLCAiY2xlYW5lciAgIikpOwogICAgfQp9CgovKgogKiBwYXJzZV9sb29rdXBDdGxUYWJsZSgpOgogKiAgIHBhcnNlcyAuY29uZiBmaWxlIGVudHJpZXMgbmVlZGVkIHRvIGNvbmZpZ3VyZSB0aGUgbWliLgogKi8Kdm9pZApwYXJzZV9sb29rdXBDdGxUYWJsZShjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqbGluZSkKewogICAgc2l6ZV90ICAgICAgICAgIHRtcGludDsKICAgIHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICpTdG9yYWdlVG1wID0gU05NUF9NQUxMT0NfU1RSVUNUKGxvb2t1cFRhYmxlX2RhdGEpOwoKICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsICJwYXJzaW5nIGNvbmZpZy4uLiAgIikpOwoKCiAgICBpZiAoU3RvcmFnZVRtcCA9PSBOVUxMKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigibWFsbG9jIGZhaWx1cmUiKTsKICAgICAgICByZXR1cm47CiAgICB9CgoKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfZGF0YShBU05fT0NURVRfU1RSLCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsT3duZXJJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bE93bmVySW5kZXhMZW4pOwogICAgaWYgKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bE93bmVySW5kZXggPT0gTlVMTCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoImludmFsaWQgc3BlY2lmaWNhdGlvbiBmb3IgbG9va3VwQ3RsT3duZXJJbmRleCIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsaW5lID0KICAgICAgICByZWFkX2NvbmZpZ19yZWFkX2RhdGEoQVNOX09DVEVUX1NUUiwgbGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdG9yYWdlVG1wLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuKTsKICAgIGlmIChTdG9yYWdlVG1wLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lID09IE5VTEwpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJpbnZhbGlkIHNwZWNpZmljYXRpb24gZm9yIGxvb2t1cEN0bE9wZXJhdGlvbk5hbWUiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgbGluZSA9CiAgICAgICAgcmVhZF9jb25maWdfcmVhZF9kYXRhKEFTTl9JTlRFR0VSLCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0bXBpbnQpOwoKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfZGF0YShBU05fT0NURVRfU1RSLCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NMZW4pOwogICAgaWYgKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MgPT0gTlVMTCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoImludmFsaWQgc3BlY2lmaWNhdGlvbiBmb3IgbG9va3VwQ3RsVGFyZ2V0QWRkcmVzcyIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBsaW5lID0KICAgICAgICByZWFkX2NvbmZpZ19yZWFkX2RhdGEoQVNOX0lOVEVHRVIsIGxpbmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdG9yYWdlVG1wLT5sb29rdXBDdGxPcGVyU3RhdHVzLCAmdG1waW50KTsKCiAgICBsaW5lID0KICAgICAgICByZWFkX2NvbmZpZ19yZWFkX2RhdGEoQVNOX1VOU0lHTkVELCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGltZSwgJnRtcGludCk7CgogICAgbGluZSA9CiAgICAgICAgcmVhZF9jb25maWdfcmVhZF9kYXRhKEFTTl9JTlRFR0VSLCBsaW5lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsUmMsICZ0bXBpbnQpOwoKICAgIGxpbmUgPQogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfZGF0YShBU05fSU5URUdFUiwgbGluZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJvd1N0YXR1cywgJnRtcGludCk7CgoKICAgIFN0b3JhZ2VUbXAtPnN0b3JhZ2V0eXBlID0gU1RfTk9OVk9MQVRJTEU7CiAgICBsb29rdXBDdGxUYWJsZV9hZGQoU3RvcmFnZVRtcCk7CiAgICAvKiBsb29rdXBDdGxUYWJsZV9jbGVhbmVyKGxvb2t1cEN0bFRhYmxlU3RvcmFnZSk7ICovCgogICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgImRvbmUuXG4iKSk7Cn0KCgoKLyoKICogc3RvcmVfbG9va3VwQ3RsVGFibGUoKToKICogICBzdG9yZXMgLmNvbmYgZmlsZSBlbnRyaWVzIG5lZWRlZCB0byBjb25maWd1cmUgdGhlIG1pYi4KICovCmludApzdG9yZV9sb29rdXBDdGxUYWJsZShpbnQgbWFqb3JJRCwgaW50IG1pbm9ySUQsIHZvaWQgKnNlcnZlcmFyZywKICAgICAgICAgICAgICAgICAgICAgdm9pZCAqY2xpZW50YXJnKQp7CiAgICBjaGFyICAgICAgICAgICAgbGluZVtTTk1QX01BWEJVRl07CiAgICBjaGFyICAgICAgICAgICAqY3B0cjsKICAgIHNpemVfdCAgICAgICAgICB0bXBpbnQ7CiAgICBzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqU3RvcmFnZVRtcDsKICAgIHN0cnVjdCBoZWFkZXJfY29tcGxleF9pbmRleCAqaGNpbmRleDsKCiAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLCAic3RvcmluZyBkYXRhLi4uICAiKSk7CgogICAgZm9yIChoY2luZGV4ID0gbG9va3VwQ3RsVGFibGVTdG9yYWdlOyBoY2luZGV4ICE9IE5VTEw7CiAgICAgICAgIGhjaW5kZXggPSBoY2luZGV4LT5uZXh0KSB7CiAgICAgICAgU3RvcmFnZVRtcCA9IChzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqKSBoY2luZGV4LT5kYXRhOwoKICAgICAgICBpZiAoU3RvcmFnZVRtcC0+c3RvcmFnZXR5cGUgIT0gU1RfUkVBRE9OTFkpIHsKICAgICAgICAgICAgbWVtc2V0KGxpbmUsIDAsIHNpemVvZihsaW5lKSk7CiAgICAgICAgICAgIHN0cmNhdChsaW5lLCAibG9va3VwQ3RsVGFibGUgIik7CiAgICAgICAgICAgIGNwdHIgPSBsaW5lICsgc3RybGVuKGxpbmUpOwoKICAgICAgICAgICAgY3B0ciA9CiAgICAgICAgICAgICAgICByZWFkX2NvbmZpZ19zdG9yZV9kYXRhKEFTTl9PQ1RFVF9TVFIsIGNwdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdG9yYWdlVG1wLT5sb29rdXBDdGxPd25lckluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb2t1cEN0bE93bmVySW5kZXhMZW4pOwogICAgICAgICAgICBjcHRyID0KICAgICAgICAgICAgICAgIHJlYWRfY29uZmlnX3N0b3JlX2RhdGEoQVNOX09DVEVUX1NUUiwgY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZTdG9yYWdlVG1wLT4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbik7CiAgICAgICAgICAgIGNwdHIgPQogICAgICAgICAgICAgICAgcmVhZF9jb25maWdfc3RvcmVfZGF0YShBU05fSU5URUdFUiwgY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29rdXBDdGxUYXJnZXRBZGRyZXNzVHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRtcGludCk7CiAgICAgICAgICAgIGNwdHIgPQogICAgICAgICAgICAgICAgcmVhZF9jb25maWdfc3RvcmVfZGF0YShBU05fT0NURVRfU1RSLCBjcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb29rdXBDdGxUYXJnZXRBZGRyZXNzTGVuKTsKCiAgICAgICAgICAgIGNwdHIgPQogICAgICAgICAgICAgICAgcmVhZF9jb25maWdfc3RvcmVfZGF0YShBU05fSU5URUdFUiwgY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bE9wZXJTdGF0dXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0bXBpbnQpOwogICAgICAgICAgICBjcHRyID0KICAgICAgICAgICAgICAgIHJlYWRfY29uZmlnX3N0b3JlX2RhdGEoQVNOX1VOU0lHTkVELCBjcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRtcGludCk7CiAgICAgICAgICAgIGNwdHIgPQogICAgICAgICAgICAgICAgcmVhZF9jb25maWdfc3RvcmVfZGF0YShBU05fSU5URUdFUiwgY3B0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJjLCAmdG1waW50KTsKICAgICAgICAgICAgY3B0ciA9CiAgICAgICAgICAgICAgICByZWFkX2NvbmZpZ19zdG9yZV9kYXRhKEFTTl9JTlRFR0VSLCBjcHRyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdG1waW50KTsKICAgICAgICAgICAgc25tcGRfc3RvcmVfY29uZmlnKGxpbmUpOwogICAgICAgIH0KICAgIH0KICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsICJkb25lLlxuIikpOwogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKCgoKLyoKICogdmFyX2xvb2t1cEN0bFRhYmxlKCk6CiAqICAgSGFuZGxlIHRoaXMgdGFibGUgc2VwYXJhdGVseSBmcm9tIHRoZSBzY2FsYXIgdmFsdWUgY2FzZS4KICogICBUaGUgd29ya2luZ3Mgb2YgdGhpcyBhcmUgYmFzaWNhbGx5IHRoZSBzYW1lIGFzIGZvciB2YXJfbXRlT2JqZWN0c1RhYmxlIGFib3ZlLgogKi8KdW5zaWduZWQgY2hhciAgKgp2YXJfbG9va3VwQ3RsVGFibGUoc3RydWN0IHZhcmlhYmxlICp2cCwKICAgICAgICAgICAgICAgICAgIG9pZCAqIG5hbWUsCiAgICAgICAgICAgICAgICAgICBzaXplX3QgKmxlbmd0aCwKICAgICAgICAgICAgICAgICAgIGludCBleGFjdCwgc2l6ZV90ICp2YXJfbGVuLCBXcml0ZU1ldGhvZCAqKiB3cml0ZV9tZXRob2QpCnsKICAgIHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICpTdG9yYWdlVG1wID0gTlVMTDsKICAgICAgICAqd3JpdGVfbWV0aG9kID0gTlVMTDsKCiAgICAvKgogICAgICogdGhpcyBhc3N1bWVzIHlvdSBoYXZlIHJlZ2lzdGVyZWQgYWxsIHlvdXIgZGF0YSBwcm9wZXJseQogICAgICovCiAgICBpZiAoKFN0b3JhZ2VUbXAgPQogICAgICAgICBoZWFkZXJfY29tcGxleChsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIHZwLCBuYW1lLCBsZW5ndGgsIGV4YWN0LAogICAgICAgICAgICAgICAgICAgICAgICB2YXJfbGVuLCB3cml0ZV9tZXRob2QpKSA9PSBOVUxMKSB7CiAgICAgICAgaWYgKHZwLT5tYWdpYyA9PSBDT0xVTU5fTE9PS1VQQ1RMUk9XU1RBVFVTKQogICAgICAgICAgICAqd3JpdGVfbWV0aG9kID0gd3JpdGVfbG9va3VwQ3RsUm93U3RhdHVzOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qCiAgICAgKiB0aGlzIGlzIHdoZXJlIHdlIGRvIHRoZSB2YWx1ZSBhc3NpZ25tZW50cyBmb3IgdGhlIG1pYiByZXN1bHRzLgogICAgICovCiAgICBzd2l0Y2ggKHZwLT5tYWdpYykgewogICAgY2FzZSBDT0xVTU5fTE9PS1VQQ1RMVEFSR0VUQUREUkVTU1RZUEU6CiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCiAgICAgICAgKndyaXRlX21ldGhvZCA9IHdyaXRlX2xvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlOwojZW5kaWYgLyogIU5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVCAqLwogICAgICAgICp2YXJfbGVuID0gc2l6ZW9mKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlKTsKICAgICAgICByZXR1cm4gKHVfY2hhciAqKSAmIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlOwoKICAgIGNhc2UgQ09MVU1OX0xPT0tVUENUTFRBUkdFVEFERFJFU1M6CiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCiAgICAgICAgKndyaXRlX21ldGhvZCA9IHdyaXRlX2xvb2t1cEN0bFRhcmdldEFkZHJlc3M7CiNlbmRpZiAvKiAhTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICAgICAgKnZhcl9sZW4gPSAoU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc0xlbik7CiAgICAgICAgcmV0dXJuICh1X2NoYXIgKikgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzczsKCiAgICBjYXNlIENPTFVNTl9MT09LVVBDVExPUEVSU1RBVFVTOgogICAgICAgICp2YXJfbGVuID0gc2l6ZW9mKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bE9wZXJTdGF0dXMpOwogICAgICAgIHJldHVybiAodV9jaGFyICopICYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsT3BlclN0YXR1czsKCiAgICBjYXNlIENPTFVNTl9MT09LVVBDVExUSU1FOgogICAgICAgICp2YXJfbGVuID0gc2l6ZW9mKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRpbWUpOwogICAgICAgIHJldHVybiAodV9jaGFyICopICYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGltZTsKCiAgICBjYXNlIENPTFVNTl9MT09LVVBDVExSQzoKICAgICAgICAqdmFyX2xlbiA9IHNpemVvZihTdG9yYWdlVG1wLT5sb29rdXBDdGxSYyk7CiAgICAgICAgcmV0dXJuICh1X2NoYXIgKikgJiBTdG9yYWdlVG1wLT5sb29rdXBDdGxSYzsKCiAgICBjYXNlIENPTFVNTl9MT09LVVBDVExST1dTVEFUVVM6CiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCiAgICAgICAgKndyaXRlX21ldGhvZCA9IHdyaXRlX2xvb2t1cEN0bFJvd1N0YXR1czsKI2VuZGlmIC8qICFORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQgKi8KICAgICAgICAqdmFyX2xlbiA9IHNpemVvZihTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXMpOwogICAgICAgIHJldHVybiAodV9jaGFyICopICYgU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgRVJST1JfTVNHKCIiKTsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgoKc3RhdGljIHN0cnVjdCBsb29rdXBSZXN1bHRzVGFibGVfZGF0YSAqCmFkZF9yZXN1bHQoc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKml0ZW0sIGludCBpbmRleCwKICAgICAgICBpbnQgaWF0eXBlLCBjb25zdCB2b2lkICpkYXRhLCBzaXplX3QgZGF0YV9sZW4pCnsKICAgIHN0cnVjdCBsb29rdXBSZXN1bHRzVGFibGVfZGF0YSAqdGVtcDsKICAgIHRlbXAgPSBTTk1QX01BTExPQ19TVFJVQ1QobG9va3VwUmVzdWx0c1RhYmxlX2RhdGEpOwogICAgaWYgKHRlbXAgPT0gTlVMTCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJPdXQgb2YgbWVtb3J5IGluIG5zbG9va3VwLW1pYi9ydW5fbG9va3VwXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHRlbXAtPmxvb2t1cFJlc3VsdHNJbmRleCA9IGluZGV4OwogICAgdGVtcC0+bmV4dCA9IE5VTEw7CgogICAgdGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleCA9IG1hbGxvYyhpdGVtLT5sb29rdXBDdGxPd25lckluZGV4TGVuICsgMSk7CiAgICBpZiAodGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleCA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIk91dCBvZiBtZW1vcnkgaW4gbnNsb29rdXAtbWliL3J1bl9sb29rdXBcbiIpOwogICAgICAgIGZyZWUodGVtcCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBtZW1jcHkodGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleCwKICAgICAgICAgICBpdGVtLT5sb29rdXBDdGxPd25lckluZGV4LAogICAgICAgICAgIGl0ZW0tPmxvb2t1cEN0bE93bmVySW5kZXhMZW4gKyAxKTsKICAgIHRlbXAtPmxvb2t1cEN0bE93bmVySW5kZXhbaXRlbS0+bG9va3VwQ3RsT3duZXJJbmRleExlbl0gPSAnXDAnOwogICAgdGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleExlbiA9IGl0ZW0tPmxvb2t1cEN0bE93bmVySW5kZXhMZW47CgogICAgdGVtcC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSA9IG1hbGxvYyhpdGVtLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuICsgMSk7CiAgICBpZiAodGVtcC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIk91dCBvZiBtZW1vcnkgaW4gbnNsb29rdXAtbWliL3J1bl9sb29rdXBcbiIpOwogICAgICAgIGZyZWUodGVtcC0+bG9va3VwQ3RsT3duZXJJbmRleCk7CiAgICAgICAgZnJlZSh0ZW1wKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIG1lbWNweSh0ZW1wLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lLAogICAgICAgICAgIGl0ZW0tPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgICAgaXRlbS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbiArIDEpOwogICAgdGVtcC0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZVtpdGVtLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuXSA9ICdcMCc7CiAgICB0ZW1wLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuID0gaXRlbS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbjsKCiAgICB0ZW1wLT5sb29rdXBSZXN1bHRzQWRkcmVzc1R5cGUgPSBpYXR5cGU7CiAgICB0ZW1wLT5sb29rdXBSZXN1bHRzQWRkcmVzcyA9IG1hbGxvYyhkYXRhX2xlbiArIDEpOwogICAgbWVtY3B5KHRlbXAtPmxvb2t1cFJlc3VsdHNBZGRyZXNzLCBkYXRhLCBkYXRhX2xlbik7CiAgICB0ZW1wLT5sb29rdXBSZXN1bHRzQWRkcmVzc1tkYXRhX2xlbl0gPSAnXDAnOwogICAgdGVtcC0+bG9va3VwUmVzdWx0c0FkZHJlc3NMZW4gPSBkYXRhX2xlbjsKICAgIGlmICghaXRlbS0+UmVzdWx0c1RhYmxlKQogICAgICAgIGl0ZW0tPlJlc3VsdHNUYWJsZSA9IHRlbXA7CgogICAgcmV0dXJuIHRlbXA7Cn0KCnZvaWQKcnVuX2xvb2t1cChzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqaXRlbSkKewogICAgbG9uZyAgICAgICAgICAgIGFkZHJlc3NUeXBlOwogICAgY2hhciAgICAgICAgICAgKmFkZHJlc3MgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIGFkZHJlc3NsZW47CiAgICBzdHJ1Y3QgbG9va3VwUmVzdWx0c1RhYmxlX2RhdGEgKmN1cnJlbnQgPSBOVUxMOwogICAgc3RydWN0IGxvb2t1cFJlc3VsdHNUYWJsZV9kYXRhICp0ZW1wID0gTlVMTDsKICAgIGludCAgICAgICAgICAgICBpID0gMCwgbiA9IDE7CgogICAgc3RydWN0IHRpbWV2YWwgIHRwc3RhcnQsIHRwZW5kOwogICAgdW5zaWduZWQgbG9uZyAgIHRpbWV1c2UsIHRpbWV1c2U0ID0gMCwgdGltZXVzZTYgPSAwOwoKICAgIGlmIChpdGVtID09IE5VTEwpCiAgICAgICAgcmV0dXJuOwoKICAgIGFkZHJlc3NUeXBlID0gKGxvbmcpIGl0ZW0tPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NUeXBlOwogICAgYWRkcmVzc2xlbiA9IChzaXplX3QpIGl0ZW0tPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NMZW47CiAgICBhZGRyZXNzID0gKGNoYXIgKikgbWFsbG9jKGFkZHJlc3NsZW4gKyAxKTsKICAgIG1lbWNweShhZGRyZXNzLCBpdGVtLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzLCBhZGRyZXNzbGVuICsgMSk7CiAgICBhZGRyZXNzW2FkZHJlc3NsZW5dID0gJ1wwJzsKCiAgICBpZiAoYWRkcmVzc1R5cGUgPT0gSU5FVEFERFJFU1NUWVBFX0lQVjQpIHsKICAgICAgICBzdHJ1Y3QgaW5fYWRkciBhZGRyX2luOwogICAgICAgIHN0cnVjdCBob3N0ZW50ICpsb29rdXA7CgogICAgICAgIGlmICghaW5ldF9hdG9uKGFkZHJlc3MsICZhZGRyX2luKSkgewogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwUmVzdWx0c1RhYmxlIiwgIkludmFsaWQgYXJndW1lbnQ6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzKSk7CiAgICAgICAgICAgIG1vZGlmeV9sb29rdXBDdGxSYyhpdGVtLCA5OSk7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIG5ldHNubXBfZ2V0X21vbm90b25pY19jbG9jaygmdHBzdGFydCk7CiAgICAgICAgbG9va3VwID0gbmV0c25tcF9nZXRob3N0YnlhZGRyKCZhZGRyX2luLCBzaXplb2YoYWRkcl9pbiksIEFGX0lORVQpOwogICAgICAgIG5ldHNubXBfZ2V0X21vbm90b25pY19jbG9jaygmdHBlbmQpOwogICAgICAgIHRpbWV1c2UgPSAxMDAwMDAwICogKHRwZW5kLnR2X3NlYyAtIHRwc3RhcnQudHZfc2VjKSArCiAgICAgICAgICAgIHRwZW5kLnR2X3VzZWMgLSB0cHN0YXJ0LnR2X3VzZWM7CiAgICAgICAgdGltZXVzZSAvPSAxMDAwOwogICAgICAgIG1vZGlmeV9sb29rdXBDdGxUaW1lKGl0ZW0sIHRpbWV1c2UpOwogICAgICAgIG1vZGlmeV9sb29rdXBDdGxPcGVyU3RhdHVzKGl0ZW0sIDNMKTsKCiAgICAgICAgaWYgKGxvb2t1cCA9PSBOVUxMKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJDYW4ndCBnZXQgYSBuZXR3b3JrIGhvc3QgZW50cnkgZm9yIGlwdjQgYWRkcmVzczogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3MpKTsKICAgICAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFJjKGl0ZW0sIGhfZXJybm8pOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFJjKGl0ZW0sIDBMKTsKICAgICAgICAgICAgaWYgKGxvb2t1cC0+aF9uYW1lICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnQgPSB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfRE5TLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9va3VwLT5oX25hbWUsIHN0cmxlbihsb29rdXAtPmhfbmFtZSkpOwogICAgICAgICAgICAgICAgbiA9IG4gKyAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgd2hpbGUgKGxvb2t1cC0+aF9hbGlhc2VzW2ldKSB7CiAgICAgICAgICAgICAgICB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfRE5TLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9va3VwLT5oX2FsaWFzZXNbaV0sIHN0cmxlbihsb29rdXAtPmhfYWxpYXNlc1tpXSkpOwogICAgICAgICAgICAgICAgY3VycmVudC0+bmV4dCA9IHRlbXA7CiAgICAgICAgICAgICAgICBjdXJyZW50ID0gdGVtcDsKICAgICAgICAgICAgICAgIGkgPSBpICsgMTsKICAgICAgICAgICAgICAgIG4gPSBuICsgMTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKGl0ZW0tPlJlc3VsdHNUYWJsZSAhPSBOVUxMKQogICAgICAgICAgICBpZiAobG9va3VwUmVzdWx0c1RhYmxlX2FkZChpdGVtKSAhPSBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwUmVzdWx0c1RhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZWdpc3RlcmVkIGFuIGVudHJ5IGVycm9yXG4iKSk7CiAgICAgICAgU05NUF9GUkVFKGFkZHJlc3MpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBlbHNlIGlmIChhZGRyZXNzVHlwZSA9PSBJTkVUQUREUkVTU1RZUEVfRE5TKSB7CiAgICAgICAgc3RydWN0IGhvc3RlbnQgKmxvb2t1cDsKI2lmIEhBVkVfR0VUQUREUklORk8KICAgICAgICBpbnQgICAgICAgICAgICAgcmVzOwogICAgICAgIHN0cnVjdCBhZGRyaW5mbyAqYWlzOwogICAgICAgIHN0cnVjdCBhZGRyaW5mbyBoaW50cyA9IHsgMCwgQUZfSU5FVDYsIFNPQ0tfREdSQU0gfTsKI2VuZGlmCgogICAgICAgIG5ldHNubXBfZ2V0X21vbm90b25pY19jbG9jaygmdHBzdGFydCk7CiAgICAgICAgbG9va3VwID0gbmV0c25tcF9nZXRob3N0YnluYW1lKGFkZHJlc3MpOwogICAgICAgIG5ldHNubXBfZ2V0X21vbm90b25pY19jbG9jaygmdHBlbmQpOwogICAgICAgIHRpbWV1c2U0ID0gMTAwMDAwMCAqICh0cGVuZC50dl9zZWMgLSB0cHN0YXJ0LnR2X3NlYykgKwogICAgICAgICAgICB0cGVuZC50dl91c2VjIC0gdHBzdGFydC50dl91c2VjOwogICAgICAgIGlmIChsb29rdXAgPT0gTlVMTCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IGEgbmV0d29yayBob3N0IGVudHJ5IGZvciAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcykpOwogICAgICAgICAgICBtb2RpZnlfbG9va3VwQ3RsUmMoaXRlbSwgaF9lcnJubyk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgd2hpbGUgKGxvb2t1cC0+aF9hZGRyX2xpc3RbaV0pIHsKICAgICAgICAgICAgICAgIGNoYXIgYnVmWzY0XTsKICAgICAgICAgICAgICAgIGludCBidWZsZW47CgogICAgICAgICAgICAgICAgaW5ldF9udG9wKGxvb2t1cC0+aF9hZGRydHlwZSwgbG9va3VwLT5oX2FkZHJfbGlzdFtpXSwgYnVmLCBzaXplb2YoYnVmKSk7CiAgICAgICAgICAgICAgICBidWZsZW4gPSBzdHJsZW4oYnVmKTsKICAgICAgICAgICAgICAgIHN3aXRjaCAobG9va3VwLT5oX2FkZHJ0eXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlIEFGX0lORVQ6CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0lQVjQsIGJ1ZiwgYnVmbGVuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQUZfSU5FVDY6CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0lQVjYsIGJ1ZiwgYnVmbGVuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5zbG9va3VwLW1pYi9ydW5fbG9va3VwOiBVbmtub3duIGFkZHJlc3MgdHlwZSAlZFxuIiwgbG9va3VwLT5oX2FkZHJ0eXBlKTsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfVU5LTk9XTiwgIiIsIDApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgIkFkZGluZyAlZCAlc1xuIiwgbiwgYnVmKSk7CgogICAgICAgICAgICAgICAgaWYgKG4gPT0gMSkKICAgICAgICAgICAgICAgICAgICBpdGVtLT5SZXN1bHRzVGFibGUgPSB0ZW1wOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQtPm5leHQgPSB0ZW1wOwogICAgICAgICAgICAgICAgY3VycmVudCA9IHRlbXA7CiAgICAgICAgICAgICAgICBuID0gbiArIDE7CiAgICAgICAgICAgICAgICBpID0gaSArIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgojaWYgSEFWRV9HRVRBRERSSU5GTwogICAgICAgIG5ldHNubXBfZ2V0X21vbm90b25pY19jbG9jaygmdHBzdGFydCk7CiAgICAgICAgcmVzID0gbmV0c25tcF9nZXRhZGRyaW5mbyhhZGRyZXNzLCBOVUxMLCAmaGludHMsICZhaXMpOwogICAgICAgIG5ldHNubXBfZ2V0X21vbm90b25pY19jbG9jaygmdHBlbmQpOwogICAgICAgIHRpbWV1c2U2ID0gMTAwMDAwMCAqICh0cGVuZC50dl9zZWMgLSB0cHN0YXJ0LnR2X3NlYykgKwogICAgICAgICAgICB0cGVuZC50dl91c2VjIC0gdHBzdGFydC50dl91c2VjOwoKICAgICAgICBpZiAocmVzICE9IDApIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIkNhbid0IGdldCBhIGlwdjYgbmV0d29yayBob3N0IGVudHJ5IGZvciAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzcykpOwogICAgICAgICAgICBtb2RpZnlfbG9va3VwQ3RsUmMoaXRlbSwgcmVzKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzdHJ1Y3QgYWRkcmluZm8gKmFpcCA9IGFpczsKICAgICAgICAgICAgd2hpbGUgKGFpcCkgewogICAgICAgICAgICAgICAgY2hhciBidWZbNjRdOwogICAgICAgICAgICAgICAgaW50IGJ1ZmxlbjsKCiAgICAgICAgICAgICAgICBzd2l0Y2ggKGFpcC0+YWlfZmFtaWx5KSB7CiAgICAgICAgICAgICAgICBjYXNlIEFGX0lORVQ6CiAgICAgICAgICAgICAgICAgICAgaW5ldF9udG9wKGFpcC0+YWlfZmFtaWx5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJigoc3RydWN0IHNvY2thZGRyX2luICopYWlwLT5haV9hZGRyKS0+c2luX2FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Ziwgc2l6ZW9mKGJ1ZikpOwogICAgICAgICAgICAgICAgICAgIGJ1ZmxlbiA9IHN0cmxlbihidWYpOwogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBhZGRfcmVzdWx0KGl0ZW0sIG4sIElORVRBRERSRVNTVFlQRV9JUFY0LCBidWYsIGJ1Zmxlbik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIEFGX0lORVQ2OgogICAgICAgICAgICAgICAgICAgIGluZXRfbnRvcChhaXAtPmFpX2ZhbWlseSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICYoKHN0cnVjdCBzb2NrYWRkcl9pbjYgKilhaXAtPmFpX2FkZHIpLT5zaW42X2FkZHIsCiAgICAgICAgICAgICAgICAgICAgICAgIGJ1Ziwgc2l6ZW9mKGJ1ZikpOwogICAgICAgICAgICAgICAgICAgIGJ1ZmxlbiA9IHN0cmxlbihidWYpOwogICAgICAgICAgICAgICAgICAgIHRlbXAgPSBhZGRfcmVzdWx0KGl0ZW0sIG4sIElORVRBRERSRVNTVFlQRV9JUFY2LCBidWYsIGJ1Zmxlbik7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJuc2xvb2t1cC1taWIvcnVuX2xvb2t1cDogVW5rbm93biBhZGRyZXNzIHR5cGUgJWRcbiIsIGFpcC0+YWlfZmFtaWx5KTsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfVU5LTk9XTiwgIiIsIDApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgIkFkZGluZyAlZCAlc1xuIiwgbiwgYnVmKSk7CgogICAgICAgICAgICAgICAgaWYgKG4gPT0gMSkKICAgICAgICAgICAgICAgICAgICBpdGVtLT5SZXN1bHRzVGFibGUgPSB0ZW1wOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQtPm5leHQgPSB0ZW1wOwogICAgICAgICAgICAgICAgY3VycmVudCA9IHRlbXA7CiAgICAgICAgICAgICAgICBuID0gbiArIDE7CiAgICAgICAgICAgICAgICBhaXAgPSBhaXAtPmFpX25leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZnJlZWFkZHJpbmZvKGFpcyk7CiAgICAgICAgfQojZWxpZiBIQVZFX0dFVEhPU1RCWU5BTUUyCiAgICAgICAgbmV0c25tcF9nZXRfbW9ub3RvbmljX2Nsb2NrKCZ0cHN0YXJ0KTsKICAgICAgICBsb29rdXAgPSBnZXRob3N0YnluYW1lMihhZGRyZXNzLCBBRl9JTkVUNik7CiAgICAgICAgbmV0c25tcF9nZXRfbW9ub3RvbmljX2Nsb2NrKCZ0cGVuZCk7CiAgICAgICAgdGltZXVzZTYgPSAxMDAwMDAwICogKHRwZW5kLnR2X3NlYyAtIHRwc3RhcnQudHZfc2VjKSArCiAgICAgICAgICAgIHRwZW5kLnR2X3VzZWMgLSB0cHN0YXJ0LnR2X3VzZWM7CgogICAgICAgIGlmIChsb29rdXAgPT0gTlVMTCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IGEgaXB2NiBuZXR3b3JrIGhvc3QgZW50cnkgZm9yICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBhZGRyZXNzKSk7CiAgICAgICAgICAgIG1vZGlmeV9sb29rdXBDdGxSYyhpdGVtLCBoX2Vycm5vKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgd2hpbGUgKGxvb2t1cC0+aF9hZGRyX2xpc3RbaV0pIHsKICAgICAgICAgICAgICAgIGNoYXIgYnVmWzY0XTsKICAgICAgICAgICAgICAgIGludCBidWZsZW47CgogICAgICAgICAgICAgICAgaW5ldF9udG9wKGxvb2t1cC0+aF9hZGRydHlwZSwgbG9va3VwLT5oX2FkZHJfbGlzdFtpXSwKICAgICAgICAgICAgICAgICAgICAgICAgYnVmLCBzaXplb2YoYnVmKSk7CiAgICAgICAgICAgICAgICBidWZsZW4gPSBzdHJsZW4oYnVmKTsKICAgICAgICAgICAgICAgIHN3aXRjaCAobG9va3VwLT5oX2FkZHJ0eXBlKSB7CiAgICAgICAgICAgICAgICBjYXNlIEFGX0lORVQ6CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0lQVjQsIGJ1ZiwgYnVmbGVuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgQUZfSU5FVDY6CiAgICAgICAgICAgICAgICAgICAgdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0lQVjYsIGJ1ZiwgYnVmbGVuKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5zbG9va3VwLW1pYi9ydW5fbG9va3VwOiBVbmtub3duIGFkZHJlc3MgdHlwZSAlZFxuIiwgbG9va3VwLT5oX2FkZHJ0eXBlKTsKICAgICAgICAgICAgICAgICAgICB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfVU5LTk9XTiwgIiIsIDApOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgIkFkZGluZyAlZCAlc1xuIiwgbiwgYnVmKSk7CgogICAgICAgICAgICAgICAgaWYgKG4gPT0gMSkKICAgICAgICAgICAgICAgICAgICBpdGVtLT5SZXN1bHRzVGFibGUgPSB0ZW1wOwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIGN1cnJlbnQtPm5leHQgPSB0ZW1wOwogICAgICAgICAgICAgICAgY3VycmVudCA9IHRlbXA7CiAgICAgICAgICAgICAgICBuID0gbiArIDE7CiAgICAgICAgICAgICAgICBpID0gaSArIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZgoKICAgICAgICB0aW1ldXNlID0gdGltZXVzZTQgKyB0aW1ldXNlNjsKICAgICAgICB0aW1ldXNlIC89IDEwMDA7CiAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFRpbWUoaXRlbSwgdGltZXVzZSk7CiAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bE9wZXJTdGF0dXMoaXRlbSwgM0wpOwoKICAgICAgICBpZiAoaXRlbS0+UmVzdWx0c1RhYmxlICE9IE5VTEwpIHsKICAgICAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFJjKGl0ZW0sIDBMKTsKICAgICAgICAgICAgaWYgKGxvb2t1cFJlc3VsdHNUYWJsZV9hZGQoaXRlbSkgIT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cFJlc3VsdHNUYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVnaXN0ZXJlZCBhbiBlbnRyeSBlcnJvclxuIikpOwogICAgICAgIH0KICAgICAgICBTTk1QX0ZSRUUoYWRkcmVzcyk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGVsc2UgaWYgKGFkZHJlc3NUeXBlID09IElORVRBRERSRVNTVFlQRV9JUFY2KSB7CiAgICAgICAgc3RydWN0IGluNl9hZGRyIGFkZHJfaW42OwogICAgICAgIHN0cnVjdCBob3N0ZW50ICpsb29rdXA7CgogICAgICAgIGlmIChpbmV0X3B0b24oQUZfSU5FVDYsIGFkZHJlc3MsICZhZGRyX2luNikgPT0gMSkKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgInN1Y2Nlc3MhIFxuIikpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwgImVycm9yISBcbiIpKTsKCiAgICAgICAgbmV0c25tcF9nZXRfbW9ub3RvbmljX2Nsb2NrKCZ0cHN0YXJ0KTsKICAgICAgICBsb29rdXAgPSBuZXRzbm1wX2dldGhvc3RieWFkZHIoJmFkZHJfaW42LCBzaXplb2YoYWRkcl9pbjYpLCBBRl9JTkVUNik7CiAgICAgICAgbmV0c25tcF9nZXRfbW9ub3RvbmljX2Nsb2NrKCZ0cGVuZCk7CiAgICAgICAgdGltZXVzZSA9IDEwMDAwMDAgKiAodHBlbmQudHZfc2VjIC0gdHBzdGFydC50dl9zZWMpICsKICAgICAgICAgICAgdHBlbmQudHZfdXNlYyAtIHRwc3RhcnQudHZfdXNlYzsKICAgICAgICB0aW1ldXNlIC89IDEwMDA7CiAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFRpbWUoaXRlbSwgdGltZXVzZSk7CiAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bE9wZXJTdGF0dXMoaXRlbSwgM0wpOwoKICAgICAgICBpZiAobG9va3VwID09IE5VTEwpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cEN0bFRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIkNhbid0IGdldCBhIG5ldHdvcmsgaG9zdCBlbnRyeSBmb3IgJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIGFkZHJlc3MpKTsKICAgICAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFJjKGl0ZW0sIGhfZXJybm8pOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bFJjKGl0ZW0sIDBMKTsKICAgICAgICAgICAgaWYgKGxvb2t1cC0+aF9uYW1lICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIGN1cnJlbnQgPSB0ZW1wID0gYWRkX3Jlc3VsdChpdGVtLCBuLCBJTkVUQUREUkVTU1RZUEVfRE5TLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9va3VwLT5oX25hbWUsIHN0cmxlbihsb29rdXAtPmhfbmFtZSkpOwogICAgICAgICAgICAgICAgbiA9IG4gKyAxOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpID0gMDsKICAgICAgICAgICAgd2hpbGUgKGxvb2t1cC0+aF9hbGlhc2VzW2ldKSB7CiAgICAgICAgICAgICAgICBjdXJyZW50ID0gdGVtcCA9IGFkZF9yZXN1bHQoaXRlbSwgbiwgSU5FVEFERFJFU1NUWVBFX0ROUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvb2t1cC0+aF9hbGlhc2VzW2ldLCBzdHJsZW4obG9va3VwLT5oX2FsaWFzZXNbaV0pKTsKICAgICAgICAgICAgICAgIGN1cnJlbnQtPm5leHQgPSB0ZW1wOwogICAgICAgICAgICAgICAgY3VycmVudCA9IHRlbXA7CiAgICAgICAgICAgICAgICBpID0gaSArIDE7CiAgICAgICAgICAgICAgICBuID0gbiArIDE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChpdGVtLT5SZXN1bHRzVGFibGUgIT0gTlVMTCkKICAgICAgICAgICAgICAgIGN1cnJlbnQtPm5leHQgPSBOVUxMOwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICBjdXJyZW50ID0gTlVMTDsKICAgICAgICB9CgogICAgICAgIGlmIChpdGVtLT5SZXN1bHRzVGFibGUgIT0gTlVMTCkKICAgICAgICAgICAgaWYgKGxvb2t1cFJlc3VsdHNUYWJsZV9hZGQoaXRlbSkgIT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImxvb2t1cFJlc3VsdHNUYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVnaXN0ZXJlZCBhbiBlbnRyeSBlcnJvclxuIikpOwogICAgICAgIFNOTVBfRlJFRShhZGRyZXNzKTsKICAgICAgICByZXR1cm47CiAgICB9IGVsc2UgewogICAgICAgIFNOTVBfRlJFRShhZGRyZXNzKTsKICAgICAgICByZXR1cm47CiAgICB9Cn0KCgppbnQKbW9kaWZ5X2xvb2t1cEN0bE9wZXJTdGF0dXMoc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKnRoZWRhdGEsIGxvbmcgdmFsKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMgPSBOVUxMOwogICAgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VUbXAgPSBOVUxMOwoKICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleCwgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleExlbik7CiAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZ2YXJzLCBOVUxMLCAwLCBBU05fT0NURVRfU1RSLAogICAgICAgIChjaGFyICopIHRoZWRhdGEtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgdGhlZGF0YS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbik7CgoKICAgIGlmICgoU3RvcmFnZVRtcCA9CiAgICAgICAgIGhlYWRlcl9jb21wbGV4X2dldChsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIHZhcnMpKSA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmFycyk7CiAgICAgICAgdmFycyA9IE5VTEw7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PU1VDSE5BTUU7CiAgICB9CiAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxPcGVyU3RhdHVzID0gdmFsOwoKICAgIHNubXBfZnJlZV92YXJiaW5kKHZhcnMpOwogICAgdmFycyA9IE5VTEw7CgogICAgREVCVUdNU0dUTCgoImxvb2t1cE9wZXJTdGF0dXMiLCAiZG9uZS5cbiIpKTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCmludAptb2RpZnlfbG9va3VwQ3RsVGltZShzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqdGhlZGF0YSwgdW5zaWduZWQgbG9uZyB2YWwpCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFycyA9IE5VTEw7CiAgICBzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqU3RvcmFnZVRtcCA9IE5VTEw7CgogICAgc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSgmdmFycywgTlVMTCwgMCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAoY2hhciAqKSB0aGVkYXRhLT5sb29rdXBDdGxPd25lckluZGV4LCB0aGVkYXRhLT5sb29rdXBDdGxPd25lckluZGV4TGVuKTsKICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSwKICAgICAgICB0aGVkYXRhLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuKTsKCgogICAgaWYgKChTdG9yYWdlVG1wID0KICAgICAgICAgaGVhZGVyX2NvbXBsZXhfZ2V0KGxvb2t1cEN0bFRhYmxlU3RvcmFnZSwgdmFycykpID09IE5VTEwpIHsKICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2YXJzKTsKICAgICAgICB2YXJzID0gTlVMTDsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9TVUNITkFNRTsKICAgIH0KICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRpbWUgPSB2YWw7CgogICAgc25tcF9mcmVlX3ZhcmJpbmQodmFycyk7CiAgICB2YXJzID0gTlVMTDsKCiAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGltZSIsICJkb25lLlxuIikpOwogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKaW50Cm1vZGlmeV9sb29rdXBDdGxSYyhzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqdGhlZGF0YSwgbG9uZyB2YWwpCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFycyA9IE5VTEw7CiAgICBzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqU3RvcmFnZVRtcCA9IE5VTEw7CgogICAgc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSgmdmFycywgTlVMTCwgMCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAoY2hhciAqKSB0aGVkYXRhLT5sb29rdXBDdGxPd25lckluZGV4LCB0aGVkYXRhLT5sb29rdXBDdGxPd25lckluZGV4TGVuKTsKICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSwKICAgICAgICB0aGVkYXRhLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lTGVuKTsKCgogICAgaWYgKChTdG9yYWdlVG1wID0KICAgICAgICAgaGVhZGVyX2NvbXBsZXhfZ2V0KGxvb2t1cEN0bFRhYmxlU3RvcmFnZSwgdmFycykpID09IE5VTEwpIHsKICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2YXJzKTsKICAgICAgICB2YXJzID0gTlVMTDsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9TVUNITkFNRTsKICAgIH0KICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJjID0gdmFsOwoKICAgIHNubXBfZnJlZV92YXJiaW5kKHZhcnMpOwogICAgdmFycyA9IE5VTEw7CiAgICBERUJVR01TR1RMKCgibG9va3VwT3BlclN0YXR1cyIsICJkb25lLlxuIikpOwogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKCmludApsb29rdXBSZXN1bHRzVGFibGVfZGVsKHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICp0aGVkYXRhKQp7CiAgICBzdHJ1Y3QgaGVhZGVyX2NvbXBsZXhfaW5kZXggKmhjaXB0cjIgPSBOVUxMOwogICAgc3RydWN0IGxvb2t1cFJlc3VsdHNUYWJsZV9kYXRhICpTdG9yYWdlRGVsID0gTlVMTDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFycyA9IE5VTEw7CiAgICBvaWQgICAgICAgICAgICAgbmV3b2lkW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCAgICAgICAgICBuZXdvaWRfbGVuOwoKICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgKGNoYXIgKikgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleCwgdGhlZGF0YS0+bG9va3VwQ3RsT3duZXJJbmRleExlbik7CiAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZ2YXJzLCBOVUxMLCAwLCBBU05fT0NURVRfU1RSLAogICAgICAgIChjaGFyICopIHRoZWRhdGEtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUsCiAgICAgICAgdGhlZGF0YS0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbik7CiAgICBtZW1zZXQobmV3b2lkLCAnXDAnLCBNQVhfT0lEX0xFTiAqIHNpemVvZihvaWQpKTsKICAgIGhlYWRlcl9jb21wbGV4X2dlbmVyYXRlX29pZChuZXdvaWQsICZuZXdvaWRfbGVuLCBOVUxMLCAwLCB2YXJzKTsKCgogICAgc25tcF9mcmVlX3ZhcmJpbmQodmFycyk7CiAgICB2YXJzID0gTlVMTDsKICAgIGZvciAoaGNpcHRyMiA9IGxvb2t1cFJlc3VsdHNUYWJsZVN0b3JhZ2U7IGhjaXB0cjIgIT0gTlVMTDsKICAgICAgICAgaGNpcHRyMiA9IGhjaXB0cjItPm5leHQpIHsKICAgICAgICBpZiAoc25tcF9vaWRfY29tcGFyZShuZXdvaWQsIG5ld29pZF9sZW4sIGhjaXB0cjItPm5hbWUsIG5ld29pZF9sZW4pCiAgICAgICAgICAgID09IDApIHsKICAgICAgICAgICAgU3RvcmFnZURlbCA9CiAgICAgICAgICAgICAgICBoZWFkZXJfY29tcGxleF9leHRyYWN0X2VudHJ5KCZsb29rdXBSZXN1bHRzVGFibGVTdG9yYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoY2lwdHIyKTsKICAgICAgICAgICAgaWYgKFN0b3JhZ2VEZWwgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgU05NUF9GUkVFKFN0b3JhZ2VEZWwtPmxvb2t1cEN0bE93bmVySW5kZXgpOwogICAgICAgICAgICAgICAgU05NUF9GUkVFKFN0b3JhZ2VEZWwtPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWUpOwogICAgICAgICAgICAgICAgU05NUF9GUkVFKFN0b3JhZ2VEZWwtPmxvb2t1cFJlc3VsdHNBZGRyZXNzKTsKICAgICAgICAgICAgICAgIFNOTVBfRlJFRShTdG9yYWdlRGVsKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwUmVzdWx0c1RhYmxlIiwgImRlbGV0ZSAgc3VjY2VzcyFcbiIpKTsKCiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKCiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCmludAp3cml0ZV9sb29rdXBDdGxUYXJnZXRBZGRyZXNzVHlwZShpbnQgYWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiB2YXJfdmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgdmFyX3ZhbF90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgdmFyX3ZhbF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqIHN0YXRQLCBvaWQgKiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbmFtZV9sZW4pCnsKICAgIHN0YXRpYyBzaXplX3QgICB0bXB2YXI7CiAgICBzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqU3RvcmFnZVRtcCA9IE5VTEw7CiAgICBzaXplX3QgICAgICAgICAgbmV3bGVuID0KICAgICAgICBuYW1lX2xlbiAtIChzaXplb2YobG9va3VwQ3RsVGFibGVfdmFyaWFibGVzX29pZCkgLyBzaXplb2Yob2lkKSArCiAgICAgICAgICAgICAgICAgICAgMyAtIDEpOwoKICAgIGlmICgoU3RvcmFnZVRtcCA9CiAgICAgICAgIGhlYWRlcl9jb21wbGV4KGxvb2t1cEN0bFRhYmxlU3RvcmFnZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgJm5hbWVbc2l6ZW9mKGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc19vaWQpIC8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG9pZCkgKyAzIC0gMV0sICZuZXdsZW4sIDEsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpKSA9PSBOVUxMKQogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1NVQ0hOQU1FOyAgICAgLyogcmVtb3ZlIGlmIHlvdSBzdXBwb3J0IGNyZWF0aW9uIGhlcmUgKi8KCiAgICBpZiAoU3RvcmFnZVRtcCAmJiBTdG9yYWdlVG1wLT5zdG9yYWdldHlwZSA9PSBTVF9SRUFET05MWSkgewogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1RXUklUQUJMRTsKICAgIH0KCiAgICBpZiAoU3RvcmFnZVRtcCAmJiBTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXMgPT0gUlNfQUNUSVZFKSB7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PVFdSSVRBQkxFOwogICAgfQogICAgc3dpdGNoIChhY3Rpb24pIHsKICAgIGNhc2UgUkVTRVJWRTE6CiAgICAgICAgaWYgKHZhcl92YWxfdHlwZSAhPSBBU05fSU5URUdFUikgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAid3JpdGUgdG8gbG9va3VwQ3RsVGFyZ2V0QWRkcmVzc1R5cGUgbm90IEFTTl9JTlRFR0VSXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX1dST05HVFlQRTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBSRVNFUlZFMjoKICAgICAgICAvKgogICAgICAgICAqIG1lbW9yeSByZXNldmVyYXRpb24sIGZpbmFsIHByZXBhcmF0aW9uLi4uIAogICAgICAgICAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgRlJFRToKICAgICAgICAvKgogICAgICAgICAqIFJlbGVhc2UgYW55IHJlc291cmNlcyB0aGF0IGhhdmUgYmVlbiBhbGxvY2F0ZWQgCiAgICAgICAgICovCiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBBQ1RJT046CiAgICAgICAgLyoKICAgICAgICAgKiBUaGUgdmFyaWFibGUgaGFzIGJlZW4gc3RvcmVkIGluIG9iamlkIGZvcgogICAgICAgICAqIHlvdSB0byB1c2UsIGFuZCB5b3UgaGF2ZSBqdXN0IGJlZW4gYXNrZWQgdG8gZG8gc29tZXRoaW5nIHdpdGgKICAgICAgICAgKiBpdC4gIE5vdGUgdGhhdCBhbnl0aGluZyBkb25lIGhlcmUgbXVzdCBiZSByZXZlcnNhYmxlIGluIHRoZSBVTkRPIGNhc2UKICAgICAgICAgKi8KICAgICAgICB0bXB2YXIgPSBTdG9yYWdlVG1wLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzVHlwZTsKICAgICAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzVHlwZSA9ICooKGxvbmcgKikgdmFyX3ZhbCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBVTkRPOgogICAgICAgIC8qCiAgICAgICAgICogQmFjayBvdXQgYW55IGNoYW5nZXMgbWFkZSBpbiB0aGUgQUNUSU9OIGNhc2UgCiAgICAgICAgICovCiAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzc1R5cGUgPSB0bXB2YXI7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBDT01NSVQ6CiAgICAgICAgLyoKICAgICAgICAgKiBUaGluZ3MgYXJlIHdvcmtpbmcgd2VsbCwgc28gaXQncyBub3cgc2FmZSB0byBtYWtlIHRoZSBjaGFuZ2UKICAgICAgICAgKiBwZXJtYW5lbnRseS4gIE1ha2Ugc3VyZSB0aGF0IGFueXRoaW5nIGRvbmUgaGVyZSBjYW4ndCBmYWlsISAKICAgICAgICAgKi8KCiAgICAgICAgLyoqIHNldCB1cCB0byBzYXZlIHBlcnNpc3RlbnQgc3RvcmUgKi8KICAgICAgICBzbm1wX3N0b3JlX25lZWRlZChOVUxMKTsKCiAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKCgppbnQKd3JpdGVfbG9va3VwQ3RsVGFyZ2V0QWRkcmVzcyhpbnQgYWN0aW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqIHZhcl92YWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyIHZhcl92YWxfdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgdmFyX3ZhbF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyICogc3RhdFAsIG9pZCAqIG5hbWUsIHNpemVfdCBuYW1lX2xlbikKewogICAgc3RhdGljIGNoYXIgICAgKnRtcHZhciA9IE5VTEw7CiAgICBzdGF0aWMgc2l6ZV90ICAgdG1wbGVuOwogICAgc3RydWN0IGxvb2t1cFRhYmxlX2RhdGEgKlN0b3JhZ2VUbXAgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIG5ld2xlbiA9CiAgICAgICAgbmFtZV9sZW4gLSAoc2l6ZW9mKGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc19vaWQpIC8gc2l6ZW9mKG9pZCkgKwogICAgICAgICAgICAgICAgICAgIDMgLSAxKTsKICAgIGlmICgoU3RvcmFnZVRtcCA9CiAgICAgICAgIGhlYWRlcl9jb21wbGV4KGxvb2t1cEN0bFRhYmxlU3RvcmFnZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgJm5hbWVbc2l6ZW9mKGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc19vaWQpIC8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG9pZCkgKyAzIC0gMV0sICZuZXdsZW4sIDEsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpKSA9PSBOVUxMKQogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1NVQ0hOQU1FOyAgICAgLyogcmVtb3ZlIGlmIHlvdSBzdXBwb3J0IGNyZWF0aW9uIGhlcmUgKi8KCiAgICBpZiAoU3RvcmFnZVRtcCAmJiBTdG9yYWdlVG1wLT5zdG9yYWdldHlwZSA9PSBTVF9SRUFET05MWSkgewogICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1RXUklUQUJMRTsKICAgIH0KCiAgICBpZiAoU3RvcmFnZVRtcCAmJiBTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXMgPT0gUlNfQUNUSVZFKSB7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PVFdSSVRBQkxFOwogICAgfQoKICAgIHN3aXRjaCAoYWN0aW9uKSB7CiAgICBjYXNlIFJFU0VSVkUxOgogICAgICAgIGlmICh2YXJfdmFsX3R5cGUgIT0gQVNOX09DVEVUX1NUUikgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAid3JpdGUgdG8gbG9va3VwQ3RsVGFyZ2V0QWRkcmVzcyBub3QgQVNOX09DVEVUX1NUUlxuIik7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9XUk9OR1RZUEU7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgUkVTRVJWRTI6CiAgICAgICAgLyoKICAgICAgICAgKiBtZW1vcnkgcmVzZXZlcmF0aW9uLCBmaW5hbCBwcmVwYXJhdGlvbi4uLiAKICAgICAgICAgKi8KICAgICAgICBicmVhazsKCiAgICBjYXNlIEZSRUU6CiAgICAgICAgLyoKICAgICAgICAgKiBSZWxlYXNlIGFueSByZXNvdXJjZXMgdGhhdCBoYXZlIGJlZW4gYWxsb2NhdGVkIAogICAgICAgICAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQUNUSU9OOgogICAgICAgIC8qCiAgICAgICAgICogVGhlIHZhcmlhYmxlIGhhcyBiZWVuIHN0b3JlZCBpbiBsb25nX3JldCBmb3IKICAgICAgICAgKiB5b3UgdG8gdXNlLCBhbmQgeW91IGhhdmUganVzdCBiZWVuIGFza2VkIHRvIGRvIHNvbWV0aGluZyB3aXRoCiAgICAgICAgICogaXQuICBOb3RlIHRoYXQgYW55dGhpbmcgZG9uZSBoZXJlIG11c3QgYmUgcmV2ZXJzYWJsZSBpbiB0aGUgVU5ETyBjYXNlCiAgICAgICAgICovCiAgICAgICAgdG1wdmFyID0gU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzczsKICAgICAgICB0bXBsZW4gPSBTdG9yYWdlVG1wLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzTGVuOwoKICAgICAgICBpZiAoKFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MgPQogICAgICAgICAgICAgKGNoYXIgKikgbWFsbG9jKHZhcl92YWxfbGVuICsgMSkpID09IE5VTEwpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIk91dCBvZiBtZW1vcnkgaW4gbnNsb29rdXAtbWliL3dyaXRlX2xvb2t1cEN0bFRhcmdldEFkZHJlc3NcbiIpOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KICAgICAgICBtZW1jcHkoU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzcywgdmFyX3ZhbCwgdmFyX3ZhbF9sZW4pOwogICAgICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3NbdmFyX3ZhbF9sZW5dID0gJ1wwJzsKICAgICAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzTGVuID0gdmFyX3ZhbF9sZW47CgogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgVU5ETzoKICAgICAgICAvKgogICAgICAgICAqIEJhY2sgb3V0IGFueSBjaGFuZ2VzIG1hZGUgaW4gdGhlIEFDVElPTiBjYXNlIAogICAgICAgICAqLwogICAgICAgIGZyZWUoU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzcyk7CiAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzcyA9IE5VTEw7CiAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsVGFyZ2V0QWRkcmVzcyA9IHRtcHZhcjsKICAgICAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzTGVuID0gdG1wbGVuOwoKICAgICAgICBicmVhazsKCiAgICBjYXNlIENPTU1JVDoKICAgICAgICAvKgogICAgICAgICAqIFRoaW5ncyBhcmUgd29ya2luZyB3ZWxsLCBzbyBpdCdzIG5vdyBzYWZlIHRvIG1ha2UgdGhlIGNoYW5nZQogICAgICAgICAqIHBlcm1hbmVudGx5LiAgTWFrZSBzdXJlIHRoYXQgYW55dGhpbmcgZG9uZSBoZXJlIGNhbid0IGZhaWwhIAogICAgICAgICAqLwoKICAgICAgICBmcmVlKHRtcHZhcik7CiAgICAgICAgdG1wdmFyID0gTlVMTDsKCiAgICAgICAgLyoqIHNldCB1cCB0byBzYXZlIHBlcnNpc3RlbnQgc3RvcmUgKi8KICAgICAgICBzbm1wX3N0b3JlX25lZWRlZChOVUxMKTsKCiAgICAgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKCgppbnQKd3JpdGVfbG9va3VwQ3RsUm93U3RhdHVzKGludCBhY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiB2YXJfdmFsLAogICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyIHZhcl92YWxfdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCB2YXJfdmFsX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqIHN0YXRQLCBvaWQgKiBuYW1lLCBzaXplX3QgbmFtZV9sZW4pCnsKICAgIHN0cnVjdCBsb29rdXBUYWJsZV9kYXRhICpTdG9yYWdlVG1wID0gTlVMTDsKICAgIHN0YXRpYyBzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqU3RvcmFnZU5ldyA9IE5VTEwsICpTdG9yYWdlRGVsID0gTlVMTDsKICAgIHNpemVfdCAgICAgICAgICBuZXdsZW4gPQogICAgICAgIG5hbWVfbGVuIC0gKHNpemVvZihsb29rdXBDdGxUYWJsZV92YXJpYWJsZXNfb2lkKSAvIHNpemVvZihvaWQpICsKICAgICAgICAgICAgICAgICAgICAzIC0gMSk7CiAgICBzdGF0aWMgaW50ICAgICAgb2xkX3ZhbHVlOwogICAgaW50ICAgICAgICAgICAgIHNldF92YWx1ZTsKICAgIHN0YXRpYyBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMsICp2cDsKICAgIHN0cnVjdCBoZWFkZXJfY29tcGxleF9pbmRleCAqaGNpcHRyID0gTlVMTDsKCiAgICBTdG9yYWdlVG1wID0KICAgICAgICBoZWFkZXJfY29tcGxleChsb29rdXBDdGxUYWJsZVN0b3JhZ2UsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgJm5hbWVbc2l6ZW9mKGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc19vaWQpIC8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yob2lkKSArIDMgLSAxXSwgJm5ld2xlbiwgMSwgTlVMTCwgTlVMTCk7CgogICAgaWYgKHZhcl92YWxfdHlwZSAhPSBBU05fSU5URUdFUiB8fCB2YXJfdmFsID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAid3JpdGUgdG8gbG9va3VwQ3RsUm93U3RhdHVzIG5vdCBBU05fSU5URUdFUlxuIik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX1dST05HVFlQRTsKICAgIH0KICAgIGlmIChTdG9yYWdlVG1wICYmIFN0b3JhZ2VUbXAtPnN0b3JhZ2V0eXBlID09IFNUX1JFQURPTkxZKSB7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PVFdSSVRBQkxFOwogICAgfQoKICAgIHNldF92YWx1ZSA9ICooKGxvbmcgKikgdmFyX3ZhbCk7CgoKICAgIC8qCiAgICAgKiBjaGVjayBsZWdhbCByYW5nZSwgYW5kIG5vdFJlYWR5IGlzIHJlc2VydmVkIGZvciB1cywgbm90IGEgdXNlciAKICAgICAqLwogICAgaWYgKHNldF92YWx1ZSA8IDEgfHwgc2V0X3ZhbHVlID4gNiB8fCBzZXRfdmFsdWUgPT0gUlNfTk9UUkVBRFkpCiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0lOQ09OU0lTVEVOVFZBTFVFOwoKCiAgICBzd2l0Y2ggKGFjdGlvbikgewogICAgY2FzZSBSRVNFUlZFMToKICAgICAgICAvKgogICAgICAgICAqIHN0YWdlIG9uZTogdGVzdCB2YWxpZGl0eSAKICAgICAgICAgKi8KICAgICAgICBpZiAoU3RvcmFnZVRtcCA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNyZWF0ZSB0aGUgcm93IG5vdz8gCiAgICAgICAgICAgICAqLwoKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGRpdGNoIGlsbGVnYWwgdmFsdWVzIG5vdyAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChzZXRfdmFsdWUgPT0gUlNfQUNUSVZFIHx8IHNldF92YWx1ZSA9PSBSU19OT1RJTlNFUlZJQ0UpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9JTkNPTlNJU1RFTlRWQUxVRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZGVzdHJveWluZyBhIG5vbi1leGlzdGVudCByb3cgaXMgYWN0dWFsbHkgbGVnYWwgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoc2V0X3ZhbHVlID09IFJTX0RFU1RST1kpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgICAgICB9CgoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaWxsZWdhbCBjcmVhdGlvbiB2YWx1ZXMgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoc2V0X3ZhbHVlID09IFJTX0FDVElWRSB8fCBzZXRfdmFsdWUgPT0gUlNfTk9USU5TRVJWSUNFKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfSU5DT05TSVNURU5UVkFMVUU7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByb3cgZXhpc3RzLiAgQ2hlY2sgZm9yIGEgdmFsaWQgc3RhdGUgY2hhbmdlIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHNldF92YWx1ZSA9PSBSU19DUkVBVEVBTkRHTwogICAgICAgICAgICAgICAgfHwgc2V0X3ZhbHVlID09IFJTX0NSRUFURUFORFdBSVQpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBjYW4ndCBjcmVhdGUgYSByb3cgdGhhdCBleGlzdHMgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9JTkNPTlNJU1RFTlRWQUxVRTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogWFhYOiBpbnRlcmFjdGlvbiB3aXRoIHJvdyBzdG9yYWdlIHR5cGUgbmVlZGVkIAogICAgICAgICAgICAgKi8KCiAgICAgICAgICAgIGlmIChTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXMgPT0gUlNfQUNUSVZFICYmCiAgICAgICAgICAgICAgICBzZXRfdmFsdWUgIT0gUlNfREVTVFJPWSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqICJPbmNlIG1hZGUgYWN0aXZlIGFuIGVudHJ5IG1heSBub3QgYmUgbW9kaWZpZWQgZXhjZXB0IHRvIAogICAgICAgICAgICAgICAgICogZGVsZXRlIGl0LiIgIFhYWDogZG9lc24ndCB0aGlzIGluIGZhY3QgYXBwbHkgdG8gQUxMCiAgICAgICAgICAgICAgICAgKiBjb2x1bW5zIG9mIHRoZSB0YWJsZSBhbmQgbm90IGp1c3QgdGhpcyBvbmU/ICAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0lOQ09OU0lTVEVOVFZBTFVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChTdG9yYWdlVG1wLT5zdG9yYWdldHlwZSAhPSBTVF9OT05WT0xBVElMRSkKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT1RXUklUQUJMRTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgoKCgogICAgY2FzZSBSRVNFUlZFMjoKICAgICAgICAvKgogICAgICAgICAqIG1lbW9yeSByZXNldmVyYXRpb24sIGZpbmFsIHByZXBhcmF0aW9uLi4uIAogICAgICAgICAqLwogICAgICAgIGlmIChTdG9yYWdlVG1wID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogY3JlYXRpb24gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoc2V0X3ZhbHVlID09IFJTX0RFU1RST1kpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHZhcnMgPSBOVUxMOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogvatuYW1lzqq/1bXEyP249sv30v3X1rbOvNO1vXZhcrHkwb/B0LHttcTEqc6yIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSgmdmFycywgTlVMTCwgMCwgQVNOX09DVEVUX1NUUiwgTlVMTCwgMCk7ICAvKiBsb29rdXBDdGxPd25lckluZGV4ICovCiAgICAgICAgICAgIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnZhcnMsIE5VTEwsIDAsIEFTTl9PQ1RFVF9TVFIsIE5VTEwsIDApOyAgLyogbG9va3VwQ3RsT3BlcmF0aW9uTmFtZSAqLwoKICAgICAgICAgICAgaWYgKGhlYWRlcl9jb21wbGV4X3BhcnNlX29pZAogICAgICAgICAgICAgICAgKCYKICAgICAgICAgICAgICAgICAobmFtZQogICAgICAgICAgICAgICAgICBbc2l6ZW9mKGxvb2t1cEN0bFRhYmxlX3ZhcmlhYmxlc19vaWQpIC8gc2l6ZW9mKG9pZCkgKwogICAgICAgICAgICAgICAgICAgMl0pLCBuZXdsZW4sIHZhcnMpICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFhYWDogZnJlZSwgemVybyB2YXJzIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2YXJzKTsKICAgICAgICAgICAgICAgIHZhcnMgPSBOVUxMOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0lOQ09OU0lTVEVOVE5BTUU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdnAgPSB2YXJzOwogICAgICAgICAgICBTdG9yYWdlTmV3ID0gY3JlYXRlX2xvb2t1cFRhYmxlX2RhdGEoKTsKICAgICAgICAgICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsT3duZXJJbmRleCA9IG1hbGxvYyh2cC0+dmFsX2xlbiArIDEpOwogICAgICAgICAgICBtZW1jcHkoU3RvcmFnZU5ldy0+bG9va3VwQ3RsT3duZXJJbmRleCwgdnAtPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICB2cC0+dmFsX2xlbik7CiAgICAgICAgICAgIFN0b3JhZ2VOZXctPmxvb2t1cEN0bE93bmVySW5kZXhbdnAtPnZhbF9sZW5dID0gJ1wwJzsKICAgICAgICAgICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsT3duZXJJbmRleExlbiA9IHZwLT52YWxfbGVuOwogICAgICAgICAgICB2cCA9IHZwLT5uZXh0X3ZhcmlhYmxlOwoKICAgICAgICAgICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSA9IG1hbGxvYyh2cC0+dmFsX2xlbiArIDEpOwogICAgICAgICAgICBtZW1jcHkoU3RvcmFnZU5ldy0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZSwgdnAtPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICB2cC0+dmFsX2xlbik7CiAgICAgICAgICAgIFN0b3JhZ2VOZXctPmxvb2t1cEN0bE9wZXJhdGlvbk5hbWVbdnAtPnZhbF9sZW5dID0gJ1wwJzsKICAgICAgICAgICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsT3BlcmF0aW9uTmFtZUxlbiA9IHZwLT52YWxfbGVuOwogICAgICAgICAgICB2cCA9IHZwLT5uZXh0X3ZhcmlhYmxlOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogWFhYOiBmaWxsIGluIGRlZmF1bHQgcm93IHZhbHVlcyBoZXJlIGludG8gU3RvcmFnZU5ldyAKICAgICAgICAgICAgICovCgogICAgICAgICAgICBTdG9yYWdlTmV3LT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzVHlwZSA9IElORVRBRERSRVNTVFlQRV9JUFY0OwoKICAgICAgICAgICAgU3RvcmFnZU5ldy0+bG9va3VwQ3RsUm93U3RhdHVzID0gc2V0X3ZhbHVlOwoKICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmFycyk7CiAgICAgICAgICAgIHZhcnMgPSBOVUxMOwoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogWFhYOiBmcmVlLCB6ZXJvIHZhcnMsIG5vIGxvbmdlciBuZWVkZWQ/IAogICAgICAgICAgICAgKi8KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBGUkVFOgogICAgICAgIC8qCiAgICAgICAgICogWFhYOiBmcmVlLCB6ZXJvIHZhcnMgCiAgICAgICAgICovCiAgICAgICAgLyoKICAgICAgICAgKiBSZWxlYXNlIGFueSByZXNvdXJjZXMgdGhhdCBoYXZlIGJlZW4gYWxsb2NhdGVkIAogICAgICAgICAqLwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQUNUSU9OOgogICAgICAgIC8qCiAgICAgICAgICogVGhlIHZhcmlhYmxlIGhhcyBiZWVuIHN0b3JlZCBpbiBzZXRfdmFsdWUgZm9yIHlvdSB0bwogICAgICAgICAqIHVzZSwgYW5kIHlvdSBoYXZlIGp1c3QgYmVlbiBhc2tlZCB0byBkbyBzb21ldGhpbmcgd2l0aAogICAgICAgICAqIGl0LiAgTm90ZSB0aGF0IGFueXRoaW5nIGRvbmUgaGVyZSBtdXN0IGJlIHJldmVyc2FibGUgaW4KICAgICAgICAgKiB0aGUgVU5ETyBjYXNlIAogICAgICAgICAqLwogICAgICAgIGlmIChTdG9yYWdlVG1wID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcm93IGNyZWF0aW9uLCBzbyBhZGQgaXQgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoc2V0X3ZhbHVlID09IFJTX0RFU1RST1kpIHsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChTdG9yYWdlTmV3ICE9IE5VTEwpCiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIndyaXRlX2xvb2t1cEN0bFJvd1N0YXR1cyBlbnRlcmluZyBuZXc9JWQuLi4gIFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGlvbikpOwogICAgICAgICAgICBsb29rdXBDdGxUYWJsZV9hZGQoU3RvcmFnZU5ldyk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFhYWDogYWNrLCBhbmQgaWYgaXQgaXMgTlVMTD8gCiAgICAgICAgICAgICAqLwogICAgICAgIH0gZWxzZSBpZiAoc2V0X3ZhbHVlICE9IFJTX0RFU1RST1kpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogc2V0IHRoZSBmbGFnPyAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIG9sZF92YWx1ZSA9IFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJvd1N0YXR1czsKICAgICAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzID0gKigobG9uZyAqKSB2YXJfdmFsKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBkZXN0cm95Li4uICBleHRyYWN0IGl0IGZvciBub3cgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TR1RMKCgibG9va3VwQ3RsVGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAid3JpdGVfbG9va3VwQ3RsVGFibGVfZGVsZXRlIDEgXG4iKSk7CiAgICAgICAgICAgIGhjaXB0ciA9CiAgICAgICAgICAgICAgICBoZWFkZXJfY29tcGxleF9maW5kX2VudHJ5KGxvb2t1cEN0bFRhYmxlU3RvcmFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RvcmFnZVRtcCk7CgogICAgICAgICAgICBTdG9yYWdlRGVsID0KICAgICAgICAgICAgICAgIGhlYWRlcl9jb21wbGV4X2V4dHJhY3RfZW50cnkoJmxvb2t1cEN0bFRhYmxlU3RvcmFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGNpcHRyKTsKICAgICAgICAgICAgbG9va3VwUmVzdWx0c1RhYmxlX2RlbChTdG9yYWdlVG1wKTsKCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJ3cml0ZV9sb29rdXBDdGxUYWJsZV9kZWxldGUgIFxuIikpOwoKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBVTkRPOgogICAgICAgIC8qCiAgICAgICAgICogQmFjayBvdXQgYW55IGNoYW5nZXMgbWFkZSBpbiB0aGUgQUNUSU9OIGNhc2UgCiAgICAgICAgICovCiAgICAgICAgaWYgKFN0b3JhZ2VUbXAgPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiByb3cgY3JlYXRpb24sIHNvIHJlbW92ZSBpdCBhZ2FpbiAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGhjaXB0ciA9CiAgICAgICAgICAgICAgICBoZWFkZXJfY29tcGxleF9maW5kX2VudHJ5KGxvb2t1cEN0bFRhYmxlU3RvcmFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RvcmFnZVRtcCk7CiAgICAgICAgICAgIFN0b3JhZ2VEZWwgPQogICAgICAgICAgICAgICAgaGVhZGVyX2NvbXBsZXhfZXh0cmFjdF9lbnRyeSgmbG9va3VwQ3RsVGFibGVTdG9yYWdlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoY2lwdHIpOwoKICAgICAgICAgICAgbG9va3VwUmVzdWx0c1RhYmxlX2RlbChTdG9yYWdlVG1wKTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFhYWDogZnJlZSBpdCAKICAgICAgICAgICAgICovCiAgICAgICAgfSBlbHNlIGlmIChTdG9yYWdlRGVsICE9IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogcm93IGRlbGV0aW9uLCBzbyBhZGQgaXQgYWdhaW4gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBsb29rdXBDdGxUYWJsZV9hZGQoU3RvcmFnZURlbCk7CiAgICAgICAgICAgIGxvb2t1cFJlc3VsdHNUYWJsZV9hZGQoU3RvcmFnZURlbCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzID0gb2xkX3ZhbHVlOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIENPTU1JVDoKICAgICAgICAvKgogICAgICAgICAqIFRoaW5ncyBhcmUgd29ya2luZyB3ZWxsLCBzbyBpdCdzIG5vdyBzYWZlIHRvIG1ha2UgdGhlIGNoYW5nZQogICAgICAgICAqIHBlcm1hbmVudGx5LiAgTWFrZSBzdXJlIHRoYXQgYW55dGhpbmcgZG9uZSBoZXJlIGNhbid0IGZhaWwhIAogICAgICAgICAqLwogICAgICAgIGlmIChTdG9yYWdlVG1wID09IE5VTEwpIHsKICAgICAgICAgICAgaWYgKHNldF92YWx1ZSA9PSBSU19ERVNUUk9ZKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKFN0b3JhZ2VEZWwgIT0gTlVMTCkgewogICAgICAgICAgICBTTk1QX0ZSRUUoU3RvcmFnZURlbC0+bG9va3VwQ3RsT3duZXJJbmRleCk7CiAgICAgICAgICAgIFNOTVBfRlJFRShTdG9yYWdlRGVsLT5sb29rdXBDdGxPcGVyYXRpb25OYW1lKTsKICAgICAgICAgICAgU05NUF9GUkVFKFN0b3JhZ2VEZWwtPmxvb2t1cEN0bFRhcmdldEFkZHJlc3MpOwogICAgICAgICAgICBTTk1QX0ZSRUUoU3RvcmFnZURlbCk7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFhYWDogZnJlZSBpdCwgaXRzIGRlYWQgCiAgICAgICAgICAgICAqLwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChTdG9yYWdlVG1wCiAgICAgICAgICAgICAgICAmJiBTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXMgPT0gUlNfQ1JFQVRFQU5ER08pIHsKICAgICAgICAgICAgICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJvd1N0YXR1cyA9IFJTX0FDVElWRTsKICAgICAgICAgICAgfSBlbHNlIGlmIChTdG9yYWdlVG1wICYmCiAgICAgICAgICAgICAgICAgICAgICAgU3RvcmFnZVRtcC0+bG9va3VwQ3RsUm93U3RhdHVzID09CiAgICAgICAgICAgICAgICAgICAgICAgUlNfQ1JFQVRFQU5EV0FJVCkgewoKICAgICAgICAgICAgICAgIFN0b3JhZ2VUbXAtPmxvb2t1cEN0bFJvd1N0YXR1cyA9IFJTX05PVElOU0VSVklDRTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoU3RvcmFnZVRtcCAmJiBTdG9yYWdlVG1wLT5sb29rdXBDdGxSb3dTdGF0dXMgPT0gUlNfQUNUSVZFKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJsb29rdXBDdGxUYWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJ3cml0ZV9sb29rdXBDdGxSb3dTdGF0dXMgZW50ZXJpbmcgcnVuYmVmb3JlPSVsZC4uLiAgXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBTdG9yYWdlVG1wLT5sb29rdXBDdGxUYXJnZXRBZGRyZXNzVHlwZSkpOwoKICAgICAgICAgICAgbW9kaWZ5X2xvb2t1cEN0bE9wZXJTdGF0dXMoU3RvcmFnZVRtcCwgMkwpOwogICAgICAgICAgICBydW5fbG9va3VwKChzdHJ1Y3QgbG9va3VwVGFibGVfZGF0YSAqKSBTdG9yYWdlVG1wKTsKCiAgICAgICAgfQoKICAgICAgICAvKiogc2V0IHVwIHRvIHNhdmUgcGVyc2lzdGVudCBzdG9yZSAqLwogICAgICAgIHNubXBfc3RvcmVfbmVlZGVkKE5VTEwpOwoKICAgICAgICBicmVhazsKICAgIH0KICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwp9CiNlbmRpZiAvKiAhTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCg==