I2lmbmRlZiBXSU5FTElCCi8qIAogKiAgQ29weXJpZ2h0CTE5OTQJRXJpYyBZb3VuZGFsZSAmIEVyaWsgQm9zCiAqICBDb3B5cmlnaHQJMTk5NQlNYXJ0aW4gdm9uIEz2d2lzCiAqICBDb3B5cmlnaHQgICAxOTk2ICAgIE1hcmN1cyBNZWlzc25lcgogKgogKgliYXNlZCBvbiBFcmljIFlvdW5kYWxlJ3MgcGUtdGVzdCBhbmQ6CiAqCiAqCWZ0cC5taWNyb3NvZnQuY29tOi9wdWIvZGV2ZWxvcGVyL01TRE4vQ0Q4L1BFRklMRS5aSVAKICogbWFrZSB0aGF0OgogKglmdHAubWljcm9zb2Z0LmNvbTovZGV2ZWxvcHIvTVNETi9PY3RDRC9QRUZJTEUuWklQCiAqLwoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgIndpbmRvd3MuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgImNhbGxiYWNrLmgiCiNpbmNsdWRlICJuZWV4ZS5oIgojaW5jbHVkZSAicGVleGUuaCIKI2luY2x1ZGUgInByb2Nlc3MuaCIKI2luY2x1ZGUgInBlX2ltYWdlLmgiCiNpbmNsdWRlICJtb2R1bGUuaCIKI2luY2x1ZGUgImdsb2JhbC5oIgojaW5jbHVkZSAidGFzay5oIgojaW5jbHVkZSAibGR0LmgiCiNpbmNsdWRlICJvcHRpb25zLmgiCiNpbmNsdWRlICJzdGRkZWJ1Zy5oIgojaW5jbHVkZSAiZGVidWcuaCIKI2luY2x1ZGUgImRlYnVnZ2VyLmgiCiNpbmNsdWRlICJ4bWFsbG9jLmgiCgpzdGF0aWMgdm9pZCBQRV9Jbml0RExMKFBFX01PRFJFRiogbW9kcmVmLCBEV09SRCB0eXBlLCBMUFZPSUQgbHBSZXNlcnZlZCk7CgovKiBjb252ZXJ0IFBFIGltYWdlIFZpcnR1YWxBZGRyZXNzIHRvIFJlYWwgQWRkcmVzcyAqLwojZGVmaW5lIFJWQSh4KSAoKHVuc2lnbmVkIGludClsb2FkX2FkZHIrKHVuc2lnbmVkIGludCkoeCkpCgp2b2lkIGR1bXBfZXhwb3J0cyhJTUFHRV9FWFBPUlRfRElSRUNUT1JZICogcGVfZXhwb3J0cywgdW5zaWduZWQgaW50IGxvYWRfYWRkcikKeyAKICBjaGFyCQkqTW9kdWxlOwogIGludAkJaTsKICB1X3Nob3J0CSpvcmRpbmFsOwogIHVfbG9uZwkqZnVuY3Rpb24sKmZ1bmN0aW9uczsKICB1X2NoYXIJKipuYW1lLCplbmFtZTsKICBjaGFyCQlidWZmZXJbMTAwMF07CiAgREJHX0FERFIJZGFkZHI7CgogIGRhZGRyLnNlZyA9IDA7CiAgZGFkZHIudHlwZSA9IE5VTEw7CiAgTW9kdWxlID0gKGNoYXIqKVJWQShwZV9leHBvcnRzLT5OYW1lKTsKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiXG4qKioqKioqRVhQT1JUIERBVEEqKioqKioqXG5Nb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLCAKCSBNb2R1bGUsCgkgcGVfZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMsCgkgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWw9KHVfc2hvcnQqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZU9yZGluYWxzKTsKICBmdW5jdGlvbnM9ZnVuY3Rpb249KHVfbG9uZyopIFJWQShwZV9leHBvcnRzLT5BZGRyZXNzT2ZGdW5jdGlvbnMpOwogIG5hbWU9KHVfY2hhcioqKSBSVkEocGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiJS0zMnMgT3JkaW5hbCBWaXJ0IEFkZHJcbiIsICJGdW5jdGlvbiBOYW1lIik7CiAgZm9yIChpPTA7aTxwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucztpKyspIHsKICAgICAgaWYgKGk8cGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcykgewoJICBlbmFtZT0oY2hhciopUlZBKCpuYW1lKyspOwoJICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiJS0zMnMgJTRkICAgICU4LjhseCAoJTguOGx4KVxuIixlbmFtZSwqb3JkaW5hbCxmdW5jdGlvbnNbKm9yZGluYWxdLCpmdW5jdGlvbik7CgkgIHNwcmludGYoYnVmZmVyLCIlc18lcyIsTW9kdWxlLGVuYW1lKTsKCSAgZGFkZHIub2ZmPVJWQShmdW5jdGlvbnNbKm9yZGluYWxdKTsKCSAgb3JkaW5hbCsrOwoJICBmdW5jdGlvbisrOwogICAgICB9IGVsc2UgewogICAgICAJICAvKiBvcmRpbmFscy9uYW1lcyBubyBsb25nZXIgdmFsaWQsIGJ1dCB3ZSBzdGlsbCBnb3QgZnVuY3Rpb25zICovCgkgIGRwcmludGZfd2luMzIoc3RkZGViLCIlLTMycyAlNHMgICAgJThzICU4LjhseFxuIiwiIiwiIiwiIiwqZnVuY3Rpb24pOwoJICBzcHJpbnRmKGJ1ZmZlciwiJXNfJWQiLE1vZHVsZSxpKTsKCSAgZGFkZHIub2ZmPVJWQSgqZnVuY3Rpb25zKTsKCSAgZnVuY3Rpb24rKzsKICAgICAgfQogICAgICBERUJVR19BZGRTeW1ib2woYnVmZmVyLCZkYWRkciwgTlVMTCwgU1lNX1dJTjMyIHwgU1lNX0ZVTkMpOwogIH0KfQoKLyogTG9vayB1cCB0aGUgc3BlY2lmaWVkIGZ1bmN0aW9uIG9yIG9yZGluYWwgaW4gdGhlIGV4cG9ydGxpc3Q6CiAqIElmIGl0IGlzIGEgc3RyaW5nOgogKiAJLSBsb29rIHVwIHRoZSBuYW1lIGluIHRoZSBOYW1lIGxpc3QuIAogKgktIGxvb2sgdXAgdGhlIG9yZGluYWwgd2l0aCB0aGF0IGluZGV4LgogKgktIHVzZSB0aGUgb3JkaW5hbCBhcyBvZmZzZXQgaW50byB0aGUgZnVuY3Rpb25saXN0CiAqIElmIGl0IGlzIGEgb3JkaW5hbDoKICoJLSB1c2Ugb3JkaW5hbC1wZV9leHBvcnQtPkJhc2UgYXMgb2Zmc2V0IGludG8gdGhlIGZ1bmN0aW9ubGlzdAogKi8KRkFSUFJPQzMyIFBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKHN0cnVjdCBwZV9kYXRhICpwZSwgTFBDU1RSIGZ1bmNOYW1lKQp7CglJTUFHRV9FWFBPUlRfRElSRUNUT1JZIAkJKmV4cG9ydHM7Cgl1bnNpZ25lZAkJCWxvYWRfYWRkcjsKCXVfc2hvcnQJCQkJKiBvcmRpbmFsOwoJdV9sb25nCQkJCSogZnVuY3Rpb247Cgl1X2NoYXIJCQkJKiogbmFtZSwgKmVuYW1lOwoJaW50CQkJCWk7CglQREIzMgkJCQkqcHJvY2Vzcz0oUERCMzIqKUdldEN1cnJlbnRQcm9jZXNzSWQoKTsKCVBFX01PRFJFRgkJCSpwZW07CgoJcGVtID0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cgl3aGlsZSAocGVtICYmIChwZW0tPnBlX21vZHVsZSAhPSBwZSkpCgkJcGVtPXBlbS0+bmV4dDsKCWlmICghcGVtKSB7CgkJZnByaW50ZihzdGRlcnIsIk5vIE1PRFJFRiBmb3VuZCBmb3IgUEVfTU9EVUxFICVwIGluIHByb2Nlc3MgJXBcbiIscGUscHJvY2Vzcyk7CgkJcmV0dXJuIE5VTEw7Cgl9Cglsb2FkX2FkZHIJPSBwZW0tPmxvYWRfYWRkcjsKCWV4cG9ydHMJCT0gcGVtLT5wZV9leHBvcnQ7CgoJaWYgKEhJV09SRChmdW5jTmFtZSkpCgkJZHByaW50Zl93aW4zMihzdGRkZWIsIlBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCVzKVxuIixmdW5jTmFtZSk7CgllbHNlCgkJZHByaW50Zl93aW4zMihzdGRkZWIsIlBFX0ZpbmRFeHBvcnRlZEZ1bmN0aW9uKCVkKVxuIiwoaW50KWZ1bmNOYW1lKTsKCWlmICghZXhwb3J0cykgewoJCWZwcmludGYoc3RkZXJyLCJNb2R1bGUgJXAvTU9EUkVGICVwIGRvZXNuJ3QgaGF2ZSBhIGV4cG9ydHMgdGFibGUuXG4iLHBlLHBlbSk7CgkJcmV0dXJuIE5VTEw7Cgl9CglvcmRpbmFsCT0gKHVfc2hvcnQqKSAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CglmdW5jdGlvbj0gKHVfbG9uZyopICAgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CgluYW1lCT0gKHVfY2hhciAqKikgUlZBKGV4cG9ydHMtPkFkZHJlc3NPZk5hbWVzKTsKCglpZiAoSElXT1JEKGZ1bmNOYW1lKSkgewoJCWZvcihpPTA7IGk8ZXhwb3J0cy0+TnVtYmVyT2ZOYW1lczsgaSsrKSB7CgkJCWVuYW1lPShjaGFyKilSVkEoKm5hbWUpOwoJCQlpZighc3RyY21wKGVuYW1lLGZ1bmNOYW1lKSkKCQkJCXJldHVybiAoRkFSUFJPQzMyKSBSVkEoZnVuY3Rpb25bKm9yZGluYWxdKTsKCQkJb3JkaW5hbCsrOwoJCQluYW1lKys7CgkJfQoJfSBlbHNlIHsKCQlpZiAoTE9XT1JEKGZ1bmNOYW1lKS1leHBvcnRzLT5CYXNlID4gZXhwb3J0cy0+TnVtYmVyT2ZGdW5jdGlvbnMpIHsKCQkJZHByaW50Zl93aW4zMihzdGRkZWIsIglvcmRpbmFsICVkIG91dCBvZiByYW5nZSFcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9XT1JEKGZ1bmNOYW1lKSk7CgkJCXJldHVybiBOVUxMOwoJCX0KCQlyZXR1cm4gKEZBUlBST0MzMikgUlZBKGZ1bmN0aW9uWyhpbnQpZnVuY05hbWUtZXhwb3J0cy0+QmFzZV0pOwoJfQoJcmV0dXJuIE5VTEw7Cn0KCnZvaWQgCmZpeHVwX2ltcG9ydHMgKFBEQjMyICpwcm9jZXNzLFBFX01PRFJFRiAqcGVtKQp7CiAgICBQRV9NT0RVTEUJCQkqcGUgPSBwZW0tPnBlX21vZHVsZTsKICAgIElNQUdFX0lNUE9SVF9ERVNDUklQVE9SCSpwZV9pbXA7CiAgICBpbnQJZml4dXBfZmFpbGVkCQk9IDA7CiAgICB1bnNpZ25lZCBpbnQgbG9hZF9hZGRyCT0gcGVtLT5sb2FkX2FkZHI7CiAgICBpbnQJCQkJaTsKICAgIGNoYXIJCQkqbW9kbmFtZTsKICAgIAogICAgaWYgKHBlbS0+cGVfZXhwb3J0KQogICAgCW1vZG5hbWUgPSAoY2hhciopIFJWQShwZW0tPnBlX2V4cG9ydC0+TmFtZSk7CiAgICBlbHNlCiAgICAgICAgbW9kbmFtZSA9ICI8dW5rbm93bj4iOwoKICAgIC8qIE9LLCBub3cgZHVtcCB0aGUgaW1wb3J0IGxpc3QgKi8KICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIlxuRHVtcGluZyBpbXBvcnRzIGxpc3RcbiIpOwoKICAgIC8qIGZpcnN0LCBjb3VudCB0aGUgbnVtYmVyIG9mIGltcG9ydGVkIG5vbi1pbnRlcm5hbCBtb2R1bGVzICovCiAgICBwZV9pbXAgPSBwZW0tPnBlX2ltcG9ydDsKICAgIGlmICghcGVfaW1wKSAKICAgIAlmcHJpbnRmKHN0ZGVyciwibm8gaW1wb3J0IGRpcmVjdG9yeT8/Pz9cbiIpOwoKICAgIC8qIEZJWE1FOiBzaG91bGQgdGVybWluYXRlIG9uIDAgQ2hhcmFjdGVyaXN0aWNzICovCiAgICBmb3IgKGkgPSAwOyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKQoJaSsrOwoKICAgIC8qIGxvYWQgdGhlIGltcG9ydGVkIG1vZHVsZXMuIFRoZXkgYXJlIGF1dG9tYXRpY2FsbHkgCiAgICAgKiBhZGRlZCB0byB0aGUgbW9kcmVmIGxpc3Qgb2YgdGhlIHByb2Nlc3MuCiAgICAgKi8KIAogICAgLyogRklYTUU6IHNob3VsZCB0ZXJtaW5hdGUgb24gMCBDaGFyYWN0ZXJpc3RpY3MgKi8KICAgIGZvciAoaSA9IDAsIHBlX2ltcCA9IHBlbS0+cGVfaW1wb3J0OyBwZV9pbXAtPk5hbWU7IHBlX2ltcCsrKSB7CiAgICAJSE1PRFVMRTMyCXJlczsKCVBFX01PRFJFRgkqeHBlbSwqKnlwZW07CgoKIAljaGFyICpuYW1lID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CgoJLyogZG9uJ3QgdXNlIE1PRFVMRV9Mb2FkLCBXaW4zMiBjcmVhdGVzIG5ldyB0YXNrIGRpZmZlcmVudGx5ICovCglyZXMgPSBQRV9Mb2FkTGlicmFyeUV4MzJBKCBuYW1lLCAwLCAwICk7CglpZiAocmVzIDw9IChITU9EVUxFMzIpIDMyKSB7CgkgICAgY2hhciAqcCwgYnVmZmVyWzI1Nl07CgoJICAgIC8qIFRyeSB3aXRoIHByZXBlbmRpbmcgdGhlIHBhdGggb2YgdGhlIGN1cnJlbnQgbW9kdWxlICovCgkgICAgR2V0TW9kdWxlRmlsZU5hbWUzMkEgKHBlLT5tYXBwZWRkbGwsIGJ1ZmZlciwgc2l6ZW9mIChidWZmZXIpKTsKCSAgICBpZiAoIShwID0gc3RycmNociAoYnVmZmVyLCAnXFwnKSkpCgkJcCA9IGJ1ZmZlcjsKCSAgICBzdHJjcHkgKHAgKyAxLCBuYW1lKTsKCSAgICByZXMgPSBQRV9Mb2FkTGlicmFyeUV4MzJBKCBidWZmZXIsIDAsIDAgKTsKCX0KCWlmIChyZXMgPD0gKEhNT0RVTEUzMikgMzIpIHsKCSAgICBmcHJpbnRmIChzdGRlcnIsICJNb2R1bGUgJXMgbm90IGZvdW5kXG4iLCBuYW1lKTsKCSAgICBleGl0ICgwKTsKCX0KCXJlcyA9IE1PRFVMRV9IQU5ETEV0b0hNT0RVTEUzMihyZXMpOwoJeHBlbSA9IHBlbS0+bmV4dDsKCXdoaWxlICh4cGVtKSB7CgkJaWYgKHhwZW0tPnBlX21vZHVsZS0+bWFwcGVkZGxsID09IHJlcykKCQkJYnJlYWs7CgkJeHBlbSA9IHhwZW0tPm5leHQ7Cgl9CglpZiAoeHBlbSkgewoJCS8qIGl0IGhhcyBiZWVuIGxvYWRlZCAqQkVGT1JFKiB1cywgc28gd2UgaGF2ZSB0byBpbml0CgkJICogaXQgYmVmb3JlIHVzLiB3ZSBqdXN0IHN3YXAgdGhlIHR3byBtb2R1bGVzIHdoaWNoIHNob3VsZAoJCSAqIHdvcmsuCgkJICovCgkJLyogdW5saW5rIHhwZW0gZnJvbSBjaGFpbiAqLwoJCXlwZW0gPSAmKHByb2Nlc3MtPm1vZHJlZl9saXN0KTsKCQl3aGlsZSAoKnlwZW0pIHsKCQkJaWYgKCgqeXBlbSk9PXhwZW0pCgkJCQlicmVhazsKCQkJeXBlbSA9ICYoKCp5cGVtKS0+bmV4dCk7CgkJfQoJCSp5cGVtCQk9IHhwZW0tPm5leHQ7CgoJCS8qIGxpbmsgaXQgZGlyZWN0bHkgYmVmb3JlIHBlbSAqLwoJCXlwZW0JCT0gJihwcm9jZXNzLT5tb2RyZWZfbGlzdCk7CgkJd2hpbGUgKCp5cGVtKSB7CgkJCWlmICgoKnlwZW0pPT1wZW0pCgkJCQlicmVhazsKCQkJeXBlbSA9ICYoKCp5cGVtKS0+bmV4dCk7CgkJfQoJCSp5cGVtCQk9IHhwZW07CgkJeHBlbS0+bmV4dAk9IHBlbTsKCQkKCX0KCWkrKzsKICAgIH0KICAgIHBlX2ltcCA9IHBlbS0+cGVfaW1wb3J0OwogICAgd2hpbGUgKHBlX2ltcC0+TmFtZSkgewoJY2hhcgkJCSpNb2R1bGU7CglJTUFHRV9JTVBPUlRfQllfTkFNRQkqcGVfbmFtZTsKCUxQSU1BR0VfVEhVTktfREFUQQlpbXBvcnRfbGlzdCx0aHVua19saXN0OwoJaW50CQkJb3JkaW1wb3J0d2FybmVkOwoKICAgICAgICBvcmRpbXBvcnR3YXJuZWQgPSAwOwoJTW9kdWxlID0gKGNoYXIgKikgUlZBKHBlX2ltcC0+TmFtZSk7CglkcHJpbnRmX3dpbjMyIChzdGRkZWIsICIlc1xuIiwgTW9kdWxlKTsKCgkvKiBGSVhNRTogZm9yd2FyZGVyIGVudHJpZXMgLi4uICovCgoJaWYgKHBlX2ltcC0+dS5PcmlnaW5hbEZpcnN0VGh1bmsgIT0gMCkgeyAvKiBvcmlnaW5hbCBNUyBzdHlsZSAqLwoJICAgIGRwcmludGZfd2luMzIgKHN0ZGRlYiwgIk1pY3Jvc29mdCBzdHlsZSBpbXBvcnRzIHVzZWRcbiIpOwoJICAgIGltcG9ydF9saXN0ID0oTFBJTUFHRV9USFVOS19EQVRBKSBSVkEocGVfaW1wLT51Lk9yaWdpbmFsRmlyc3RUaHVuayk7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoKCSAgICB3aGlsZSAoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpIHsKCQlpZiAoSU1BR0VfU05BUF9CWV9PUkRJTkFMKGltcG9ydF9saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICBpbnQgb3JkaW5hbCA9IElNQUdFX09SRElOQUwoaW1wb3J0X2xpc3QtPnUxLk9yZGluYWwpOwoKCQkgICAgaWYoIWxzdHJuY21waTMyQShNb2R1bGUsImtlcm5lbDMyIiw4KSAmJiAhb3JkaW1wb3J0d2FybmVkKXsKCQkgICAgICAgZnByaW50ZihzdGRlcnIsIiVzIGltcG9ydHMga2VybmVsMzIuZGxsIGJ5IG9yZGluYWwuIE1heSBjcmFzaC5cbiIsbW9kbmFtZSk7CgkJICAgICAgIG9yZGltcG9ydHdhcm5lZCA9IDE7CgkJICAgIH0KCQkgICAgZHByaW50Zl93aW4zMiAoc3RkZGViLCAiLS0tIE9yZGluYWwgJXMsJWRcbiIsIE1vZHVsZSwgb3JkaW5hbCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoTU9EVUxFX0ZpbmRNb2R1bGUoTW9kdWxlKSwoTFBDU1RSKW9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCJObyBpbXBsZW1lbnRhdGlvbiBmb3IgJXMuJWQsIHNldHRpbmcgdG8gTlVMTFxuIiwKCQkJCU1vZHVsZSwgb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsJCS8qIGltcG9ydCBieSBuYW1lICovCgkJICAgIHBlX25hbWUgPSAoTFBJTUFHRV9JTVBPUlRfQllfTkFNRSlSVkEoaW1wb3J0X2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICItLS0gJXMgJXMuJWRcbiIsIHBlX25hbWUtPk5hbWUsIE1vZHVsZSwgcGVfbmFtZS0+SGludCk7CgkJICAgIHRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uPShMUERXT1JEKUdldFByb2NBZGRyZXNzMzIoCgkJCQkJCU1PRFVMRV9GaW5kTW9kdWxlIChNb2R1bGUpLAoJCQkJCQlwZV9uYW1lLT5OYW1lKTsKCQkgICAgaWYgKCF0aHVua19saXN0LT51MS5GdW5jdGlvbikgewoJCQlmcHJpbnRmKHN0ZGVyciwiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkKCVzKSwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLHBlX25hbWUtPkhpbnQscGVfbmFtZS0+TmFtZSk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCWltcG9ydF9saXN0Kys7CgkJdGh1bmtfbGlzdCsrOwoJICAgIH0KCX0gZWxzZSB7CS8qIEJvcmxhbmQgc3R5bGUgKi8KCSAgICBkcHJpbnRmX3dpbjMyIChzdGRkZWIsICJCb3JsYW5kIHN0eWxlIGltcG9ydHMgdXNlZFxuIik7CgkgICAgdGh1bmtfbGlzdCA9IChMUElNQUdFX1RIVU5LX0RBVEEpIFJWQShwZV9pbXAtPkZpcnN0VGh1bmspOwoJICAgIHdoaWxlICh0aHVua19saXN0LT51MS5PcmRpbmFsKSB7CgkJaWYgKElNQUdFX1NOQVBfQllfT1JESU5BTCh0aHVua19saXN0LT51MS5PcmRpbmFsKSkgewoJCSAgICAvKiBub3Qgc3VyZSBhYm91dCB0aGlzIGJyYW5jaCwgYnV0IGl0IHNlZW1zIHRvIHdvcmsgKi8KCQkgICAgaW50IG9yZGluYWwgPSBJTUFHRV9PUkRJTkFMKHRodW5rX2xpc3QtPnUxLk9yZGluYWwpOwoKCgkJICAgIGlmICghbHN0cm5jbXBpMzJBKE1vZHVsZSwia2VybmVsMzIiLDgpICYmIAoJCSAgICAJIW9yZGltcG9ydHdhcm5lZAoJCSAgICApIHsKCQkgICAgICAgZnByaW50ZihzdGRlcnIsIiVzIGltcG9ydHMga2VybmVsMzIuZGxsIGJ5IG9yZGluYWwuIE1heSBjcmFzaC5cbiIsbW9kbmFtZSk7CgkJICAgICAgIG9yZGltcG9ydHdhcm5lZCA9IDE7CgkJICAgIH0KCQkgICAgZHByaW50Zl93aW4zMihzdGRkZWIsIi0tLSBPcmRpbmFsICVzLiVkXG4iLE1vZHVsZSxvcmRpbmFsKTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLAoJCQkJCQkgICAgIChMUENTVFIpIG9yZGluYWwpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJCWZwcmludGYoc3RkZXJyLCAiTm8gaW1wbGVtZW50YXRpb24gZm9yICVzLiVkLCBzZXR0aW5nIHRvIE5VTExcbiIsCgkJCQlNb2R1bGUsb3JkaW5hbCk7CgkJCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfSBlbHNlIHsKCQkgICAgcGVfbmFtZT0oTFBJTUFHRV9JTVBPUlRfQllfTkFNRSkgUlZBKHRodW5rX2xpc3QtPnUxLkFkZHJlc3NPZkRhdGEpOwoJCSAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwiLS0tICVzICVzLiVkXG4iLAoJCSAgIAkJICBwZV9uYW1lLT5OYW1lLE1vZHVsZSxwZV9uYW1lLT5IaW50KTsKCQkgICAgdGh1bmtfbGlzdC0+dTEuRnVuY3Rpb249KExQRFdPUkQpR2V0UHJvY0FkZHJlc3MzMihNT0RVTEVfRmluZE1vZHVsZShNb2R1bGUpLHBlX25hbWUtPk5hbWUpOwoJCSAgICBpZiAoIXRodW5rX2xpc3QtPnUxLkZ1bmN0aW9uKSB7CgkJICAgIAlmcHJpbnRmKHN0ZGVyciwgIk5vIGltcGxlbWVudGF0aW9uIGZvciAlcy4lZCwgc2V0dGluZyB0byBOVUxMXG4iLAoJCQkJTW9kdWxlLCBwZV9uYW1lLT5IaW50KTsKCQkgICAgCS8qIGZpeHVwX2ZhaWxlZD0xOyAqLwoJCSAgICB9CgkJfQoJCXRodW5rX2xpc3QrKzsKCSAgICB9Cgl9CglwZV9pbXArKzsKICAgIH0KICAgIGlmIChmaXh1cF9mYWlsZWQpIGV4aXQoMSk7Cn0KCnN0YXRpYyBpbnQgY2FsY192bWFfc2l6ZShzdHJ1Y3QgcGVfZGF0YSAqcGUpCnsKICBpbnQgaSx2bWFfc2l6ZSA9IDA7CgogIGRwcmludGZfd2luMzIoc3RkZGViLCAiRHVtcCBvZiBzZWdtZW50IHRhYmxlXG4iKTsKICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIiAgIE5hbWUgICAgVlN6ICBWYWRkciAgICAgU3pSYXcgICBGaWxlYWRyICAqUmVsb2MgKkxpbmV1bSAjUmVsb2MgI0xpbnVtIENoYXJcbiIpOwogIGZvcihpPTA7IGk8IHBlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuTnVtYmVyT2ZTZWN0aW9uczsgaSsrKQogICAgewogICAgICBkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIiU4czogJTQuNGx4ICU4LjhseCAlOC44bHggJTguOGx4ICU4LjhseCAlOC44bHggJTQuNHggJTQuNHggJTguOGx4XG4iLCAKCSAgICAgcGUtPnBlX3NlZ1tpXS5OYW1lLCAKCSAgICAgcGUtPnBlX3NlZ1tpXS5NaXNjLlZpcnR1YWxTaXplLAoJICAgICBwZS0+cGVfc2VnW2ldLlZpcnR1YWxBZGRyZXNzLAoJICAgICBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEsCgkgICAgIHBlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmF3RGF0YSwKCSAgICAgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9SZWxvY2F0aW9ucywKCSAgICAgcGUtPnBlX3NlZ1tpXS5Qb2ludGVyVG9MaW5lbnVtYmVycywKCSAgICAgcGUtPnBlX3NlZ1tpXS5OdW1iZXJPZlJlbG9jYXRpb25zLAoJICAgICBwZS0+cGVfc2VnW2ldLk51bWJlck9mTGluZW51bWJlcnMsCgkgICAgIHBlLT5wZV9zZWdbaV0uQ2hhcmFjdGVyaXN0aWNzKTsKCSAgdm1hX3NpemUgPSBNQVgodm1hX3NpemUsCgkgIAkJcGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyArIAoJCQlwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpOwogICAgfQogICAgcmV0dXJuIHZtYV9zaXplOwp9CgpzdGF0aWMgdm9pZCBkb19yZWxvY2F0aW9ucyhQRV9NT0RSRUYgKnBlbSkKewoJaW50IGRlbHRhID0gcGVtLT5sb2FkX2FkZHIgLSBwZW0tPnBlX21vZHVsZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CgoJdW5zaWduZWQgaW50CQkJbG9hZF9hZGRyPSBwZW0tPmxvYWRfYWRkcjsKCUlNQUdFX0JBU0VfUkVMT0NBVElPTgkJKnIgPSBwZW0tPnBlX3JlbG9jOwoJaW50CQkJCWhkZWx0YSA9IChkZWx0YSA+PiAxNikgJiAweEZGRkY7CglpbnQJCQkJbGRlbHRhID0gZGVsdGEgJiAweEZGRkY7CgoJLyogaW50IHJlbG9jX3NpemUgPSAqLwoKCWlmKGRlbHRhID09IDApCgkJLyogTm90aGluZyB0byBkbyAqLwoJCXJldHVybjsKCXdoaWxlKHItPlZpcnR1YWxBZGRyZXNzKQoJewoJCWNoYXIgKnBhZ2UgPSAoY2hhciopIFJWQShyLT5WaXJ0dWFsQWRkcmVzcyk7CgkJaW50IGNvdW50ID0gKHItPlNpemVPZkJsb2NrIC0gOCkvMjsKCQlpbnQgaTsKCQlkcHJpbnRmX2ZpeHVwKHN0ZGRlYiwgIiV4IHJlbG9jYXRpb25zIGZvciBwYWdlICVseFxuIiwKCQkJY291bnQsIHItPlZpcnR1YWxBZGRyZXNzKTsKCQkvKiBwYXRjaGluZyBpbiByZXZlcnNlIG9yZGVyICovCgkJZm9yKGk9MDtpPGNvdW50O2krKykKCQl7CgkJCWludCBvZmZzZXQgPSByLT5UeXBlT2Zmc2V0W2ldICYgMHhGRkY7CgkJCWludCB0eXBlID0gci0+VHlwZU9mZnNldFtpXSA+PiAxMjsKCQkJZHByaW50Zl9maXh1cChzdGRkZWIsInBhdGNoaW5nICV4IHR5cGUgJXhcbiIsIG9mZnNldCwgdHlwZSk7CgkJCXN3aXRjaCh0eXBlKQoJCQl7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0FCU09MVVRFOiBicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSDoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gaGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0xPVzoKCQkJCSooc2hvcnQqKShwYWdlK29mZnNldCkgKz0gbGRlbHRhOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX0hJR0hMT1c6CiNpZiAxCgkJCQkqKGludCopKHBhZ2Urb2Zmc2V0KSArPSBkZWx0YTsKI2Vsc2UKCQkJCXsgaW50IGg9Kih1bnNpZ25lZCBzaG9ydCopKHBhZ2Urb2Zmc2V0KTsKCQkJCSAgaW50IGw9ci0+VHlwZU9mZnNldFsrK2ldOwoJCQkJICAqKHVuc2lnbmVkIGludCopKHBhZ2UgKyBvZmZzZXQpID0gKGg8PDE2KSArIGwgKyBkZWx0YTsKCQkJCX0KI2VuZGlmCgkJCQlicmVhazsKCQkJY2FzZSBJTUFHRV9SRUxfQkFTRURfSElHSEFESjoKCQkJCWZwcmludGYoc3RkZXJyLCAiRG9uJ3Qga25vdyB3aGF0IHRvIGRvIHdpdGggSU1BR0VfUkVMX0JBU0VEX0hJR0hBREpcbiIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgSU1BR0VfUkVMX0JBU0VEX01JUFNfSk1QQUREUjoKCQkJCWZwcmludGYoc3RkZXJyLCAiSXMgdGhpcyBhIE1JUFMgbWFjaGluZSA/Pz9cbiIpOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gZml4dXAgdHlwZVxuIik7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlyID0gKElNQUdFX0JBU0VfUkVMT0NBVElPTiopKChjaGFyKilyICsgci0+U2l6ZU9mQmxvY2spOwoJfQp9CgkJCgoJCgkKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQkJUEVfTG9hZEltYWdlCiAqIExvYWQgb25lIFBFIGZvcm1hdCBETEwvRVhFIGludG8gbWVtb3J5CiAqIAogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvciAKICogKGF0IGxlYXN0KSBMaW51eCBkb2VzIG9ubHkgc3VwcG9ydCBvZmZzZXQgd2l0aCBhcmUgbXVsdGlwbGVzIG9mIHRoZQogKiB1bmRlcmx5aW5nIGZpbGVzeXN0ZW1ibG9ja3NpemUsIGJ1dCBQRSBETExzIHVzdWFsbHkgaGF2ZSBhbGlnbm1lbnRzIG9mIDUxMgogKiBieXRlLiBUaGlzIGZhaWxzIGZvciBpbnN0YW5jZSB3aGVuIHlvdSB0cnkgdG8gbWFwIGZyb20gQ0RST00gKGJzaXplIDIwNDgpLgogKgogKiBCVVQgd2UgaGF2ZSB0byBtYXAgdGhlIHdob2xlIGltYWdlIGFueXdheSwgZm9yIFdpbjMyIHByb2dyYW1zIHNvbWV0aW1lcwogKiB3YW50IHRvIGFjY2VzcyB0aGVtLiAoSE1PRFVMRTMyIHBvaW50IHRvIHRoZSBzdGFydCBvZiBpdCkKICovCnN0YXRpYyBQRV9NT0RVTEUgKlBFX0xvYWRJbWFnZSggaW50IGZkICkKewoJc3RydWN0IHBlX2RhdGEJCSpwZTsKCURCR19BRERSCQlkYWRkcjsKCXN0cnVjdCBzdGF0CQlzdGJ1ZjsKCglkYWRkci5zZWc9MDsKCWRhZGRyLnR5cGUgPSBOVUxMOwoJaWYgKC0xPT1mc3RhdChmZCwmc3RidWYpKSB7CgkJcGVycm9yKCJQRV9Mb2FkSW1hZ2U6ZnN0YXQiKTsKCQlyZXR1cm4gTlVMTDsKCX0KCXBlID0geG1hbGxvYyhzaXplb2Yoc3RydWN0IHBlX2RhdGEpKTsKCW1lbXNldChwZSwwLHNpemVvZihzdHJ1Y3QgcGVfZGF0YSkpOwoKCS8qIG1hcCB0aGUgUEUgaW1hZ2Ugc29tZXdoZXJlICovCglwZS0+bWFwcGVkZGxsID0gKEhNT0RVTEUzMiltbWFwKE5VTEwsc3RidWYuc3Rfc2l6ZSxQUk9UX1JFQUQsTUFQX1NIQVJFRCxmZCwwKTsKCWlmICghcGUtPm1hcHBlZGRsbCB8fCBwZS0+bWFwcGVkZGxsPT0tMSkgewoJCXBlcnJvcigiUEVfTG9hZEltYWdlOm1tYXAiKTsKCQlmcmVlKHBlKTsKCQlyZXR1cm4gTlVMTDsKCX0KCS8qIGxpbmsgUEUgaGVhZGVyICovCglwZS0+cGVfaGVhZGVyID0gKElNQUdFX05UX0hFQURFUlMqKShwZS0+bWFwcGVkZGxsKygoKElNQUdFX0RPU19IRUFERVIqKXBlLT5tYXBwZWRkbGwpLT5lX2xmYW5ldykpOwoJaWYgKHBlLT5wZV9oZWFkZXItPlNpZ25hdHVyZSE9SU1BR0VfTlRfU0lHTkFUVVJFKSB7CgkJZnByaW50ZihzdGRlcnIsImltYWdlIGRvZXNuJ3QgaGF2ZSBQRSBzaWduYXR1cmUsIGJ1dCAweCUwOGx4XG4iLAoJCQlwZS0+cGVfaGVhZGVyLT5TaWduYXR1cmUKCQkpOwoJCWZyZWUocGUpOwoJCXJldHVybiBOVUxMOwoJfQoKCWlmIChwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk1hY2hpbmUgIT0gSU1BR0VfRklMRV9NQUNISU5FX0kzODYpIHsKCQlmcHJpbnRmKHN0ZGVyciwidHJ5aW5nIHRvIGxvYWQgUEUgaW1hZ2UgZm9yIHVuc3VwcG9ydGVkIGFyY2hpdGVjdHVyZSAoIik7CgkJc3dpdGNoIChwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk1hY2hpbmUpIHsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9VTktOT1dOOgoJCQlmcHJpbnRmKHN0ZGVyciwiVW5rbm93biIpO2JyZWFrOwoJCWNhc2UgSU1BR0VfRklMRV9NQUNISU5FX0k4NjA6CgkJCWZwcmludGYoc3RkZXJyLCJJODYwIik7YnJlYWs7CgkJY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUjMwMDA6CgkJCWZwcmludGYoc3RkZXJyLCJSMzAwMCIpO2JyZWFrOwoJCWNhc2UgSU1BR0VfRklMRV9NQUNISU5FX1I0MDAwOgoJCQlmcHJpbnRmKHN0ZGVyciwiUjQwMDAiKTticmVhazsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9SMTAwMDA6CgkJCWZwcmludGYoc3RkZXJyLCJSMTAwMDAiKTticmVhazsKCQljYXNlIElNQUdFX0ZJTEVfTUFDSElORV9BTFBIQToKCQkJZnByaW50ZihzdGRlcnIsIkFscGhhIik7YnJlYWs7CgkJY2FzZSBJTUFHRV9GSUxFX01BQ0hJTkVfUE9XRVJQQzoKCQkJZnByaW50ZihzdGRlcnIsIlBvd2VyUEMiKTticmVhazsKCQlkZWZhdWx0OgoJCQlmcHJpbnRmKHN0ZGVyciwiVW5rbm93bi0lMDR4IixwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk1hY2hpbmUpO2JyZWFrOwoJCX0KCQlmcHJpbnRmKHN0ZGVyciwiKVxuIik7CgkJcmV0dXJuIE5VTEw7Cgl9CglwZS0+cGVfc2VnID0gKElNQUdFX1NFQ1RJT05fSEVBREVSKikoKChMUEJZVEUpKHBlLT5wZV9oZWFkZXIrMSkpLQoJCSAoMTYgLSBwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5OdW1iZXJPZlJ2YUFuZFNpemVzKSAqIHNpemVvZihJTUFHRV9EQVRBX0RJUkVDVE9SWSkpOwoKLyogRklYTUU6IHRoZSAoMTYtLi4uKSBpcyBhICpob3JyaWJsZSogaGFjayB0byBtYWtlIENPTURMRzMyLkRMTCBsb2FkIE9LLiBUaGUKICogcHJvYmxlbSBuZWVkcyB0byBiZSBmaXhlZCBwcm9wZXJseSBhdCBzb21lIHN0YWdlLgogKi8KIAlyZXR1cm4gcGU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoaXMgbWFwcyBhIGxvYWRlZCBQRSBkbGwgaW50byB0aGUgYWRkcmVzcyBzcGFjZSBvZiB0aGUgc3BlY2lmaWVkIHByb2Nlc3MuCiAqLwp2b2lkClBFX01hcEltYWdlKFBFX01PRFVMRSAqcGUsUERCMzIgKnByb2Nlc3MsIE9GU1RSVUNUICpvZnMsIERXT1JEIGZsYWdzKSB7CglQRV9NT0RSRUYJCSpwZW07CglpbnQJCQlpLCByZXN1bHQ7CglpbnQJCQlsb2FkX2FkZHI7CglJTUFHRV9EQVRBX0RJUkVDVE9SWQlkaXI7CgljaGFyCQkJYnVmZmVyWzIwMF07CglEQkdfQUREUgkJZGFkZHI7CgljaGFyCQkJKm1vZG5hbWU7CglpbnQJCQl2bWFfc2l6ZTsKCQoJcGVtCQk9IChQRV9NT0RSRUYqKUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLEhFQVBfWkVST19NRU1PUlksc2l6ZW9mKCpwZW0pKTsKCS8qIE5PVEU6IGZpeHVwX2ltcG9ydHMgdGFrZXMgY2FyZSBvZiB0aGUgY29ycmVjdCBvcmRlciAqLwoJcGVtLT5uZXh0CT0gcHJvY2Vzcy0+bW9kcmVmX2xpc3Q7Cglwcm9jZXNzLT5tb2RyZWZfbGlzdCA9IHBlbTsKCglwZW0tPnBlX21vZHVsZQk9IHBlOwoJaWYgKCEocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkpIHsKCQlpZiAocHJvY2Vzcy0+ZXhlX21vZHJlZikKCQkJZnByaW50ZihzdGRlcnIsIm92ZXJ3cml0aW5nIG9sZCBleGVfbW9kcmVmLi4uIGFycmdoXG4iKTsKCQlwcm9jZXNzLT5leGVfbW9kcmVmID0gcGVtOwoJfQoKCWxvYWRfYWRkciAJPSBwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5JbWFnZUJhc2U7CglkcHJpbnRmX3dpbjMyKHN0ZGRlYiwgIkxvYWQgYWRkciBpcyAleFxuIixsb2FkX2FkZHIpOwoJdm1hX3NpemUgPSBjYWxjX3ZtYV9zaXplKHBlKTsKCWxvYWRfYWRkciAJPSAoaW50KSBWaXJ0dWFsQWxsb2MoICh2b2lkKilsb2FkX2FkZHIsIHZtYV9zaXplLCBNRU1fUkVTRVJWRXxNRU1fQ09NTUlULCBQQUdFX0VYRUNVVEVfUkVBRFdSSVRFICk7CiAgICAgICAgcGVtLT5sb2FkX2FkZHIJPSBsb2FkX2FkZHI7CgoJZHByaW50Zl93aW4zMihzdGRkZWIsICJMb2FkIGFkZHIgaXMgcmVhbGx5ICVseCwgcmFuZ2UgJXhcbiIsCgkJcGVtLT5sb2FkX2FkZHIsIHZtYV9zaXplKTsKCQoKCWZvcihpPTA7IGkgPCBwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7IGkrKykKCXsKCQkvKiBtZW1jcHkgb25seSBub24tQlNTIHNlZ21lbnRzICovCgkJLyogRklYTUU6IHRoaXMgc2hvdWxkIGJlIGRvbmUgYnkgbW1hcCguLk1BUF9QUklWQVRFfE1BUF9GSVhFRC4uKQoJCSAqIGJ1dCBpdCBpcyBub3QgcG9zc2libGUgZm9yIChhdCBsZWFzdCkgTGludXggbmVlZHMgYW4gb2Zmc2V0CgkJICogYWxpZ25lZCB0byBhIGJsb2NrIG9uIHRoZSBmaWxlc3lzdGVtLgoJCSAqLwoJCWlmKCEocGUtPnBlX3NlZ1tpXS5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9TQ05fQ05UX1VOSU5JVElBTElaRURfREFUQSkpCgkJICAgIG1lbWNweSgoY2hhciopUlZBKHBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MpLAoJCSAgICAJKGNoYXIqKShwZS0+bWFwcGVkZGxsK3BlLT5wZV9zZWdbaV0uUG9pbnRlclRvUmF3RGF0YSksCgkJCXBlLT5wZV9zZWdbaV0uU2l6ZU9mUmF3RGF0YQoJCSAgICApOwoKCQlyZXN1bHQgPSBSVkEgKHBlLT5wZV9zZWdbaV0uVmlydHVhbEFkZHJlc3MpOwojaWYgMQoJCS8qIG5vdCBuZWVkZWQsIG1lbW9yeSBpcyB6ZXJvICovCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5ic3MiKSA9PSAwKQoJCSAgICBtZW1zZXQoKHZvaWQgKilyZXN1bHQsIDAsIAoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgPwoJCQkgICBwZS0+cGVfc2VnW2ldLk1pc2MuVmlydHVhbFNpemUgOgoJCQkgICBwZS0+cGVfc2VnW2ldLlNpemVPZlJhd0RhdGEpOwojZW5kaWYKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5pZGF0YSIpID09IDApCgkJCXBlbS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIHJlc3VsdDsKCgkJaWYoc3RyY21wKHBlLT5wZV9zZWdbaV0uTmFtZSwgIi5lZGF0YSIpID09IDApCgkJCXBlbS0+cGVfZXhwb3J0ID0gKExQSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSkgcmVzdWx0OwoKCQlpZihzdHJjbXAocGUtPnBlX3NlZ1tpXS5OYW1lLCAiLnJzcmMiKSA9PSAwKQoJCQlwZW0tPnBlX3Jlc291cmNlID0gKExQSU1BR0VfUkVTT1VSQ0VfRElSRUNUT1JZKSByZXN1bHQ7CgoJCWlmKHN0cmNtcChwZS0+cGVfc2VnW2ldLk5hbWUsICIucmVsb2MiKSA9PSAwKQoJCQlwZW0tPnBlX3JlbG9jID0gKExQSU1BR0VfQkFTRV9SRUxPQ0FUSU9OKSByZXN1bHQ7Cgl9CgoJLyogVGhlcmUgaXMgd29yZCB0aGF0IHRoZSBhY3R1YWwgbG9hZGVyIGRvZXMgbm90IGNhcmUgYWJvdXQgdGhlCgkgICBzZWN0aW9uIG5hbWVzLCBhbmQgb25seSBnb2VzIGZvciB0aGUgRGF0YURpcmVjdG9yeSAqLwoJZGlyPXBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0VYUE9SVF07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX2V4cG9ydCAmJiAoaW50KXBlbS0+cGVfZXhwb3J0IT1SVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIGV4cG9ydCBkaXJlY3Rvcnk/P1xuIik7CgkJLyogYWx3YXlzIHRydXN0IHRoZSBkaXJlY3RvcnkgKi8KCQlwZW0tPnBlX2V4cG9ydCA9IChMUElNQUdFX0VYUE9SVF9ESVJFQ1RPUlkpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9JTVBPUlRdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGVtLT5wZV9pbXBvcnQgJiYgKGludClwZW0tPnBlX2ltcG9ydCE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyBpbXBvcnQgZGlyZWN0b3J5Pz9cbiIpOwoJCXBlbS0+cGVfaW1wb3J0ID0gKExQSU1BR0VfSU1QT1JUX0RFU0NSSVBUT1IpIFJWQShkaXIuVmlydHVhbEFkZHJlc3MpOwoJfQoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9SRVNPVVJDRV07CglpZihkaXIuU2l6ZSkKCXsKCQlpZihwZW0tPnBlX3Jlc291cmNlICYmIChpbnQpcGVtLT5wZV9yZXNvdXJjZSE9UlZBKGRpci5WaXJ0dWFsQWRkcmVzcykpCgkJCWZwcmludGYoc3RkZXJyLCJ3cm9uZyByZXNvdXJjZSBkaXJlY3Rvcnk/P1xuIik7CgkJcGVtLT5wZV9yZXNvdXJjZSA9IChMUElNQUdFX1JFU09VUkNFX0RJUkVDVE9SWSkgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiRXhjZXB0aW9uIGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlNlY3VyaXR5IGRpcmVjdG9yeSBpZ25vcmVkXG4iKTsKCgoKCWRpcj1wZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0NdOwoJaWYoZGlyLlNpemUpCgl7CgkJaWYocGVtLT5wZV9yZWxvYyAmJiAoaW50KXBlbS0+cGVfcmVsb2MhPSBSVkEoZGlyLlZpcnR1YWxBZGRyZXNzKSkKCQkJZnByaW50ZihzdGRlcnIsIndyb25nIHJlbG9jYXRpb24gbGlzdD8/XG4iKTsKCQlwZW0tPnBlX3JlbG9jID0gKHZvaWQgKikgUlZBKGRpci5WaXJ0dWFsQWRkcmVzcyk7Cgl9CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlNpemUpCgkgIHsKCSAgICBERUJVR19SZWdpc3RlckRlYnVnSW5mbyhwZSwgbG9hZF9hZGRyLCAKCQkJcGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfREVCVUddLlZpcnR1YWxBZGRyZXNzLAoJCQlwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5W0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVR10uU2l6ZSk7CgkgIH0KCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9DT1BZUklHSFRdLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJDb3B5cmlnaHQgc3RyaW5nIGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUl0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkdsb2JhbCBQb2ludGVyIChNSVBTKSBpZ25vcmVkXG4iKTsKCglpZihwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5CgkJW0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFNdLlNpemUpCgkJIGZwcmludGYoc3RkbmltcCwiVGhyZWFkIGxvY2FsIHN0b3JhZ2UgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfTE9BRF9DT05GSUddLlNpemUpCgkJZHByaW50Zl93aW4zMihzdGRuaW1wLCJMb2FkIENvbmZpZ3VyYXRpb24gZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoKCWlmKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkKCQlbSU1BR0VfRElSRUNUT1JZX0VOVFJZX0JPVU5EX0lNUE9SVF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIkJvdW5kIEltcG9ydCBkaXJlY3RvcnkgaWdub3JlZFxuIik7CgoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeQoJCVtJTUFHRV9ESVJFQ1RPUllfRU5UUllfSUFUXS5TaXplKQoJCWRwcmludGZfd2luMzIoc3RkbmltcCwiSW1wb3J0IEFkZHJlc3MgVGFibGUgZGlyZWN0b3J5IGlnbm9yZWRcbiIpOwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxM10uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDEzIGlnbm9yZWRcbiIpOwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNF0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIpOwoJaWYocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVsxNV0uU2l6ZSkKCQlkcHJpbnRmX3dpbjMyKHN0ZG5pbXAsIlVua25vd24gZGlyZWN0b3J5IDE1IGlnbm9yZWRcbiIpOwoKCWlmKHBlbS0+cGVfcmVsb2MpCWRvX3JlbG9jYXRpb25zKHBlbSk7CglpZihwZW0tPnBlX2V4cG9ydCkJZHVtcF9leHBvcnRzKHBlbS0+cGVfZXhwb3J0LGxvYWRfYWRkcik7CglpZihwZW0tPnBlX2ltcG9ydCkJZml4dXBfaW1wb3J0cyhwcm9jZXNzLHBlbSk7CiAgCQkKCWlmIChwZW0tPnBlX2V4cG9ydCkKCQltb2RuYW1lID0gKGNoYXIqKVJWQShwZW0tPnBlX2V4cG9ydC0+TmFtZSk7CgllbHNlIHsKCQljaGFyICpzOwoJCW1vZG5hbWUgPSBzID0gb2ZzLT5zelBhdGhOYW1lOwoJCXdoaWxlICgocz1zdHJjaHIobW9kbmFtZSwnXFwnKSkpCgkJCW1vZG5hbWUgPSBzKzE7CgkJaWYgKChzPXN0cmNocihtb2RuYW1lLCcuJykpKQoJCQkqcz0nXDAnOwoJfQoKCS8qIGFkZCBzdGFydCBvZiBzZWN0aW9ucyBhcyBkZWJ1Z3N5bWJvbHMgKi8KCWZvcihpPTA7aTxwZS0+cGVfaGVhZGVyLT5GaWxlSGVhZGVyLk51bWJlck9mU2VjdGlvbnM7aSsrKSB7CgkJc3ByaW50ZihidWZmZXIsIiVzXyVzIixtb2RuYW1lLHBlLT5wZV9zZWdbaV0uTmFtZSk7CgkJZGFkZHIub2ZmPSBSVkEocGUtPnBlX3NlZ1tpXS5WaXJ0dWFsQWRkcmVzcyk7CgkJREVCVUdfQWRkU3ltYm9sKGJ1ZmZlciwmZGFkZHIsIE5VTEwsIFNZTV9XSU4zMiB8IFNZTV9GVU5DKTsKCX0KCS8qIGFkZCBlbnRyeSBwb2ludCAqLwoJc3ByaW50ZihidWZmZXIsIiVzX0VudHJ5UG9pbnQiLG1vZG5hbWUpOwoJZGFkZHIub2ZmPVJWQShwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KTsKCURFQlVHX0FkZFN5bWJvbChidWZmZXIsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7CgkvKiBhZGQgc3RhcnQgb2YgRExMICovCglkYWRkci5vZmY9bG9hZF9hZGRyOwoJREVCVUdfQWRkU3ltYm9sKG1vZG5hbWUsJmRhZGRyLCBOVUxMLCBTWU1fV0lOMzIgfCBTWU1fRlVOQyk7Cn0KCkhJTlNUQU5DRTE2IE1PRFVMRV9DcmVhdGVJbnN0YW5jZShITU9EVUxFMTYgaE1vZHVsZSxMT0FEUEFSQU1TICpwYXJhbXMpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBUaGUgUEUgTGlicmFyeSBMb2FkZXIgZnJvbnRlbmQuIAogKiBGSVhNRTogaGFuZGxlIHRoZSBmbGFncy4KICovCkhNT0RVTEUzMiBQRV9Mb2FkTGlicmFyeUV4MzJBIChMUENTVFIgbmFtZSwgSEZJTEUzMiBoRmlsZSwgRFdPUkQgZmxhZ3MpIHsKCU9GU1RSVUNUCW9mczsKCUhNT0RVTEUzMgloTW9kdWxlOwoJTkVfTU9EVUxFCSpwTW9kdWxlOwoKCWlmICgoaE1vZHVsZSA9IE1PRFVMRV9GaW5kTW9kdWxlKCBuYW1lICkpKQoJCXJldHVybiBoTW9kdWxlOwoKCS8qIHRyeSB0byBsb2FkIGJ1aWx0aW4sIGVuYWJsZWQgbW9kdWxlcyBmaXJzdCAqLwoJaWYgKChoTW9kdWxlID0gQlVJTFRJTl9Mb2FkTW9kdWxlKCBuYW1lLCBGQUxTRSApKSkKCQlyZXR1cm4gaE1vZHVsZTsKCgkvKiB0cnkgdG8gb3BlbiB0aGUgc3BlY2lmaWVkIGZpbGUgKi8KCWlmIChIRklMRV9FUlJPUjMyPT0oaEZpbGU9T3BlbkZpbGUzMihuYW1lLCZvZnMsT0ZfUkVBRCkpKSB7CgkJLyogTm93IHRyeSB0aGUgYnVpbHQtaW4gZXZlbiBpZiBkaXNhYmxlZCAqLwoJCWlmICgoaE1vZHVsZSA9IEJVSUxUSU5fTG9hZE1vZHVsZSggbmFtZSwgVFJVRSApKSkgewoJCQlmcHJpbnRmKCBzdGRlcnIsICJXYXJuaW5nOiBjb3VsZCBub3QgbG9hZCBXaW5kb3dzIERMTCAnJXMnLCB1c2luZyBidWlsdC1pbiBtb2R1bGUuXG4iLCBuYW1lICk7CgkJCXJldHVybiBoTW9kdWxlOwoJCX0KCQlyZXR1cm4gMTsKCX0KCWlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggJm9mcyApKSA8IDMyKSB7CgkJX2xjbG9zZTMyKGhGaWxlKTsKCQlyZXR1cm4gaE1vZHVsZTsKCX0KCglwTW9kdWxlCQk9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUgKTsKCXBNb2R1bGUtPmZsYWdzCT0gTkVfRkZMQUdTX1dJTjMyOwoKCS8qIEZJWE1FOiBjaGVjayBpZiBwZSBpbWFnZSBsb2FkZWQgYWxyZWFkeSAuLi4gKi8KCXBNb2R1bGUtPnBlX21vZHVsZSA9IFBFX0xvYWRJbWFnZSggRklMRV9HZXRVbml4SGFuZGxlKGhGaWxlKSApOwoJX2xjbG9zZTMyKGhGaWxlKTsKCWlmICghcE1vZHVsZS0+cGVfbW9kdWxlKQoJCXJldHVybiAyMTsKCS8qIHJlY3Vyc2UgKi8KCVBFX01hcEltYWdlKHBNb2R1bGUtPnBlX21vZHVsZSwoUERCMzIqKUdldEN1cnJlbnRQcm9jZXNzSWQoKSwmb2ZzLGZsYWdzKTsKCXJldHVybiBwTW9kdWxlLT5wZV9tb2R1bGUtPm1hcHBlZGRsbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIExvYWQgdGhlIFBFIG1haW4gLkVYRS4gQWxsIG90aGVyIGxvYWRpbmcgaXMgZG9uZSBieSBQRV9Mb2FkTGlicmFyeUV4MzJBCiAqIEZJWE1FOiB0aGlzIGZ1bmN0aW9uIHNob3VsZCB1c2UgUEVfTG9hZExpYnJhcnlFeDMyQSwgYnV0IGN1cnJlbnRseSBjYW4ndAogKiBkdWUgdG8gdGhlIFRBU0tfQ3JlYXRlVGFzayBzdHVmZi4KICovCkhJTlNUQU5DRTE2IFBFX0xvYWRNb2R1bGUoIEhGSUxFMzIgaEZpbGUsIE9GU1RSVUNUICpvZnMsIExPQURQQVJBTVMqIHBhcmFtcyApCnsKICAgIEhNT0RVTEUxNiBoTW9kdWxlOwogICAgSElOU1RBTkNFMTYgaEluc3RhbmNlOwogICAgTkVfTU9EVUxFICpwTW9kdWxlOwoKICAgIGlmICgoaE1vZHVsZSA9IE1PRFVMRV9DcmVhdGVEdW1teU1vZHVsZSggb2ZzICkpIDwgMzIpIHJldHVybiBoTW9kdWxlOwogICAgcE1vZHVsZSA9IChORV9NT0RVTEUgKilHbG9iYWxMb2NrMTYoIGhNb2R1bGUgKTsKICAgIHBNb2R1bGUtPmZsYWdzID0gTkVfRkZMQUdTX1dJTjMyOwoKICAgIHBNb2R1bGUtPnBlX21vZHVsZSA9IFBFX0xvYWRJbWFnZSggRklMRV9HZXRVbml4SGFuZGxlKGhGaWxlKSApOwogICAgX2xjbG9zZTMyKGhGaWxlKTsKICAgIGlmICghcE1vZHVsZS0+cGVfbW9kdWxlKQogICAgCXJldHVybiAyMTsKCiAgICBoSW5zdGFuY2UgPSBNT0RVTEVfQ3JlYXRlSW5zdGFuY2UoIGhNb2R1bGUsIHBhcmFtcyApOwogICAgaWYgKCEocE1vZHVsZS0+cGVfbW9kdWxlLT5wZV9oZWFkZXItPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpKQogICAgewogICAgICAgIFRBU0tfQ3JlYXRlVGFzayggaE1vZHVsZSwgaEluc3RhbmNlLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgcGFyYW1zLT5oRW52aXJvbm1lbnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAoTFBTVFIpUFRSX1NFR19UT19MSU4oIHBhcmFtcy0+Y21kTGluZSApLAogICAgICAgICAgICAgICAgICAgICAgICAgKigoV09SRCopUFRSX1NFR19UT19MSU4ocGFyYW1zLT5zaG93Q21kKSArIDEpICk7CiAgICB9CiAgICBQRV9NYXBJbWFnZShwTW9kdWxlLT5wZV9tb2R1bGUsKFBEQjMyKilHZXRDdXJyZW50UHJvY2Vzc0lkKCksb2ZzLDApOwogICAgcmV0dXJuIGhJbnN0YW5jZTsKfQoKaW50IFBFX1VubG9hZEltYWdlKCBITU9EVUxFMzIgaE1vZHVsZSApCnsKCXByaW50ZigiUEV1bmxvYWRJbWFnZSgpIGNhbGxlZCFcbiIpOwoJLyogZnJlZSByZXNvdXJjZXMsIGltYWdlLCB1bm1hcCAqLwoJcmV0dXJuIDE7Cn0KCi8qIENhbGxlZCBpZiB0aGUgbGlicmFyeSBpcyBsb2FkZWQgb3IgZnJlZWQuCiAqIE5PVEU6IGlmIGEgdGhyZWFkIGF0dGFjaGVzIGEgRExMLCB0aGUgY3VycmVudCB0aHJlYWQgd2lsbCBvbmx5IGRvCiAqIERMTF9QUk9DRVNTX0FUVEFDSC4gT25seSBuZXcgY3JlYXRlZCB0aHJlYWRzIGRvIERMTF9USFJFQURfQVRUQUNICiAqIChTREspCiAqLwpzdGF0aWMgdm9pZCBQRV9Jbml0RExMKFBFX01PRFJFRiAqcGVtLCBEV09SRCB0eXBlLExQVk9JRCBscFJlc2VydmVkKQp7CiAgICBQRV9NT0RVTEUJCSpwZSA9IHBlbS0+cGVfbW9kdWxlOwogICAgdW5zaWduZWQgaW50CWxvYWRfYWRkciA9IHBlbS0+bG9hZF9hZGRyOwoKICAgIGlmICh0eXBlPT1ETExfUFJPQ0VTU19BVFRBQ0gpCglwZW0tPmZsYWdzIHw9IFBFX01PRFJFRl9QUk9DRVNTX0FUVEFDSEVEOwojaWZuZGVmIFdJTkVMSUIKICAgIGlmIChPcHRpb25zLmRlYnVnKSB7CiAgICAgICAgICAgIERCR19BRERSIGFkZHIgPSB7IE5VTEwsIDAsIFJWQShwZS0+cGVfaGVhZGVyLT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50KSB9OwogICAgICAgICAgICBERUJVR19BZGRCcmVha3BvaW50KCAmYWRkciApOwoJICAgIERFQlVHX1NldEJyZWFrcG9pbnRzKFRSVUUpOwogICAgfQojZW5kaWYKCiAgICAvKiAgRExMX0FUVEFDSF9QUk9DRVNTOgogICAgICoJCWxwcmVzZXJ2ZWQgaXMgTlVMTCBmb3IgZHluYW1pYyBsb2Fkcywgbm90LU5VTEwgZm9yIHN0YXRpYyBsb2FkcwogICAgICogIERMTF9ERVRBQ0hfUFJPQ0VTUzoKICAgICAqCQlscHJlc2VydmVkIGlzIE5VTEwgaWYgY2FsbGVkIGJ5IEZyZWVMaWJyYXJ5LCBub3QtTlVMTCBvdGhlcndpc2UKICAgICAqICB0aGUgU0RLIGRvZXNuJ3QgbWVudGlvbiBhbnl0aGluZyBmb3IgRExMX1RIUkVBRF8qCiAgICAgKi8KICAgICAgICAKICAgIC8qIElzIHRoaXMgYSBsaWJyYXJ5PyBBbmQgaGFzIGl0IGdvdCBhbiBlbnRyeXBvaW50PyAqLwogICAgaWYgKAkocGUtPnBlX2hlYWRlci0+RmlsZUhlYWRlci5DaGFyYWN0ZXJpc3RpY3MgJiBJTUFHRV9GSUxFX0RMTCkgJiYKCQkocGUtPnBlX2hlYWRlci0+T3B0aW9uYWxIZWFkZXIuQWRkcmVzc09mRW50cnlQb2ludCkKICAgICkgewogICAgICAgIEZBUlBST0MzMiBlbnRyeSA9IChGQVJQUk9DMzIpUlZBKHBlLT5wZV9oZWFkZXItPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpOwogICAgICAgIGRwcmludGZfcmVsYXkoIHN0ZGRlYiwgIkNhbGxUbzMyKGVudHJ5cHJvYz0lcCxtb2R1bGU9JWQsdHlwZT0lbGQscmVzPSVwKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBlbnRyeSwgcGUtPm1hcHBlZGRsbCwgdHlwZSwgbHBSZXNlcnZlZCApOwogICAgICAgIGVudHJ5KCBwZS0+bWFwcGVkZGxsLCB0eXBlLCBscFJlc2VydmVkICk7CiAgICB9Cn0KCi8qIENhbGwgdGhlIERMTGVudHJ5IGZ1bmN0aW9uIG9mIGFsbCBkbGxzIHVzZWQgYnkgdGhhdCBwcm9jZXNzLgogKiAoTk9URTogdGhpcyBtYXkgcmVjdXJzaXZlbHkgY2FsbCB0aGlzIGZ1bmN0aW9uIChpZiBhIGxpYnJhcnkgY2FsbHMKICogTG9hZExpYnJhcnkpIC4uLiBidXQgaXQgd29uJ3QgbWF0dGVyKQogKi8Kdm9pZCBQRV9Jbml0aWFsaXplRExMcyhQREIzMiAqcHJvY2VzcyxEV09SRCB0eXBlLExQVk9JRCBscFJlc2VydmVkKSB7CglQRV9NT0RSRUYJKnBlbTsKCglwZW0gPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCXdoaWxlIChwZW0pIHsKCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9OT19ETExfQ0FMTFMpIHsKCQkJcGVtID0gcGVtLT5uZXh0OwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHR5cGU9PURMTF9QUk9DRVNTX0FUVEFDSCkgewoJCQlpZiAocGVtLT5mbGFncyAmIFBFX01PRFJFRl9QUk9DRVNTX0FUVEFDSEVEKSB7CgkJCQlwZW0gPSBwZW0tPm5leHQ7CgkJCQljb250aW51ZTsKCQkJfQoJCX0KCQlQRV9Jbml0RExMKCBwZW0sIHR5cGUsIGxwUmVzZXJ2ZWQgKTsKCQlwZW0gPSBwZW0tPm5leHQ7Cgl9Cn0KCnZvaWQgUEVfSW5pdFRscyhQREIzMiAqcGRiKQp7CgkvKiBGSVhNRTogdGxzIGNhbGxiYWNrcyA/Pz8gKi8KCVBFX01PRFJFRgkJKnBlbTsKCUlNQUdFX05UX0hFQURFUlMJKnBlaDsKCURXT1JECQkJc2l6ZSxkYXRhc2l6ZSxpbmRleDsKCUxQVk9JRAkJCW1lbTsKCUxQSU1BR0VfVExTX0RJUkVDVE9SWQlwZGlyOwoKCXBlbSA9IHBkYi0+bW9kcmVmX2xpc3Q7Cgl3aGlsZSAocGVtKSB7CgkJcGVoID0gcGVtLT5wZV9tb2R1bGUtPnBlX2hlYWRlcjsKCQlpZiAoIXBlaC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeVtJTUFHRV9GSUxFX1RIUkVBRF9MT0NBTF9TVE9SQUdFXS5WaXJ0dWFsQWRkcmVzcykgewoJCQlwZW0gPSBwZW0tPm5leHQ7CgkJCWNvbnRpbnVlOwoJCX0KCQlwZGlyID0gKExQVk9JRCkocGVtLT5sb2FkX2FkZHIgKyBwZWgtPk9wdGlvbmFsSGVhZGVyLgoJCQlEYXRhRGlyZWN0b3J5W0lNQUdFX0ZJTEVfVEhSRUFEX0xPQ0FMX1NUT1JBR0VdLlZpcnR1YWxBZGRyZXNzKTsKCQlpbmRleAk9IFRsc0FsbG9jKCk7CgkJZGF0YXNpemU9IHBkaXItPkVuZEFkZHJlc3NPZlJhd0RhdGEtcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhOwoJCXNpemUJPSBkYXRhc2l6ZSArIHBkaXItPlNpemVPZlplcm9GaWxsOwoJCW1lbT1WaXJ0dWFsQWxsb2MoMCxzaXplLE1FTV9SRVNFUlZFfE1FTV9DT01NSVQsUEFHRV9SRUFEV1JJVEUpOwoJCW1lbWNweShtZW0sKExQVk9JRCkgcGRpci0+U3RhcnRBZGRyZXNzT2ZSYXdEYXRhLCBkYXRhc2l6ZSk7CgkJVGxzU2V0VmFsdWUoaW5kZXgsbWVtKTsKCQkqKHBkaXItPkFkZHJlc3NPZkluZGV4KT1pbmRleDsgICAKCQlwZW09cGVtLT5uZXh0OwoJfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJRGlzYWJsZVRocmVhZExpYnJhcnlDYWxscyAoS0VSTkVMMzIuNzQpCiAqIERvbid0IGNhbGwgRGxsRW50cnlQb2ludCBmb3IgRExMX1RIUkVBRF97QVRUQUNILERFVEFDSH0gaWYgc2V0LgogKi8KQk9PTDMyIFdJTkFQSSBEaXNhYmxlVGhyZWFkTGlicmFyeUNhbGxzKEhNT0RVTEUzMiBoTW9kdWxlKQp7CglQREIzMgkqcHJvY2VzcyA9IChQREIzMiopR2V0Q3VycmVudFByb2Nlc3NJZCgpOwoJUEVfTU9EUkVGCSpwZW0gPSBwcm9jZXNzLT5tb2RyZWZfbGlzdDsKCgl3aGlsZSAocGVtKSB7CgkJaWYgKHBlbS0+cGVfbW9kdWxlLT5tYXBwZWRkbGwgPT0gaE1vZHVsZSkKCQkJcGVtLT5mbGFnc3w9UEVfTU9EUkVGX05PX0RMTF9DQUxMUzsKCQlwZW0gPSBwZW0tPm5leHQ7Cgl9CglyZXR1cm4gVFJVRTsKfQoKI2VuZGlmIC8qIFdJTkVMSUIgKi8K