LyogCiAqICBDb3B5cmlnaHQJMTk5NAlFcmljIFlvdW5kYWxlICYgRXJpayBCb3MKICogIENvcHlyaWdodAkxOTk1CU1hcnRpbiB2b24gTPZ3aXMKICogIENvcHlyaWdodCAgIDE5OTYgICAgTWFyY3VzIE1laXNzbmVyCiAqCiAqCWJhc2VkIG9uIEVyaWMgWW91bmRhbGUncyBwZS10ZXN0IGFuZDoKICoKICoJZnRwLm1pY3Jvc29mdC5jb206L3B1Yi9kZXZlbG9wZXIvTVNETi9DRDgvUEVGSUxFLlpJUAogKiBtYWtlIHRoYXQ6CiAqCWZ0cC5taWNyb3NvZnQuY29tOi9kZXZlbG9wci9NU0ROL09jdENEL1BFRklMRS5aSVAKICovCgojaW5jbHVkZSA8Y3R5cGUuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJmaWxlLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInRocmVhZC5oIgojaW5jbHVkZSAicGVfaW1hZ2UuaCIKI2luY2x1ZGUgIm1vZHVsZS5oIgojaW5jbHVkZSAiZ2xvYmFsLmgiCiNpbmNsdWRlICJ0YXNrLmgiCiNpbmNsdWRlICJsZHQuaCIKI2luY2x1ZGUgInN0ZGRlYnVnLmgiCiNpbmNsdWRlICJkZWJ1Zy5oIgojaW5jbHVkZSAieG1hbGxvYy5oIgoKc3RhdGljIHZvaWQgUEVfSW5pdERMTChQRV9NT0RSRUYqIG1vZHJlZiwgRFdPUkQgdHlwZSwgTFBWT0lEIGxwUmVzZXJ2ZWQpOwoKLyogY29udmVydCBQRSBpbWFnZSBWaXJ0dWFsQWRkcmVzcyB0byBSZWFsIEFkZHJlc3MgKi8KI2RlZmluZSBSVkEoeCkgKCh1bnNpZ25lZCBpbnQpbG9hZF9hZGRyKyh1bnNpZ25lZCBpbnQpKHgpKQoKdm9pZCBkdW1wX2V4cG9ydHMoIEhNT0RVTEUzMiBoTW9kdWxlICkKeyAKICBjaGFyCQkqTW9kdWxlOwogIGludAkJaSwgajsKICB1X3Nob3J0CSpvcmRpbmFsOwogIHVfbG9uZwkqZnVuY3Rpb24sKmZ1bmN0aW9uczsKICB1X2NoYXIJKipuYW1lOwogIHVuc2lnbmVkIGludCBsb2FkX2FkZHIgPSBoTW9kdWxlOwoKICBEV09SRCBydmFfc3RhcnQgPSBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCiAgICAgICAgICAgICAgICAgICAuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5WaXJ0dWFsQWRkcmVzczsKICBEV09SRCBydmFfZW5kID0gcnZhX3N0YXJ0ICsgUEVfSEVBREVSKGhNb2R1bGUpLT5PcHRpb25hbEhlYWRlcgogICAgICAgICAgICAgICAgICAgLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uU2l6ZTsKICBJTUFHRV9FWFBPUlRfRElSRUNUT1JZICpwZV9leHBvcnRzID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkqKVJWQShydmFfc3RhcnQpOwoKICBNb2R1bGUgPSAoY2hhciopUlZBKHBlX2V4cG9ydHMtPk5hbWUpOwogIGRwcmludGZfd2luMzIoc3RkZGViLCJcbioqKioqKipFWFBPUlQgREFUQSoqKioqKipcbk1vZHVsZSBuYW1lIGlzICVzLCAlbGQgZnVuY3Rpb25zLCAlbGQgbmFtZXNcbiIsIAoJIE1vZHVsZSwKCSBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywKCSBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzKTsKCiAgb3JkaW5hbD0odV9zaG9ydCopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwogIGZ1bmN0aW9ucz1mdW5jdGlvbj0odV9sb25nKikgUlZBKHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZT0odV9jaGFyKiopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7CgogIGRwcmludGZfd2luMzIoc3RkZGViLCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgZHByaW50Zl93aW4zMiggc3RkZGViLCIlNGxkICUwOGx4ICUwOHgiLAogICAgICAgICAgICAgICAgICAgICBpICsgcGVfZXhwb3J0cy0+QmFzZSwgKmZ1bmN0aW9uLCBSVkEoKmZ1bmN0aW9uKSApOwogICAgICAvKiBDaGVjayBpZiB3ZSBoYXZlIGEgbmFtZSBmb3IgaXQgKi8KICAgICAgZm9yIChqID0gMDsgaiA8IHBlX2V4cG9ydHMtPk51bWJlck9mTmFtZXM7IGorKykKICAgICAgICAgIGlmIChvcmRpbmFsW2pdID09IGkpCiAgICAgICAgICAgICAgZHByaW50Zl93aW4zMiggc3RkZGViLCAiICAlcyIsIChjaGFyKilSVkEobmFtZVtqXSkgKTsKICAgICAgaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9lbmQpKQoJICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIiAoZm9yd2FyZGVkIC0+ICVzKSIsIChjaGFyICopUlZBKCpmdW5jdGlvbikpOwogICAgICBkcHJpbnRmX3dpbjMyKCBzdGRkZWIsIlxuIiApOwogIH0KfQoKLyogTG9vayB1cCB0aGUgc3BlY2lmaWVkIGZ1bmN0aW9uIG9yIG9yZGluYWwgaW4gdGhlIGV4cG9ydGxpc3Q6CiAqIElmIGl0IGlzIGEgc3RyaW5nOgogKiAJLSBsb29rIHVwIHRoZSBuYW1lIGluIHRoZSBOYW1lIGxpc3QuIAogKgktIGxvb2sgdXAgdGhlIG9yZGluYWwgd2l0aCB0aGF0IGluZGV4LgogKgktIHVzZSB0aGUgb3JkaW5hbCBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqIElmIGl0IGlzIGEgb3JkaW5hbDoKICoJLSB1c2Ugb3JkaW5hbC1wZV9leHBvcnQtPkJhc2UgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKi8KRkFSUFJPQzMyIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCBITU9EVUxFMzIgaE1vZHVsZSwgTFBDU1RSIGZ1bmNOYW1lKQp7CglJTUFHRV9FWFBPUlRfRElSRUNUT1JZIAkJKmV4cG9ydHM7Cgl1bnNpZ25lZAkJCWxvYWRfYWRkcjsKCXVfc2hvcnQJCQkJKiBvcmRpbmFsOwoJdV9sb25nCQkJCSogZnVuY3Rpb247Cgl1X2NoYXIJCQkJKiogbmFtZSwgKmVuYW1lOwoJaW50CQkJCWk7CglQREIzMgkJCQkqcHJvY2Vzcz1QUk9DRVNTX0N1cnJlbnQoKTsKCVBFX01PRFJFRgkJCSpwZW07Cgl1X2xvbmcJCQkJcnZhX3N0YXJ0LCBydmFfZW5kLCBhZGRyOwoJY2hhcgkJCQkqIGZvcndhcmQ7CgoJcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cgl3aGlsZSAocGVtICYmIChwZW0tPm1vZHVsZSAhPSBoTW9kdWxlKSkKCQlwZW09cGVtLT5uZXh0OwoJaWYgKCFwZW0pIHsKCQlmcHJpbnRmKHN0ZGVyciwiTm8gTU9EUkVGIGZvdW5kIGZvciBQRV9NT0RVTEUgJTA4eCBpbiBwcm9jZXNzICVwXG4iLGhNb2R1bGUscHJvY2Vzcyk7CgkJcmV0dXJuIE5VTEw7Cgl9Cglsb2FkX2FkZHIgPSBoTW9kdWxlOwoJZXhwb3J0cyAgID0gcGVtLT5wZV9leHBvcnQ7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJZHByaW50Zl93aW4zMihzdGRkZWIsIlBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCVzKVxuIixmdW5jTmFtZSk7CgllbHNlCgkJZHByaW50Zl93aW4zMihzdGRkZWIsIlBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCVkKVxuIiwoaW50KWZ1bmNOYW1lKTsKCWlmICghZXhwb3J0cykgewoJCWZwcmludGYoc3RkZXJyLCJNb2R1bGUgJTA4eC9NT0RSRUYgJXAgZG9lc24ndCBoYXZlIGEgZXhwb3J0cyB0YWJsZS5cbiIsaE1vZHVsZSxwZW0pOwoJCXJldHVybiBOVUxMOwoJfQoJb3JkaW5hbAk9ICh1X3Nob3J0KikgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lT3JkaW5hbHMpOwoJZnVuY3Rpb249ICh1X2xvbmcqKSAgIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwoJbmFtZQk9ICh1X2NoYXIgKiopIFJWQShleHBvcnRzLT5BZGRyZXNzT2ZOYW1lcyk7Cglmb3J3YXJkID0gTlVMTDsKCXJ2YV9zdGFydCA9IFBFX0hFQURFUihoTW9kdWxlKS0+T3B0aW9uYWxIZWFkZXIKCQkuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXS5WaXJ0dWFsQWRkcmVzczsKCXJ2YV9lbmQgPSBydmFfc3RhcnQgKyBQRV9IRUFERVIoaE1vZHVsZSktPk9wdGlvbmFsSGVhZGVyCgkJLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF0uU2l6ZTsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkgewoJCWZvcihpPTA7IGk8ZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKSB7CgkJCWVuYW1lPShjaGFyKilSVkEoKm5hbWUpOwoJCQlpZighc3RyY21wKGVuYW1lLGZ1bmNOYW1lKSkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkciA9IGZ1bmN0aW9uWypvcmRpbmFsXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoYWRkciA8IHJ2YV9zdGFydCkgfHwgKGFkZHIgPj0gcnZhX2VuZCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChGQVJQUk9DMzIpUlZBKGFkZHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yd2FyZCA9IChjaGFyICopUlZBKGFkZHIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkJCX0KCQkJb3JkaW5hbCsrOwoJCQluYW1lKys7CgkJfQoJfSBlbHNlIHsKCQlpZiAoTE9XT1JEKGZ1bmNOYW1lKS1leHBvcnRzLT5CYXNlID4gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpIHsKCQkJZHByaW50Zl93aW4zMihzdGRkZWIsIglvcmRpbmFsICVkIG91dCBvZiByYW5nZSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9XT1JEKGZ1bmNOYW1lKSk7CgkJCXJldHVybiBOVUxMOwoJCX0KCQlhZGRyID0gZnVuY3Rpb25bKGludClmdW5jTmFtZS1leHBvcnRzLT5CYXNlXTsKCQlpZiAoKGFkZHIgPCBydmFfc3RhcnQpIHx8IChhZGRyID49IHJ2YV9lbmQpKQoJCQlyZXR1cm4gKEZBUlBST0MzMilSVkEoYWRkcik7CgkJZm9yd2FyZCA9IChjaGFyICopUlZBKGFkZHIpOwoJfQoJaWYgKGZvcndhcmQpCiAgICAgICAgewoJCWNoYXIgbW9kdWxlWzI1Nl07CgkJY2hhciAqZW5kID0gc3RyY2hyKGZvcndhcmQsICcuJyk7CgkJaWYgKCFlbmQpIHJldHVybiBOVUxMOwoJCXN0cm5jcHkobW9kdWxlLCBmb3J3YXJkLCAoZW5kIC0gZm9yd2FyZCkpOwoJCW1vZHVsZVtlbmQtZm9yd2FyZF0gPSAwOwoJCXJldHVybiBHZXRQcm9jQWRkcmVzczMyKE1PRFVMRV9GaW5kTW9kdWxlKG1vZHVsZSksIGVuZCArIDEpOwoJfQoJcmV0dXJuIE5VTEw7Cn0KCkRXT1JEIGZpeHVwX2ltcG9ydHMgKFBEQjMyICpwcm9jZXNzLFBFX01PRFJFRiAqcGVtLEhNT0RVTEUzMiBoTW9kdWxlKQp7CiAgICBJTUFHRV9JTVBPUlRfREVTQ1JJUFRPUgkqcGVfaW1wOwogICAgaW50CWZpeHVwX2ZhaWxlZAkJPSAwOwogICAgdW5zaWduZWQgaW50IGxvYWRfYWRkcgk9IHBlbS0+bW9kdWxlOwogICAgaW50CQkJCWk7CiAgICBjaGFyCQkJKm1vZG5hbWU7CiAgICAKICAgIGlmIChwZW0tPnBlX2V4cG9ydCkKICAgIAltb2RuYW1lID0gKGNoYXIqKSBSVkEocGVtLT5wZV9leHBvcnQtPk5hbWUpOwogICAgZWxzZQogICAgICAgIG1vZG5hbWUgPSAiPHVua25vd24+IjsKCiAgICAvKiBPSywgbm93IGR1bXAgdGhlIGltcG9ydCBsaXN0ICovCiAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICJcbkR1bXBpbmcgaW1wb3J0cyBsaXN0XG4iKTsKCiAgICAvKiBmaXJzdCwgY291bnQgdGhlIG51bWJlciBvZiBpbXBvcnRlZCBub24taW50ZXJuYWwgbW9kdWxlcyAqLwogICAgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7CiAgICBpZiAoIXBlX2ltcCkgCiAgICAJZnByaW50ZihzdGRlcnIsIm5vIGltcG9ydCBkaXJlY3Rvcnk/Pz8/XG4iKTsKCiAgICAvKiBGSVhNRTogc2hvdWxkIHRlcm1pbmF0ZSBvbiAwIENoYXJhY3RlcmlzdGljcyAqLwogICAgZm9yIChpID0gMDsgcGVfaW1wLT5OYW1lOyBwZV9pbXArKykKCWkrKzsKCiAgICAvKiBsb2FkIHRoZSBpbXBvcnRlZCBtb2R1bGVzLiBUaGV5IGFyZSBhdXRvbWF0aWNhbGx5IAogICAgICogYWRkZWQgdG8gdGhlIG1vZHJlZiBsaXN0IG9mIHRoZSBwcm9jZXNzLgogICAgICovCiAKICAgIC8qIEZJWE1FOiBzaG91bGQgdGVybWluYXRlIG9uIDAgQ2hhcmFjdGVyaXN0aWNzICovCiAgICBmb3IgKGkgPSAwLCBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsgcGVfaW1wLT5OYW1lOyBwZV9pbXArKykgewogICAgCUhNT0RVTEUzMglyZXM7CglQRV9NT0RSRUYJKnhwZW0sKip5cGVtOwoKCiAJY2hhciAqbmFtZSA9IChjaGFyICopIFJWQShwZV9pbXAtPk5hbWUpOwoKCS8qIGRvbid0IHVzZSBNT0RVTEVfTG9hZCwgV2luMzIgY3JlYXRlcyBuZXcgdGFzayBkaWZmZXJlbnRseSAqLwoJcmVzID0gUEVfTG9hZExpYnJhcnlFeDMyQSggbmFtZSwgcHJvY2VzcywgMCwgMCApOwoJaWYgKHJlcyA8PSAoSE1PRFVMRTMyKSAzMikgewoJICAgIGNoYXIgKnAsIGJ1ZmZlclsxMDI0XTsKCgkgICAgLyogVHJ5IHdpdGggcHJlcGVuZGluZyB0aGUgcGF0aCBvZiB0aGUgY3VycmVudCBtb2R1bGUgKi8KCSAgICBHZXRNb2R1bGVGaWxlTmFtZTMyQSggaE1vZHVsZSwgYnVmZmVyLCBzaXplb2YgKGJ1ZmZlcikpOwoJICAgIGlmICghKHAgPSBzdHJyY2hyIChidWZmZXIsICdcXCcpKSkKCQlwID0gYnVmZmVyOwoJICAgIHN0cmNweSAocCArIDEsIG5hbWUpOwoJICAgIHJlcyA9IFBFX0xvYWRMaWJyYXJ5RXgzMkEoIGJ1ZmZlciwgcHJvY2VzcywgMCwgMCApOwoJfQoJaWYgKHJlcyA8PSAoSE1PRFVMRTMyKSAzMikgewoJICAgIGZwcmludGYgKHN0ZGVyciwgIk1vZHVsZSAlcyBub3QgZm91bmRcbiIsIG5hbWUpOwoJICAgIHJldHVybiByZXM7Cgl9CglyZXMgPSBNT0RVTEVfSEFORExFdG9ITU9EVUxFMzIocmVzKTsKCXhwZW0gPSBwZW0tPm5leHQ7Cgl3aGlsZSAoeHBlbSkgewoJCWlmICh4cGVtLT5tb2R1bGUgPT0gcmVzKQoJCQlicmVhazsKCQl4cGVtID0geHBlbS0+bmV4dDsKCX0KCWlmICh4cGVtKSB7CgkJLyogaXQgaGFzIGJlZW4gbG9hZGVkICpCRUZPUkUqIHVzLCBzbyB3ZSBoYXZlIHRvIGluaXQKCQkgKiBpdCBiZWZvcmUgdXMuIHdlIGp1c3Qgc3dhcCB0aGUgdHdvIG1vZHVsZXMgd2hpY2ggc2hvdWxkCgkJICogd29yay4KCQkgKi8KCQkvKiB1bmxpbmsgeHBlbSBmcm9tIGNoYWluICovCgkJeXBlbSA9ICYocHJvY2Vzcy0+bW9kcmVmX2xpc3QpOwoJCXdoaWxlICgqeXBlbSkgewoJCQlpZiAoKCp5cGVtKT09eHBlbSkKCQkJCWJyZWFrOwoJCQl5cGVtID0gJigoKnlwZW0pLT5uZXh0KTsKCQl9CgkJKnlwZW0JCT0geHBlbS0+bmV4dDsKCgkJLyogbGluayBpdCBkaXJlY3RseSBiZWZvcmUgcGVtICovCgkJeXBlbQkJPSAmKHByb2Nlc3MtPm1vZHJlZl9saXN0KTsKCQl3aGlsZSAoKnlwZW0pIHsKCQkJaWYgKCgqeXBlbSk9PXBlbSkKCQkJCWJyZWFrOwoJCQl5cGVtID0gJigoKnlwZW0pLT5uZXh0KTsKCQl9CgkJKnlwZW0JCT0geHBlbTsKCQl4cGVtLT5uZXh0CT0gcGVtOwoJCQoJfQoJaSsrOwogICAgfQogICAgcGVfaW1wID0gcGVtLT5wZV9pbXBvcnQ7CiAgICB3aGlsZSAocGVfaW1wLT5OYW1lKSB7CgljaGFyCQkJKk1vZHVsZTsKCUlNQUdFX0lNUE9SVF9CWV9OQU1FCSpwZV9uYW1lOwoJTFBJTUFHRV9USFVOS19EQVRBCWltcG9ydF9saXN0LHRodW5rX2xpc3Q7CgoJTW9kdWxlID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CglkcHJpbnRmX3dpbjMyIChzdGRkZWIsICIlc1xuIiwgTW9kdWxlKTsKCgkvKiBGSVhNRTogZm9yd2FyZGVyIGVudHJpZXMgLi4uICovCgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayk7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiLS0tIE9yZGluYWwgJXMsJWRcbiIsIE1vZHVsZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSwoTFBDU1RSKW9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoTFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICItLS0gJXMgJXMuJWRcbiIsIHBlX25hbWUtPk5hbWUsIE1vZHVsZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoCgkJCQkJCU1PRFVMRV9GaW5kTW9kdWxlIChNb2R1bGUpLAoJCQkJCQlwZV9uYW1lLT5OYW1lKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgZHByaW50Zl93aW4zMihzdGRkZWIsIi0tLSBPcmRpbmFsICVzLiVkXG4iLE1vZHVsZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLAoJCQkJCQkgICAgIChMUENTVFIpIG9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oTFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLE1vZHVsZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLHBlX25hbWUtPk5hbWUpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJICAgIAlmcHJpbnRmKHN0ZGVyciwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CglwZV9pbXArKzsKICAgIH0KICAgIGlmIChmaXh1cF9mYWlsZWQpIHJldHVybiAyMjsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50IGNhbGNfdm1hX3NpemUoIEhNT0RVTEUzMiBoTW9kdWxlICkKewogICAgaW50IGksdm1hX3NpemUgPSAwOwogICAgSU1BR0VfU0VDVElPTl9IRUFERVIgKnBlX3NlZyA9IFBFX1NFQ1RJT05TKGhNb2R1bGUpOwoKICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiRHVtcCBvZiBzZWdtZW50IHRhYmxlXG4iKTsKICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiICAgTmFtZSAgICBWU3ogIFZhZGRyICAgICBTelJhdyAgIEZpbGVhZHIgICpSZWxvYyAqTGluZXVtICNSZWxvYyAjTGludW0gQ2hhclxuIik7CiAgICBmb3IgKGkgPSAwOyBpPCBQRV9IRUFERVIoaE1vZHVsZSktPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQogICAgewogICAgICAgIGRwcmludGZfd2luMzIoc3RkZGViLCAiJThzOiAlNC40bHggJTguOGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlNC40eCAlNC40eCAlOC44bHhcbiIsIAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5OYW1lLCAKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TWlzYy5WaXJ0dWFsU2l6ZSwKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+VmlydHVhbEFkZHJlc3MsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlNpemVPZlJhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1Jhd0RhdGEsCiAgICAgICAgICAgICAgICAgICAgICBwZV9zZWctPlBvaW50ZXJUb1JlbG9jYXRpb25zLAogICAgICAgICAgICAgICAgICAgICAgcGVfc2VnLT5Qb2ludGVyVG9MaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZSZWxvY2F0aW9ucywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+TnVtYmVyT2ZMaW5lbnVtYmVycywKICAgICAgICAgICAgICAgICAgICAgIHBlX3NlZy0+Q2hhcmFjdGVyaXN0aWNzKTsKICAgICAgICB2bWFfc2l6ZSA9IE1BWCh2bWFfc2l6ZSwgcGVfc2VnLT5WaXJ0dWFsQWRkcmVzcytwZV9zZWctPlNpemVPZlJhd0RhdGEpOwogICAgICAgIHBlX3NlZysrOwogICAgfQogICAgcmV0dXJuIHZtYV9zaXplOwp9CgpzdGF0aWMgdm9pZCBkb19yZWxvY2F0aW9ucyhQRV9NT0RSRUYgKnBlbSkKewogICAgaW50IGRlbHRhID0gcGVtLT5tb2R1bGUgLSBQRV9IRUFERVIocGVtLT5tb2R1bGUpLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyPSBwZW0tPm1vZHVsZTsKCUlNQUdFX0JBU0VfUkVMT0NBVElPTgkJKnIgPSBwZW0tPnBlX3JlbG9jOwoJaW50CQkJCWhkZWx0YSA9IChkZWx0YSA+PiAxNikgJiAweEZGRkY7CglpbnQJCQkJbGRlbHRhID0gZGVsdGEgJiAweEZGRkY7CgoJLyogaW50IHJlbG9jX3NpemUgPSAqLwoKCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlZpcnR1YWxBZGRyZXNzKQoJewoJCWNoYXIgKnBhZ2UgPSAoY2hhciopIFJWQShyLT5WaXJ0dWFsQWRkcmVzcyk7CgkJaW50IGNvdW50ID0gKHItPlNpemVPZkJsb2NrIC0gOCkvMjsKCQlpbnQgaTsKCQlkcHJpbnRmX2ZpeHVwKHN0ZGRlYiwgIiV4IHJlbG9jYXRpb25zIGZvciBwYWdlICVseFxuIiwKCQkJY291bnQsIHItPlZpcnR1YWxBZGRyZXNzKTsKCQkvKiBwYXRjaGluZyBpbiByZXZlcnNlIG9yZGVyICovCgkJZm9yKGk9MDtpPGNvdW50O2krKykKCQl7CgkJCWludCBvZmZzZXQgPSByLT5UeXBlT2Zmc2V0W2ldICYgMHhGRkY7CgkJCWludCB0eXBlID0gci0+VHlwZU9mZnNldFtpXSA+PiAxMjsKCQkJZHByaW50Zl9maXh1cChzdGRkZWIsInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CiNpZiAxCgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKI2Vsc2UKCQkJCXsgaW50IGg9Kih1bnNpZ25lZCBzaG9ydCopKHBhZ2Urb2Zmc2V0KTsKCQkJCSAgaW50IGw9ci0+VHlwZU9mZnNldFsrK2ldOwoJCQkJICAqKHVuc2lnbmVkIGludCopKHBhZ2UgKyBvZmZzZXQpID0gKGg8PDE2KSArIGwgKyBkZWx0YTsKCQkJCX0KI2VuZGlmCgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSEFESjoKCQkJCWZwcmludGYoc3RkZXJyLCAiRG9uJ3Qga25vdyB3aGF0IHRvIGRvIHdpdGggSU1BR0VfUkVMX0JBU0VEX0hJR0hBREpcbiIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX01JUFNfSk1QQUREUjoKCQkJCWZwcmludGYoc3RkZXJyLCAiSXMgdGhpcyBhIE1JUFMgbWFjaGluZSA/Pz9cbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gZml4dXAgdHlwZVxuIik7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyICsgci0+U2l6ZU9mQmxvY2spOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqIAogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvciAKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXRzIHdoaWNoIGFyZSBwYWdlLWFsaWduZWQuCiAqCiAqIEJVVCB3ZSBoYXZlIHRvIG1hcCB0aGUgd2hvbGUgaW1hZ2UgYW55d2F5LCBmb3IgV2luMzIgcHJvZ3JhbXMgc29tZXRpbWVzCiAqIHdhbnQgdG8gYWNjZXNzIHRoZW0uIChITU9EVUxFMzIgcG9pbnQgdG8gdGhlIHN0YXJ0IG9mIGl0KQogKi8Kc3RhdGljIEhNT0RVTEUzMiBQRV9Mb2FkSW1hZ2UoIEhGSUxFMzIgaEZpbGUgKQp7CiAgICBITU9EVUxFMzIgaE1vZHVsZTsKICAgIEhBTkRMRTMyIG1hcHBpbmc7CgogICAgLyogbWFwIHRoZSBQRSBmaWxlIHNvbWV3aGVyZSAqLwogICAgbWFwcGluZyA9IENyZWF0ZUZpbGVNYXBwaW5nMzJBKCBoRmlsZSwgTlVMTCwgUEFHRV9SRUFET05MWSB8IFNFQ19DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIE5VTEwgKTsKICAgIGlmICghbWFwcGluZykKICAgIHsKICAgICAgICBmcHJpbnRmKCBzdGRlcnIsICJQRV9Mb2FkSW1hZ2U6IENyZWF0ZUZpbGVNYXBwaW5nIGVycm9yICVsZFxuIiwKICAgICAgICAgICAgICAgICBHZXRMYXN0RXJyb3IoKSApOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgaE1vZHVsZSA9IChITU9EVUxFMzIpTWFwVmlld09mRmlsZSggbWFwcGluZywgRklMRV9NQVBfUkVBRCwgMCwgMCwgMCApOwogICAgQ2xvc2VIYW5kbGUoIG1hcHBpbmcgKTsKICAgIGlmICghaE1vZHVsZSkKICAgIHsKICAgICAgICBmcHJpbnRmKCBzdGRlcnIsICJQRV9Mb2FkSW1hZ2U6IE1hcFZpZXdPZkZpbGUgZXJyb3IgJWxkXG4iLAogICAgICAgICAgICAgICAgIEdldExhc3RFcnJvcigpICk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKFBFX0hFQURFUihoTW9kdWxlKS0+U2lnbmF0dXJlICE9IElNQUdFX05UX1NJR05BVFVSRSkKICAgIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwiaW1hZ2UgZG9lc24ndCBoYXZlIFBFIHNpZ25hdHVyZSwgYnV0IDB4JTA4bHhcbiIsCiAgICAgICAgICAgICAgICBQRV9IRUFERVIoaE1vZHVsZSktPlNpZ25hdHVyZSApOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CgogICAgaWYgKFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5NYWNoaW5lICE9IElNQUdFX0ZJTEVfTUFDSElORV9JMzg2KQogICAgewogICAgICAgIGZwcmludGYoc3RkZXJyLCJ0cnlpbmcgdG8gbG9hZCBQRSBpbWFnZSBmb3IgdW5zdXBwb3J0ZWQgYXJjaGl0ZWN0dXJlICgiKTsKICAgICAgICBzd2l0Y2ggKFBFX0hFQURFUihoTW9kdWxlKS0+RmlsZUhlYWRlci5NYWNoaW5lKQogICAgICAgIHsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9VTktOT1dOOiBmcHJpbnRmKHN0ZGVyciwiVW5rbm93biIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9JODYwOiAgICBmcHJpbnRmKHN0ZGVyciwiSTg2MCIpOyBicmVhazsKICAgICAgICBjYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMzAwMDogICBmcHJpbnRmKHN0ZGVyciwiUjMwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjQwMDA6ICAgZnByaW50ZihzdGRlcnIsIlI0MDAwIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1IxMDAwMDogIGZwcmludGYoc3RkZXJyLCJSMTAwMDAiKTsgYnJlYWs7CiAgICAgICAgY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfQUxQSEE6ICAgZnByaW50ZihzdGRlcnIsIkFscGhhIik7IGJyZWFrOwogICAgICAgIGNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1BPV0VSUEM6IGZwcmludGYoc3RkZXJyLCJQb3dlclBDIik7IGJyZWFrOwogICAgICAgIGRlZmF1bHQ6IGZwcmludGYoc3RkZXJyLCJVbmtub3duLSUwNHgiLAogICAgICAgICAgICAgICAgICAgICAgICAgUEVfSEVBREVSKGhNb2R1bGUpLT5GaWxlSGVhZGVyLk1hY2hpbmUpOyBicmVhazsKICAgICAgICB9CiAgICAgICAgZnByaW50ZihzdGRlcnIsIilcbiIpOwogICAgICAgIGdvdG8gZXJyb3I7CiAgICB9CiAgICByZXR1cm4gaE1vZHVsZTsKCmVycm9yOgogICAgVW5tYXBWaWV3T2ZGaWxlKCAoTFBWT0lEKWhNb2R1bGUgKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGlzIG1hcHMgYSBsb2FkZWQgUEUgZGxsIGludG8gdGhlIGFkZHJlc3Mgc3BhY2Ugb2YgdGhlIHNwZWNpZmllZCBwcm9jZXNzLgogKi8Kc3RhdGljIEhNT0RVTEUzMiBQRV9NYXBJbWFnZSggSE1PRFVMRTMyIGhNb2R1bGUsIFBEQjMyICpwcm9jZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPRlNUUlVDVCAqb2ZzLCBEV09SRCBmbGFncyApCnsKCVBFX01PRFJFRgkJKnBlbTsKCWludAkJCWksIHJlc3VsdDsKCURXT1JECQkJbG9hZF9hZGRyOwoJSU1BR0VfREFUQV9ESVJFQ1RPUlkJZGlyOwoJY2hhcgkJCSptb2RuYW1lOwoJaW50CQkJdm1hX3NpemU7CgogICAgICAgIElNQUdFX1NFQ1RJT05fSEVBREVSICpwZV9zZWc7CiAgICAgICAgSU1BR0VfRE9TX0hFQURFUiAqZG9zX2hlYWRlciA9IChJTUFHRV9ET1NfSEVBREVSICopaE1vZHVsZTsKICAgICAgICBJTUFHRV9OVF9IRUFERVJTICpudF9oZWFkZXIgPSBQRV9IRUFERVIoaE1vZHVsZSk7CgkKCXBlbSA9IChQRV9NT0RSRUYqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZigqcGVtKSk7CgkvKiBOT1RFOiBmaXh1cF9pbXBvcnRzIHRha2VzIGNhcmUgb2YgdGhlIGNvcnJlY3Qgb3JkZXIgKi8KCXBlbS0+bmV4dAk9IHByb2Nlc3MtPm1vZHJlZl9saXN0OwoJcHJvY2Vzcy0+bW9kcmVmX2xpc3QgPSBwZW07CgoJaWYgKCEobnRfaGVhZGVyLT5GaWxlSGVhZGVyLkNoYXJhY3RlcmlzdGljcyAmIElNQUdFX0ZJTEVfRExMKSkKICAgICAgICB7CgkJaWYgKHByb2Nlc3MtPmV4ZV9tb2RyZWYpCgkJCWZwcmludGYoc3RkZXJyLCJvdmVyd3JpdGluZyBvbGQgZXhlX21vZHJlZi4uLiBhcnJnaFxuIik7CgkJcHJvY2Vzcy0+ZXhlX21vZHJlZiA9IHBlbTsKCX0KCglsb2FkX2FkZHIgPSBudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkltYWdlQmFzZTsKCXZtYV9zaXplID0gY2FsY192bWFfc2l6ZSggaE1vZHVsZSApOwoJZHByaW50Zl93aW4zMihzdGRkZWIsICJMb2FkIGFkZHIgaXMgJWx4XG4iLGxvYWRfYWRkcik7Cglsb2FkX2FkZHIgPSAoRFdPUkQpVmlydHVhbEFsbG9jKCAodm9pZCopbG9hZF9hZGRyLCB2bWFfc2l6ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNRU1fUkVTRVJWRSB8IE1FTV9DT01NSVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUEFHRV9FWEVDVVRFX1JFQURXUklURSApOwoJaWYgKGxvYWRfYWRkciA9PSAwKSB7CgkJbG9hZF9hZGRyID0gKERXT1JEKVZpcnR1YWxBbGxvYyggTlVMTCwgdm1hX3NpemUsCgkJCQkJCSBNRU1fUkVTRVJWRSB8IE1FTV9DT01NSVQsCgkJCQkJCSBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7Cgl9CglwZW0tPm1vZHVsZSA9IChITU9EVUxFMzIpbG9hZF9hZGRyOwoKCWRwcmludGZfd2luMzIoc3RkZGViLCAiTG9hZCBhZGRyIGlzIHJlYWxseSAlbHgsIHJhbmdlICV4XG4iLAogICAgICAgICAgICAgICAgICAgICAgbG9hZF9hZGRyLCB2bWFfc2l6ZSk7CgkKICAgICAgICAvKiBTdG9yZSB0aGUgTlQgaGVhZGVyIGF0IHRoZSBsb2FkIGFkZHIKICAgICAgICAgKiAoRklYTUU6IHNob3VsZCByZWFsbHkgdXNlIG1tYXApCiAgICAgICAgICovCiAgICAgICAgKihJTUFHRV9ET1NfSEVBREVSICopbG9hZF9hZGRyID0gKmRvc19oZWFkZXI7CiAgICAgICAgKihJTUFHRV9OVF9IRUFERVJTICopKGxvYWRfYWRkciArIGRvc19oZWFkZXItPmVfbGZhbmV3KSA9ICpudF9oZWFkZXI7CgogICAgICAgIHBlX3NlZyA9IFBFX1NFQ1RJT05TKGhNb2R1bGUpOwoJZm9yIChpID0gMDsgaSA8IG50X2hlYWRlci0+RmlsZUhlYWRlci5OdW1iZXJPZlNlY3Rpb25zOyBpKyssIHBlX3NlZysrKQoJewoJCS8qIG1lbWNweSBvbmx5IG5vbi1CU1Mgc2VnbWVudHMgKi8KCQkvKiBGSVhNRTogdGhpcyBzaG91bGQgYmUgZG9uZSBieSBtbWFwKC4uTUFQX1BSSVZBVEV8TUFQX0ZJWEVELi4pCgkJICogYnV0IGl0IGlzIG5vdCBwb3NzaWJsZSBmb3IgKGF0IGxlYXN0KSBMaW51eCBuZWVkcwoJCSAqIGEgcGFnZS1hbGlnbmVkIG9mZnNldC4KCQkgKi8KCQlpZighKHBlX3NlZy0+Q2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfU0NOX0NOVF9VTklOSVRJQUxJWkVEX0RBVEEpKQoJCSAgICBtZW1jcHkoKGNoYXIqKVJWQShwZV9zZWctPlZpcnR1YWxBZGRyZXNzKSwKCQkgICAgCShjaGFyKikoaE1vZHVsZSArIHBlX3NlZy0+UG9pbnRlclRvUmF3RGF0YSksCgkJCXBlX3NlZy0+U2l6ZU9mUmF3RGF0YQoJCSAgICApOwoKCQlyZXN1bHQgPSBSVkEgKHBlX3NlZy0+VmlydHVhbEFkZHJlc3MpOwojaWYgMQoJCS8qIG5vdCBuZWVkZWQsIG1lbW9yeSBpcyB6ZXJvICovCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5ic3MiKSA9PSAwKQoJCSAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAoJCQkgICBwZV9zZWctPk1pc2MuVmlydHVhbFNpemUgPwoJCQkgICBwZV9zZWctPk1pc2MuVmlydHVhbFNpemUgOgoJCQkgICBwZV9zZWctPlNpemVPZlJhd0RhdGEpOwojZW5kaWYKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5pZGF0YSIpID09IDApCgkJCXBlbS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlX3NlZy0+TmFtZSwgIi5lZGF0YSIpID09IDApCgkJCXBlbS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGVfc2VnLT5OYW1lLCAiLnJzcmMiKSA9PSAwKQoJCQlwZW0tPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZV9zZWctPk5hbWUsICIucmVsb2MiKSA9PSAwKQoJCQlwZW0tPnBlX3JlbG9jID0gKExQSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKSByZXN1bHQ7Cgl9CgoJLyogVGhlcmUgaXMgd29yZCB0aGF0IHRoZSBhY3R1YWwgbG9hZGVyIGRvZXMgbm90IGNhcmUgYWJvdXQgdGhlCgkgICBzZWN0aW9uIG5hbWVzLCBhbmQgb25seSBnb2VzIGZvciB0aGUgRGF0YURpcmVjdG9yeSAqLwoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCWlmKHBlbS0+cGVfZXhwb3J0ICYmIChpbnQpcGVtLT5wZV9leHBvcnQhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgZXhwb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQkvKiBhbHdheXMgdHJ1c3QgdGhlIGRpcmVjdG9yeSAqLwoJCXBlbS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJZGlyPW50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfSU1QT1JUXTsKCWlmKGRpci5TaXplKQoJewoJCS8qIAoJCWlmKHBlbS0+cGVfaW1wb3J0ICYmIChpbnQpcGVtLT5wZV9pbXBvcnQhPVJWQShkaXIuVmlydHVhbEFkZHJlc3MpKQoJCQlmcHJpbnRmKHN0ZGVyciwid3JvbmcgaW1wb3J0IGRpcmVjdG9yeT8/XG4iKTsKCQkgKi8KCQlwZW0tPnBlX2ltcG9ydCA9IChMUElNQUdFX0lNUE9SVF9ERVNDUklQVE9SKSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKTsKCX0KCglkaXI9bnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9SRVNPVVJDRV07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX3Jlc291cmNlICYmIChpbnQpcGVtLT5wZV9yZXNvdXJjZSE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZXNvdXJjZSBkaXJlY3Rvcnk/P1xuIik7CgkJcGVtLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9FWENFUFRJT05dLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJFeGNlcHRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfU0VDVVJJVFldLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJTZWN1cml0eSBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoKCglkaXI9bnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0NdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGVtLT5wZV9yZWxvYyAmJiAoaW50KXBlbS0+cGVfcmVsb2MhPSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIHJlbG9jYXRpb24gbGlzdD8/XG4iKTsKCQlwZW0tPnBlX3JlbG9jID0gKHZvaWQgKikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT1BZUklHSFRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfR0xPQkFMUFRSXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiR2xvYmFsIFBvaW50ZXIgKE1JUFMpIGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUddLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfQk9VTkRfSU1QT1JUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiQm91bmQgSW1wb3J0IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkltcG9ydCBBZGRyZXNzIFRhYmxlIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCWlmKG50X2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxM10uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDEzIGlnbm9yZWRcbiIpOwoJaWYobnRfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5WzE0XS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiVW5rbm93biBkaXJlY3RvcnkgMTQgaWdub3JlZFxuIik7CglpZihudF9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbMTVdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJVbmtub3duIGRpcmVjdG9yeSAxNSBpZ25vcmVkXG4iKTsKCglpZihwZW0tPnBlX3JlbG9jKQlkb19yZWxvY2F0aW9ucyhwZW0pOwoJaWYocGVtLT5wZV9leHBvcnQpCWR1bXBfZXhwb3J0cyhwZW0tPm1vZHVsZSk7CglpZihwZW0tPnBlX2ltcG9ydCkJewoJCWlmIChmaXh1cF9pbXBvcnRzKHByb2Nlc3MscGVtLGhNb2R1bGUpKSB7CgkJCVBFX01PRFJFRgkqKnhwZW07CgoJCQkvKiByZW1vdmUgZW50cnkgZnJvbSBtb2RyZWYgY2hhaW4gKi8KCQkJeHBlbSA9ICYocHJvY2Vzcy0+bW9kcmVmX2xpc3QpOwoJCQl3aGlsZSAoKnhwZW0pIHsKCQkJCWlmICgqeHBlbT09cGVtKSB7CgkJCQkJKnhwZW0gPSBwZW0tPm5leHQ7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQl4cGVtID0gJigoKnhwZW0pLT5uZXh0KTsKCQkJfQoJCQkvKiBGSVhNRTogdGhlcmUgYXJlIHNldmVyYWwgbW9yZSBkYW5nbGluZyByZWZlcmVuY2VzCgkJCSAqIGxlZnQuIEluY2x1ZGluZyBkbGxzIGxvYWRlZCBieSB0aGlzIGRsbCBiZWZvcmUgdGhlCgkJCSAqIGZhaWxlZCBvbmUuIFVucm9sbGluZyBpcyByYXRoZXIgZGlmZmljdWx0IHdpdGggdGhlCgkJCSAqIGN1cnJlbnQgc3RydWN0dXJlIGFuZCB3ZSBjYW4gbGVhdmUgaXQgdGhlbSBseWluZwoJCQkgKiBhcm91bmQgd2l0aCBubyBwcm9ibGVtcywgc28gd2UgZG9uJ3QgY2FyZQoJCQkgKi8KCQkJcmV0dXJuIDA7CgkJfQoJfQogIAkJCglpZiAocGVtLT5wZV9leHBvcnQpCgkJbW9kbmFtZSA9IChjaGFyKilSVkEocGVtLT5wZV9leHBvcnQtPk5hbWUpOwoJZWxzZSB7CgkJY2hhciAqczsKCQltb2RuYW1lID0gcyA9IG9mcy0+c3pQYXRoTmFtZTsKCQl3aGlsZSAoKHM9c3RyY2hyKG1vZG5hbWUsJ1xcJykpKQoJCQltb2RuYW1lID0gcysxOwoJCWlmICgocz1zdHJjaHIobW9kbmFtZSwnLicpKSkKCQkJKnM9J1wwJzsKCX0KCiAgICAgICAgLyogTm93IHRoYXQgd2UgZ290IGV2ZXJ5dGhpbmcgYXQgdGhlIHJpZ2h0IGFkZHJlc3MsCiAgICAgICAgICogd2UgY2FuIHVubWFwIHRoZSBwcmV2aW91cyBtb2R1bGUgKi8KICAgICAgICBVbm1hcFZpZXdPZkZpbGUoIChMUFZPSUQpaE1vZHVsZSApOwogICAgICAgIHJldHVybiAoSE1PRFVMRTMyKWxvYWRfYWRkcjsKfQoKSElOU1RBTkNFMTYgTU9EVUxFX0NyZWF0ZUluc3RhbmNlKEhNT0RVTEUxNiBoTW9kdWxlLExPQURQQVJBTVMgKnBhcmFtcyk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4gCiAqIEZJWE1FOiBoYW5kbGUgdGhlIGZsYWdzLgogKiAgICAgICAgaW50ZXJuYWwgbW9kdWxlIGhhbmRsaW5nIHNob3VsZCBiZSBtYWRlIGJldHRlciBoZXJlIChhbmQgaW4gYnVpbHRpbi5jKQogKi8KSE1PRFVMRTMyIFBFX0xvYWRMaWJyYXJ5RXgzMkEgKExQQ1NUUiBuYW1lLCBQREIzMiAqcHJvY2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhGSUxFMzIgaEZpbGUsIERXT1JEIGZsYWdzKQp7CglPRlNUUlVDVAlvZnM7CglITU9EVUxFMzIJaE1vZHVsZSxyZXQ7CglORV9NT0RVTEUJKnBNb2R1bGU7CglQRV9NT0RSRUYJKnBlbTsKCglpZiAoKGhNb2R1bGUgPSBNT0RVTEVfRmluZE1vZHVsZSggbmFtZSApKSkgewoJCS8qIHRoZSAuRExMIGlzIGVpdGhlciBsb2FkZWQgb3IgaW50ZXJuYWwgKi8KCQloTW9kdWxlID0gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKGhNb2R1bGUpOwoJCWlmICghSElXT1JEKGhNb2R1bGUpKSAvKiBpbnRlcm5hbCAob3IgYmFkKSAqLwoJCQlyZXR1cm4gaE1vZHVsZTsKCQkvKiBjaGVjayBpZiB0aGlzIG1vZHVsZSBpcyBhbHJlYWR5IG1hcHBlZCAqLwoJCXBlbSAJPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCQl3aGlsZSAocGVtKSB7CgkJCWlmIChwZW0tPm1vZHVsZSA9PSBoTW9kdWxlKSByZXR1cm4gaE1vZHVsZTsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCX0KCQlwTW9kdWxlID0gTU9EVUxFX0dldFB0cihoTW9kdWxlKTsKCQlpZiAocE1vZHVsZS0+ZmxhZ3MgJiBORV9GRkxBR1NfQlVJTFRJTikgewoJCQlJTUFHRV9ET1NfSEVBREVSCSpkaDsKCQkJSU1BR0VfTlRfSEVBREVSUwkqbmg7CgkJCUlNQUdFX1NFQ1RJT05fSEVBREVSCSpzaDsKCgkJCS8qIHdlIG9ubHkgY29tZSBoZXJlIGlmIHdlIGFscmVhZHkgaGF2ZSAnbG9hZGVkJyB0aGUKCQkJICogaW50ZXJuYWwgZGxsIGJ1dCBpbiBhbm90aGVyIHByb2Nlc3MuIEp1c3QgY3JlYXRlCgkJCSAqIGEgUEVfTU9EUkVGIGFuZCByZXR1cm4uCgkJCSAqLwoJCQlwZW0gPSAoUEVfTU9EUkVGKilIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwKCQkJCUhFQVBfWkVST19NRU1PUlksc2l6ZW9mKCpwZW0pKTsKCQkJcGVtLT5tb2R1bGUgCSAgICAgPSBoTW9kdWxlOwoJCQlkaCA9IChJTUFHRV9ET1NfSEVBREVSKilwZW0tPm1vZHVsZTsKCQkJbmggPSAoSU1BR0VfTlRfSEVBREVSUyopKGRoKzEpOwoJCQlzaCA9IChJTUFHRV9TRUNUSU9OX0hFQURFUiopKG5oKzEpOwoJCQlwZW0tPnBlX2V4cG9ydAkgICAgID0gKElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkqKShzaCsyKTsKCQkJcGVtLT5uZXh0CSAgICAgPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCQkJcHJvY2Vzcy0+bW9kcmVmX2xpc3QgPSBwZW07CgkJCXJldHVybiBoTW9kdWxlOwoJCX0KCX0gZWxzZSB7CgoJCS8qIHRyeSB0byBsb2FkIGJ1aWx0aW4sIGVuYWJsZWQgbW9kdWxlcyBmaXJzdCAqLwoJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU4zMl9Mb2FkTW9kdWxlKCBuYW1lLCBGQUxTRSApKSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKCBoTW9kdWxlICk7CgoJCS8qIHRyeSB0byBvcGVuIHRoZSBzcGVjaWZpZWQgZmlsZSAqLwoJCWlmIChIRklMRV9FUlJPUjMyPT0oaEZpbGU9T3BlbkZpbGUzMihuYW1lLCZvZnMsT0ZfUkVBRCkpKSB7CgkJCS8qIE5vdyB0cnkgdGhlIGJ1aWx0LWluIGV2ZW4gaWYgZGlzYWJsZWQgKi8KCQkJaWYgKChoTW9kdWxlID0gQlVJTFRJTjMyX0xvYWRNb2R1bGUoIG5hbWUsIFRSVUUgKSkpIHsKCQkJCWZwcmludGYoIHN0ZGVyciwgIldhcm5pbmc6IGNvdWxkIG5vdCBsb2FkIFdpbmRvd3MgRExMICclcycsIHVzaW5nIGJ1aWx0LWluIG1vZHVsZS5cbiIsIG5hbWUgKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTU9EVUxFX0hBTkRMRXRvSE1PRFVMRTMyKCBoTW9kdWxlICk7CgkJCX0KCQkJcmV0dXJuIDE7CgkJfQoJCWlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggJm9mcyApKSA8IDMyKSB7CgkJCV9sY2xvc2UzMihoRmlsZSk7CgkJCXJldHVybiBoTW9kdWxlOwoJCX0KCQlwTW9kdWxlCQk9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUgKTsKCQlwTW9kdWxlLT5mbGFncwk9IE5FX0ZGTEFHU19XSU4zMjsKCQlwTW9kdWxlLT5tb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggaEZpbGUgKTsKCQlDbG9zZUhhbmRsZSggaEZpbGUgKTsKCQlpZiAocE1vZHVsZS0+bW9kdWxlMzIgPCAzMikgcmV0dXJuIDIxOwoJfQoJLyogcmVjdXJzZSAqLwoJcmV0ID0gUEVfTWFwSW1hZ2UoIHBNb2R1bGUtPm1vZHVsZTMyLCBwcm9jZXNzLCAmb2ZzLGZsYWdzKTsKCWlmICghcmV0KSB7CgkJLyogc2hvdWxkIGZyZWUgdGhpcyBtb2R1bGUgYW5kIHRoZSBhbHJlYWR5IHJlZmVyZW5jZWQgb25lcyAqLwoJCXJldHVybiAwOwoJfQoJcE1vZHVsZS0+bW9kdWxlMzIgPSByZXQ7CglyZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogTG9hZCB0aGUgUEUgbWFpbiAuRVhFLiBBbGwgb3RoZXIgbG9hZGluZyBpcyBkb25lIGJ5IFBFX0xvYWRMaWJyYXJ5RXgzMkEKICogRklYTUU6IHRoaXMgZnVuY3Rpb24gc2hvdWxkIHVzZSBQRV9Mb2FkTGlicmFyeUV4MzJBLCBidXQgY3VycmVudGx5IGNhbid0CiAqIGR1ZSB0byB0aGUgVEFTS19DcmVhdGVUYXNrIHN0dWZmLgogKi8KSElOU1RBTkNFMTYgUEVfTG9hZE1vZHVsZSggSEZJTEUzMiBoRmlsZSwgT0ZTVFJVQ1QgKm9mcywgTE9BRFBBUkFNUyogcGFyYW1zICkKewogICAgSE1PRFVMRTE2IGhNb2R1bGUxNjsKICAgIEhNT0RVTEUzMiBoTW9kdWxlMzIsIHJldDsKICAgIEhJTlNUQU5DRTE2IGhJbnN0YW5jZTsKICAgIE5FX01PRFVMRSAqcE1vZHVsZTsKICAgIFRIREIgKnRoZGIgPSBUSFJFQURfQ3VycmVudCgpOwogICAgCiAgICBpZiAoKGhNb2R1bGUxNiA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggb2ZzICkpIDwgMzIpIHJldHVybiBoTW9kdWxlMTY7CiAgICBwTW9kdWxlID0gKE5FX01PRFVMRSAqKUdsb2JhbExvY2sxNiggaE1vZHVsZTE2ICk7CiAgICBwTW9kdWxlLT5mbGFncyA9IE5FX0ZGTEFHU19XSU4zMjsKCiAgICBwTW9kdWxlLT5tb2R1bGUzMiA9IGhNb2R1bGUzMiA9IFBFX0xvYWRJbWFnZSggaEZpbGUgKTsKICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwogICAgaWYgKGhNb2R1bGUzMiA8IDMyKSByZXR1cm4gMjE7CgogICAgaEluc3RhbmNlID0gTU9EVUxFX0NyZWF0ZUluc3RhbmNlKCBoTW9kdWxlMTYsIHBhcmFtcyApOwogICAgaWYgKCEoUEVfSEVBREVSKGhNb2R1bGUzMiktPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpKQogICAgewogICAgICAgIEhUQVNLMTYgaFRhc2sgPSBUQVNLX0NyZWF0ZVRhc2soIGhNb2R1bGUxNiwgaEluc3RhbmNlLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcmFtcy0+aEVudmlyb25tZW50LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUFNUUilQVFJfU0VHX1RPX0xJTiggcGFyYW1zLT5jbWRMaW5lICksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqKChXT1JEKilQVFJfU0VHX1RPX0xJTihwYXJhbXMtPnNob3dDbWQpICsgMSkgKTsKICAgICAgICBUREIgKnBUYXNrID0gKFREQiAqKUdsb2JhbExvY2sxNiggaFRhc2sgKTsKICAgICAgICB0aGRiID0gcFRhc2stPnRoZGI7CiAgICB9CiAgICBpZiAoIShyZXQgPSBQRV9NYXBJbWFnZSggaE1vZHVsZTMyLCB0aGRiLT5wcm9jZXNzLCBvZnMsIDAgKSkpCiAgICB7CiAgICAgCS8qIEZJWE1FOiBzaG91bGQgZGVzdHJveSB0aGUgdGFzayBjcmVhdGVkIC4uLiAqLwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgcE1vZHVsZS0+bW9kdWxlMzIgPSByZXQ7CiAgICAvKiB5dWNrLiBidXQgdGhlcmUgaXMgbm8gb3RoZXIgZ29vZCBwbGFjZSB0byBkbyB0aGF0Li4uICovCiAgICBQRV9Jbml0VGxzKCB0aGRiICk7CiAgICByZXR1cm4gaEluc3RhbmNlOwp9CgppbnQgUEVfVW5sb2FkSW1hZ2UoIEhNT0RVTEUzMiBoTW9kdWxlICkKewoJcHJpbnRmKCJQRXVubG9hZEltYWdlKCkgY2FsbGVkIVxuIik7CgkvKiBmcmVlIHJlc291cmNlcywgaW1hZ2UsIHVubWFwICovCglyZXR1cm4gMTsKfQoKLyogQ2FsbGVkIGlmIHRoZSBsaWJyYXJ5IGlzIGxvYWRlZCBvciBmcmVlZC4KICogTk9URTogaWYgYSB0aHJlYWQgYXR0YWNoZXMgYSBETEwsIHRoZSBjdXJyZW50IHRocmVhZCB3aWxsIG9ubHkgZG8KICogRExMX1BST0NFU1NfQVRUQUNILiBPbmx5IG5ldyBjcmVhdGVkIHRocmVhZHMgZG8gRExMX1RIUkVBRF9BVFRBQ0gKICogKFNESykKICovCnN0YXRpYyB2b2lkIFBFX0luaXRETEwoUEVfTU9EUkVGICpwZW0sIERXT1JEIHR5cGUsTFBWT0lEIGxwUmVzZXJ2ZWQpCnsKICAgIGlmICh0eXBlPT1ETExfUFJPQ0VTU19BVFRBQ0gpCglwZW0tPmZsYWdzIHw9IFBFX01PRFJFRl9QUk9DRVNTX0FUVEFDSEVEOwoKICAgIC8qICBETExfQVRUQUNIX1BST0NFU1M6CiAgICAgKgkJbHByZXNlcnZlZCBpcyBOVUxMIGZvciBkeW5hbWljIGxvYWRzLCBub3QtTlVMTCBmb3Igc3RhdGljIGxvYWRzCiAgICAgKiAgRExMX0RFVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBpZiBjYWxsZWQgYnkgRnJlZUxpYnJhcnksIG5vdC1OVUxMIG90aGVyd2lzZQogICAgICogIHRoZSBTREsgZG9lc24ndCBtZW50aW9uIGFueXRoaW5nIGZvciBETExfVEhSRUFEXyoKICAgICAqLwogICAgICAgIAogICAgLyogSXMgdGhpcyBhIGxpYnJhcnk/IEFuZCBoYXMgaXQgZ290IGFuIGVudHJ5cG9pbnQ/ICovCiAgICBpZiAoKFBFX0hFQURFUihwZW0tPm1vZHVsZSktPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpICYmCiAgICAgICAgKFBFX0hFQURFUihwZW0tPm1vZHVsZSktPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICApIHsKICAgICAgICBGQVJQUk9DMzIgZW50cnkgPSAoRkFSUFJPQzMyKVJWQV9QVFIoIHBlbS0+bW9kdWxlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICk7CiAgICAgICAgZHByaW50Zl9yZWxheSggc3RkZGViLCAiQ2FsbFRvMzIoZW50cnlwcm9jPSVwLG1vZHVsZT0lMDh4LHR5cGU9JWxkLHJlcz0lcClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgZW50cnksIHBlbS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICAgICAgZW50cnkoIHBlbS0+bW9kdWxlLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICB9Cn0KCi8qIENhbGwgdGhlIERMTGVudHJ5IGZ1bmN0aW9uIG9mIGFsbCBkbGxzIHVzZWQgYnkgdGhhdCBwcm9jZXNzLgogKiAoTk9URTogdGhpcyBtYXkgcmVjdXJzaXZlbHkgY2FsbCB0aGlzIGZ1bmN0aW9uIChpZiBhIGxpYnJhcnkgY2FsbHMKICogTG9hZExpYnJhcnkpIC4uLiBidXQgaXQgd29uJ3QgbWF0dGVyKQogKi8Kdm9pZCBQRV9Jbml0aWFsaXplRExMcyhQREIzMiAqcHJvY2VzcyxEV09SRCB0eXBlLExQVk9JRCBscFJlc2VydmVkKSB7CglQRV9NT0RSRUYJKnBlbTsKCglwZW0gPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCXdoaWxlIChwZW0pIHsKCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9OT19ETExfQ0FMTFMpIHsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHR5cGU9PURMTF9QUk9DRVNTX0FUVEFDSCkgewoJCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9QUk9DRVNTX0FUVEFDSEVEKSB7CgkJCQlwZW0gPSBwZW0tPm5leHQ7CgkJCQljb250aW51ZTsKCQkJfQoJCX0KCQlQRV9Jbml0RExMKCBwZW0sIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKCQlwZW0gPSBwZW0tPm5leHQ7Cgl9Cn0KCnZvaWQgUEVfSW5pdFRscyhUSERCICp0aGRiKQp7CgkvKiBGSVhNRTogdGxzIGNhbGxiYWNrcyA/Pz8gKi8KCVBFX01PRFJFRgkJKnBlbTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZTsKCUxQVk9JRAkJCW1lbTsKCUxQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwoJUERCMzIJCQkqcGRiID0gdGhkYi0+cHJvY2VzczsKCglwZW0gPSBwZGItPm1vZHJlZl9saXN0OwoJd2hpbGUgKHBlbSkgewoJCXBlaCA9IFBFX0hFQURFUihwZW0tPm1vZHVsZSk7CgkJaWYgKCFwZWgtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRklMRV9USFJFQURfTE9DQUxfU1RPUkFHRV0uVmlydHVhbEFkZHJlc3MpIHsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJcGRpciA9IChMUFZPSUQpKHBlbS0+bW9kdWxlICsgcGVoLT5PcHRpb25hbEhlYWRlci4KCQkJRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcyk7CgkJCgkJaWYgKCEocGVtLT5mbGFncyAmIFBFX01PRFJFRl9UTFNfQUxMT0NFRCkpIHsKCQkJcGVtLT50bHNpbmRleCA9IFRsc0FsbG9jKCk7CgkJCSoocGRpci0+QWRkcmVzc09mSW5kZXgpPXBlbS0+dGxzaW5kZXg7ICAgCgkJfQoJCXBlbS0+ZmxhZ3MgfD0gUEVfTU9EUkVGX1RMU19BTExPQ0VEOwoJCWRhdGFzaXplPSBwZGlyLT5FbmRBZGRyZXNzT2ZSYXdEYXRhLXBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YTsKCQlzaXplCT0gZGF0YXNpemUgKyBwZGlyLT5TaXplT2ZaZXJvRmlsbDsKCQltZW09VmlydHVhbEFsbG9jKDAsc2l6ZSxNRU1fUkVTRVJWRXxNRU1fQ09NTUlULFBBR0VfUkVBRFdSSVRFKTsKCQltZW1jcHkobWVtLChMUFZPSUQpIHBkaXItPlN0YXJ0QWRkcmVzc09mUmF3RGF0YSwgZGF0YXNpemUpOwoJCS8qIGRvbid0IHVzZSBUbHNTZXRWYWx1ZSwgd2UgYXJlIGluIHRoZSB3cm9uZyB0aHJlYWQgKi8KCQl0aGRiLT50bHNfYXJyYXlbcGVtLT50bHNpbmRleF0gPSBtZW07CgkJcGVtPXBlbS0+bmV4dDsKCX0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCURpc2FibGVUaHJlYWRMaWJyYXJ5Q2FsbHMgKEtFUk5FTDMyLjc0KQogKiBEb24ndCBjYWxsIERsbEVudHJ5UG9pbnQgZm9yIERMTF9USFJFQURfe0FUVEFDSCxERVRBQ0h9IGlmIHNldC4KICovCkJPT0wzMiBXSU5BUEkgRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyhITU9EVUxFMzIgaE1vZHVsZSkKewoJUERCMzIJKnByb2Nlc3MgPSBQUk9DRVNTX0N1cnJlbnQoKTsKCVBFX01PRFJFRgkqcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7CgoJd2hpbGUgKHBlbSkgewoJCWlmIChwZW0tPm1vZHVsZSA9PSBoTW9kdWxlKQoJCQlwZW0tPmZsYWdzfD1QRV9NT0RSRUZfTk9fRExMX0NBTExTOwoJCXBlbSA9IHBlbS0+bmV4dDsKCX0KCXJldHVybiBUUlVFOwp9Cgo=