LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYtOTggTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCi8qIE5vdGVzOgogKiBCZWZvcmUgeW91IHN0YXJ0IGNoYW5naW5nIHNvbWV0aGluZyBpbiB0aGlzIGZpbGUgYmUgYXdhcmUgb2YgdGhlIGZvbGxvd2luZzoKICoKICogLSBUaGVyZSBhcmUgc2V2ZXJhbCBmdW5jdGlvbnMgY2FsbGVkIHJlY3Vyc2l2ZWx5LiBJbiBhIHZlcnkgc3VidGxlIGFuZCAKICogICBvYnNjdXJlIHdheS4gRExMcyBjYW4gcmVmZXJlbmNlIGVhY2ggb3RoZXIgcmVjdXJzaXZlbHkgZXRjLgogKiAtIElmIHlvdSB3YW50IHRvIGVuaGFuY2UsIHNwZWVkIHVwIG9yIGNsZWFuIHVwIHNvbWV0aGluZyBpbiBoZXJlLCB0aGluawogKiAgIHR3aWNlIFdIWSBpdCBpcyBpbXBsZW1lbnRlZCBpbiB0aGF0IHN0cmFuZ2Ugd2F5LiBUaGVyZSBpcyB1c3VhbGx5IGEgcmVhc29uLgogKiAgIFRob3VnaCBzb21ldGltZXMgaXQgbWlnaHQganVzdCBiZSBsYXp5bmVzcyA7KQogKiAtIEluIFBFX01hcEltYWdlLCByaWdodCBiZWZvcmUgZml4dXBfaW1wb3J0cygpIGFsbCBleHRlcm5hbCBhbmQgaW50ZXJuYWwgCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqIC0gTm8sIHlvdSAodXN1YWxseSkgY2Fubm90IHVzZSBMaW51eCBtbWFwKCkgdG8gbW1hcCgpIHRoZSBpbWFnZXMgZGlyZWN0bHkuCiAqCiAqICAgVGhlIHByb2JsZW0gaXMsIHRoYXQgdGhlcmUgaXMgbm90IGRpcmVjdCAxOjEgbWFwcGluZyBmcm9tIGEgZGlza2ltYWdlIGFuZAogKiAgIGEgbWVtb3J5aW1hZ2UuIFRoZSBoZWFkZXJzIGF0IHRoZSBzdGFydCBhcmUgbWFwcGVkIGxpbmVhciwgYnV0IHRoZSBzZWN0aW9ucwogKiAgIGFyZSBub3QuIEZvciB4ODYgdGhlIHNlY3Rpb25zIGFyZSA1MTIgYnl0ZSBhbGlnbmVkIGluIGZpbGUgYW5kIDQwOTYgYnl0ZQogKiAgIGFsaWduZWQgaW4gbWVtb3J5LiBMaW51eCBsaWtlcyB0aGVtIDQwOTYgYnl0ZSBhbGlnbmVkIGluIG1lbW9yeSAoZHVlIHRvCiAqICAgeDg2IHBhZ2VzaXplLCB0aGlzIGNhbm5vdCBiZSBmaXhlZCB3aXRob3V0IGEgcmF0aGVyIGxhcmdlIGtlcm5lbCByZXdyaXRlKQogKiAgIGFuZCAnYmxvY2tzaXplJyBmaWxlLWFsaWduZWQgKG9mZnNldHMpLiBTaW5jZSB3ZSBoYXZlIDUxMi8xMDI0LzIwNDggKENEUk9NKQogKiAgIGFuZCBvdGhlciBieXRlIGJsb2Nrc2l6ZXMsIHdlIGNhbid0IGRvIHRoaXMuIEhvd2V2ZXIsIHRoaXMgY291bGQgYmUgbGVzcwogKiAgIGRpZmZpY3VsdCB0byBzdXBwb3J0Li4uIChTZWUgbW0vZmlsZW1hcC5jKS4KICovCgojaW5jbHVkZSAiY29uZmlnLmgiCgojaW5jbHVkZSA8ZXJybm8uaD4KI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgIndpbmRlZi5oIgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJoZWFwLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAicGVfaW1hZ2UuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJzbm9vcC5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKHdpbjMyKQpERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGVsYXlobHApCkRFQ0xBUkVfREVCVUdfQ0hBTk5FTChmaXh1cCkKREVDTEFSRV9ERUJVR19DSEFOTkVMKG1vZHVsZSkKREVDTEFSRV9ERUJVR19DSEFOTkVMKHJlbGF5KQpERUNMQVJFX0RFQlVHX0NIQU5ORUwoc2VnbWVudCkKCgovKiBjb252ZXJ0IFBFIGltYWdlIFZpcnR1YWxBZGRyZXNzIHRvIFJlYWwgQWRkcmVzcyAqLwojZGVmaW5lIFJWQSh4KSAoKHVuc2lnbmVkIGludClsb2FkX2FkZHIrKHVuc2lnbmVkIGludCkoeCkpCgojZGVmaW5lIEFkanVzdFB0cihwdHIsZGVsdGEpICgoY2hhciAqKShwdHIpICsgKGRlbHRhKSkKCnZvaWQgZHVtcF9leHBvcnRzKCBITU9EVUxFIGhNb2R1bGUgKQp7IAogIGNoYXIJCSpNb2R1bGU7CiAgaW50CQlpLCBqOwogIHVfc2hvcnQJKm9yZGluYWw7CiAgdV9sb25nCSpmdW5jdGlvbiwqZnVuY3Rpb25zOwogIHVfY2hhcgkqKm5hbWU7CiAgdW5zaWduZWQgaW50IGxvYWRfYWRkciA9IGhNb2R1bGU7CgogIERXT1JEIHJ2YV9zdGFydCA9IFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKICAgICAgICAgICAgICAgICAgIC5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlZpcnR1YWxBZGRyZXNzOwogIERXT1JEIHJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5TaXplOwogIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydHMgPSAoSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSopUlZBKHJ2YV9zdGFydCk7CgogIE1vZHVsZSA9IChjaGFyKilSVkEocGVfZXhwb3J0cy0+TmFtZSk7CiAgVFJBQ0UoIioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbiIpOwogIFRSQUNFKCJNb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKICAgICAgICBNb2R1bGUsIHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zLCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKTsKCiAgb3JkaW5hbD0odV9zaG9ydCopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucz1mdW5jdGlvbj0odV9sb25nKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZT0odV9jaGFyKiopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIFRSQUNFKCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgaWYgKFRSQUNFX09OKHdpbjMyKSkKICAgICAgewoJRFBSSU5URiggIiU0bGQgJTA4bHggJTA4eCIsIGkgKyBwZV9leHBvcnRzLT5CYXNlLCAqZnVuY3Rpb24sIFJWQSgqZnVuY3Rpb24pICk7CgkvKiBDaGVjayBpZiB3ZSBoYXZlIGEgbmFtZSBmb3IgaXQgKi8KCWZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQogICAgICAgICAgewogICAgICAgICAgICAgIERQUklOVEYoICIgICVzIiwgKGNoYXIqKVJWQShuYW1lW2pdKSApOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgfQoJaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9lbmQpKQoJICBEUFJJTlRGKCIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKVJWQSgqZnVuY3Rpb24pKTsKCURQUklOVEYoIlxuIik7CiAgICAgIH0KICB9Cn0KCi8qIExvb2sgdXAgdGhlIHNwZWNpZmllZCBmdW5jdGlvbiBvciBvcmRpbmFsIGluIHRoZSBleHBvcnRsaXN0OgogKiBJZiBpdCBpcyBhIHN0cmluZzoKICogCS0gbG9vayB1cCB0aGUgbmFtZSBpbiB0aGUgTmFtZSBsaXN0LiAKICoJLSBsb29rIHVwIHRoZSBvcmRpbmFsIHdpdGggdGhhdCBpbmRleC4KICoJLSB1c2UgdGhlIG9yZGluYWwgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKiBJZiBpdCBpcyBhIG9yZGluYWw6CiAqCS0gdXNlIG9yZGluYWwtcGVfZXhwb3J0LT5CYXNlIGFzIG9mZnNldCBpbnRvIHRoZSBmdW5jdGlvbmxpc3QKICovCkZBUlBST0MgUEVfRmluZEV4cG9ydGVkRnVuY3Rpb24oIAoJV0lORV9NT0RSRUYgKndtLAkvKiBbaW5dIFdJTkUgbW9kcmVmZXJlbmNlICovCglMUENTVFIgZnVuY05hbWUsCS8qIFtpbl0gZnVuY3Rpb24gbmFtZSAqLwogICAgICAgIEJPT0wgc25vb3AgKQp7Cgl1X3Nob3J0CQkJCSogb3JkaW5hbDsKCXVfbG9uZwkJCQkqIGZ1bmN0aW9uOwoJdV9jaGFyCQkJCSoqIG5hbWUsICplbmFtZTsKCWludAkJCQlpOwoJUEVfTU9EUkVGCQkJKnBlbSA9ICYod20tPmJpbmZtdC5wZSk7CglJTUFHRV9FWFBPUlRfRElSRUNUT1JZIAkJKmV4cG9ydHMgPSBwZW0tPnBlX2V4cG9ydDsKCXVuc2lnbmVkIGludAkJCWxvYWRfYWRkciA9IHdtLT5tb2R1bGU7Cgl1X2xvbmcJCQkJcnZhX3N0YXJ0LCBydmFfZW5kLCBhZGRyOwoJY2hhcgkJCQkqIGZvcndhcmQ7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJVFJBQ0UoIiglcylcbiIsZnVuY05hbWUpOwoJZWxzZQoJCVRSQUNFKCIoJWQpXG4iLChpbnQpZnVuY05hbWUpOwoJaWYgKCFleHBvcnRzKSB7CgkJLyogTm90IGEgZmF0YWwgcHJvYmxlbSwgc29tZSBhcHBzIGRvCgkJICogR2V0UHJvY0FkZHJlc3MoMCwiUmVnaXN0ZXJQZW5BcHAiKSB3aGljaCB0cmlnZ2VycyB0aGlzCgkJICogY2FzZS4KCQkgKi8KCQlXQVJOKCJNb2R1bGUgJTA4eCglcykvTU9EUkVGICVwIGRvZXNuJ3QgaGF2ZSBhIGV4cG9ydHMgdGFibGUuXG4iLHdtLT5tb2R1bGUsd20tPm1vZG5hbWUscGVtKTsKCQlyZXR1cm4gTlVMTDsKCX0KCW9yZGluYWwJPSAodV9zaG9ydCopICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKCWZ1bmN0aW9uPSAodV9sb25nKikgICBSVkEoZXhwb3J0cy0+QWRkcmVzc09mRnVuY3Rpb25zKTsKCW5hbWUJPSAodV9jaGFyICoqKSBSVkEoZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoJZm9yd2FyZCA9IE5VTEw7CglydmFfc3RhcnQgPSBQRV9IRUFERVIod20tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uVmlydHVhbEFkZHJlc3M7CglydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKHdtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlcgoJCS5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlRdLlNpemU7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpIHsKCQlmb3IoaT0wOyBpPGV4cG9ydHMtPk51bWJlck9mTmFtZXM7IGkrKykgewoJCQllbmFtZT0oY2hhciopUlZBKCpuYW1lKTsKCQkJaWYoIXN0cmNtcChlbmFtZSxmdW5jTmFtZSkpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkZHIgPSBmdW5jdGlvblsqb3JkaW5hbF07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWFkZHIpIHJldHVybiBOVUxMOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChhZGRyIDwgcnZhX3N0YXJ0KSB8fCAoYWRkciA+PSBydmFfZW5kKSkKCQkJCXJldHVybiBzbm9vcD8gU05PT1BfR2V0UHJvY0FkZHJlc3Mod20tPm1vZHVsZSxlbmFtZSwqb3JkaW5hbCwoRkFSUFJPQylSVkEoYWRkcikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAoRkFSUFJPQylSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3J3YXJkID0gKGNoYXIgKilSVkEoYWRkcik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCQkJfQoJCQlvcmRpbmFsKys7CgkJCW5hbWUrKzsKCQl9Cgl9IGVsc2UgCXsKCQlpbnQgaTsKCQlpZiAoTE9XT1JEKGZ1bmNOYW1lKS1leHBvcnRzLT5CYXNlID4gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpIHsKCQkJVFJBQ0UoIglvcmRpbmFsICVkIG91dCBvZiByYW5nZSFcbiIsIExPV09SRChmdW5jTmFtZSkpOwoJCQlyZXR1cm4gTlVMTDsKCQl9CgkJYWRkciA9IGZ1bmN0aW9uWyhpbnQpZnVuY05hbWUtZXhwb3J0cy0+QmFzZV07CiAgICAgICAgICAgICAgICBpZiAoIWFkZHIpIHJldHVybiBOVUxMOwoJCWVuYW1lID0gIiI7CgkJaWYgKG5hbWUpIHsKCQkgICAgZm9yIChpPTA7aTxleHBvcnRzLT5OdW1iZXJPZk5hbWVzO2krKykgewoJCQkgICAgZW5hbWUgPSAoY2hhciopUlZBKCpuYW1lKTsKCQkJICAgIGlmICgqb3JkaW5hbCA9PSBMT1dPUkQoZnVuY05hbWUpLWV4cG9ydHMtPkJhc2UpCgkJCSAgICAJYnJlYWs7CgkJCSAgICBvcmRpbmFsKys7CgkJCSAgICBuYW1lKys7CgkJICAgIH0KCQkgICAgaWYgKGk9PWV4cG9ydHMtPk51bWJlck9mTmFtZXMpCgkJICAgIAllbmFtZSA9ICIiOwoJCX0KCQlpZiAoKGFkZHIgPCBydmFfc3RhcnQpIHx8IChhZGRyID49IHJ2YV9lbmQpKQoJCQlyZXR1cm4gc25vb3A/IFNOT09QX0dldFByb2NBZGRyZXNzKHdtLT5tb2R1bGUsZW5hbWUsKERXT1JEKWZ1bmNOYW1lLWV4cG9ydHMtPkJhc2UsKEZBUlBST0MpUlZBKGFkZHIpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IChGQVJQUk9DKVJWQShhZGRyKTsKCQlmb3J3YXJkID0gKGNoYXIgKilSVkEoYWRkcik7Cgl9CglpZiAoZm9yd2FyZCkKICAgICAgICB7CiAgICAgICAgICAgICAgICBXSU5FX01PRFJFRiAqd207CgkJY2hhciBtb2R1bGVbMjU2XTsKCQljaGFyICplbmQgPSBzdHJjaHIoZm9yd2FyZCwgJy4nKTsKCgkJaWYgKCFlbmQpIHJldHVybiBOVUxMOwoJCWFzc2VydChlbmQtZm9yd2FyZDwyNTYpOwoJCXN0cm5jcHkobW9kdWxlLCBmb3J3YXJkLCAoZW5kIC0gZm9yd2FyZCkpOwoJCW1vZHVsZVtlbmQtZm9yd2FyZF0gPSAwOwogICAgICAgICAgICAgICAgaWYgKCEod20gPSBNT0RVTEVfRmluZE1vZHVsZSggbW9kdWxlICkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEVSUigibW9kdWxlIG5vdCBmb3VuZCBmb3IgZm9yd2FyZCAnJXMnXG4iLCBmb3J3YXJkICk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgICAgICB9CgkJcmV0dXJuIE1PRFVMRV9HZXRQcm9jQWRkcmVzcyggd20tPm1vZHVsZSwgZW5kICsgMSwgc25vb3AgKTsKCX0KCXJldHVybiBOVUxMOwp9CgpEV09SRCBmaXh1cF9pbXBvcnRzKCBXSU5FX01PRFJFRiAqd20gKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUgkqcGVfaW1wOwogICAgUEVfTU9EUkVGCQkJKnBlbTsKICAgIHVuc2lnbmVkIGludCBsb2FkX2FkZHIJPSB3bS0+bW9kdWxlOwogICAgaW50CQkJCWksY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbj0xOwogICAgY2hhcgkJCSptb2RuYW1lOwogICAgCiAgICBhc3NlcnQod20tPnR5cGU9PU1PRFVMRTMyX1BFKTsKICAgIHBlbSA9ICYod20tPmJpbmZtdC5wZSk7CiAgICBpZiAocGVtLT5wZV9leHBvcnQpCiAgICAJbW9kbmFtZSA9IChjaGFyKikgUlZBKHBlbS0+cGVfZXhwb3J0LT5OYW1lKTsKICAgIGVsc2UKICAgICAgICBtb2RuYW1lID0gIjx1bmtub3duPiI7CgogICAgLyogT0ssIG5vdyBkdW1wIHRoZSBpbXBvcnQgbGlzdCAqLwogICAgVFJBQ0UoIkR1bXBpbmcgaW1wb3J0cyBsaXN0XG4iKTsKCiAgICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogICAgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7CiAgICBpZiAoIXBlX2ltcCkgcmV0dXJuIDA7CgogICAgLyogV2UgYXNzdW1lIHRoYXQgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgaW1wb3J0IHdpdGggITAgY2hhcmFjdGVyaXN0aWNzIGFuZAogICAgICogZGV0ZWN0IGJyb2tlbiBpbXBvcnRzIHdpdGggYWxsIGNoYXJhY3RlcmlzdHNpY3MgMCAobm90YWJseSBCb3JsYW5kKSBhbmQKICAgICAqIHN3aXRjaCB0aGUgZGV0ZWN0aW9uIG9mZiBmb3IgdGhlbS4KICAgICAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lIDsgcGVfaW1wKyspIHsKCWlmICghaSAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQljaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uID0gMDsKCWlmIChjaGFyYWN0ZXJpc3RpY3NfZGV0ZWN0aW9uICYmICFwZV9pbXAtPnUuQ2hhcmFjdGVyaXN0aWNzKQoJCWJyZWFrOwoJaSsrOwogICAgfQogICAgaWYgKCFpKSByZXR1cm4gMDsgIC8qIG5vIGltcG9ydHMgKi8KCiAgICAvKiBBbGxvY2F0ZSBtb2R1bGUgZGVwZW5kZW5jeSBsaXN0ICovCiAgICB3bS0+bkRlcHMgPSBpOwogICAgd20tPmRlcHMgID0gSGVhcEFsbG9jKCBHZXRQcm9jZXNzSGVhcCgpLCAwLCBpKnNpemVvZihXSU5FX01PRFJFRiAqKSApOwoKICAgIC8qIGxvYWQgdGhlIGltcG9ydGVkIG1vZHVsZXMuIFRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgCiAgICAgKiBhZGRlZCB0byB0aGUgbW9kcmVmIGxpc3Qgb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KIAogICAgZm9yIChpID0gMCwgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7IHBlX2ltcC0+TmFtZSA7IHBlX2ltcCsrKSB7CiAgICAJV0lORV9NT0RSRUYJCSp3bUltcDsKCUlNQUdFX0lNUE9SVF9CWV9OQU1FCSpwZV9uYW1lOwoJUElNQUdFX1RIVU5LX0RBVEEJaW1wb3J0X2xpc3QsdGh1bmtfbGlzdDsKIAljaGFyCQkJKm5hbWUgPSAoY2hhciAqKSBSVkEocGVfaW1wLT5OYW1lKTsKCglpZiAoY2hhcmFjdGVyaXN0aWNzX2RldGVjdGlvbiAmJiAhcGVfaW1wLT51LkNoYXJhY3RlcmlzdGljcykKCQlicmVhazsKCgl3bUltcCA9IE1PRFVMRV9Mb2FkTGlicmFyeUV4QSggbmFtZSwgMCwgMCApOwoJaWYgKCF3bUltcCkgewoJICAgIEVSUl8obW9kdWxlKSgiTW9kdWxlICVzIG5vdCBmb3VuZFxuIiwgbmFtZSk7CgkgICAgcmV0dXJuIDE7Cgl9CiAgICAgICAgd20tPmRlcHNbaSsrXSA9IHdtSW1wOwoKCS8qIEZJWE1FOiBmb3J3YXJkZXIgZW50cmllcyAuLi4gKi8KCglpZiAocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayAhPSAwKSB7IC8qIG9yaWdpbmFsIE1TIHN0eWxlICovCgkgICAgVFJBQ0UoIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPnUuT3JpZ2luYWxGaXJzdFRodW5rKTsKCSAgICB0aHVua19saXN0ID0gKFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT5GaXJzdFRodW5rKTsKCgkgICAgd2hpbGUgKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTChpbXBvcnRfbGlzdC0+dTEuT3JkaW5hbCkpIHsKCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKTsKCgkJICAgIFRSQUNFKCItLS0gT3JkaW5hbCAlcywlZFxuIiwgbmFtZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgKExQQ1NUUilvcmRpbmFsLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsIG9yZGluYWwpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChGQVJQUk9DKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9IGVsc2UgewkJLyogaW1wb3J0IGJ5IG5hbWUgKi8KCQkgICAgcGVfbmFtZSA9IChQSU1BR0VfSU1QT1JUX0JZX05BTUUpUlZBKGltcG9ydF9saXN0LT51MS5BZGRyZXNzT2ZEYXRhKTsKCQkgICAgVFJBQ0UoIi0tLSAlcyAlcy4lZFxuIiwgcGVfbmFtZS0+TmFtZSwgbmFtZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgcGVfbmFtZS0+TmFtZSwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCUVSUigiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSxwZV9uYW1lLT5IaW50LHBlX25hbWUtPk5hbWUpOwogICAgICAgICAgICAgICAgICAgICAgICB0aHVua19saXN0LT51MS5GdW5jdGlvbiA9IChGQVJQUk9DKTB4ZGVhZGJlZWY7CgkJICAgIH0KCQl9CgkJaW1wb3J0X2xpc3QrKzsKCQl0aHVua19saXN0Kys7CgkgICAgfQoJfSBlbHNlIHsJLyogQm9ybGFuZCBzdHlsZSAqLwoJICAgIFRSQUNFKCJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChQSU1BR0VfVEhVTktfREFUQSkgUlZBKHBlX2ltcC0+Rmlyc3RUaHVuayk7CgkgICAgd2hpbGUgKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpKSB7CgkJICAgIC8qIG5vdCBzdXJlIGFib3V0IHRoaXMgYnJhbmNoLCBidXQgaXQgc2VlbXMgdG8gd29yayAqLwoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwodGh1bmtfbGlzdC0+dTEuT3JkaW5hbCk7CgoJCSAgICBUUkFDRSgiLS0tIE9yZGluYWwgJXMuJWRcbiIsbmFtZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249TU9EVUxFX0dldFByb2NBZGRyZXNzKAogICAgICAgICAgICAgICAgICAgICAgICB3bUltcC0+bW9kdWxlLCAoTFBDU1RSKSBvcmRpbmFsLCBUUlVFCgkJICAgICk7CgkJICAgIGlmICghdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb24pIHsKCQkJRVJSKCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gMHhkZWFkYmVlZlxuIiwKCQkJCW5hbWUsb3JkaW5hbCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIHBlX25hbWU9KFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBUUkFDRSgiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLG5hbWUscGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPU1PRFVMRV9HZXRQcm9jQWRkcmVzcygKICAgICAgICAgICAgICAgICAgICAgICAgd21JbXAtPm1vZHVsZSwgcGVfbmFtZS0+TmFtZSwgVFJVRQoJCSAgICApOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJICAgIAlFUlIoIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byAweGRlYWRiZWVmXG4iLAoJCQkJbmFtZSwgcGVfbmFtZS0+SGludCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uID0gKEZBUlBST0MpMHhkZWFkYmVlZjsKCQkgICAgfQoJCX0KCQl0aHVua19saXN0Kys7CgkgICAgfQoJfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgY2FsY192bWFfc2l6ZSggSE1PRFVMRSBoTW9kdWxlICkKewogICAgaW50IGksdm1hX3NpemUgPSAwOwogICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlZyA9IFBFX1NFQ1RJT05TKGhNb2R1bGUpOwoKICAgIFRSQUNFKCJEdW1wIG9mIHNlZ21lbnQgdGFibGVcbiIpOwogICAgVFJBQ0UoIiAgIE5hbWUgICAgVlN6ICBWYWRkciAgICAgU3pSYXcgICBGaWxlYWRyICAqUmVsb2MgKkxpbmV1bSAjUmVsb2MgI0xpbnVtIENoYXJcbiIpOwogICAgZm9yIChpID0gMDsgaTwgUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKICAgIHsKICAgICAgICBUUkFDRSgiJThzOiAlNC40bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlNC40eCAlNC40eCAlOC44bHhcbiIsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OYW1lLCAKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TWlzYy5WaXJ0dWFsU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlNpemVPZlJhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1Jhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1JlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9MaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZSZWxvY2F0aW9ucywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZMaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+Q2hhcmFjdGVyaXN0aWNzKTsKICAgICAgICB2bWFfc2l6ZT1NQVgodm1hX3NpemUsIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MrcGVfc2VnLT5TaXplT2ZSYXdEYXRhKTsKICAgICAgICB2bWFfc2l6ZT1NQVgodm1hX3NpemUsIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MrcGVfc2VnLT5NaXNjLlZpcnR1YWxTaXplKTsKICAgICAgICBwZV9zZWcrKzsKICAgIH0KICAgIHJldHVybiB2bWFfc2l6ZTsKfQoKc3RhdGljIHZvaWQgZG9fcmVsb2NhdGlvbnMoIHVuc2lnbmVkIGludCBsb2FkX2FkZHIsIElNQUdFX0JBU0VfUkVMT0NBVElPTiAqciApCnsKICAgIGludCBkZWx0YSA9IGxvYWRfYWRkciAtIFBFX0hFQURFUihsb2FkX2FkZHIpLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICBpbnQJaGRlbHRhID0gKGRlbHRhID4+IDE2KSAmIDB4RkZGRjsKICAgIGludAlsZGVsdGEgPSBkZWx0YSAmIDB4RkZGRjsKCglpZihkZWx0YSA9PSAwKQoJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCQlyZXR1cm47Cgl3aGlsZShyLT5WaXJ0dWFsQWRkcmVzcykKCXsKCQljaGFyICpwYWdlID0gKGNoYXIqKSBSVkEoci0+VmlydHVhbEFkZHJlc3MpOwoJCWludCBjb3VudCA9IChyLT5TaXplT2ZCbG9jayAtIDgpLzI7CgkJaW50IGk7CgkJVFJBQ0VfKGZpeHVwKSgiJXggcmVsb2NhdGlvbnMgZm9yIHBhZ2UgJWx4XG4iLAoJCQljb3VudCwgci0+VmlydHVhbEFkZHJlc3MpOwoJCS8qIHBhdGNoaW5nIGluIHJldmVyc2Ugb3JkZXIgKi8KCQlmb3IoaT0wO2k8Y291bnQ7aSsrKQoJCXsKCQkJaW50IG9mZnNldCA9IHItPlR5cGVPZmZzZXRbaV0gJiAweEZGRjsKCQkJaW50IHR5cGUgPSByLT5UeXBlT2Zmc2V0W2ldID4+IDEyOwoJCQlUUkFDRV8oZml4dXApKCJwYXRjaGluZyAleCB0eXBlICV4XG4iLCBvZmZzZXQsIHR5cGUpOwoJCQlzd2l0Y2godHlwZSkKCQkJewoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9BQlNPTFVURTogYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0g6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGhkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9MT1c6CgkJCQkqKHNob3J0KikocGFnZStvZmZzZXQpICs9IGxkZWx0YTsKCQkJCWJyZWFrOwoJCQljYXNlIElNQUdFX1JFTF9CQVNFRF9ISUdITE9XOgoJCQkJKihpbnQqKShwYWdlK29mZnNldCkgKz0gZGVsdGE7CgkJCQkvKiBGSVhNRTogaWYgdGhpcyBpcyBhbiBleHBvcnRlZCBhZGRyZXNzLCBmaXJlIHVwIGVuaGFuY2VkIGxvZ2ljICovCgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSEFESjoKCQkJCUZJWE1FKCJEb24ndCBrbm93IHdoYXQgdG8gZG8gd2l0aCBJTUFHRV9SRUxfQkFTRURfSElHSEFESlxuIik7CgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfTUlQU19KTVBBRERSOgoJCQkJRklYTUUoIklzIHRoaXMgYSBNSVBTIG1hY2hpbmUgPz8/XG4iKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJRklYTUUoIlVua25vd24gZml4dXAgdHlwZVxuIik7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyICsgci0+U2l6ZU9mQmxvY2spOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqIAogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvciAKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXRzIHdoaWNoIGFyZSBwYWdlLWFsaWduZWQuCiAqCiAqIEJVVCB3ZSBoYXZlIHRvIG1hcCB0aGUgd2hvbGUgaW1hZ2UgYW55d2F5LCBmb3IgV2luMzIgcHJvZ3JhbXMgc29tZXRpbWVzCiAqIHdhbnQgdG8gYWNjZXNzIHRoZW0uIChITU9EVUxFMzIgcG9pbnQgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8KSE1PRFVMRSBQRV9Mb2FkSW1hZ2UoIEhBTkRMRSBoRmlsZSwgTFBDU1RSIGZpbGVuYW1lLCBXT1JEICp2ZXJzaW9uICkKewogICAgSE1PRFVMRQloTW9kdWxlOwogICAgSEFORExFCW1hcHBpbmc7CgogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQ7CiAgICBJTUFHRV9TRUNUSU9OX0hFQURFUiAqcGVfc2VjOwogICAgSU1BR0VfREFUQV9ESVJFQ1RPUlkgKmRpcjsKICAgIEJZX0hBTkRMRV9GSUxFX0lORk9STUFUSU9OIGJoZmk7CiAgICBpbnQJaSwgcmF3c2l6ZSwgbG93ZXN0X3ZhLCBsb3dlc3RfZmEsIHZtYV9zaXplLCBmaWxlX3NpemUgPSAwOwogICAgRFdPUkQgbG9hZF9hZGRyLCBhb2VwLCByZWxvYyA9IDA7CgogICAgLyogUmV0cmlldmUgZmlsZSBzaXplICovCiAgICBpZiAoIEdldEZpbGVJbmZvcm1hdGlvbkJ5SGFuZGxlKCBoRmlsZSwgJmJoZmkgKSApIAogICAgCWZpbGVfc2l6ZSA9IGJoZmkubkZpbGVTaXplTG93OyAvKiBGSVhNRTogNjQgYml0ICovCgogICAgLyogTWFwIHRoZSBQRSBmaWxlIHNvbWV3aGVyZSAqLwogICAgbWFwcGluZyA9IENyZWF0ZUZpbGVNYXBwaW5nQSggaEZpbGUsIE5VTEwsIFBBR0VfUkVBRE9OTFkgfCBTRUNfQ09NTUlULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAwLCBOVUxMICk7CiAgICBpZiAoIW1hcHBpbmcpCiAgICB7CiAgICAgICAgV0FSTigiQ3JlYXRlRmlsZU1hcHBpbmcgZXJyb3IgJWxkXG4iLCBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaE1vZHVsZSA9IChITU9EVUxFKU1hcFZpZXdPZkZpbGUoIG1hcHBpbmcsIEZJTEVfTUFQX1JFQUQsIDAsIDAsIDAgKTsKICAgIENsb3NlSGFuZGxlKCBtYXBwaW5nICk7CiAgICBpZiAoIWhNb2R1bGUpCiAgICB7CiAgICAgICAgV0FSTigiTWFwVmlld09mRmlsZSBlcnJvciAlbGRcbiIsIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBudCA9IFBFX0hFQURFUiggaE1vZHVsZSApOwoKICAgIC8qIENoZWNrIHNpZ25hdHVyZSAqLwogICAgaWYgKCBudC0+U2lnbmF0dXJlICE9IElNQUdFX05UX1NJR05BVFVSRSApCiAgICB7CiAgICAgICAgV0FSTigiaW1hZ2UgZG9lc24ndCBoYXZlIFBFIHNpZ25hdHVyZSwgYnV0IDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICAgICAgbnQtPlNpZ25hdHVyZSApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgLyogQ2hlY2sgYXJjaGl0ZWN0dXJlICovCiAgICBpZiAoIG50LT5GaWxlSGVhZGVyLk1hY2hpbmUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYgKQogICAgewogICAgICAgIE1FU1NBR0UoIlRyeWluZyB0byBsb2FkIFBFIGltYWdlIGZvciB1bnN1cHBvcnRlZCBhcmNoaXRlY3R1cmUgKCIpOwogICAgICAgIHN3aXRjaCAobnQtPkZpbGVIZWFkZXIuTWFjaGluZSkKICAgICAgICB7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfVU5LTk9XTjogTUVTU0FHRSgiVW5rbm93biIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9JODYwOiAgICBNRVNTQUdFKCJJODYwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IzMDAwOiAgIE1FU1NBR0UoIlIzMDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1I0MDAwOiAgIE1FU1NBR0UoIlI0MDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IxMDAwMDogIE1FU1NBR0UoIlIxMDAwMCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9BTFBIQTogICBNRVNTQUdFKCJBbHBoYSIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9QT1dFUlBDOiBNRVNTQUdFKCJQb3dlclBDIik7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6IE1FU1NBR0UoIlVua25vd24tJTA0eCIsIG50LT5GaWxlSGVhZGVyLk1hY2hpbmUpOyBicmVhazsKICAgICAgICB9CiAgICAgICAgTUVTU0FHRSgiKVxuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICAvKiBGaW5kIG91dCBob3cgbGFyZ2UgdGhpcyBleGVjdXRlYWJsZSBzaG91bGQgYmUgKi8KICAgIHBlX3NlYyA9IFBFX1NFQ1RJT05TKCBoTW9kdWxlICk7CiAgICByYXdzaXplID0gMDsgbG93ZXN0X3ZhID0gMHgxMDAwMDsgbG93ZXN0X2ZhID0gMHgxMDAwMDsKICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyspIAogICAgewogICAgICAgIGlmIChsb3dlc3RfdmEgPiBwZV9zZWNbaV0uVmlydHVhbEFkZHJlc3MpCiAgICAgICAgICAgbG93ZXN0X3ZhID0gcGVfc2VjW2ldLlZpcnR1YWxBZGRyZXNzOwogICAgCWlmIChwZV9zZWNbaV0uQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpCgkgICAgY29udGludWU7CiAgICAJaWYgKHBlX3NlY1tpXS5Qb2ludGVyVG9SYXdEYXRhIDwgbG93ZXN0X2ZhKQogICAgICAgICAgICBsb3dlc3RfZmEgPSBwZV9zZWNbaV0uUG9pbnRlclRvUmF3RGF0YTsKCWlmIChwZV9zZWNbaV0uUG9pbnRlclRvUmF3RGF0YStwZV9zZWNbaV0uU2l6ZU9mUmF3RGF0YSA+IHJhd3NpemUpCgkgICAgcmF3c2l6ZSA9IHBlX3NlY1tpXS5Qb2ludGVyVG9SYXdEYXRhK3BlX3NlY1tpXS5TaXplT2ZSYXdEYXRhOwogICAgfQogCiAgICAvKiBDaGVjayBmaWxlIHNpemUgKi8KICAgIGlmICggZmlsZV9zaXplICYmIGZpbGVfc2l6ZSA8IHJhd3NpemUgKQogICAgewogICAgICAgIEVSUigiUEUgbW9kdWxlIGlzIHRvbyBzbWFsbCAoaGVhZGVyOiAlZCwgZmlsZXNpemU6ICVkKSwgIgogICAgICAgICAgICAgICAgICAgICJwcm9iYWJseSB0cnVuY2F0ZWQgZG93bmxvYWQ/XG4iLCAKICAgICAgICAgICAgICAgICAgICByYXdzaXplLCBmaWxlX3NpemUgKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQoKICAgIC8qIENoZWNrIGVudHJ5cG9pbnQgYWRkcmVzcyAqLwogICAgYW9lcCA9IG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50OwogICAgaWYgKGFvZXAgJiYgKGFvZXAgPCBsb3dlc3RfdmEpKQogICAgICAgIEZJWE1FKCJXQVJOSU5HOiAnJXMnIGhhcyBhbiBpbnZhbGlkIGVudHJ5cG9pbnQgKDB4JTA4bHgpICIKICAgICAgICAgICAgICAgICAgICAgICJiZWxvdyB0aGUgZmlyc3QgdmlydHVhbCBhZGRyZXNzICgweCUwOHgpICIKICAgICAgICAgICAgICAgICAgICAgICIocG9zc2libGUgVmlydXMgSW5mZWN0aW9uIG9yIGJyb2tlbiBiaW5hcnkpIVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgYW9lcCwgbG93ZXN0X3ZhICk7CgoKICAgIC8qIEZJWE1FOiAgSGFjayEgIFdoaWxlIHdlIGRvbid0IHJlYWxseSBzdXBwb3J0IHNoYXJlZCBzZWN0aW9ucyB5ZXQsCiAgICAgKiAgICAgICAgIHRoaXMgY2hlY2tzIGZvciB0aG9zZSBzcGVjaWFsIGNhc2VzIHdoZXJlIHRoZSB3aG9sZSBETEwKICAgICAqICAgICAgICAgY29uc2lzdHMgb25seSBvZiBzaGFyZWQgc2VjdGlvbnMgYW5kIGlzIG1hcHBlZCBpbnRvIHRoZQogICAgICogICAgICAgICBzaGFyZWQgYWRkcmVzcyBzcGFjZSA+IDJHQi4gIEluIHRoaXMgY2FzZSwgd2UgYXNzdW1lIHRoYXQKICAgICAqICAgICAgICAgdGhlIG1vZHVsZSBnb3QgbWFwcGVkIGF0IGl0cyBiYXNlIGFkZHJlc3MuIFRodXMgd2Ugc2ltcGx5CiAgICAgKiAgICAgICAgIGNoZWNrIHdoZXRoZXIgdGhlIG1vZHVsZSBoYXMgYWN0dWFsbHkgYmVlbiBtYXBwZWQgdGhlcmUKICAgICAqICAgICAgICAgYW5kIHVzZSBpdCwgaWYgc28uICBUaGlzIGlzIG5lZWRlZCB0byBnZXQgV2luOTUgVVNFUjMyLkRMTAogICAgICogICAgICAgICB0byB3b3JrICh1bnRpbCB3ZSBzdXBwb3J0IHNoYXJlZCBzZWN0aW9ucyBwcm9wZXJseSkuCiAgICAgKi8KCiAgICBpZiAoIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgJiAweDgwMDAwMDAwICkKICAgIHsKICAgICAgICBITU9EVUxFIHNoYXJlZE1vZCA9IChITU9EVUxFKW50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7IAogICAgICAgIElNQUdFX05UX0hFQURFUlMgKnNoYXJlZE50ID0gKFBJTUFHRV9OVF9IRUFERVJTKQogICAgICAgICAgICAgICAoIChMUEJZVEUpc2hhcmVkTW9kICsgKChMUEJZVEUpbnQgLSAoTFBCWVRFKWhNb2R1bGUpICk7CgogICAgICAgIC8qIFdlbGwsIHRoaXMgY2hlY2sgaXMgbm90IHJlYWxseSBjb21wcmVoZW5zaXZlLCAKICAgICAgICAgICBidXQgc2hvdWxkIGJlIGdvb2QgZW5vdWdoIGZvciBub3cgLi4uICovCiAgICAgICAgaWYgKCAgICAhSXNCYWRSZWFkUHRyKCAoTFBCWVRFKXNoYXJlZE1vZCwgc2l6ZW9mKElNQUdFX0RPU19IRUFERVIpICkKICAgICAgICAgICAgICYmIG1lbWNtcCggKExQQllURSlzaGFyZWRNb2QsIChMUEJZVEUpaE1vZHVsZSwgc2l6ZW9mKElNQUdFX0RPU19IRUFERVIpICkgPT0gMAogICAgICAgICAgICAgJiYgIUlzQmFkUmVhZFB0ciggc2hhcmVkTnQsIHNpemVvZihJTUFHRV9OVF9IRUFERVJTKSApCiAgICAgICAgICAgICAmJiBtZW1jbXAoIHNoYXJlZE50LCBudCwgc2l6ZW9mKElNQUdFX05UX0hFQURFUlMpICkgPT0gMCApCiAgICAgICAgewogICAgICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgICAgICAgICByZXR1cm4gc2hhcmVkTW9kOwogICAgICAgIH0KICAgIH0KCgogICAgLyogQWxsb2NhdGUgbWVtb3J5IGZvciBtb2R1bGUgKi8KICAgIGxvYWRfYWRkciA9IG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICB2bWFfc2l6ZSA9IGNhbGNfdm1hX3NpemUoIGhNb2R1bGUgKTsKCiAgICBsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCAodm9pZCopbG9hZF9hZGRyLCB2bWFfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FTV9SRVNFUlZFIHwgTUVNX0NPTU1JVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBBR0VfRVhFQ1VURV9SRUFEV1JJVEUgKTsKICAgIGlmIChsb2FkX2FkZHIgPT0gMCkgCiAgICB7CiAgICAgICAgLyogV2UgbmVlZCB0byBwZXJmb3JtIGJhc2UgcmVsb2NhdGlvbnMgKi8KCWRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0M7CiAgICAgICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICAgICAgcmVsb2MgPSBkaXItPlZpcnR1YWxBZGRyZXNzOwogICAgICAgIGVsc2UgCiAgICAgICAgewogICAgICAgICAgICBGSVhNRSgKICAgICAgICAgICAgICAgICAgICJGQVRBTDogTmVlZCB0byByZWxvY2F0ZSAlcywgYnV0IG5vIHJlbG9jYXRpb24gcmVjb3JkcyBwcmVzZW50ICglcykuIFRyeSB0byBydW4gdGhhdCBmaWxlIGRpcmVjdGx5ICFcbiIsCiAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwKICAgICAgICAgICAgICAgICAgIChudC0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MmSU1BR0VfRklMRV9SRUxPQ1NfU1RSSVBQRUQpPwogICAgICAgICAgICAgICAgICAgInN0cmlwcGVkIGR1cmluZyBsaW5rIiA6ICJ1bmtub3duIHJlYXNvbiIgKTsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CgogICAgICAgIC8qIEZJWE1FOiBJZiB3ZSBuZWVkIHRvIHJlbG9jYXRlIGEgc3lzdGVtIERMTCAoYmFzZSA+IDJHQikgd2Ugc2hvdWxkCiAgICAgICAgICogICAgICAgIHJlYWxseSBtYWtlIHN1cmUgdGhhdCB0aGUgKm5ldyogYmFzZSBhZGRyZXNzIGlzIGFsc28gPiAyR0IuCiAgICAgICAgICogICAgICAgIFNvbWUgRExMcyByZWFsbHkgY2hlY2sgdGhlIE1TQiBvZiB0aGUgbW9kdWxlIGhhbmRsZSA6LS8KICAgICAgICAgKi8KICAgICAgICBpZiAoIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UgJiAweDgwMDAwMDAwICkKICAgICAgICAgICAgRVJSKCAiRm9yY2VkIHRvIHJlbG9jYXRlIHN5c3RlbSBETEwgKGJhc2UgPiAyR0IpLiBUaGlzIGlzIG5vdCBnb29kLlxuIiApOwoKICAgICAgICBsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCBOVUxMLCB2bWFfc2l6ZSwKCQkJCQkgTUVNX1JFU0VSVkUgfCBNRU1fQ09NTUlULAoJCQkJCSBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CglpZiAoIWxvYWRfYWRkcikgewogICAgICAgICAgICBGSVhNRV8od2luMzIpKAogICAgICAgICAgICAgICAgICAgIkZBVEFMOiBDb3VsZG4ndCBsb2FkIG1vZHVsZSAlcyAob3V0IG9mIG1lbW9yeSwgJWQgbmVlZGVkKSFcbiIsIGZpbGVuYW1lLCB2bWFfc2l6ZSk7CiAgICAgICAgICAgIGdvdG8gZXJyb3I7Cgl9CiAgICB9CgogICAgVFJBQ0UoIkxvYWQgYWRkciBpcyAlbHggKGJhc2UgJWx4KSwgcmFuZ2UgJXhcbiIsCiAgICAgICAgICBsb2FkX2FkZHIsIG50LT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2UsIHZtYV9zaXplICk7CiAgICBUUkFDRV8oc2VnbWVudCkoIkxvYWRpbmcgJXMgYXQgJWx4LCByYW5nZSAleFxuIiwKICAgICAgICAgICAgICAgICAgICBmaWxlbmFtZSwgbG9hZF9hZGRyLCB2bWFfc2l6ZSApOwoKICAgIC8qIFN0b3JlIHRoZSBOVCBoZWFkZXIgYXQgdGhlIGxvYWQgYWRkciAqLwogICAgKihQSU1BR0VfRE9TX0hFQURFUilsb2FkX2FkZHIgPSAqKFBJTUFHRV9ET1NfSEVBREVSKWhNb2R1bGU7CiAgICAqUEVfSEVBREVSKCBsb2FkX2FkZHIgKSA9ICpudDsKICAgIG1lbWNweSggUEVfU0VDVElPTlMobG9hZF9hZGRyKSwgUEVfU0VDVElPTlMoaE1vZHVsZSksCiAgICAgICAgICAgIHNpemVvZihJTUFHRV9TRUNUSU9OX0hFQURFUikgKiBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zICk7CiNpZiAwCiAgICAvKiBDb3BpZXMgYWxsIHN0dWZmIHVwIHRvIHRoZSBmaXJzdCBzZWN0aW9uLiBJbmNsdWRpbmcgd2luMzIgdmlydXNlcy4gKi8KICAgIG1lbWNweSggbG9hZF9hZGRyLCBoTW9kdWxlLCBsb3dlc3RfZmEgKTsKI2VuZGlmCgogICAgLyogQ29weSBzZWN0aW9ucyBpbnRvIG1vZHVsZSBpbWFnZSAqLwogICAgcGVfc2VjID0gUEVfU0VDVElPTlMoIGhNb2R1bGUgKTsKICAgIGZvciAoaSA9IDA7IGkgPCBudC0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyssIHBlX3NlYysrKQogICAgewogICAgICAgIC8qIG1lbWNweSBvbmx5IG5vbi1CU1Mgc2VnbWVudHMgKi8KICAgICAgICAvKiBGSVhNRTogdGhpcyBzaG91bGQgYmUgZG9uZSBieSBtbWFwKC4uTUFQX1BSSVZBVEV8TUFQX0ZJWEVELi4pCiAgICAgICAgICogYnV0IGl0IGlzIG5vdCBwb3NzaWJsZSBmb3IgKGF0IGxlYXN0KSBMaW51eCBuZWVkcwogICAgICAgICAqIGEgcGFnZS1hbGlnbmVkIG9mZnNldC4KICAgICAgICAgKi8KICAgICAgICBpZighKHBlX3NlYy0+Q2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpKQogICAgICAgICAgICBtZW1jcHkoKGNoYXIqKVJWQShwZV9zZWMtPlZpcnR1YWxBZGRyZXNzKSwKICAgICAgICAgICAgICAgICAgIChjaGFyKikoaE1vZHVsZSArIHBlX3NlYy0+UG9pbnRlclRvUmF3RGF0YSksCiAgICAgICAgICAgICAgICAgICBwZV9zZWMtPlNpemVPZlJhd0RhdGEpOwojaWYgMAogICAgICAgIC8qIG5vdCBuZWVkZWQsIG1lbW9yeSBpcyB6ZXJvICovCiAgICAgICAgaWYoc3RyY21wKHBlX3NlYy0+TmFtZSwgIi5ic3MiKSA9PSAwKQogICAgICAgICAgICBtZW1zZXQoKHZvaWQgKilSVkEocGVfc2VjLT5WaXJ0dWFsQWRkcmVzcyksIDAsIAogICAgICAgICAgICAgICAgICAgcGVfc2VjLT5NaXNjLlZpcnR1YWxTaXplID8KICAgICAgICAgICAgICAgICAgIHBlX3NlYy0+TWlzYy5WaXJ0dWFsU2l6ZSA6CiAgICAgICAgICAgICAgICAgICBwZV9zZWMtPlNpemVPZlJhd0RhdGEpOwojZW5kaWYKICAgIH0KCiAgICAvKiBQZXJmb3JtIGJhc2UgcmVsb2NhdGlvbiwgaWYgbmVjZXNzYXJ5ICovCiAgICBpZiAoIHJlbG9jICkKICAgICAgICBkb19yZWxvY2F0aW9ucyggbG9hZF9hZGRyLCAoSU1BR0VfQkFTRV9SRUxPQ0FUSU9OICopUlZBKHJlbG9jKSApOwoKICAgIC8qIEdldCBleHBlY3RlZCBPUyAvIFN1YnN5c3RlbSB2ZXJzaW9uICovCiAgICAqdmVyc2lvbiA9ICAgKCAobnQtPk9wdGlvbmFsSGVhZGVyLk1ham9yU3Vic3lzdGVtVmVyc2lvbiAmIDB4ZmYpIDw8IDggKQogICAgICAgICAgICAgICB8ICAgKG50LT5PcHRpb25hbEhlYWRlci5NaW5vclN1YnN5c3RlbVZlcnNpb24gJiAweGZmKTsKCiAgICAvKiBXZSBkb24ndCBuZWVkIHRoZSBvcmlnbmFsIG1hcHBpbmcgYW55IG1vcmUgKi8KICAgIFVubWFwVmlld09mRmlsZSggKExQVk9JRCloTW9kdWxlICk7CiAgICByZXR1cm4gKEhNT0RVTEUpbG9hZF9hZGRyOwoKZXJyb3I6CiAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICAgICBQRV9DcmVhdGVNb2R1bGUKICoKICogQ3JlYXRlIFdJTkVfTU9EUkVGIHN0cnVjdHVyZSBmb3IgbG9hZGVkIEhNT0RVTEUzMiwgbGluayBpdCBpbnRvCiAqIHByb2Nlc3MgbW9kcmVmX2xpc3QsIGFuZCBmaXh1cCBhbGwgaW1wb3J0cy4KICoKICogTm90ZTogaE1vZHVsZSBtdXN0IHBvaW50IHRvIGEgY29ycmVjdGx5IGFsbG9jYXRlZCBQRSBpbWFnZSwKICogICAgICAgd2l0aCBiYXNlIHJlbG9jYXRpb25zIGFwcGxpZWQ7IHRoZSAxNi1iaXQgZHVtbXkgbW9kdWxlCiAqICAgICAgIGFzc29jaWF0ZWQgdG8gaE1vZHVsZSBtdXN0IGFscmVhZHkgZXhpc3QuCiAqCiAqIE5vdGU6IFRoaXMgcm91dGluZSBtdXN0IGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlCiAqICAgICAgIHByb2Nlc3MgdGhhdCBpcyB0byBvd24gdGhlIG1vZHVsZSB0byBiZSBjcmVhdGVkLgogKi8KV0lORV9NT0RSRUYgKlBFX0NyZWF0ZU1vZHVsZSggSE1PRFVMRSBoTW9kdWxlLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDU1RSIGZpbGVuYW1lLCBEV09SRCBmbGFncywgQk9PTCBidWlsdGluICkKewogICAgRFdPUkQgbG9hZF9hZGRyID0gKERXT1JEKWhNb2R1bGU7ICAvKiBmb3IgUlZBICovCiAgICBJTUFHRV9OVF9IRUFERVJTICpudCA9IFBFX0hFQURFUihoTW9kdWxlKTsKICAgIElNQUdFX0RBVEFfRElSRUNUT1JZICpkaXI7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUiAqcGVfaW1wb3J0ID0gTlVMTDsKICAgIElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkgKnBlX2V4cG9ydCA9IE5VTEw7CiAgICBJTUFHRV9SRVNPVVJDRV9ESVJFQ1RPUlkgKnBlX3Jlc291cmNlID0gTlVMTDsKICAgIFdJTkVfTU9EUkVGICp3bTsKICAgIGludAlyZXN1bHQ7CgoKICAgIC8qIFJldHJpZXZlIERhdGFEaXJlY3RvcnkgZW50cmllcyAqLwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWFBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgICAgIHBlX2V4cG9ydCA9IChQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSlSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICAgICAgcGVfaW1wb3J0ID0gKFBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX1JFU09VUkNFOwogICAgaWYgKGRpci0+U2l6ZSkKICAgICAgICBwZV9yZXNvdXJjZSA9IChQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKVJWQShkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJTZWN1cml0eSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0MgaGFuZGxlZCBpbiBQRV9Mb2FkSW1hZ2UgKi8KICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVRyBoYW5kbGVkIGJ5IGRlYnVnZ2VyICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFQlVHOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkRlYnVnIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPUFlSSUdIVDsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iICk7CgogICAgLyogSU1BR0VfRElSRUNUT1JZX0VOVFJZX1RMUyBoYW5kbGVkIGluIFBFX1Rsc0luaXQgKi8KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUc7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiTG9hZCBDb25maWd1cmF0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJCb3VuZCBJbXBvcnQgZGlyZWN0b3J5IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUOwogICAgaWYgKGRpci0+U2l6ZSkgVFJBQ0UoIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0RFTEFZX0lNUE9SVDsKICAgIGlmIChkaXItPlNpemUpCiAgICB7CgkJVFJBQ0UoIkRlbGF5ZWQgaW1wb3J0LCBzdHViIGNhbGxzIExvYWRMaWJyYXJ5XG4iICk7CgkJLyoKCQkgKiBOb3RoaW5nIHRvIGRvIGhlcmUuCgkJICovCgojaWZkZWYgSW1nRGVsYXlEZXNjcgoJCS8qCgkJICogVGhpcyBjb2RlIGlzIHVzZWZ1bCB0byBvYnNlcnZlIHdoYXQgdGhlIGhlY2sgaXMgZ29pbmcgb24uCgkJICovCgkJewoJCUltZ0RlbGF5RGVzY3IgKnBlX2RlbGF5ID0gTlVMTDsKICAgICAgICBwZV9kZWxheSA9IChQSW1nRGVsYXlEZXNjcilSVkEoZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPmdyQXR0cnMgPSAlMDh4XG4iLCBwZV9kZWxheS0+Z3JBdHRycyk7CiAgICAgICAgVFJBQ0VfKGRlbGF5aGxwKSgicGVfZGVsYXktPnN6TmFtZSA9ICVzXG4iLCBwZV9kZWxheS0+c3pOYW1lKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJQVQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wSU5UID0gJTA4eFxuIiwgcGVfZGVsYXktPnBJTlQpOwogICAgICAgIFRSQUNFXyhkZWxheWhscCkoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+cFVubG9hZElBVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wVW5sb2FkSUFUKTsKICAgICAgICBUUkFDRV8oZGVsYXlobHApKCJwZV9kZWxheS0+ZHdUaW1lU3RhbXAgPSAlMDh4XG4iLCBwZV9kZWxheS0+ZHdUaW1lU3RhbXApOwogICAgICAgIH0KI2VuZGlmIC8qIEltZ0RlbGF5RGVzY3IgKi8KCX0KCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfQ09NX0RFU0NSSVBUT1I7CiAgICBpZiAoZGlyLT5TaXplKSBGSVhNRSgiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5KzE1OwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIgKTsKCgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICB3bSA9IChXSU5FX01PRFJFRiAqKUhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKCp3bSkgKTsKICAgIHdtLT5tb2R1bGUgPSBoTW9kdWxlOwoKICAgIGlmICggYnVpbHRpbiApIAogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9JTlRFUk5BTDsKICAgIGlmICggZmxhZ3MgJiBET05UX1JFU09MVkVfRExMX1JFRkVSRU5DRVMgKQogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUzsKICAgIGlmICggZmxhZ3MgJiBMT0FEX0xJQlJBUllfQVNfREFUQUZJTEUgKQogICAgICAgIHdtLT5mbGFncyB8PSBXSU5FX01PRFJFRl9MT0FEX0FTX0RBVEFGSUxFOwoKICAgIHdtLT50eXBlID0gTU9EVUxFMzJfUEU7CiAgICB3bS0+YmluZm10LnBlLnBlX2V4cG9ydCA9IHBlX2V4cG9ydDsKICAgIHdtLT5iaW5mbXQucGUucGVfaW1wb3J0ID0gcGVfaW1wb3J0OwogICAgd20tPmJpbmZtdC5wZS5wZV9yZXNvdXJjZSA9IHBlX3Jlc291cmNlOwogICAgd20tPmJpbmZtdC5wZS50bHNpbmRleCA9IC0xOwoKICAgIHdtLT5maWxlbmFtZSA9IEhFQVBfc3RyZHVwQSggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZmlsZW5hbWUgKTsKICAgIHdtLT5tb2RuYW1lID0gc3RycmNociggd20tPmZpbGVuYW1lLCAnXFwnICk7CiAgICBpZiAoIXdtLT5tb2RuYW1lKSB3bS0+bW9kbmFtZSA9IHdtLT5maWxlbmFtZTsKICAgIGVsc2Ugd20tPm1vZG5hbWUrKzsKCiAgICByZXN1bHQgPSBHZXRTaG9ydFBhdGhOYW1lQSggd20tPmZpbGVuYW1lLCBOVUxMLCAwICk7CiAgICB3bS0+c2hvcnRfZmlsZW5hbWUgPSAoY2hhciAqKUhlYXBBbGxvYyggR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcmVzdWx0KzEgKTsKICAgIEdldFNob3J0UGF0aE5hbWVBKCB3bS0+ZmlsZW5hbWUsIHdtLT5zaG9ydF9maWxlbmFtZSwgcmVzdWx0KzEgKTsKICAgIHdtLT5zaG9ydF9tb2RuYW1lID0gc3RycmNociggd20tPnNob3J0X2ZpbGVuYW1lLCAnXFwnICk7CiAgICBpZiAoIXdtLT5zaG9ydF9tb2RuYW1lKSB3bS0+c2hvcnRfbW9kbmFtZSA9IHdtLT5zaG9ydF9maWxlbmFtZTsKICAgIGVsc2Ugd20tPnNob3J0X21vZG5hbWUrKzsKCiAgICAvKiBMaW5rIE1PRFJFRiBpbnRvIHByb2Nlc3MgbGlzdCAqLwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCAmUFJPQ0VTU19DdXJyZW50KCktPmNyaXRfc2VjdGlvbiApOwoKICAgIHdtLT5uZXh0ID0gUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0OwogICAgUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0ID0gd207CiAgICBpZiAoIHdtLT5uZXh0ICkgd20tPm5leHQtPnByZXYgPSB3bTsKCiAgICBpZiAoICAgICEoIG50LT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMICkKICAgICAgICAgJiYgISggd20tPmZsYWdzICYgV0lORV9NT0RSRUZfTE9BRF9BU19EQVRBRklMRSApICkKCiAgICB7CiAgICAgICAgaWYgKCBQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiApCiAgICAgICAgICAgIEZJWE1FKCAiVHJ5aW5nIHRvIGxvYWQgc2Vjb25kIC5FWEUgZmlsZTogJXNcbiIsIGZpbGVuYW1lICk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBQUk9DRVNTX0N1cnJlbnQoKS0+ZXhlX21vZHJlZiA9IHdtOwogICAgfQoKICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCAmUFJPQ0VTU19DdXJyZW50KCktPmNyaXRfc2VjdGlvbiApOwoKCiAgICAvKiBEdW1wIEV4cG9ydHMgKi8KCiAgICBpZiAoIHBlX2V4cG9ydCApCiAgICAgICAgZHVtcF9leHBvcnRzKCBoTW9kdWxlICk7CgogICAgLyogRml4dXAgSW1wb3J0cyAqLwoKICAgIGlmICggICAgcGVfaW1wb3J0CiAgICAgICAgICYmICEoIHdtLT5mbGFncyAmIFdJTkVfTU9EUkVGX0xPQURfQVNfREFUQUZJTEUgKQogICAgICAgICAmJiAhKCB3bS0+ZmxhZ3MgJiBXSU5FX01PRFJFRl9ET05UX1JFU09MVkVfUkVGUyApIAogICAgICAgICAmJiBmaXh1cF9pbXBvcnRzKCB3bSApICkgCiAgICB7CiAgICAgICAgLyogcmVtb3ZlIGVudHJ5IGZyb20gbW9kcmVmIGNoYWluICovCiAgICAgICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgogICAgICAgIGlmICggIXdtLT5wcmV2ICkKICAgICAgICAgICAgUFJPQ0VTU19DdXJyZW50KCktPm1vZHJlZl9saXN0ID0gd20tPm5leHQ7CiAgICAgICAgZWxzZQogICAgICAgICAgICB3bS0+cHJldi0+bmV4dCA9IHdtLT5uZXh0OwoKICAgICAgICBpZiAoIHdtLT5uZXh0ICkgd20tPm5leHQtPnByZXYgPSB3bS0+cHJldjsKICAgICAgICB3bS0+bmV4dCA9IHdtLT5wcmV2ID0gTlVMTDsKCiAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oICZQUk9DRVNTX0N1cnJlbnQoKS0+Y3JpdF9zZWN0aW9uICk7CgogICAgICAgIC8qIEZJWE1FOiB0aGVyZSBhcmUgc2V2ZXJhbCBtb3JlIGRhbmdsaW5nIHJlZmVyZW5jZXMKICAgICAgICAgKiBsZWZ0LiBJbmNsdWRpbmcgZGxscyBsb2FkZWQgYnkgdGhpcyBkbGwgYmVmb3JlIHRoZQogICAgICAgICAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCiAgICAgICAgICogY3VycmVudCBzdHJ1Y3R1cmUgYW5kIHdlIGNhbiBsZWF2ZSBpdCB0aGVtIGx5aW5nCiAgICAgICAgICogYXJvdW5kIHdpdGggbm8gcHJvYmxlbXMsIHNvIHdlIGRvbid0IGNhcmUuCiAgICAgICAgICogQXMgdGhlc2UgbWlnaHQgcmVmZXJlbmNlIG91ciB3bSwgd2UgZG9uJ3QgZnJlZSBpdC4KICAgICAgICAgKi8KICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKi8KV0lORV9NT0RSRUYgKlBFX0xvYWRMaWJyYXJ5RXhBIChMUENTVFIgbmFtZSwgRFdPUkQgZmxhZ3MsIERXT1JEICplcnIpCnsKCUhNT0RVTEUJCWhNb2R1bGUzMjsKCUhNT0RVTEUxNgloTW9kdWxlMTY7CglORV9NT0RVTEUJKnBNb2R1bGU7CglXSU5FX01PRFJFRgkqd207CgljaGFyICAgICAgICAJZmlsZW5hbWVbMjU2XTsKCUhBTkRMRQkJaEZpbGU7CglXT1JECQl2ZXJzaW9uID0gMDsKCgkvKiBTZWFyY2ggZm9yIGFuZCBvcGVuIFBFIGZpbGUgKi8KCWlmICggU2VhcmNoUGF0aEEoIE5VTEwsIG5hbWUsICIuRExMIiwgCgkgICAgICAgICAgICAgICAgICBzaXplb2YoZmlsZW5hbWUpLCBmaWxlbmFtZSwgTlVMTCApID09IDAgKQoJewoJCSplcnIgPSBFUlJPUl9GSUxFX05PVF9GT1VORDsKCQlyZXR1cm4gTlVMTDsKCX0KICAgICAgIAoJaEZpbGUgPSBDcmVhdGVGaWxlQSggZmlsZW5hbWUsIEdFTkVSSUNfUkVBRCwgRklMRV9TSEFSRV9SRUFELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIE9QRU5fRVhJU1RJTkcsIDAsIC0xICk7CglpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkKCXsKCQkqZXJyID0gRVJST1JfRklMRV9OT1RfRk9VTkQ7CgkJcmV0dXJuIE5VTEw7Cgl9CgkKCS8qIExvYWQgUEUgbW9kdWxlICovCgloTW9kdWxlMzIgPSBQRV9Mb2FkSW1hZ2UoIGhGaWxlLCBmaWxlbmFtZSwgJnZlcnNpb24gKTsKCUNsb3NlSGFuZGxlKCBoRmlsZSApOwoJaWYgKCFoTW9kdWxlMzIpCgl7CgkJKmVyciA9IEVSUk9SX09VVE9GTUVNT1JZOwkvKiBOb3QgZW50aXJlbHkgcmlnaHQsIGJ1dCBnb29kIGVub3VnaCAqLwoJCXJldHVybiBOVUxMOwoJfQoKCS8qIENyZWF0ZSAxNi1iaXQgZHVtbXkgbW9kdWxlICovCglpZiAoKGhNb2R1bGUxNiA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggZmlsZW5hbWUsIHZlcnNpb24gKSkgPCAzMikKCXsKCQkqZXJyID0gKERXT1JEKWhNb2R1bGUxNjsJLyogVGhpcyBzaG91bGQgZ2l2ZSB0aGUgY29ycmVjdCBlcnJvciAqLwoJCXJldHVybiBOVUxMOwoJfQoJcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUxNiApOwoJcE1vZHVsZS0+ZmxhZ3MgICAgPSBORV9GRkxBR1NfTElCTU9EVUxFIHwgTkVfRkZMQUdTX1NJTkdMRURBVEEgfCBORV9GRkxBR1NfV0lOMzI7CglwTW9kdWxlLT5tb2R1bGUzMiA9IGhNb2R1bGUzMjsKCgkvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwoJaWYgKCAhKHdtID0gUEVfQ3JlYXRlTW9kdWxlKCBoTW9kdWxlMzIsIGZpbGVuYW1lLCBmbGFncywgRkFMU0UgKSkgKQoJewoJCUVSUiggImNhbid0IGxvYWQgJXNcbiIsIGZpbGVuYW1lICk7CgkJRnJlZUxpYnJhcnkxNiggaE1vZHVsZTE2ICk7CgkJKmVyciA9IEVSUk9SX09VVE9GTUVNT1JZOwoJCXJldHVybiBOVUxMOwoJfQoKCWlmICh3bS0+YmluZm10LnBlLnBlX2V4cG9ydCkKCQlTTk9PUF9SZWdpc3RlckRMTCh3bS0+bW9kdWxlLHdtLT5tb2RuYW1lLHdtLT5iaW5mbXQucGUucGVfZXhwb3J0LT5OdW1iZXJPZkZ1bmN0aW9ucyk7CgoJKmVyciA9IDA7CglyZXR1cm4gd207Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJUEVfVW5sb2FkTGlicmFyeQogKgogKiBVbmxvYWQgdGhlIGxpYnJhcnkgdW5tYXBwaW5nIHRoZSBpbWFnZSBhbmQgZnJlZWluZyB0aGUgbW9kcmVmIHN0cnVjdHVyZS4KICovCnZvaWQgUEVfVW5sb2FkTGlicmFyeShXSU5FX01PRFJFRiAqd20pCnsKICAgIERXT1JEIHZtYV9zaXplID0gY2FsY192bWFfc2l6ZSggd20tPm1vZHVsZSApOwogICAgVmlydHVhbEZyZWUoIChMUFZPSUQpd20tPm1vZHVsZSwgdm1hX3NpemUsIE1FTV9SRUxFQVNFICk7CgogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdtLT5maWxlbmFtZSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdtLT5zaG9ydF9maWxlbmFtZSApOwogICAgSGVhcEZyZWUoIEdldFByb2Nlc3NIZWFwKCksIDAsIHdtICk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBMb2FkIHRoZSBQRSBtYWluIC5FWEUuIEFsbCBvdGhlciBsb2FkaW5nIGlzIGRvbmUgYnkgUEVfTG9hZExpYnJhcnlFeEEKICogRklYTUU6IHRoaXMgZnVuY3Rpb24gc2hvdWxkIHVzZSBQRV9Mb2FkTGlicmFyeUV4QSwgYnV0IGN1cnJlbnRseSBjYW4ndAogKiBkdWUgdG8gdGhlIFBST0NFU1NfQ3JlYXRlIHN0dWZmLgogKi8KQk9PTCBQRV9DcmVhdGVQcm9jZXNzKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgTFBDU1RSIGNtZF9saW5lLCBMUENTVFIgZW52LCAKICAgICAgICAgICAgICAgICAgICAgICBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgcHNhLCBMUFNFQ1VSSVRZX0FUVFJJQlVURVMgdHNhLAogICAgICAgICAgICAgICAgICAgICAgIEJPT0wgaW5oZXJpdCwgRFdPUkQgZmxhZ3MsIExQU1RBUlRVUElORk9BIHN0YXJ0dXAsCiAgICAgICAgICAgICAgICAgICAgICAgTFBQUk9DRVNTX0lORk9STUFUSU9OIGluZm8gKQp7CiAgICBXT1JEIHZlcnNpb24gPSAwOwogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKICAgIEhNT0RVTEUgaE1vZHVsZTMyOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwoKICAgIC8qIExvYWQgZmlsZSAqLwogICAgaWYgKCAoaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgZmlsZW5hbWUsICZ2ZXJzaW9uICkpIDwgMzIgKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggaE1vZHVsZTMyICk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQojaWYgMAogICAgaWYgKFBFX0hFQURFUihoTW9kdWxlMzIpLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKQogICAgewogICAgICAgIFNldExhc3RFcnJvciggMjAgKTsgIC8qIEZJWE1FOiBub3QgdGhlIHJpZ2h0IGVycm9yIGNvZGUgKi8KICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CiNlbmRpZgoKICAgIC8qIENyZWF0ZSAxNi1iaXQgZHVtbXkgbW9kdWxlICovCiAgICBpZiAoIChoTW9kdWxlMTYgPSBNT0RVTEVfQ3JlYXRlRHVtbXlNb2R1bGUoIGZpbGVuYW1lLCB2ZXJzaW9uICkpIDwgMzIgKSAKICAgIHsKICAgICAgICBTZXRMYXN0RXJyb3IoIGhNb2R1bGUxNiApOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KICAgIHBNb2R1bGUgPSAoTkVfTU9EVUxFICopR2xvYmFsTG9jazE2KCBoTW9kdWxlMTYgKTsKICAgIHBNb2R1bGUtPmZsYWdzICAgID0gTkVfRkZMQUdTX1dJTjMyOwogICAgcE1vZHVsZS0+bW9kdWxlMzIgPSBoTW9kdWxlMzI7CgogICAgLyogQ3JlYXRlIG5ldyBwcm9jZXNzICovCiAgICBpZiAoICFQUk9DRVNTX0NyZWF0ZSggcE1vZHVsZSwgY21kX2xpbmUsIGVudiwKICAgICAgICAgICAgICAgICAgICAgICAgICBwc2EsIHRzYSwgaW5oZXJpdCwgZmxhZ3MsIHN0YXJ0dXAsIGluZm8gKSApCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIC8qIE5vdGU6IFBFX0NyZWF0ZU1vZHVsZSBhbmQgdGhlIHJlbWFpbmluZyBwcm9jZXNzIGluaXRpYWxpemF0aW9uIHdpbGwKICAgICAgICAgICAgIGJlIGRvbmUgaW4gdGhlIGNvbnRleHQgb2YgdGhlIG5ldyBwcm9jZXNzLCBpbiBUQVNLX0NhbGxUb1N0YXJ0ICovCgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogUEVfVW5sb2FkSW1hZ2UgW2ludGVybmFsXQogKi8KaW50IFBFX1VubG9hZEltYWdlKCBITU9EVUxFIGhNb2R1bGUgKQp7CglGSVhNRSgic3R1Yi5cbiIpOwoJLyogZnJlZSByZXNvdXJjZXMsIGltYWdlLCB1bm1hcCAqLwoJcmV0dXJuIDE7Cn0KCi8qIENhbGxlZCBpZiB0aGUgbGlicmFyeSBpcyBsb2FkZWQgb3IgZnJlZWQuCiAqIE5PVEU6IGlmIGEgdGhyZWFkIGF0dGFjaGVzIGEgRExMLCB0aGUgY3VycmVudCB0aHJlYWQgd2lsbCBvbmx5IGRvCiAqIERMTF9QUk9DRVNTX0FUVEFDSC4gT25seSBuZXcgY3JlYXRlZCB0aHJlYWRzIGRvIERMTF9USFJFQURfQVRUQUNICiAqIChTREspCiAqLwpCT09MIFBFX0luaXRETEwoIFdJTkVfTU9EUkVGICp3bSwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQgKQp7CiAgICBCT09MIHJldHYgPSBUUlVFOwogICAgYXNzZXJ0KCB3bS0+dHlwZSA9PSBNT0RVTEUzMl9QRSApOwoKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKChQRV9IRUFERVIod20tPm1vZHVsZSktPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCiAgICAgICAgKFBFX0hFQURFUih3bS0+bW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIERMTEVOVFJZUFJPQyBlbnRyeSA9ICh2b2lkKilSVkFfUFRSKCB3bS0+bW9kdWxlLE9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgKTsKICAgICAgICBUUkFDRV8ocmVsYXkpKCJDYWxsVG8zMihlbnRyeXByb2M9JXAsbW9kdWxlPSUwOHgsdHlwZT0lbGQscmVzPSVwKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSwgd20tPm1vZHVsZSwgdHlwZSwgbHBSZXNlcnZlZCApOwoKICAgICAgICByZXR2ID0gZW50cnkoIHdtLT5tb2R1bGUsIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKICAgIH0KCiAgICByZXR1cm4gcmV0djsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglQRV9Jbml0VGxzCQkJKGludGVybmFsKQogKgogKiBJZiBpbmNsdWRlZCwgaW5pdGlhbGlzZXMgdGhlIHRocmVhZCBsb2NhbCBzdG9yYWdlcyBvZiBtb2R1bGVzLgogKiBQb2ludGVycyBpbiB0aG9zZSBzdHJ1Y3RzIGFyZSBub3QgUlZBcyBidXQgcmVhbCBwb2ludGVycyB3aGljaCBoYXZlIGJlZW4KICogcmVsb2NhdGVkIGJ5IGRvX3JlbG9jYXRpb25zKCkgYWxyZWFkeS4KICovCnN0YXRpYyBMUFZPSUQKX2ZpeHVwX2FkZHJlc3MoUElNQUdFX09QVElPTkFMX0hFQURFUiBvcHQsaW50IGRlbHRhLExQVk9JRCBhZGRyKSB7CglpZiAoCSgoRFdPUkQpYWRkcj5vcHQtPkltYWdlQmFzZSkgJiYKCQkoKERXT1JEKWFkZHI8b3B0LT5JbWFnZUJhc2Urb3B0LT5TaXplT2ZJbWFnZSkKCSkKCQkvKiB0aGUgYWRkcmVzcyBoYXMgbm90IGJlZW4gcmVsb2NhdGVkISAqLwoJCXJldHVybiAoTFBWT0lEKSgoKERXT1JEKWFkZHIpK2RlbHRhKTsKCWVsc2UKCQkvKiB0aGUgYWRkcmVzcyBoYXMgYmVlbiByZWxvY2F0ZWQgYWxyZWFkeSAqLwoJCXJldHVybiBhZGRyOwp9CnZvaWQgUEVfSW5pdFRscyggdm9pZCApCnsKCVdJTkVfTU9EUkVGCQkqd207CglQRV9NT0RSRUYJCSpwZW07CglJTUFHRV9OVF9IRUFERVJTCSpwZWg7CglEV09SRAkJCXNpemUsZGF0YXNpemU7CglMUFZPSUQJCQltZW07CglQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwogICAgICAgIGludCBkZWx0YTsKCQoJZm9yICh3bSA9IFBST0NFU1NfQ3VycmVudCgpLT5tb2RyZWZfbGlzdDt3bTt3bT13bS0+bmV4dCkgewoJCWlmICh3bS0+dHlwZSE9TU9EVUxFMzJfUEUpCgkJCWNvbnRpbnVlOwoJCXBlbSA9ICYod20tPmJpbmZtdC5wZSk7CgkJcGVoID0gUEVfSEVBREVSKHdtLT5tb2R1bGUpOwoJCWRlbHRhID0gd20tPm1vZHVsZSAtIHBlaC0+T3B0aW9uYWxIZWFkZXIuSW1hZ2VCYXNlOwoJCWlmICghcGVoLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKQoJCQljb250aW51ZTsKCQlwZGlyID0gKExQVk9JRCkod20tPm1vZHVsZSArIHBlaC0+T3B0aW9uYWxIZWFkZXIuCgkJCURhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpOwoJCQoJCQoJCWlmICggcGVtLT50bHNpbmRleCA9PSAtMSApIHsKCQkJTFBEV09SRCB4YWRkcjsKCQkJcGVtLT50bHNpbmRleCA9IFRsc0FsbG9jKCk7CgkJCXhhZGRyID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwKCQkJCQlwZGlyLT5BZGRyZXNzT2ZJbmRleAoJCQkpOwoJCQkqeGFkZHI9cGVtLT50bHNpbmRleDsKCQl9CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSwoTFBWT0lEKXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSksZGF0YXNpemUpOwoJCWlmIChwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpIHsKCQkgICAgIFBJTUFHRV9UTFNfQ0FMTEJBQ0sgKmNiczsgCgoJCSAgICAgY2JzID0gX2ZpeHVwX2FkZHJlc3MoJihwZWgtPk9wdGlvbmFsSGVhZGVyKSxkZWx0YSxwZGlyLT5BZGRyZXNzT2ZDYWxsQmFja3MpOwoJCSAgICAgaWYgKCpjYnMpCgkJICAgICAgIEZJWE1FKCJUTFMgQ2FsbGJhY2tzIGFyZW4ndCBnb2luZyB0byBiZSBjYWxsZWRcbiIpOwoJCX0KCgkJVGxzU2V0VmFsdWUoIHBlbS0+dGxzaW5kZXgsIG1lbSApOwoJfQp9Cgo=