LyoKICogRE9TIFZpcnR1YWwgTWFjaGluZQogKgogKiBDb3B5cmlnaHQgMTk5OCBPdmUgS+V2ZW4KICoKICogVGhpcyBjb2RlIGhhc24ndCBiZWVuIGNvbXBsZXRlbHkgY2xlYW5lZCB1cCB5ZXQuCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3RpbWUuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KCiNpbmNsdWRlICJ3aW5lL3dpbmJhc2UxNi5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lubnQuaCIKI2luY2x1ZGUgInNpZ19jb250ZXh0LmgiCiNpbmNsdWRlICJtc2Rvcy5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAiZGVidWdnZXIuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJkb3NleGUuaCIKI2luY2x1ZGUgImRvc21vZC5oIgojaW5jbHVkZSAiZGVidWcuaCIKCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChpbnQpCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChtb2R1bGUpCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChyZWxheSkKCiNpZmRlZiBNWl9TVVBQT1JURUQKCiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojaW5jbHVkZSA8c3lzL3ZtODYuaD4KCiNkZWZpbmUgSUZfQ0xSKGN0eCkgRUZMX3JlZyhjdHgpICY9IH5WSUZfTUFTSwojZGVmaW5lIElGX0VOQUJMRUQoY3R4KSAoRUZMX3JlZyhjdHgpICYgVklGX01BU0spCiNkZWZpbmUgU0VUX1BFTkQoY3R4KSBFRkxfcmVnKGN0eCkgfD0gVklQX01BU0sKI2RlZmluZSBDTFJfUEVORChjdHgpIEVGTF9yZWcoY3R4KSAmPSB+VklQX01BU0sKI2RlZmluZSBJU19QRU5EKGN0eCkgKEVGTF9yZWcoY3R4KSAmIFZJUF9NQVNLKQoKI3VuZGVmIFRSWV9QSUNSRVRVUk4KCnN0YXRpYyB2b2lkIERPU1ZNX0R1bXAoIExQRE9TVEFTSyBscERvc1Rhc2ssIGludCBmbiwgaW50IHNpZywKICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHZtODZwbHVzX3N0cnVjdCpWTTg2ICkKewogdW5zaWduZWQgaW9mczsKIEJZVEUqaW5zdDsKIGludCB4OwoKIHN3aXRjaCAoVk04Nl9UWVBFKGZuKSkgewogIGNhc2UgVk04Nl9TSUdOQUw6CiAgIHByaW50ZigiVHJhcHBlZCBzaWduYWwgJWRcbiIsc2lnKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1VOS05PV046CiAgIHByaW50ZigiVHJhcHBlZCB1bmhhbmRsZWQgR1BGXG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X0lOVHg6CiAgIHByaW50ZigiVHJhcHBlZCBJTlQgJTAyeFxuIixWTTg2X0FSRyhmbikpOyBicmVhazsKICBjYXNlIFZNODZfU1RJOgogICBwcmludGYoIlRyYXBwZWQgU1RJXG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1BJQ1JFVFVSTjoKICAgcHJpbnRmKCJUcmFwcGVkIGR1ZSB0byBwZW5kaW5nIFBJQyByZXF1ZXN0XG4iKTsgYnJlYWs7CiAgY2FzZSBWTTg2X1RSQVA6CiAgIHByaW50ZigiVHJhcHBlZCBkZWJ1ZyByZXF1ZXN0XG4iKTsgYnJlYWs7CiAgZGVmYXVsdDoKICAgcHJpbnRmKCJUcmFwcGVkIHVua25vd24gVk04NiB0eXBlICVkIGFyZyAlZFxuIixWTTg2X1RZUEUoZm4pLFZNODZfQVJHKGZuKSk7IGJyZWFrOwogfQojZGVmaW5lIFJFR1MgVk04Ni0+cmVncwogZnByaW50ZihzdGRlcnIsIkFYPSUwNGxYIENYPSUwNGxYIERYPSUwNGxYIEJYPSUwNGxYXG4iLFJFR1MuZWF4LFJFR1MuZWN4LFJFR1MuZWR4LFJFR1MuZWJ4KTsKIGZwcmludGYoc3RkZXJyLCJTST0lMDRsWCBEST0lMDRsWCBTUD0lMDRsWCBCUD0lMDRsWFxuIixSRUdTLmVzaSxSRUdTLmVkaSxSRUdTLmVzcCxSRUdTLmVicCk7CiBmcHJpbnRmKHN0ZGVyciwiQ1M9JTA0WCBEUz0lMDRYIEVTPSUwNFggU1M9JTA0WFxuIixSRUdTLmNzLFJFR1MuZHMsUkVHUy5lcyxSRUdTLnNzKTsKIGZwcmludGYoc3RkZXJyLCJJUD0lMDRsWCBFRkxBR1M9JTA4bFhcbiIsUkVHUy5laXAsUkVHUy5lZmxhZ3MpOwoKIGlvZnM9KChEV09SRClSRUdTLmNzPDw0KStSRUdTLmVpcDsKI3VuZGVmIFJFR1MKIGluc3Q9KEJZVEUqKWxwRG9zVGFzay0+aW1nK2lvZnM7CiBwcmludGYoIk9wY29kZXM6Iik7CiBmb3IgKHg9MDsgeDw4OyB4KyspIHByaW50ZigiICUwMngiLGluc3RbeF0pOwogcHJpbnRmKCJcbiIpOwp9CgpzdGF0aWMgaW50IERPU1ZNX0ludCggaW50IHZlY3QsIFBDT05URVhUIGNvbnRleHQsIExQRE9TVEFTSyBscERvc1Rhc2sgKQp7CiBleHRlcm4gVUlOVDE2IERQTUlfd3JhcF9zZWc7CgogaWYgKHZlY3Q9PTB4MzEpIHsKICBpZiAoQ1NfcmVnKGNvbnRleHQpPT1EUE1JX3dyYXBfc2VnKSB7CiAgIC8qIGV4aXQgZnJvbSByZWFsLW1vZGUgd3JhcHBlciAqLwogICByZXR1cm4gLTE7CiAgfQogIC8qIHdlIGNvdWxkIHByb2JhYmx5IG1vdmUgc29tZSBvdGhlciBkb2RneSBzdHVmZiBoZXJlIHRvbyBmcm9tIGRwbWkuYyAqLwogfQogSU5UX1JlYWxNb2RlSW50ZXJydXB0KHZlY3QsY29udGV4dCk7CiByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgRE9TVk1fU2ltdWxhdGVJbnQoIGludCB2ZWN0LCBQQ09OVEVYVCBjb250ZXh0LCBMUERPU1RBU0sgbHBEb3NUYXNrICkKewogIEZBUlBST0MxNiBoYW5kbGVyPUlOVF9HZXRSTUhhbmRsZXIodmVjdCk7CgogIGlmIChTRUxFQ1RPUk9GKGhhbmRsZXIpPT0weGYwMDApIHsKICAgIC8qIGlmIGludGVybmFsIGludGVycnVwdCwgY2FsbCBpdCBkaXJlY3RseSAqLwogICAgSU5UX1JlYWxNb2RlSW50ZXJydXB0KHZlY3QsY29udGV4dCk7CiAgfSBlbHNlIHsKICAgIFdPUkQqc3RhY2s9KFdPUkQqKShWODZCQVNFKGNvbnRleHQpKygoKERXT1JEKVNTX3JlZyhjb250ZXh0KSk8PDQpK1NQX3JlZyhjb250ZXh0KSk7CiAgICBXT1JEIGZsYWc9RkxfcmVnKGNvbnRleHQpOwoKICAgIGlmIChJRl9FTkFCTEVEKGNvbnRleHQpKSBmbGFnfD1JRl9NQVNLOwogICAgZWxzZSBmbGFnJj1+SUZfTUFTSzsKCiAgICAqKC0tc3RhY2spPWZsYWc7CiAgICAqKC0tc3RhY2spPUNTX3JlZyhjb250ZXh0KTsKICAgICooLS1zdGFjayk9SVBfcmVnKGNvbnRleHQpOwogICAgU1BfcmVnKGNvbnRleHQpLT02OwogICAgQ1NfcmVnKGNvbnRleHQpPVNFTEVDVE9ST0YoaGFuZGxlcik7CiAgICBJUF9yZWcoY29udGV4dCk9T0ZGU0VUT0YoaGFuZGxlcik7CiAgICBJRl9DTFIoY29udGV4dCk7CiAgfQp9CgojZGVmaW5lIFNIT1VMRF9QRU5EKHgpIFwKICAoeCAmJiAoKCFscERvc1Rhc2stPmN1cnJlbnQpIHx8ICh4LT5wcmlvcml0eSA8IGxwRG9zVGFzay0+Y3VycmVudC0+cHJpb3JpdHkpKSkKCnN0YXRpYyB2b2lkIERPU1ZNX1NlbmRRdWV1ZWRFdmVudChQQ09OVEVYVCBjb250ZXh0LCBMUERPU1RBU0sgbHBEb3NUYXNrKQp7CiAgTFBET1NFVkVOVCBldmVudCA9IGxwRG9zVGFzay0+cGVuZGluZzsKCiAgaWYgKFNIT1VMRF9QRU5EKGV2ZW50KSkgewogICAgLyogcmVtb3ZlIGZyb20gInBlbmRpbmciIGxpc3QgKi8KICAgIGxwRG9zVGFzay0+cGVuZGluZyA9IGV2ZW50LT5uZXh0OwogICAgLyogcHJvY2VzcyBldmVudCAqLwogICAgaWYgKGV2ZW50LT5pcnE+PTApIHsKICAgICAgLyogaXQncyBhbiBJUlEsIG1vdmUgaXQgdG8gImN1cnJlbnQiIGxpc3QgKi8KICAgICAgZXZlbnQtPm5leHQgPSBscERvc1Rhc2stPmN1cnJlbnQ7CiAgICAgIGxwRG9zVGFzay0+Y3VycmVudCA9IGV2ZW50OwogICAgICBUUkFDRShpbnQsImRpc3BhdGNoaW5nIElSUSAlZFxuIixldmVudC0+aXJxKTsKICAgICAgLyogbm90ZSB0aGF0IGlmIERPU1ZNX1NpbXVsYXRlSW50IGNhbGxzIGFuIGludGVybmFsIGludGVycnVwdCBkaXJlY3RseSwKICAgICAgICogbHBEb3NUYXNrLT5jdXJyZW50IG1pZ2h0IGJlIGNsZWFyZWQgKGFuZCBldmVudCBmcmVlZCkgaW4gdGhpcyB2ZXJ5IGNhbGwhICovCiAgICAgIERPU1ZNX1NpbXVsYXRlSW50KChldmVudC0+aXJxPDgpPyhldmVudC0+aXJxKzgpOihldmVudC0+aXJxLTgrMHg3MCksY29udGV4dCxscERvc1Rhc2spOwogICAgfSBlbHNlIHsKICAgICAgLyogY2FsbGJhY2sgZXZlbnQgKi8KICAgICAgVFJBQ0UoaW50LCJkaXNwYXRjaGluZyBjYWxsYmFjayBldmVudFxuIik7CiAgICAgICgqZXZlbnQtPnJlbGF5KShscERvc1Rhc2ssY29udGV4dCxldmVudC0+ZGF0YSk7CiAgICAgIGZyZWUoZXZlbnQpOwogICAgfQogIH0KICBpZiAoIVNIT1VMRF9QRU5EKGxwRG9zVGFzay0+cGVuZGluZykpIHsKICAgIFRSQUNFKGludCwiY2xlYXJpbmcgUGVuZGluZyBmbGFnXG4iKTsKICAgIENMUl9QRU5EKGNvbnRleHQpOwogIH0KfQoKc3RhdGljIHZvaWQgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cyhQQ09OVEVYVCBjb250ZXh0LCBMUERPU1RBU0sgbHBEb3NUYXNrKQp7CiAgLyogd2Ugd2lsbCBzZW5kIGFsbCBxdWV1ZWQgZXZlbnRzIGFzIGxvbmcgYXMgaW50ZXJydXB0cyBhcmUgZW5hYmxlZCwKICAgKiBidXQgSVJRIGV2ZW50cyB3aWxsIGRpc2FibGUgaW50ZXJydXB0cyBhZ2FpbiAqLwogIHdoaWxlIChJU19QRU5EKGNvbnRleHQpICYmIElGX0VOQUJMRUQoY29udGV4dCkpCiAgICBET1NWTV9TZW5kUXVldWVkRXZlbnQoY29udGV4dCxscERvc1Rhc2spOwp9Cgp2b2lkIERPU1ZNX1F1ZXVlRXZlbnQoIGludCBpcnEsIGludCBwcmlvcml0eSwgdm9pZCAoKnJlbGF5KShMUERPU1RBU0ssUENPTlRFWFQsdm9pZCopLCB2b2lkICpkYXRhKQp7CiAgVERCICpwVGFzayA9IChUREIgKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBORV9NT0RVTEUgKnBNb2R1bGUgPSBORV9HZXRQdHIoIHBUYXNrLT5oTW9kdWxlICk7CiAgTFBET1NFVkVOVCBldmVudCwgY3VyLCBwcmV2OwoKICBHbG9iYWxVbmxvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogIGlmIChwTW9kdWxlICYmIHBNb2R1bGUtPmxwRG9zVGFzaykgewogICAgZXZlbnQgPSBtYWxsb2Moc2l6ZW9mKERPU0VWRU5UKSk7CiAgICBpZiAoIWV2ZW50KSB7CiAgICAgIEVSUihpbnQsIm91dCBvZiBtZW1vcnkgYWxsb2NhdGluZyBldmVudCBlbnRyeVxuIik7CiAgICAgIHJldHVybjsKICAgIH0KICAgIGV2ZW50LT5pcnEgPSBpcnE7IGV2ZW50LT5wcmlvcml0eSA9IHByaW9yaXR5OwogICAgZXZlbnQtPnJlbGF5ID0gcmVsYXk7IGV2ZW50LT5kYXRhID0gZGF0YTsKCiAgICAvKiBpbnNlcnQgZXZlbnQgaW50byBsaW5rZWQgbGlzdCwgaW4gb3JkZXIgKmFmdGVyKgogICAgICogYWxsIGVhcmxpZXIgZXZlbnRzIG9mIGhpZ2hlciBvciBlcXVhbCBwcmlvcml0eSAqLwogICAgY3VyID0gcE1vZHVsZS0+bHBEb3NUYXNrLT5wZW5kaW5nOyBwcmV2ID0gTlVMTDsKICAgIHdoaWxlIChjdXIgJiYgY3VyLT5wcmlvcml0eTw9cHJpb3JpdHkpIHsKICAgICAgcHJldiA9IGN1cjsKICAgICAgY3VyID0gY3VyLT5uZXh0OwogICAgfQogICAgZXZlbnQtPm5leHQgPSBjdXI7CiAgICBpZiAocHJldikgcHJldi0+bmV4dCA9IGV2ZW50OwogICAgZWxzZSBwTW9kdWxlLT5scERvc1Rhc2stPnBlbmRpbmcgPSBldmVudDsKICAgIAogICAgLyogZ2V0IGRvc21vZCdzIGF0dGVudGlvbiB0byB0aGUgbmV3IGV2ZW50LCBleGNlcHQgZm9yIGlycT09MCB3aGVyZSB3ZSBhbHJlYWR5IGhhdmUgaXQgKi8KICAgIGlmIChpcnEgJiYgIXBNb2R1bGUtPmxwRG9zVGFzay0+c2lnX3NlbnQpIHsKICAgICAgVFJBQ0UoaW50LCJuZXcgZXZlbnQgcXVldWVkLCBzaWduYWxsaW5nIGRvc21vZFxuIik7CiAgICAgIGtpbGwocE1vZHVsZS0+bHBEb3NUYXNrLT50YXNrLFNJR1VTUjIpOwogICAgICBwTW9kdWxlLT5scERvc1Rhc2stPnNpZ19zZW50Kys7CiAgICB9IGVsc2UgewogICAgICBUUkFDRShpbnQsIm5ldyBldmVudCBxdWV1ZWRcbiIpOwogICAgfQogIH0KfQoKI2RlZmluZSBDViBDUChlYXgsRUFYKTsgQ1AoZWN4LEVDWCk7IENQKGVkeCxFRFgpOyBDUChlYngsRUJYKTsgXAogICAgICAgICAgIENQKGVzaSxFU0kpOyBDUChlZGksRURJKTsgQ1AoZXNwLEVTUCk7IENQKGVicCxFQlApOyBcCiAgICAgICAgICAgQ1AoY3MsQ1MpOyBDUChkcyxEUyk7IENQKGVzLEVTKTsgXAogICAgICAgICAgIENQKHNzLFNTKTsgQ1AoZnMsRlMpOyBDUChncyxHUyk7IFwKICAgICAgICAgICBDUChlaXAsRUlQKTsgQ1AoZWZsYWdzLEVGTCkKCnN0YXRpYyBpbnQgRE9TVk1fUHJvY2VzcyggTFBET1NUQVNLIGxwRG9zVGFzaywgaW50IGZuLCBpbnQgc2lnLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB2bTg2cGx1c19zdHJ1Y3QqVk04NiApCnsKIFNJR0NPTlRFWFQgc2lnY29udGV4dDsKIENPTlRFWFQgY29udGV4dDsKIGludCByZXQ9MDsKCiBpZiAoVk04Nl9UWVBFKGZuKT09Vk04Nl9VTktOT1dOKSB7CiAgLyogSU5TVFJfRW11bGF0ZUluc3RydWN0aW9uIG5lZWRzIGEgU0lHQ09OVEVYVCwgbm90IGEgQ09OVEVYVC4uLiAqLwojZGVmaW5lIENQKHgseSkgeSMjX3NpZygmc2lnY29udGV4dCkgPSBWTTg2LT5yZWdzLngKICBDVjsKI3VuZGVmIENQCiAgaWYgKGZuSU5TVFJfRW11bGF0ZUluc3RydWN0aW9uKSByZXQ9Zm5JTlNUUl9FbXVsYXRlSW5zdHJ1Y3Rpb24oJnNpZ2NvbnRleHQpOwojZGVmaW5lIENQKHgseSkgVk04Ni0+cmVncy54ID0geSMjX3NpZygmc2lnY29udGV4dCkKICBDVjsKI3VuZGVmIENQCiAgaWYgKHJldCkgcmV0dXJuIDA7CiAgcmV0PTA7CiB9CiNkZWZpbmUgQ1AoeCx5KSB5IyNfcmVnKCZjb250ZXh0KSA9IFZNODYtPnJlZ3MueAogQ1Y7CiN1bmRlZiBDUAogKHZvaWQqKVY4NkJBU0UoJmNvbnRleHQpPWxwRG9zVGFzay0+aW1nOwojaWZkZWYgVFJZX1BJQ1JFVFVSTgogaWYgKFZNODYtPnZtODZwbHVzLmZvcmNlX3JldHVybl9mb3JfcGljKSB7CiAgIFNFVF9QRU5EKCZjb250ZXh0KTsKIH0KI2Vsc2UKIC8qIGxpbnV4IGRvZXNuJ3QgcHJlc2VydmUgcGVuZGluZyBmbGFnIG9uIHJldHVybiAqLwogaWYgKFNIT1VMRF9QRU5EKGxwRG9zVGFzay0+cGVuZGluZykpIHsKICAgU0VUX1BFTkQoJmNvbnRleHQpOwogfQojZW5kaWYKCiBzd2l0Y2ggKFZNODZfVFlQRShmbikpIHsKICBjYXNlIFZNODZfU0lHTkFMOgogICBUUkFDRShpbnQsIkRPUyBtb2R1bGUgY2F1Z2h0IHNpZ25hbCAlZFxuIixzaWcpOwogICBpZiAoKHNpZz09U0lHQUxSTSkgfHwgKHNpZz09U0lHVVNSMikpIHsKICAgICBpZiAoc2lnPT1TSUdBTFJNKSB7CiAgICAgICBET1NWTV9RdWV1ZUV2ZW50KDAsRE9TX1BSSU9SSVRZX1JFQUxUSU1FLE5VTEwsTlVMTCk7CiAgICAgfQogICAgIGlmIChscERvc1Rhc2stPnBlbmRpbmcpIHsKICAgICAgIFRSQUNFKGludCwic2V0dGluZyBQZW5kaW5nIGZsYWcsIGludGVycnVwdHMgYXJlIGN1cnJlbnRseSAlc1xuIiwKICAgICAgICAgICAgICAgICBJRl9FTkFCTEVEKCZjb250ZXh0KSA/ICJlbmFibGVkIiA6ICJkaXNhYmxlZCIpOwogICAgICAgU0VUX1BFTkQoJmNvbnRleHQpOwogICAgICAgRE9TVk1fU2VuZFF1ZXVlZEV2ZW50cygmY29udGV4dCxscERvc1Rhc2spOwogICAgIH0gZWxzZSB7CiAgICAgICBUUkFDRShpbnQsIm5vIGV2ZW50cyBhcmUgcGVuZGluZywgY2xlYXJpbmcgUGVuZGluZyBmbGFnXG4iKTsKICAgICAgIENMUl9QRU5EKCZjb250ZXh0KTsKICAgICB9CiAgICAgaWYgKHNpZz09U0lHVVNSMikgbHBEb3NUYXNrLT5zaWdfc2VudC0tOwogICB9IGVsc2UKICAgaWYgKHNpZz09U0lHSFVQKSB7CiAgICBpZiAoY3R4X2RlYnVnX2NhbGwpIGN0eF9kZWJ1Z19jYWxsKFNJR1RSQVAsJmNvbnRleHQpOwogICB9IGVsc2UKICAgaWYgKChzaWc9PVNJR0lMTCl8fChzaWc9PVNJR1NFR1YpKSB7CiAgICBpZiAoY3R4X2RlYnVnX2NhbGwpIGN0eF9kZWJ1Z19jYWxsKFNJR0lMTCwmY29udGV4dCk7CiAgIH0gZWxzZSB7CiAgICBET1NWTV9EdW1wKGxwRG9zVGFzayxmbixzaWcsVk04Nik7CiAgICByZXQ9LTE7CiAgIH0KICAgYnJlYWs7CiAgY2FzZSBWTTg2X1VOS05PV046IC8qIHVuaGFuZGxlZCBHUEYgKi8KICAgRE9TVk1fRHVtcChscERvc1Rhc2ssZm4sc2lnLFZNODYpOwogICBpZiAoY3R4X2RlYnVnX2NhbGwpIGN0eF9kZWJ1Z19jYWxsKFNJR1NFR1YsJmNvbnRleHQpOyBlbHNlIHJldD0tMTsKICAgYnJlYWs7CiAgY2FzZSBWTTg2X0lOVHg6CiAgIGlmIChUUkFDRV9PTihyZWxheSkpCiAgICBEUFJJTlRGKCJDYWxsIERPUyBpbnQgMHglMDJ4IChFQVg9JTA4bHgpIHJldD0lMDRseDolMDRseFxuIixWTTg2X0FSRyhmbiksY29udGV4dC5FYXgsY29udGV4dC5TZWdDcyxjb250ZXh0LkVpcCk7CiAgIHJldD1ET1NWTV9JbnQoVk04Nl9BUkcoZm4pLCZjb250ZXh0LGxwRG9zVGFzayk7CiAgIGlmIChUUkFDRV9PTihyZWxheSkpCiAgICBEUFJJTlRGKCJSZXQgIERPUyBpbnQgMHglMDJ4IChFQVg9JTA4bHgpIHJldD0lMDRseDolMDRseFxuIixWTTg2X0FSRyhmbiksY29udGV4dC5FYXgsY29udGV4dC5TZWdDcyxjb250ZXh0LkVpcCk7CiAgIGJyZWFrOwogIGNhc2UgVk04Nl9TVEk6CiAgY2FzZSBWTTg2X1BJQ1JFVFVSTjoKICAgIFRSQUNFKGludCwiRE9TIHRhc2sgZW5hYmxlZCBpbnRlcnJ1cHRzIHdpdGggZXZlbnRzIHBlbmRpbmcsIHNlbmRpbmcgZXZlbnRzXG4iKTsKICAgIERPU1ZNX1NlbmRRdWV1ZWRFdmVudHMoJmNvbnRleHQsbHBEb3NUYXNrKTsKICAgIGJyZWFrOwogIGNhc2UgVk04Nl9UUkFQOgogICBpZiAoY3R4X2RlYnVnX2NhbGwpIGN0eF9kZWJ1Z19jYWxsKFNJR1RSQVAsJmNvbnRleHQpOwogICBicmVhazsKICBkZWZhdWx0OgogICBET1NWTV9EdW1wKGxwRG9zVGFzayxmbixzaWcsVk04Nik7CiAgIHJldD0tMTsKIH0KCiNkZWZpbmUgQ1AoeCx5KSBWTTg2LT5yZWdzLnggPSB5IyNfcmVnKCZjb250ZXh0KQogQ1Y7CiN1bmRlZiBDUAojaWZkZWYgVFJZX1BJQ1JFVFVSTgogVk04Ni0+dm04NnBsdXMuZm9yY2VfcmV0dXJuX2Zvcl9waWMgPSBJU19QRU5EKCZjb250ZXh0KSA/IDEgOiAwOwogQ0xSX1BFTkQoJmNvbnRleHQpOwojZW5kaWYKIHJldHVybiByZXQ7Cn0KCnZvaWQgRE9TVk1fUHJvY2Vzc01lc3NhZ2UoTFBET1NUQVNLIGxwRG9zVGFzayxNU0cgKm1zZykKewogIEJZVEUgc2NhbiA9IDA7CgogIGZwcmludGYoc3RkZXJyLCJnb3QgbWVzc2FnZSAlMDR4LCB3cGFyYW09JTA4eCwgbHBhcmFtPSUwOGx4XG4iLG1zZy0+bWVzc2FnZSxtc2ctPndQYXJhbSxtc2ctPmxQYXJhbSk7CiAgaWYgKChtc2ctPm1lc3NhZ2U+PVdNX01PVVNFRklSU1QpJiYKICAgICAgKG1zZy0+bWVzc2FnZTw9V01fTU9VU0VMQVNUKSkgewogICAgSU5UX0ludDMzTWVzc2FnZShtc2ctPm1lc3NhZ2UsbXNnLT53UGFyYW0sbXNnLT5sUGFyYW0pOwogIH0gZWxzZSB7CiAgICBzd2l0Y2ggKG1zZy0+bWVzc2FnZSkgewogICAgY2FzZSBXTV9LRVlVUDoKICAgICAgc2NhbiA9IDB4ODA7CiAgICBjYXNlIFdNX0tFWURPV046CiAgICAgIHNjYW4gfD0gKG1zZy0+bFBhcmFtID4+IDE2KSAmIDB4N2Y7CgogICAgICAvKiBjaGVjayB3aGV0aGVyIGV4dGVuZGVkIGJpdCBpcyBzZXQsCiAgICAgICAqIGFuZCBpZiBzbywgcXVldWUgdGhlIGV4dGVuc2lvbiBwcmVmaXggKi8KICAgICAgaWYgKG1zZy0+bFBhcmFtICYgMHgxMDAwMDAwKSB7CgkvKiBGSVhNRTogc29tZSBrZXlzIChmdW5jdGlvbiBrZXlzKSBoYXZlCgkgKiBleHRlbmRlZCBiaXQgc2V0IGV2ZW4gd2hlbiB0aGV5IHNob3VsZG4ndCwKCSAqIHNob3VsZCBjaGVjayBmb3IgdGhlbSAqLwoJSU5UX0ludDA5U2VuZFNjYW4oMHhFMCk7CiAgICAgIH0KICAgICAgSU5UX0ludDA5U2VuZFNjYW4oc2Nhbik7CiAgICAgIGJyZWFrOwogICAgfQogIH0KfQoKaW50IERPU1ZNX0VudGVyKCBQQ09OVEVYVCBjb250ZXh0ICkKewogVERCICpwVGFzayA9IChUREIgKilHbG9iYWxMb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIE5FX01PRFVMRSAqcE1vZHVsZSA9IE5FX0dldFB0ciggcFRhc2stPmhNb2R1bGUgKTsKIExQRE9TVEFTSyBscERvc1Rhc2s7CiBzdHJ1Y3Qgdm04NnBsdXNfc3RydWN0IFZNODY7CiBpbnQgc3RhdCxsZW4sc2lnOwogRFdPUkQgd2FpdHJldDsKIE1TRyBtc2c7CiBmZF9zZXQgcmVhZGZkczsKIHN0cnVjdCB0aW1ldmFsIHRpbWVvdXQ9ezAsMH07CgogR2xvYmFsVW5sb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKIGlmICghcE1vZHVsZSkgewogIEVSUihtb2R1bGUsIk5vIHRhc2sgaXMgY3VycmVudGx5IGFjdGl2ZSFcbiIpOwogIHJldHVybiAtMTsKIH0KIGlmICghKGxwRG9zVGFzaz1wTW9kdWxlLT5scERvc1Rhc2spKSB7CiAgLyogTVpfQ3JlYXRlUHJvY2VzcyBvciBNWl9BbGxvY0RQTUlUYXNrIHNob3VsZCBoYXZlIGJlZW4gY2FsbGVkIGZpcnN0ICovCiAgRVJSKG1vZHVsZSwiZG9zbW9kIGhhcyBub3QgYmVlbiBpbml0aWFsaXplZCEiKTsKICByZXR1cm4gLTE7CiB9CgogaWYgKGNvbnRleHQpIHsKI2RlZmluZSBDUCh4LHkpIFZNODYucmVncy54ID0geSMjX3JlZyhjb250ZXh0KQogIENWOwojdW5kZWYgQ1AKIH0gZWxzZSB7Ci8qIGluaXRpYWwgc2V0dXAgKi8KICAvKiBhbGxvY2F0ZSBzdGFuZGFyZCBET1MgaGFuZGxlcyAqLwogIEZJTEVfSW5pdFByb2Nlc3NEb3NIYW5kbGVzKCk7IAogIC8qIHJlZ2lzdGVycyAqLwogIG1lbXNldCgmVk04NiwwLHNpemVvZihWTTg2KSk7CiAgVk04Ni5yZWdzLmNzPWxwRG9zVGFzay0+aW5pdF9jczsKICBWTTg2LnJlZ3MuZWlwPWxwRG9zVGFzay0+aW5pdF9pcDsKICBWTTg2LnJlZ3Muc3M9bHBEb3NUYXNrLT5pbml0X3NzOwogIFZNODYucmVncy5lc3A9bHBEb3NUYXNrLT5pbml0X3NwOwogIFZNODYucmVncy5kcz1scERvc1Rhc2stPnBzcF9zZWc7CiAgVk04Ni5yZWdzLmVzPWxwRG9zVGFzay0+cHNwX3NlZzsKICBWTTg2LnJlZ3MuZWZsYWdzPVZJRl9NQVNLOwogIC8qIGhtbSwgd2hhdCBlbHNlIGRvIHdlIG5lZWQ/ICovCiB9CgogLyogbWFpbiBleGNoYW5nZSBsb29wICovCiBkbyB7CiAgc3RhdCA9IFZNODZfRU5URVI7CiAgZXJybm8gPSAwOwogIC8qIHRyYW5zbWl0IFZNODYgc3RydWN0dXJlIHRvIGRvc21vZCB0YXNrICovCiAgaWYgKHdyaXRlKGxwRG9zVGFzay0+d3JpdGVfcGlwZSwmc3RhdCxzaXplb2Yoc3RhdCkpIT1zaXplb2Yoc3RhdCkpIHsKICAgRVJSKG1vZHVsZSwiZG9zbW9kIHN5bmMgbG9zdCwgZXJybm89JWQsIGZkPSVkLCBwaWQ9JWRcbiIsZXJybm8sbHBEb3NUYXNrLT53cml0ZV9waXBlLGdldHBpZCgpKTsKICAgcmV0dXJuIC0xOwogIH0KICBpZiAod3JpdGUobHBEb3NUYXNrLT53cml0ZV9waXBlLCZWTTg2LHNpemVvZihWTTg2KSkhPXNpemVvZihWTTg2KSkgewogICBFUlIobW9kdWxlLCJkb3Ntb2Qgc3luYyBsb3N0LCBlcnJubz0lZFxuIixlcnJubyk7CiAgIHJldHVybiAtMTsKICB9CiAgZG8gewogICAgLyogY2hlY2sgZm9yIG1lc3NhZ2VzICh3YXN0ZSB0aW1lIGJlZm9yZSB0aGUgcmVzcG9uc2UgY2hlY2sgYmVsb3cpICovCiAgICB3aGlsZSAoUGVla01lc3NhZ2VBKCZtc2csMCwwLDAsUE1fUkVNT1ZFfFBNX05PWUlFTEQpKSB7CiAgICAgIC8qIGdvdCBhIG1lc3NhZ2UgKi8KICAgICAgRE9TVk1fUHJvY2Vzc01lc3NhZ2UobHBEb3NUYXNrLCZtc2cpOwogICAgICAvKiB3ZSBkb24ndCBuZWVkIGEgVHJhbnNsYXRlTWVzc2FnZSBoZXJlICovCiAgICAgIERpc3BhdGNoTWVzc2FnZUEoJm1zZyk7CiAgICB9CiAgICAvKiBxdWljayBjaGVjayBmb3IgcmVzcG9uc2UgZnJvbSBkb3Ntb2QKICAgICAqIChmYXN0ZXIgdGhhbiBkb2luZyB0aGUgZnVsbCBibG9ja2luZyB3YWl0LCBpZiBkYXRhIGFscmVhZHkgYXZhaWxhYmxlKSAqLwogICAgRkRfWkVSTygmcmVhZGZkcyk7IEZEX1NFVChscERvc1Rhc2stPnJlYWRfcGlwZSwmcmVhZGZkcyk7CiAgICBpZiAoc2VsZWN0KGxwRG9zVGFzay0+cmVhZF9waXBlKzEsJnJlYWRmZHMsTlVMTCxOVUxMLCZ0aW1lb3V0KT4wKQogICAgICBicmVhazsKICAgIC8qIG5vdGhpbmcgeWV0LCBibG9jayB3aGlsZSB3YWl0aW5nIGZvciBzb21ldGhpbmcgdG8gZG8gKi8KICAgIHdhaXRyZXQ9TXNnV2FpdEZvck11bHRpcGxlT2JqZWN0cygxLCYobHBEb3NUYXNrLT5oUmVhZFBpcGUpLEZBTFNFLElORklOSVRFLFFTX0FMTElOUFVUKTsKICAgIGlmICh3YWl0cmV0PT0oRFdPUkQpLTEpIHsKICAgICAgRVJSKG1vZHVsZSwiZG9zdm0gd2FpdCBlcnJvcj0lbGRcbiIsR2V0TGFzdEVycm9yKCkpOwogICAgfQogIH0gd2hpbGUgKHdhaXRyZXQhPVdBSVRfT0JKRUNUXzApOwogIC8qIHJlYWQgcmVzcG9uc2UgKi8KICB3aGlsZSAoMSkgewogICAgaWYgKChsZW49cmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmc3RhdCxzaXplb2Yoc3RhdCkpKT09c2l6ZW9mKHN0YXQpKSBicmVhazsKICAgIGlmICgoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkmJihsZW48PTApKSB7CiAgICAgV0FSTihtb2R1bGUsInJlcmVhZGluZyBkb3Ntb2QgcmV0dXJuIGNvZGUgZHVlIHRvIGVycm5vPSVkLCByZXN1bHQ9JWRcbiIsZXJybm8sbGVuKTsKICAgICBjb250aW51ZTsKICAgIH0KICAgIEVSUihtb2R1bGUsImRvc21vZCBzeW5jIGxvc3QgcmVhZGluZyByZXR1cm4gY29kZSwgZXJybm89JWQsIHJlc3VsdD0lZFxuIixlcnJubyxsZW4pOwogICAgcmV0dXJuIC0xOwogIH0KICBUUkFDRShtb2R1bGUsImRvc21vZCByZXR1cm4gY29kZT0lZFxuIixzdGF0KTsKICB3aGlsZSAoMSkgewogICAgaWYgKChsZW49cmVhZChscERvc1Rhc2stPnJlYWRfcGlwZSwmVk04NixzaXplb2YoVk04NikpKT09c2l6ZW9mKFZNODYpKSBicmVhazsKICAgIGlmICgoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkmJihsZW48PTApKSB7CiAgICAgV0FSTihtb2R1bGUsInJlcmVhZGluZyBkb3Ntb2QgVk04NiBzdHJ1Y3R1cmUgZHVlIHRvIGVycm5vPSVkLCByZXN1bHQ9JWRcbiIsZXJybm8sbGVuKTsKICAgICBjb250aW51ZTsKICAgIH0KICAgIEVSUihtb2R1bGUsImRvc21vZCBzeW5jIGxvc3QgcmVhZGluZyBWTTg2IHN0cnVjdHVyZSwgZXJybm89JWQsIHJlc3VsdD0lZFxuIixlcnJubyxsZW4pOwogICAgcmV0dXJuIC0xOwogIH0KICBpZiAoKHN0YXQmMHhmZik9PURPU01PRF9TSUdOQUwpIHsKICAgIHdoaWxlICgxKSB7CiAgICAgIGlmICgobGVuPXJlYWQobHBEb3NUYXNrLT5yZWFkX3BpcGUsJnNpZyxzaXplb2Yoc2lnKSkpPT1zaXplb2Yoc2lnKSkgYnJlYWs7CiAgICAgIGlmICgoKGVycm5vPT1FSU5UUil8fChlcnJubz09RUFHQUlOKSkmJihsZW48PTApKSB7CglXQVJOKG1vZHVsZSwicmVyZWFkaW5nIGRvc21vZCBzaWduYWwgZHVlIHRvIGVycm5vPSVkLCByZXN1bHQ9JWRcbiIsZXJybm8sbGVuKTsKCWNvbnRpbnVlOwogICAgICB9CiAgICAgIEVSUihtb2R1bGUsImRvc21vZCBzeW5jIGxvc3QgcmVhZGluZyBzaWduYWwsIGVycm5vPSVkLCByZXN1bHQ9JWRcbiIsZXJybm8sbGVuKTsKICAgICAgcmV0dXJuIC0xOwogICAgfSB3aGlsZSAoMCk7CiAgfSBlbHNlIHNpZz0wOwogIC8qIGdvdCByZXNwb25zZSAqLwogfSB3aGlsZSAoRE9TVk1fUHJvY2VzcyhscERvc1Rhc2ssc3RhdCxzaWcsJlZNODYpPj0wKTsKCiBpZiAoY29udGV4dCkgewojZGVmaW5lIENQKHgseSkgeSMjX3JlZyhjb250ZXh0KSA9IFZNODYucmVncy54CiAgQ1Y7CiN1bmRlZiBDUAogfQogcmV0dXJuIDA7Cn0KCnZvaWQgRE9TVk1fUElDX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwpCnsKICBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogIE5FX01PRFVMRSAqcE1vZHVsZSA9IE5FX0dldFB0ciggcFRhc2stPmhNb2R1bGUgKTsKICBMUERPU0VWRU5UIGV2ZW50OwoKICBHbG9iYWxVbmxvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogIGlmIChwTW9kdWxlICYmIHBNb2R1bGUtPmxwRG9zVGFzaykgewogICAgaWYgKChwb3J0PT0weDIwKSAmJiAodmFsPT0weDIwKSkgewogICAgICBpZiAocE1vZHVsZS0+bHBEb3NUYXNrLT5jdXJyZW50KSB7CgkvKiBFT0kgKEVuZCBPZiBJbnRlcnJ1cHQpICovCglUUkFDRShpbnQsInJlY2VpdmVkIEVPSSBmb3IgY3VycmVudCBJUlEsIGNsZWFyaW5nXG4iKTsKCWV2ZW50ID0gcE1vZHVsZS0+bHBEb3NUYXNrLT5jdXJyZW50OwoJcE1vZHVsZS0+bHBEb3NUYXNrLT5jdXJyZW50ID0gZXZlbnQtPm5leHQ7CglpZiAoZXZlbnQtPnJlbGF5KQoJKCpldmVudC0+cmVsYXkpKHBNb2R1bGUtPmxwRG9zVGFzayxOVUxMLGV2ZW50LT5kYXRhKTsKCWZyZWUoZXZlbnQpOwoKCWlmIChwTW9kdWxlLT5scERvc1Rhc2stPnBlbmRpbmcgJiYKCSAgICAhcE1vZHVsZS0+bHBEb3NUYXNrLT5zaWdfc2VudCkgewoJICAvKiBhbm90aGVyIGV2ZW50IGlzIHBlbmRpbmcsIHdoaWNoIHdlIHNob3VsZCBwcm9iYWJseQoJICAgKiBiZSBhYmxlIHRvIHByb2Nlc3Mgbm93LCBzbyB0ZWxsIGRvc21vZCBhYm91dCBpdCAqLwoJICBUUkFDRShpbnQsImFub3RoZXIgZXZlbnQgcGVuZGluZywgc2lnbmFsbGluZyBkb3Ntb2RcbiIpOwoJICBraWxsKHBNb2R1bGUtPmxwRG9zVGFzay0+dGFzayxTSUdVU1IyKTsKCSAgcE1vZHVsZS0+bHBEb3NUYXNrLT5zaWdfc2VudCsrOwoJfQogICAgICB9IGVsc2UgewoJV0FSTihpbnQsIkVPSSB3aXRob3V0IGFjdGl2ZSBJUlFcbiIpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBGSVhNRShpbnQsInVucmVjb2duaXplZCBQSUMgY29tbWFuZCAlMDJ4XG4iLHZhbCk7CiAgICB9CiAgfQp9Cgp2b2lkIERPU1ZNX1NldFRpbWVyKCB1bnNpZ25lZCB0aWNrcyApCnsKIFREQiAqcFRhc2sgPSAoVERCICopR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiBORV9NT0RVTEUgKnBNb2R1bGUgPSBORV9HZXRQdHIoIHBUYXNrLT5oTW9kdWxlICk7CiBpbnQgc3RhdD1ET1NNT0RfU0VUX1RJTUVSOwogc3RydWN0IHRpbWV2YWwgdGltOwoKIEdsb2JhbFVubG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiBpZiAocE1vZHVsZSYmcE1vZHVsZS0+bHBEb3NUYXNrKSB7CiAgLyogdGhlIFBDIGNsb2NrcyB0aWNrcyBhdCAxMTkzMTgwIEh6ICovCiAgdGltLnR2X3NlYz0wOwogIHRpbS50dl91c2VjPSgodW5zaWduZWQgbG9uZyBsb25nKXRpY2tzKjEwMDAwMDApLzExOTMxODA7CiAgLyogc2FuaXR5IGNoZWNrICovCiAgaWYgKCF0aW0udHZfdXNlYykgdGltLnR2X3VzZWM9MTsKCiAgaWYgKHdyaXRlKHBNb2R1bGUtPmxwRG9zVGFzay0+d3JpdGVfcGlwZSwmc3RhdCxzaXplb2Yoc3RhdCkpIT1zaXplb2Yoc3RhdCkpIHsKICAgRVJSKG1vZHVsZSwiZG9zbW9kIHN5bmMgbG9zdCwgZXJybm89JWRcbiIsZXJybm8pOwogICByZXR1cm47CiAgfQogIGlmICh3cml0ZShwTW9kdWxlLT5scERvc1Rhc2stPndyaXRlX3BpcGUsJnRpbSxzaXplb2YodGltKSkhPXNpemVvZih0aW0pKSB7CiAgIEVSUihtb2R1bGUsImRvc21vZCBzeW5jIGxvc3QsIGVycm5vPSVkXG4iLGVycm5vKTsKICAgcmV0dXJuOwogIH0KICAvKiB0aGVyZSdzIG5vIHJldHVybiAqLwogfQp9Cgp1bnNpZ25lZCBET1NWTV9HZXRUaW1lciggdm9pZCApCnsKIFREQiAqcFRhc2sgPSAoVERCICopR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiBORV9NT0RVTEUgKnBNb2R1bGUgPSBORV9HZXRQdHIoIHBUYXNrLT5oTW9kdWxlICk7CiBpbnQgc3RhdD1ET1NNT0RfR0VUX1RJTUVSOwogc3RydWN0IHRpbWV2YWwgdGltOwoKIEdsb2JhbFVubG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiBpZiAocE1vZHVsZSYmcE1vZHVsZS0+bHBEb3NUYXNrKSB7CiAgaWYgKHdyaXRlKHBNb2R1bGUtPmxwRG9zVGFzay0+d3JpdGVfcGlwZSwmc3RhdCxzaXplb2Yoc3RhdCkpIT1zaXplb2Yoc3RhdCkpIHsKICAgRVJSKG1vZHVsZSwiZG9zbW9kIHN5bmMgbG9zdCwgZXJybm89JWRcbiIsZXJybm8pOwogICByZXR1cm4gMDsKICB9CiAgLyogcmVhZCByZXNwb25zZSAqLwogIHdoaWxlICgxKSB7CiAgICBpZiAocmVhZChwTW9kdWxlLT5scERvc1Rhc2stPnJlYWRfcGlwZSwmdGltLHNpemVvZih0aW0pKT09c2l6ZW9mKHRpbSkpIGJyZWFrOwogICAgaWYgKChlcnJubz09RUlOVFIpfHwoZXJybm89PUVBR0FJTikpIGNvbnRpbnVlOwogICAgRVJSKG1vZHVsZSwiZG9zbW9kIHN5bmMgbG9zdCwgZXJybm89JWRcbiIsZXJybm8pOwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiAoKHVuc2lnbmVkIGxvbmcgbG9uZyl0aW0udHZfdXNlYyoxMTkzMTgwKS8xMDAwMDAwOwogfQogcmV0dXJuIDA7Cn0KCnZvaWQgRE9TVk1fU2V0U3lzdGVtRGF0YSggaW50IGlkLCB2b2lkICpkYXRhICkKewogIFREQiAqcFRhc2sgPSAoVERCICopR2xvYmFsTG9jazE2KCBHZXRDdXJyZW50VGFzaygpICk7CiAgTkVfTU9EVUxFICpwTW9kdWxlID0gTkVfR2V0UHRyKCBwVGFzay0+aE1vZHVsZSApOwogIERPU1NZU1RFTSAqc3lzLCAqcHJldjsKCiAgR2xvYmFsVW5sb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBpZiAocE1vZHVsZSAmJiBwTW9kdWxlLT5scERvc1Rhc2spIHsKICAgIHN5cyA9IHBNb2R1bGUtPmxwRG9zVGFzay0+c3lzOwogICAgcHJldiA9IE5VTEw7CiAgICB3aGlsZSAoc3lzICYmIChzeXMtPmlkICE9IGlkKSkgewogICAgICBwcmV2ID0gc3lzOwogICAgICBzeXMgPSBzeXMtPm5leHQ7CiAgICB9CiAgICBpZiAoc3lzKSB7CiAgICAgIGZyZWUoc3lzLT5kYXRhKTsKICAgICAgc3lzLT5kYXRhID0gZGF0YTsKICAgIH0gZWxzZSB7CiAgICAgIHN5cyA9IG1hbGxvYyhzaXplb2YoRE9TU1lTVEVNKSk7CiAgICAgIHN5cy0+aWQgPSBpZDsKICAgICAgc3lzLT5kYXRhID0gZGF0YTsKICAgICAgc3lzLT5uZXh0ID0gTlVMTDsKICAgICAgaWYgKHByZXYpIHByZXYtPm5leHQgPSBzeXM7CiAgICAgIGVsc2UgcE1vZHVsZS0+bHBEb3NUYXNrLT5zeXMgPSBzeXM7CiAgICB9CiAgfSBlbHNlIGZyZWUoZGF0YSk7Cn0KCnZvaWQqIERPU1ZNX0dldFN5c3RlbURhdGEoIGludCBpZCApCnsKICBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggR2V0Q3VycmVudFRhc2soKSApOwogIE5FX01PRFVMRSAqcE1vZHVsZSA9IE5FX0dldFB0ciggcFRhc2stPmhNb2R1bGUgKTsKICBET1NTWVNURU0gKnN5czsKCiAgR2xvYmFsVW5sb2NrMTYoIEdldEN1cnJlbnRUYXNrKCkgKTsKICBpZiAocE1vZHVsZSAmJiBwTW9kdWxlLT5scERvc1Rhc2spIHsKICAgIHN5cyA9IHBNb2R1bGUtPmxwRG9zVGFzay0+c3lzOwogICAgd2hpbGUgKHN5cyAmJiAoc3lzLT5pZCAhPSBpZCkpCiAgICAgIHN5cyA9IHN5cy0+bmV4dDsKICAgIGlmIChzeXMpCiAgICAgIHJldHVybiBzeXMtPmRhdGE7CiAgfQogIHJldHVybiBOVUxMOwp9CgojZWxzZSAvKiAhTVpfU1VQUE9SVEVEICovCgppbnQgRE9TVk1fRW50ZXIoIFBDT05URVhUIGNvbnRleHQgKQp7CiBFUlIobW9kdWxlLCJET1MgcmVhbG1vZGUgbm90IHN1cHBvcnRlZCBvbiB0aGlzIGFyY2hpdGVjdHVyZSFcbiIpOwogcmV0dXJuIC0xOwp9Cgp2b2lkIERPU1ZNX1BJQ19pb3BvcnRfb3V0KCBXT1JEIHBvcnQsIEJZVEUgdmFsKSB7fQp2b2lkIERPU1ZNX1NldFRpbWVyKCB1bnNpZ25lZCB0aWNrcyApIHt9CnVuc2lnbmVkIERPU1ZNX0dldFRpbWVyKCB2b2lkICkgeyByZXR1cm4gMDsgfQp2b2lkIERPU1ZNX1NldFN5c3RlbURhdGEoIGludCBpZCwgdm9pZCAqZGF0YSApIHsgZnJlZShkYXRhKTsgfQp2b2lkKiBET1NWTV9HZXRTeXN0ZW1EYXRhKCBpbnQgaWQgKSB7IHJldHVybiBOVUxMOyB9CnZvaWQgRE9TVk1fUXVldWVFdmVudCggaW50IGlycSwgaW50IHByaW9yaXR5LCB2b2lkICgqcmVsYXkpKExQRE9TVEFTSyxQQ09OVEVYVCx2b2lkKiksIHZvaWQgKmRhdGEpIHsgLyogRU1QVFkgKi8gfQoKI2VuZGlmCg==