LyogIAkJCURpcmVjdFNvdW5kCiAqCiAqIENvcHlyaWdodCAxOTk4IE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMTk5OCBSb2IgUmlnZ3MKICogQ29weXJpZ2h0IDIwMDAtMjAwMiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMsIEluYy4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN5cy9mY250bC5oPgojaWZkZWYgSEFWRV9VTklTVERfSAojIGluY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxtYXRoLmg+CS8qIEluc29tbmlhIC0gcG93KCkgZnVuY3Rpb24gKi8KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbnRlcm5sLmgiCiNpbmNsdWRlICJtbWRkay5oIgojaW5jbHVkZSAid2luZS93aW5kZWYxNi5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAiZHNvdW5kLmgiCiNpbmNsdWRlICJkc2RyaXZlci5oIgojaW5jbHVkZSAiZHNvdW5kX3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRzb3VuZCk7Cgp2b2lkIERTT1VORF9SZWNhbGNWb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewoJZG91YmxlIHRlbXA7CglUUkFDRSgiKCVwKVxuIix2b2xwYW4pOwoKCVRSQUNFKCJWb2w9JWxkIFBhbj0lbGRcbiIsIHZvbHBhbi0+bFZvbHVtZSwgdm9scGFuLT5sUGFuKTsKCS8qIHRoZSBBbXBGYWN0b3JzIGFyZSBleHByZXNzZWQgaW4gMTYuMTYgZml4ZWQgcG9pbnQgKi8KCXZvbHBhbi0+ZHdWb2xBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB2b2xwYW4tPmxWb2x1bWUgLyA2MDAuMCkgKiAweGZmZmYpOwoJLyogRklYTUU6IGR3UGFue0xlZnR8UmlnaHR9QW1wRmFjdG9yICovCgoJLyogRklYTUU6IHVzZSBjYWxjdWxhdGVkIHZvbCBhbmQgcGFuIGFtcGZhY3RvcnMgKi8KCXRlbXAgPSAoZG91YmxlKSAodm9scGFuLT5sVm9sdW1lIC0gKHZvbHBhbi0+bFBhbiA+IDAgPyB2b2xwYW4tPmxQYW4gOiAwKSk7Cgl2b2xwYW4tPmR3VG90YWxMZWZ0QW1wRmFjdG9yID0gKFVMT05HKSAocG93KDIuMCwgdGVtcCAvIDYwMC4wKSAqIDB4ZmZmZik7Cgl0ZW1wID0gKGRvdWJsZSkgKHZvbHBhbi0+bFZvbHVtZSArICh2b2xwYW4tPmxQYW4gPCAwID8gdm9scGFuLT5sUGFuIDogMCkpOwoJdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IgPSAoVUxPTkcpIChwb3coMi4wLCB0ZW1wIC8gNjAwLjApICogMHhmZmZmKTsKCglUUkFDRSgibGVmdCA9ICVseCwgcmlnaHQgPSAlbHhcbiIsIHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3IsIHZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKTsKfQoKdm9pZCBEU09VTkRfQW1wRmFjdG9yVG9Wb2xQYW4oUERTVk9MVU1FUEFOIHZvbHBhbikKewogICAgZG91YmxlIGxlZnQscmlnaHQ7CiAgICBUUkFDRSgiKCVwKVxuIix2b2xwYW4pOwoKICAgIFRSQUNFKCJsZWZ0PSVseCwgcmlnaHQ9JWx4XG4iLHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3Isdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpOwogICAgaWYgKHZvbHBhbi0+ZHdUb3RhbExlZnRBbXBGYWN0b3I9PTApCiAgICAgICAgbGVmdD0tMTAwMDA7CiAgICBlbHNlCiAgICAgICAgbGVmdD02MDAgKiBsb2coKChkb3VibGUpdm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvcikgLyAweGZmZmYpIC8gbG9nKDIpOwogICAgaWYgKHZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yPT0wKQogICAgICAgIHJpZ2h0PS0xMDAwMDsKICAgIGVsc2UKICAgICAgICByaWdodD02MDAgKiBsb2coKChkb3VibGUpdm9scGFuLT5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpIC8gMHhmZmZmKSAvIGxvZygyKTsKICAgIGlmIChsZWZ0PHJpZ2h0KQogICAgewogICAgICAgIHZvbHBhbi0+bFZvbHVtZT1yaWdodDsKICAgICAgICB2b2xwYW4tPmR3Vm9sQW1wRmFjdG9yPXZvbHBhbi0+ZHdUb3RhbFJpZ2h0QW1wRmFjdG9yOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHZvbHBhbi0+bFZvbHVtZT1sZWZ0OwogICAgICAgIHZvbHBhbi0+ZHdWb2xBbXBGYWN0b3I9dm9scGFuLT5kd1RvdGFsTGVmdEFtcEZhY3RvcjsKICAgIH0KICAgIGlmICh2b2xwYW4tPmxWb2x1bWUgPCAtMTAwMDApCiAgICAgICAgdm9scGFuLT5sVm9sdW1lPS0xMDAwMDsKICAgIHZvbHBhbi0+bFBhbj1yaWdodC1sZWZ0OwogICAgaWYgKHZvbHBhbi0+bFBhbiA8IC0xMDAwMCkKICAgICAgICB2b2xwYW4tPmxQYW49LTEwMDAwOwoKICAgIFRSQUNFKCJWb2w9JWxkIFBhbj0lbGRcbiIsIHZvbHBhbi0+bFZvbHVtZSwgdm9scGFuLT5sUGFuKTsKfQoKdm9pZCBEU09VTkRfUmVjYWxjRm9ybWF0KElEaXJlY3RTb3VuZEJ1ZmZlckltcGwgKmRzYikKewoJRFdPUkQgc3c7CglUUkFDRSgiKCVwKVxuIixkc2IpOwoKCXN3ID0gZHNiLT5wd2Z4LT5uQ2hhbm5lbHMgKiAoZHNiLT5wd2Z4LT53Qml0c1BlclNhbXBsZSAvIDgpOwoJLyogY2FsY3VsYXRlIHRoZSAxMG1zIHdyaXRlIGxlYWQgKi8KCWRzYi0+d3JpdGVsZWFkID0gKGRzYi0+ZnJlcSAvIDEwMCkgKiBzdzsKfQoKdm9pZCBEU09VTkRfQ2hlY2tFdmVudChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIGludCBsZW4pCnsKCWludAkJCWk7CglEV09SRAkJCW9mZnNldDsKCUxQRFNCUE9TSVRJT05OT1RJRlkJZXZlbnQ7CglUUkFDRSgiKCVwLCVkKVxuIixkc2IsbGVuKTsKCglpZiAoZHNiLT5ucm9mbm90aWZpZXMgPT0gMCkKCQlyZXR1cm47CgoJVFJBQ0UoIiglcCkgYnVmbGVuID0gJWxkLCBwbGF5cG9zID0gJWxkLCBsZW4gPSAlZFxuIiwKCQlkc2IsIGRzYi0+YnVmbGVuLCBkc2ItPnBsYXlwb3MsIGxlbik7Cglmb3IgKGkgPSAwOyBpIDwgZHNiLT5ucm9mbm90aWZpZXMgOyBpKyspIHsKCQlldmVudCA9IGRzYi0+bm90aWZpZXMgKyBpOwoJCW9mZnNldCA9IGV2ZW50LT5kd09mZnNldDsKCQlUUkFDRSgiY2hlY2tpbmcgJWQsIHBvc2l0aW9uICVsZCwgZXZlbnQgPSAlcFxuIiwKCQkJaSwgb2Zmc2V0LCBldmVudC0+aEV2ZW50Tm90aWZ5KTsKCQkvKiBEU0JQTl9PRkZTRVRTVE9QIGhhcyB0byBiZSB0aGUgbGFzdCBlbGVtZW50LiBTbyB0aGlzIGlzICovCgkJLyogT0suIFtJbnNpZGUgRGlyZWN0WCwgcDI3NF0gKi8KCQkvKiAgKi8KCQkvKiBUaGlzIGFsc28gbWVhbnMgd2UgY2FuJ3Qgc29ydCB0aGUgZW50cmllcyBieSBvZmZzZXQsICovCgkJLyogYmVjYXVzZSBEU0JQTl9PRkZTRVRTVE9QID09IC0xICovCgkJaWYgKG9mZnNldCA9PSBEU0JQTl9PRkZTRVRTVE9QKSB7CgkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlcCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCXJldHVybjsKCQkJfSBlbHNlCgkJCQlyZXR1cm47CgkJfQoJCWlmICgoZHNiLT5wbGF5cG9zICsgbGVuKSA+PSBkc2ItPmJ1ZmxlbikgewoJCQlpZiAoKG9mZnNldCA8ICgoZHNiLT5wbGF5cG9zICsgbGVuKSAlIGRzYi0+YnVmbGVuKSkgfHwKCQkJICAgIChvZmZzZXQgPj0gZHNiLT5wbGF5cG9zKSkgewoJCQkJVFJBQ0UoInNpZ25hbGxlZCBldmVudCAlcCAoJWQpXG4iLCBldmVudC0+aEV2ZW50Tm90aWZ5LCBpKTsKCQkJCVNldEV2ZW50KGV2ZW50LT5oRXZlbnROb3RpZnkpOwoJCQl9CgkJfSBlbHNlIHsKCQkJaWYgKChvZmZzZXQgPj0gZHNiLT5wbGF5cG9zKSAmJiAob2Zmc2V0IDwgKGRzYi0+cGxheXBvcyArIGxlbikpKSB7CgkJCQlUUkFDRSgic2lnbmFsbGVkIGV2ZW50ICVwICglZClcbiIsIGV2ZW50LT5oRXZlbnROb3RpZnksIGkpOwoJCQkJU2V0RXZlbnQoZXZlbnQtPmhFdmVudE5vdGlmeSk7CgkJCX0KCQl9Cgl9Cn0KCi8qIFdBViBmb3JtYXQgaW5mbyBjYW4gYmUgZm91bmQgYXQ6CiAqCiAqICAgIGh0dHA6Ly93d3cuY3dpLm5sL2Z0cC9hdWRpby9BdWRpb0Zvcm1hdHMucGFydDIKICogICAgZnRwOi8vZnRwLmN3aS5ubC9wdWIvYXVkaW8vUklGRi1mb3JtYXQKICoKICogSW1wb3J0IHBvaW50cyB0byByZW1lbWJlcjoKICogICAgOC1iaXQgV0FWIGlzIHVuc2lnbmVkCiAqICAgIDE2LWJpdCBXQVYgaXMgc2lnbmVkCiAqLwogLyogVXNlIHRoZSBzYW1lIGZvcm11bGFzIGFzIHBjbWNvbnZlcnRlci5jICovCnN0YXRpYyBpbmxpbmUgSU5UMTYgY3Z0VTh0b1MxNihCWVRFIGIpCnsKICAgIHJldHVybiAoc2hvcnQpKChiKyhiIDw8IDgpKS0zMjc2OCk7Cn0KCnN0YXRpYyBpbmxpbmUgQllURSBjdnRTMTZ0b1U4KElOVDE2IHMpCnsKICAgIHJldHVybiAocyA+PiA4KSBeICh1bnNpZ25lZCBjaGFyKTB4ODA7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBjcF9maWVsZHMoY29uc3QgSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICppYnVmLCBCWVRFICpvYnVmICkKewogICAgICAgIElOVCBmbCxmcjsKCiAgICAgICAgaWYgKGRzYi0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCkgIHsKICAgICAgICAgICAgICAgIGlmIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCAmJgogICAgICAgICAgICAgICAgICAgIGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMgPT0gZHNiLT5wd2Z4LT5uQ2hhbm5lbHMpIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogYXZvaWQgbmVlZGxlc3MgOC0+MTYtPjggY29udmVyc2lvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICAqb2J1Zj0qaWJ1ZjsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRzYi0+cHdmeC0+bkNoYW5uZWxzPT0yKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoob2J1ZisxKT0qKGlidWYrMSk7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGZsID0gY3Z0VTh0b1MxNigqaWJ1Zik7CiAgICAgICAgICAgICAgICBmciA9IChkc2ItPnB3ZngtPm5DaGFubmVscz09MiA/IGN2dFU4dG9TMTYoKihpYnVmICsgMSkpIDogZmwpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBmbCA9ICooKElOVDE2ICopaWJ1Zik7CiAgICAgICAgICAgICAgICBmciA9IChkc2ItPnB3ZngtPm5DaGFubmVscz09MiA/ICooKChJTlQxNiAqKWlidWYpICsgMSkgIDogZmwpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMgPT0gMikgewogICAgICAgICAgICAgICAgaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICpvYnVmID0gY3Z0UzE2dG9VOChmbCk7CiAgICAgICAgICAgICAgICAgICAgICAgICoob2J1ZiArIDEpID0gY3Z0UzE2dG9VOChmcik7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gMTYpIHsKICAgICAgICAgICAgICAgICAgICAgICAgKigoSU5UMTYgKilvYnVmKSA9IGZsOwogICAgICAgICAgICAgICAgICAgICAgICAqKCgoSU5UMTYgKilvYnVmKSArIDEpID0gZnI7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMgPT0gMSkgewogICAgICAgICAgICAgICAgZmwgPSAoZmwgKyBmcikgPj4gMTsKICAgICAgICAgICAgICAgIGlmIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUgPT0gOCkgewogICAgICAgICAgICAgICAgICAgICAgICAqb2J1ZiA9IGN2dFMxNnRvVTgoZmwpOwogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDE2KSB7CiAgICAgICAgICAgICAgICAgICAgICAgICooKElOVDE2ICopb2J1ZikgPSBmbDsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOwogICAgICAgICAgICAgICAgfQogICAgICAgIH0KfQoKLyogTm93IHdpdGggUGVyZmVjdFBpdGNoICh0bSkgdGVjaG5vbG9neSAqLwpzdGF0aWMgSU5UIERTT1VORF9NaXhlck5vcm0oSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBCWVRFICpidWYsIElOVCBsZW4pCnsKCUlOVAlpLCBzaXplLCBpcG9zLCBpbGVuOwoJQllURQkqaWJwLCAqb2JwOwoJSU5UCWlBZHZhbmNlID0gZHNiLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCUlOVAlvQWR2YW5jZSA9IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCglpYnAgPSBkc2ItPmJ1ZmZlci0+bWVtb3J5ICsgZHNiLT5idWZfbWl4cG9zOwoJb2JwID0gYnVmOwoKCVRSQUNFKCIoJXAsICVwLCAlcCksIGJ1Zl9taXhwb3M9JWxkXG4iLCBkc2IsIGlicCwgb2JwLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogQ2hlY2sgZm9yIHRoZSBiZXN0IGNhc2UgKi8KCWlmICgoZHNiLT5mcmVxID09IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uU2FtcGxlc1BlclNlYykgJiYKCSAgICAoZHNiLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSBkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUpICYmCgkgICAgKGRzYi0+cHdmeC0+bkNoYW5uZWxzID09IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQ2hhbm5lbHMpKSB7CgkgICAgICAgIERXT1JEIGJ5dGVzbGVmdCA9IGRzYi0+YnVmbGVuIC0gZHNiLT5idWZfbWl4cG9zOwoJCVRSQUNFKCIoJXApIEJlc3QgY2FzZVxuIiwgZHNiKTsKCSAgICAJaWYgKGxlbiA8PSBieXRlc2xlZnQgKQoJCQltZW1jcHkob2JwLCBpYnAsIGxlbik7CgkJZWxzZSB7IC8qIHdyYXAgKi8KCQkJbWVtY3B5KG9icCwgaWJwLCBieXRlc2xlZnQgKTsKCQkJbWVtY3B5KG9icCArIGJ5dGVzbGVmdCwgZHNiLT5idWZmZXItPm1lbW9yeSwgbGVuIC0gYnl0ZXNsZWZ0KTsKCQl9CgkJcmV0dXJuIGxlbjsKCX0KCgkvKiBDaGVjayBmb3Igc2FtZSBzYW1wbGUgcmF0ZSAqLwoJaWYgKGRzYi0+ZnJlcSA9PSBkc2ItPmRzb3VuZC0+cHdmeC0+blNhbXBsZXNQZXJTZWMpIHsKCQlUUkFDRSgiKCVwKSBTYW1lIHNhbXBsZSByYXRlICVsZCA9IHByaW1hcnkgJWxkXG4iLCBkc2IsCgkJCWRzYi0+ZnJlcSwgZHNiLT5kc291bmQtPnB3ZngtPm5TYW1wbGVzUGVyU2VjKTsKCQlpbGVuID0gMDsKCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IG9BZHZhbmNlKSB7CgkJCWNwX2ZpZWxkcyhkc2IsIGlicCwgb2JwICk7CgkJCWlicCArPSBpQWR2YW5jZTsKCQkJaWxlbiArPSBpQWR2YW5jZTsKCQkJb2JwICs9IG9BZHZhbmNlOwoJCQlpZiAoaWJwID49IChCWVRFICopKGRzYi0+YnVmZmVyLT5tZW1vcnkgKyBkc2ItPmJ1ZmxlbikpCgkJCQlpYnAgPSBkc2ItPmJ1ZmZlci0+bWVtb3J5OwkvKiB3cmFwICovCgkJfQoJCXJldHVybiAoaWxlbik7Cgl9CgoJLyogTWl4IGluIGRpZmZlcmVudCBzYW1wbGUgcmF0ZXMgKi8KCS8qICovCgkvKiBOZXcgUGVyZmVjdFBpdGNoKHRtKSBUZWNobm9sb2d5IChjKSAxOTk4IFJvYiBSaWdncyAqLwoJLyogUGF0ZW50IFBlbmRpbmcgOi1dICovCgoJLyogUGF0ZW50IGVuaGFuY2VtZW50cyAoYykgMjAwMCBPdmUgS+V2ZW4sCgkgKiBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLiAqLwoKCS8qIEZJWE1FKCIoJXApIEFkanVzdGluZyBmcmVxdWVuY3k6ICVsZCAtPiAlbGQgKG5lZWQgb3B0aW1pemF0aW9uKVxuIiwKCSAgIGRzYiwgZHNiLT5mcmVxLCBkc2ItPmRzb3VuZC0+cHdmeC0+blNhbXBsZXNQZXJTZWMpOyAqLwoKCXNpemUgPSBsZW4gLyBvQWR2YW5jZTsKCWlsZW4gPSAwOwoJaXBvcyA9IGRzYi0+YnVmX21peHBvczsKCWZvciAoaSA9IDA7IGkgPCBzaXplOyBpKyspIHsKICAgICAgICAgICAgICAgIGNwX2ZpZWxkcyhkc2IsIChkc2ItPmJ1ZmZlci0+bWVtb3J5ICsgaXBvcyksIG9icCk7CgkJb2JwICs9IG9BZHZhbmNlOwoJCWRzYi0+ZnJlcUFjYyArPSBkc2ItPmZyZXFBZGp1c3Q7CgkJaWYgKGRzYi0+ZnJlcUFjYyA+PSAoMTw8RFNPVU5EX0ZSRVFTSElGVCkpIHsKCQkJVUxPTkcgYWR2ID0gKGRzYi0+ZnJlcUFjYz4+RFNPVU5EX0ZSRVFTSElGVCkgKiBpQWR2YW5jZTsKCQkJZHNiLT5mcmVxQWNjICY9ICgxPDxEU09VTkRfRlJFUVNISUZUKS0xOwoJCQlpcG9zICs9IGFkdjsgaWxlbiArPSBhZHY7CgkJCWlwb3MgJT0gZHNiLT5idWZsZW47CgkJfQoJfQoJcmV0dXJuIGlsZW47Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9NaXhlclZvbChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIEJZVEUgKmJ1ZiwgSU5UIGxlbikKewoJSU5UCWk7CglCWVRFCSpicGMgPSBidWY7CglJTlQxNgkqYnBzID0gKElOVDE2ICopIGJ1ZjsKCglUUkFDRSgiKCVwLCVwLCVkKVxuIixkc2IsYnVmLGxlbik7CglUUkFDRSgibGVmdCA9ICVseCwgcmlnaHQgPSAlbHhcbiIsIGRzYi0+Y3ZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvciwgCgkJZHNiLT5jdm9scGFuLmR3VG90YWxSaWdodEFtcEZhY3Rvcik7CgoJaWYgKCghKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fCAoZHNiLT5jdm9scGFuLmxQYW4gPT0gMCkpICYmCgkgICAgKCEoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxWT0xVTUUpIHx8IChkc2ItPmN2b2xwYW4ubFZvbHVtZSA9PSAwKSkgJiYKCSAgICAhKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMM0QpKQoJCXJldHVybjsJCS8qIE5vdGhpbmcgdG8gZG8gKi8KCgkvKiBJZiB3ZSBlbmQgdXAgd2l0aCBzb21lIGJvem8gY29kZXIgdXNpbmcgcGFubmluZyBvciAzRCBzb3VuZCAqLwoJLyogd2l0aCBhIG1vbm8gcHJpbWFyeSBidWZmZXIsIGl0IGNvdWxkIHNvdW5kIHZlcnkgd2VpcmQgdXNpbmcgKi8KCS8qIHRoaXMgbWV0aG9kLiBPaCB3ZWxsLCB0b3VnaCBwYXRvb3RpZXMuICovCgoJc3dpdGNoIChkc2ItPmRzb3VuZC0+cHdmeC0+d0JpdHNQZXJTYW1wbGUpIHsKCWNhc2UgODoKCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQsIGJ1dCB3ZSBuZWVkIHRvIG9wZXJhdGUgKi8KCQkvKiBvbiBzaWduZWQgZGF0YSBmb3IgdGhpcyB0byB3b3JrIHByb3Blcmx5ICovCgkJc3dpdGNoIChkc2ItPmRzb3VuZC0+cHdmeC0+bkNoYW5uZWxzKSB7CgkJY2FzZSAxOgoJCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKCQkJCUlOVCB2YWwgPSAqYnBjIC0gMTI4OwoJCQkJdmFsID0gKHZhbCAqIGRzYi0+Y3ZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvcikgPj4gMTY7CgkJCQkqYnBjID0gdmFsICsgMTI4OwoJCQkJYnBjKys7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKz0yKSB7CgkJCQlJTlQgdmFsID0gKmJwYyAtIDEyODsKCQkJCXZhbCA9ICh2YWwgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJKmJwYysrID0gdmFsICsgMTI4OwoJCQkJdmFsID0gKmJwYyAtIDEyODsKCQkJCXZhbCA9ICh2YWwgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbFJpZ2h0QW1wRmFjdG9yKSA+PiAxNjsKCQkJCSpicGMgPSB2YWwgKyAxMjg7CgkJCQlicGMrKzsKCQkJfQoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlGSVhNRSgiZG9lc24ndCBzdXBwb3J0ICVkIGNoYW5uZWxzXG4iLCBkc2ItPmRzb3VuZC0+cHdmeC0+bkNoYW5uZWxzKTsKCQkJYnJlYWs7CgkJfQoJCWJyZWFrOwoJY2FzZSAxNjoKCQkvKiAxNi1iaXQgV0FWIGlzIHNpZ25lZCAtLSBtdWNoIGJldHRlciAqLwoJCXN3aXRjaCAoZHNiLT5kc291bmQtPnB3ZngtPm5DaGFubmVscykgewoJCWNhc2UgMToKCQkJZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSAyKSB7CgkJCQkqYnBzID0gKCpicHMgKiBkc2ItPmN2b2xwYW4uZHdUb3RhbExlZnRBbXBGYWN0b3IpID4+IDE2OwoJCQkJYnBzKys7CgkJCX0KCQkJYnJlYWs7CgkJY2FzZSAyOgoJCQlmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHsKCQkJCSpicHMgPSAoKmJwcyAqIGRzYi0+Y3ZvbHBhbi5kd1RvdGFsTGVmdEFtcEZhY3RvcikgPj4gMTY7CgkJCQlicHMrKzsKCQkJCSpicHMgPSAoKmJwcyAqIGRzYi0+Y3ZvbHBhbi5kd1RvdGFsUmlnaHRBbXBGYWN0b3IpID4+IDE2OwoJCQkJYnBzKys7CgkJCX0KCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJRklYTUUoImRvZXNuJ3Qgc3VwcG9ydCAlZCBjaGFubmVsc1xuIiwgZHNiLT5kc291bmQtPnB3ZngtPm5DaGFubmVscyk7CgkJCWJyZWFrOwoJCX0KCQlicmVhazsKCWRlZmF1bHQ6CgkJRklYTUUoImRvZXNuJ3Qgc3VwcG9ydCAlZCBiaXQgc2FtcGxlc1xuIiwgZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlKTsKCQlicmVhazsKCX0KfQoKc3RhdGljIHZvaWQgKnRtcF9idWZmZXI7CnN0YXRpYyBzaXplX3QgdG1wX2J1ZmZlcl9sZW4gPSAwOwoKc3RhdGljIHZvaWQgKkRTT1VORF90bXBidWZmZXIoc2l6ZV90IGxlbikKewogIGlmIChsZW4+dG1wX2J1ZmZlcl9sZW4pIHsKICAgIHZvaWQgKm5ld19idWZmZXIgPSByZWFsbG9jKHRtcF9idWZmZXIsIGxlbik7CiAgICBpZiAobmV3X2J1ZmZlcikgewogICAgICB0bXBfYnVmZmVyID0gbmV3X2J1ZmZlcjsKICAgICAgdG1wX2J1ZmZlcl9sZW4gPSBsZW47CiAgICB9CiAgICByZXR1cm4gbmV3X2J1ZmZlcjsKICB9CiAgcmV0dXJuIHRtcF9idWZmZXI7Cn0KCnN0YXRpYyBEV09SRCBEU09VTkRfTWl4SW5CdWZmZXIoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgZnJhZ2xlbikKewoJSU5UCWksIGxlbiwgaWxlbiwgdGVtcCwgZmllbGQsIG5CbG9ja0FsaWduLCB0b2RvOwoJQllURQkqYnVmLCAqaWJ1ZjsKCglUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLGRzYix3cml0ZXBvcyxmcmFnbGVuKTsKCglsZW4gPSBmcmFnbGVuOwoJaWYgKCEoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpKSB7CgkJdGVtcCA9IE11bERpdihkc2ItPmRzb3VuZC0+cHdmeC0+bkF2Z0J5dGVzUGVyU2VjLCBkc2ItPmJ1ZmxlbiwKCQkJZHNiLT5uQXZnQnl0ZXNQZXJTZWMpIC0KCQkgICAgICAgTXVsRGl2KGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQXZnQnl0ZXNQZXJTZWMsIGRzYi0+YnVmX21peHBvcywKCQkJZHNiLT5uQXZnQnl0ZXNQZXJTZWMpOwoJCWxlbiA9IChsZW4gPiB0ZW1wKSA/IHRlbXAgOiBsZW47Cgl9CgluQmxvY2tBbGlnbiA9IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCWxlbiA9IGxlbiAvIG5CbG9ja0FsaWduICogbkJsb2NrQWxpZ247CS8qIGRhdGEgYWxpZ25tZW50ICovCgoJaWYgKGxlbiA9PSAwKSB7CgkJLyogVGhpcyBzaG91bGQgb25seSBoYXBwZW4gaWYgd2UgYXJlbid0IGxvb3BpbmcgYW5kIHRlbXAgPCBuQmxvY2tBbGlnbiAqLwoJCXJldHVybiAwOwoJfQoKCS8qIEJlZW4gc2VlaW5nIHNlZ2ZhdWx0cyBpbiBtYWxsb2MoKSBmb3Igc29tZSByZWFzb24uLi4gKi8KCVRSQUNFKCJhbGxvY2F0aW5nIGJ1ZmZlciAoc2l6ZSA9ICVkKVxuIiwgbGVuKTsKCWlmICgoYnVmID0gaWJ1ZiA9IChCWVRFICopIERTT1VORF90bXBidWZmZXIobGVuKSkgPT0gTlVMTCkKCQlyZXR1cm4gMDsKCglUUkFDRSgiTWl4SW5CdWZmZXIgKCVwKSBsZW4gPSAlZCwgZGVzdCA9ICVsZFxuIiwgZHNiLCBsZW4sIHdyaXRlcG9zKTsKCglpbGVuID0gRFNPVU5EX01peGVyTm9ybShkc2IsIGlidWYsIGxlbik7CglpZiAoKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUEFOKSB8fAoJICAgIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTFZPTFVNRSkgfHwKCSAgICAoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkwzRCkpCgkJRFNPVU5EX01peGVyVm9sKGRzYiwgaWJ1ZiwgbGVuKTsKCglpZiAoZHNiLT5kc291bmQtPnB3ZngtPndCaXRzUGVyU2FtcGxlID09IDgpIHsKCQlCWVRFCSpvYnVmID0gZHNiLT5kc291bmQtPmJ1ZmZlciArIHdyaXRlcG9zOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRzb3VuZC0+YnVmbGVuKQoJCQl0b2RvID0gbGVuOwoJCWVsc2UKCQkJdG9kbyA9IGRzYi0+ZHNvdW5kLT5idWZsZW4gLSB3cml0ZXBvczsKCgkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkvKiA4LWJpdCBXQVYgaXMgdW5zaWduZWQgKi8KCQkJZmllbGQgPSAoKmlidWYrKyAtIDEyOCk7CgkJCWZpZWxkICs9ICgqb2J1ZiAtIDEyOCk7CgkJCWlmIChmaWVsZCA+IDEyNykgZmllbGQgPSAxMjc7CgkJCWVsc2UgaWYgKGZpZWxkIDwgLTEyOCkgZmllbGQgPSAtMTI4OwoJCQkqb2J1ZisrID0gZmllbGQgKyAxMjg7CgkJfQogCgkJaWYgKHRvZG8gPCBsZW4pIHsKCQkJdG9kbyA9IGxlbiAtIHRvZG87CgkJCW9idWYgPSBkc2ItPmRzb3VuZC0+YnVmZmVyOwoKCQkJZm9yIChpID0gMDsgaSA8IHRvZG87IGkrKykgewoJCQkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkICovCgkJCQlmaWVsZCA9ICgqaWJ1ZisrIC0gMTI4KTsKCQkJCWZpZWxkICs9ICgqb2J1ZiAtIDEyOCk7CgkJCQlpZiAoZmllbGQgPiAxMjcpIGZpZWxkID0gMTI3OwoJCQkJZWxzZSBpZiAoZmllbGQgPCAtMTI4KSBmaWVsZCA9IC0xMjg7CgkJCQkqb2J1ZisrID0gZmllbGQgKyAxMjg7CgkJCX0KCQl9CiAgICAgICAgfSBlbHNlIHsKCQlJTlQxNgkqaWJ1ZnMsICpvYnVmczsKCgkJaWJ1ZnMgPSAoSU5UMTYgKikgaWJ1ZjsKCQlvYnVmcyA9IChJTlQxNiAqKShkc2ItPmRzb3VuZC0+YnVmZmVyICsgd3JpdGVwb3MpOwoKCQlpZiAoKHdyaXRlcG9zICsgbGVuKSA8PSBkc2ItPmRzb3VuZC0+YnVmbGVuKQoJCQl0b2RvID0gbGVuIC8gMjsKCQllbHNlCgkJCXRvZG8gPSAoZHNiLT5kc291bmQtPmJ1ZmxlbiAtIHdyaXRlcG9zKSAvIDI7CgoJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJLyogMTYtYml0IFdBViBpcyBzaWduZWQgKi8KCQkJZmllbGQgPSAqaWJ1ZnMrKzsKCQkJZmllbGQgKz0gKm9idWZzOwoJCQlpZiAoZmllbGQgPiAzMjc2NykgZmllbGQgPSAzMjc2NzsKCQkJZWxzZSBpZiAoZmllbGQgPCAtMzI3NjgpIGZpZWxkID0gLTMyNzY4OwoJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCX0KCgkJaWYgKHRvZG8gPCAobGVuIC8gMikpIHsKCQkJdG9kbyA9IChsZW4gLyAyKSAtIHRvZG87CgkJCW9idWZzID0gKElOVDE2ICopZHNiLT5kc291bmQtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCQlmaWVsZCA9ICppYnVmcysrOwoJCQkJZmllbGQgKz0gKm9idWZzOwoJCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCQllbHNlIGlmIChmaWVsZCA8IC0zMjc2OCkgZmllbGQgPSAtMzI3Njg7CgkJCQkqb2J1ZnMrKyA9IGZpZWxkOwoJCQl9CgkJfQogICAgICAgIH0KCglpZiAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+c3RhcnRwb3MgPiBkc2ItPmJ1Zl9taXhwb3MpICYmIChkc2ItPnN0YXJ0cG9zIDw9IGRzYi0+YnVmX21peHBvcyArIGlsZW4pKSB7CgkJLyogSEFDSy4uLiBsZWFkaW4gc2hvdWxkIGJlIHJlc2V0IHdoZW4gdGhlIFBMQVkgcG9zaXRpb24gcmVhY2hlcyB0aGUgc3RhcnRwb3MsCgkJICogbm90IHRoZSBNSVggcG9zaXRpb24uLi4gYnV0IGlmIHRoZSBzb3VuZCBidWZmZXIgaXMgYmlnZ2VyIHRoYW4gb3VyIHByZWJ1ZmZlcmluZwoJCSAqICh3aGljaCBtdXN0IGJlIHRoZSBjYXNlIGZvciB0aGUgc3RyZWFtaW5nIGJ1ZmZlcnMgdGhhdCBuZWVkIHRoaXMgaGFjayBhbnl3YXkpCgkJICogcGx1cyBEU19IRUxfTUFSR0lOIG9yIGVxdWl2YWxlbnQsIHRoZW4gdGhpcyBvdWdodCB0byB3b3JrIGFueXdheS4gKi8KCQlkc2ItPmxlYWRpbiA9IEZBTFNFOwoJfQoKCWRzYi0+YnVmX21peHBvcyArPSBpbGVuOwoKCWlmIChkc2ItPmJ1Zl9taXhwb3MgPj0gZHNiLT5idWZsZW4pIHsKCQlpZiAoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpIHsKCQkJLyogd3JhcCAqLwoJCQlkc2ItPmJ1Zl9taXhwb3MgJT0gZHNiLT5idWZsZW47CgkJCWlmIChkc2ItPmxlYWRpbiAmJiAoZHNiLT5zdGFydHBvcyA8PSBkc2ItPmJ1Zl9taXhwb3MpKQoJCQkJZHNiLT5sZWFkaW4gPSBGQUxTRTsgLyogSEFDSzogc2VlIGFib3ZlICovCgkJfQoJfQoKCXJldHVybiBsZW47Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9QaGFzZUNhbmNlbChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHdyaXRlcG9zLCBEV09SRCBsZW4pCnsKCUlOVCAgICAgaWxlbiwgZmllbGQsIG5CbG9ja0FsaWduOwoJVUlOVCAgICBpLCB0b2RvOwoJQllURQkqYnVmLCAqaWJ1ZjsKCglUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLGRzYix3cml0ZXBvcyxsZW4pOwoKCW5CbG9ja0FsaWduID0gZHNiLT5kc291bmQtPnB3ZngtPm5CbG9ja0FsaWduOwoJbGVuID0gbGVuIC8gbkJsb2NrQWxpZ24gKiBuQmxvY2tBbGlnbjsgIC8qIGRhdGEgYWxpZ25tZW50ICovCgoJVFJBQ0UoImFsbG9jYXRpbmcgYnVmZmVyIChzaXplID0gJWxkKVxuIiwgbGVuKTsKCWlmICgoYnVmID0gaWJ1ZiA9IChCWVRFICopIERTT1VORF90bXBidWZmZXIobGVuKSkgPT0gTlVMTCkKCQlyZXR1cm47CgoJVFJBQ0UoIlBoYXNlQ2FuY2VsICglcCkgbGVuID0gJWxkLCBkZXN0ID0gJWxkXG4iLCBkc2IsIGxlbiwgd3JpdGVwb3MpOwoKCWlsZW4gPSBEU09VTkRfTWl4ZXJOb3JtKGRzYiwgaWJ1ZiwgbGVuKTsKCWlmICgoZHNiLT5kc2JkLmR3RmxhZ3MgJiBEU0JDQVBTX0NUUkxQQU4pIHx8CgkgICAgKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMVk9MVU1FKSB8fAoJICAgIChkc2ItPmRzYmQuZHdGbGFncyAmIERTQkNBUFNfQ1RSTDNEKSkKCQlEU09VTkRfTWl4ZXJWb2woZHNiLCBpYnVmLCBsZW4pOwoKCS8qIHN1YnRyYWN0IGluc3RlYWQgb2YgYWRkLCB0byBwaGFzZSBvdXQgcHJlbWl4ZWQgZGF0YSAqLwoJaWYgKGRzYi0+ZHNvdW5kLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4KSB7CgkJQllURQkqb2J1ZiA9IGRzYi0+ZHNvdW5kLT5idWZmZXIgKyB3cml0ZXBvczsKCgkJaWYgKCh3cml0ZXBvcyArIGxlbikgPD0gZHNiLT5kc291bmQtPmJ1ZmxlbikKCQkJdG9kbyA9IGxlbjsKCQllbHNlCgkJCXRvZG8gPSBkc2ItPmRzb3VuZC0+YnVmbGVuIC0gd3JpdGVwb3M7CgoJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJLyogOC1iaXQgV0FWIGlzIHVuc2lnbmVkICovCgkJCWZpZWxkID0gKCppYnVmKysgLSAxMjgpOwoJCQlmaWVsZCAtPSAoKm9idWYgLSAxMjgpOwoJCQlpZiAoZmllbGQgPiAxMjcpIGZpZWxkID0gMTI3OwoJCQllbHNlIGlmIChmaWVsZCA8IC0xMjgpIGZpZWxkID0gLTEyODsKCQkJKm9idWYrKyA9IGZpZWxkICsgMTI4OwoJCX0KIAoJCWlmICh0b2RvIDwgbGVuKSB7CgkJCXRvZG8gPSBsZW4gLSB0b2RvOwoJCQlvYnVmID0gZHNiLT5kc291bmQtPmJ1ZmZlcjsKCgkJCWZvciAoaSA9IDA7IGkgPCB0b2RvOyBpKyspIHsKCQkJCS8qIDgtYml0IFdBViBpcyB1bnNpZ25lZCAqLwoJCQkJZmllbGQgPSAoKmlidWYrKyAtIDEyOCk7CgkJCQlmaWVsZCAtPSAoKm9idWYgLSAxMjgpOwoJCQkJaWYgKGZpZWxkID4gMTI3KSBmaWVsZCA9IDEyNzsKCQkJCWVsc2UgaWYgKGZpZWxkIDwgLTEyOCkgZmllbGQgPSAtMTI4OwoJCQkJKm9idWYrKyA9IGZpZWxkICsgMTI4OwoJCQl9CgkJfQogICAgICAgIH0gZWxzZSB7CgkJSU5UMTYJKmlidWZzLCAqb2J1ZnM7CgoJCWlidWZzID0gKElOVDE2ICopIGlidWY7CgkJb2J1ZnMgPSAoSU5UMTYgKikoZHNiLT5kc291bmQtPmJ1ZmZlciArIHdyaXRlcG9zKTsKCgkJaWYgKCh3cml0ZXBvcyArIGxlbikgPD0gZHNiLT5kc291bmQtPmJ1ZmxlbikKCQkJdG9kbyA9IGxlbiAvIDI7CgkJZWxzZQoJCQl0b2RvID0gKGRzYi0+ZHNvdW5kLT5idWZsZW4gLSB3cml0ZXBvcykgLyAyOwoKCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCS8qIDE2LWJpdCBXQVYgaXMgc2lnbmVkICovCgkJCWZpZWxkID0gKmlidWZzKys7CgkJCWZpZWxkIC09ICpvYnVmczsKCQkJaWYgKGZpZWxkID4gMzI3NjcpIGZpZWxkID0gMzI3Njc7CgkJCWVsc2UgaWYgKGZpZWxkIDwgLTMyNzY4KSBmaWVsZCA9IC0zMjc2ODsKCQkJKm9idWZzKysgPSBmaWVsZDsKCQl9CgoJCWlmICh0b2RvIDwgKGxlbiAvIDIpKSB7CgkJCXRvZG8gPSAobGVuIC8gMikgLSB0b2RvOwoJCQlvYnVmcyA9IChJTlQxNiAqKWRzYi0+ZHNvdW5kLT5idWZmZXI7CgoJCQlmb3IgKGkgPSAwOyBpIDwgdG9kbzsgaSsrKSB7CgkJCQkvKiAxNi1iaXQgV0FWIGlzIHNpZ25lZCAqLwoJCQkJZmllbGQgPSAqaWJ1ZnMrKzsKCQkJCWZpZWxkIC09ICpvYnVmczsKCQkJCWlmIChmaWVsZCA+IDMyNzY3KSBmaWVsZCA9IDMyNzY3OwoJCQkJZWxzZSBpZiAoZmllbGQgPCAtMzI3NjgpIGZpZWxkID0gLTMyNzY4OwoJCQkJKm9idWZzKysgPSBmaWVsZDsKCQkJfQoJCX0KICAgICAgICB9Cn0KCnN0YXRpYyB2b2lkIERTT1VORF9NaXhDYW5jZWwoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCB3cml0ZXBvcywgQk9PTCBjYW5jZWwpCnsKCURXT1JEICAgc2l6ZSwgZmxlbiwgbGVuLCBucG9zLCBubGVuOwoJSU5UCWlBZHZhbmNlID0gZHNiLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCUlOVAlvQWR2YW5jZSA9IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCS8qIGRldGVybWluZSBhbW91bnQgb2YgcHJlbWl4ZWQgZGF0YSB0byBjYW5jZWwgKi8KCURXT1JEIHByaW1hcnlfZG9uZSA9CgkJKChkc2ItPnByaW1hcnlfbWl4cG9zIDwgd3JpdGVwb3MpID8gZHNiLT5kc291bmQtPmJ1ZmxlbiA6IDApICsKCQlkc2ItPnByaW1hcnlfbWl4cG9zIC0gd3JpdGVwb3M7CgoJVFJBQ0UoIiglcCwgJWxkKSwgYnVmX21peHBvcz0lbGRcbiIsIGRzYiwgd3JpdGVwb3MsIGRzYi0+YnVmX21peHBvcyk7CgoJLyogYmFja3RyYWNrIHRoZSBtaXggcG9zaXRpb24gKi8KCXNpemUgPSBwcmltYXJ5X2RvbmUgLyBvQWR2YW5jZTsKCWZsZW4gPSBzaXplICogZHNiLT5mcmVxQWRqdXN0OwoJbGVuID0gKGZsZW4gPj4gRFNPVU5EX0ZSRVFTSElGVCkgKiBpQWR2YW5jZTsKCWZsZW4gJj0gKDE8PERTT1VORF9GUkVRU0hJRlQpLTE7Cgl3aGlsZSAoZHNiLT5mcmVxQWNjIDwgZmxlbikgewoJCWxlbiArPSBpQWR2YW5jZTsKCQlkc2ItPmZyZXFBY2MgKz0gMTw8RFNPVU5EX0ZSRVFTSElGVDsKCX0KCWxlbiAlPSBkc2ItPmJ1ZmxlbjsKCW5wb3MgPSAoKGRzYi0+YnVmX21peHBvcyA8IGxlbikgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBsZW47CglpZiAoZHNiLT5sZWFkaW4gJiYgKGRzYi0+c3RhcnRwb3MgPiBucG9zKSAmJiAoZHNiLT5zdGFydHBvcyA8PSBucG9zICsgbGVuKSkgewoJCS8qIHN0b3AgYmFja3RyYWNraW5nIGF0IHN0YXJ0cG9zICovCgkJbnBvcyA9IGRzYi0+c3RhcnRwb3M7CgkJbGVuID0gKChkc2ItPmJ1Zl9taXhwb3MgPCBucG9zKSA/IGRzYi0+YnVmbGVuIDogMCkgKwoJCQlkc2ItPmJ1Zl9taXhwb3MgLSBucG9zOwoJCWZsZW4gPSBkc2ItPmZyZXFBY2M7CgkJbmxlbiA9IGxlbiAvIGRzYi0+cHdmeC0+bkJsb2NrQWxpZ247CgkJbmxlbiA9ICgobmxlbiA8PCBEU09VTkRfRlJFUVNISUZUKSArIGZsZW4pIC8gZHNiLT5mcmVxQWRqdXN0OwoJCW5sZW4gKj0gZHNiLT5kc291bmQtPnB3ZngtPm5CbG9ja0FsaWduOwoJCXdyaXRlcG9zID0KCQkJKChkc2ItPnByaW1hcnlfbWl4cG9zIDwgbmxlbikgPyBkc2ItPmRzb3VuZC0+YnVmbGVuIDogMCkgKwoJCQlkc2ItPnByaW1hcnlfbWl4cG9zIC0gbmxlbjsKCX0KCglkc2ItPmZyZXFBY2MgLT0gZmxlbjsKCWRzYi0+YnVmX21peHBvcyA9IG5wb3M7Cglkc2ItPnByaW1hcnlfbWl4cG9zID0gd3JpdGVwb3M7CgoJVFJBQ0UoIm5ldyBidWZfbWl4cG9zPSVsZCwgcHJpbWFyeV9taXhwb3M9JWxkIChsZW49JWxkKVxuIiwKCSAgICAgIGRzYi0+YnVmX21peHBvcywgZHNiLT5wcmltYXJ5X21peHBvcywgbGVuKTsKCglpZiAoY2FuY2VsKSBEU09VTkRfUGhhc2VDYW5jZWwoZHNiLCB3cml0ZXBvcywgbGVuKTsKfQoKdm9pZCBEU09VTkRfTWl4Q2FuY2VsQXQoSURpcmVjdFNvdW5kQnVmZmVySW1wbCAqZHNiLCBEV09SRCBidWZfd3JpdGVwb3MpCnsKI2lmIDAKCURXT1JEICAgaSwgc2l6ZSwgZmxlbiwgbGVuLCBucG9zLCBubGVuOwoJSU5UCWlBZHZhbmNlID0gZHNiLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCUlOVAlvQWR2YW5jZSA9IGRzYi0+ZHNvdW5kLT5wd2Z4LT5uQmxvY2tBbGlnbjsKCS8qIGRldGVybWluZSBhbW91bnQgb2YgcHJlbWl4ZWQgZGF0YSB0byBjYW5jZWwgKi8KCURXT1JEIGJ1Zl9kb25lID0KCQkoKGRzYi0+YnVmX21peHBvcyA8IGJ1Zl93cml0ZXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBidWZfd3JpdGVwb3M7CiNlbmRpZgoKCVdBUk4oIiglcCwgJWxkKSwgYnVmX21peHBvcz0lbGRcbiIsIGRzYiwgYnVmX3dyaXRlcG9zLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogc2luY2UgdGhpcyBpcyBub3QgaW1wbGVtZW50ZWQgeWV0LCBqdXN0IGNhbmNlbCAqQUxMKiBwcmVidWZmZXJpbmcgZm9yIG5vdwoJICogKHdoaWNoIGlzIGZhc3RlciBhbnl3YXkgd2hlbiB0aGVyZSdzIG9ubHkgYSBzaW5nbGUgc2Vjb25kYXJ5IGJ1ZmZlcikgKi8KCWRzYi0+ZHNvdW5kLT5uZWVkX3JlbWl4ID0gVFJVRTsKfQoKdm9pZCBEU09VTkRfRm9yY2VSZW1peChJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IpCnsKCVRSQUNFKCIoJXApXG4iLGRzYik7CglFbnRlckNyaXRpY2FsU2VjdGlvbigmZHNiLT5sb2NrKTsKCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHsKI2lmIDAgLyogdGhpcyBtYXkgbm90IGJlIHF1aXRlIHJlbGlhYmxlIHlldCAqLwoJCWRzYi0+bmVlZF9yZW1peCA9IFRSVUU7CiNlbHNlCgkJZHNiLT5kc291bmQtPm5lZWRfcmVtaXggPSBUUlVFOwojZW5kaWYKCX0KCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCZkc2ItPmxvY2spOwp9CgpzdGF0aWMgRFdPUkQgRFNPVU5EX01peE9uZShJRGlyZWN0U291bmRCdWZmZXJJbXBsICpkc2IsIERXT1JEIHBsYXlwb3MsIERXT1JEIHdyaXRlcG9zLCBEV09SRCBtaXhsZW4pCnsKCURXT1JEIGxlbiwgc2xlbjsKCS8qIGRldGVybWluZSB0aGlzIGJ1ZmZlcidzIHdyaXRlIHBvc2l0aW9uICovCglEV09SRCBidWZfd3JpdGVwb3MgPSBEU09VTkRfQ2FsY1BsYXlQb3NpdGlvbihkc2IsIGRzYi0+c3RhdGUgJiBkc2ItPmRzb3VuZC0+c3RhdGUsIHdyaXRlcG9zLAoJCQkJCQkgICAgIHdyaXRlcG9zLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBkc2ItPmJ1Zl9taXhwb3MpOwoJLyogZGV0ZXJtaW5lIGhvdyBtdWNoIGFscmVhZHktbWl4ZWQgZGF0YSBleGlzdHMgKi8KCURXT1JEIGJ1Zl9kb25lID0KCQkoKGRzYi0+YnVmX21peHBvcyA8IGJ1Zl93cml0ZXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlkc2ItPmJ1Zl9taXhwb3MgLSBidWZfd3JpdGVwb3M7CglEV09SRCBwcmltYXJ5X2RvbmUgPQoJCSgoZHNiLT5wcmltYXJ5X21peHBvcyA8IHdyaXRlcG9zKSA/IGRzYi0+ZHNvdW5kLT5idWZsZW4gOiAwKSArCgkJZHNiLT5wcmltYXJ5X21peHBvcyAtIHdyaXRlcG9zOwoJRFdPUkQgYWR2X2RvbmUgPQoJCSgoZHNiLT5kc291bmQtPm1peHBvcyA8IHdyaXRlcG9zKSA/IGRzYi0+ZHNvdW5kLT5idWZsZW4gOiAwKSArCgkJZHNiLT5kc291bmQtPm1peHBvcyAtIHdyaXRlcG9zOwoJRFdPUkQgcGxheWVkID0KCQkoKGJ1Zl93cml0ZXBvcyA8IGRzYi0+cGxheXBvcykgPyBkc2ItPmJ1ZmxlbiA6IDApICsKCQlidWZfd3JpdGVwb3MgLSBkc2ItPnBsYXlwb3M7CglEV09SRCBidWZfbGVmdCA9IGRzYi0+YnVmbGVuIC0gYnVmX3dyaXRlcG9zOwoJaW50IHN0aWxsX2JlaGluZDsKCglUUkFDRSgiKCVwLCVsZCwlbGQsJWxkKVxuIixkc2IscGxheXBvcyx3cml0ZXBvcyxtaXhsZW4pOwoJVFJBQ0UoImJ1Zl93cml0ZXBvcz0lbGQsIHByaW1hcnlfd3JpdGVwb3M9JWxkXG4iLCBidWZfd3JpdGVwb3MsIHdyaXRlcG9zKTsKCVRSQUNFKCJidWZfZG9uZT0lbGQsIHByaW1hcnlfZG9uZT0lbGRcbiIsIGJ1Zl9kb25lLCBwcmltYXJ5X2RvbmUpOwoJVFJBQ0UoImJ1Zl9taXhwb3M9JWxkLCBwcmltYXJ5X21peHBvcz0lbGQsIG1peGxlbj0lbGRcbiIsIGRzYi0+YnVmX21peHBvcywgZHNiLT5wcmltYXJ5X21peHBvcywKCSAgICAgIG1peGxlbik7CglUUkFDRSgibG9vcGluZz0lbGQsIHN0YXJ0cG9zPSVsZCwgbGVhZGluPSVsZFxuIiwgZHNiLT5wbGF5ZmxhZ3MsIGRzYi0+c3RhcnRwb3MsIGRzYi0+bGVhZGluKTsKCgkvKiBjaGVjayBmb3Igbm90aWZpY2F0aW9uIHBvc2l0aW9ucyAqLwoJaWYgKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19DVFJMUE9TSVRJT05OT1RJRlkgJiYKCSAgICBkc2ItPnN0YXRlICE9IFNUQVRFX1NUQVJUSU5HKSB7CgkJRFNPVU5EX0NoZWNrRXZlbnQoZHNiLCBwbGF5ZWQpOwoJfQoKCS8qIHNhdmUgd3JpdGUgcG9zaXRpb24gZm9yIG5vbi1HRVRDVVJSRU5UUE9TSVRJT04yLi4uICovCglkc2ItPnBsYXlwb3MgPSBidWZfd3JpdGVwb3M7CgoJLyogY2hlY2sgd2hldGhlciBDYWxjUGxheVBvc2l0aW9uIGRldGVjdGVkIGEgbWl4aW5nIHVuZGVycnVuICovCglpZiAoKGJ1Zl9kb25lID09IDApICYmIChkc2ItPnByaW1hcnlfbWl4cG9zICE9IHdyaXRlcG9zKSkgewoJCS8qIGl0IGRpZCwgYnV0IGRpZCB3ZSBoYXZlIG1vcmUgdG8gcGxheT8gKi8KCQlpZiAoKGRzYi0+cGxheWZsYWdzICYgRFNCUExBWV9MT09QSU5HKSB8fAoJCSAgICAoZHNiLT5idWZfbWl4cG9zIDwgZHNiLT5idWZsZW4pKSB7CgkJCS8qIHllcywgaGF2ZSB0byByZWNvdmVyICovCgkJCUVSUigidW5kZXJydW4gb24gc291bmQgYnVmZmVyICVwXG4iLCBkc2IpOwoJCQlUUkFDRSgicmVjb3ZlcmluZyBmcm9tIHVuZGVycnVuOiBwcmltYXJ5X21peHBvcz0lbGRcbiIsIHdyaXRlcG9zKTsKCQl9CgkJZHNiLT5wcmltYXJ5X21peHBvcyA9IHdyaXRlcG9zOwoJCXByaW1hcnlfZG9uZSA9IDA7Cgl9CgkvKiBkZXRlcm1pbmUgaG93IGZhciBhaGVhZCB3ZSBzaG91bGQgbWl4ICovCglpZiAoKChkc2ItPnBsYXlmbGFncyAmIERTQlBMQVlfTE9PUElORykgfHwKCSAgICAgKGRzYi0+bGVhZGluICYmIChkc2ItPnByb2JhYmx5X3ZhbGlkX3RvICE9IDApKSkgJiYKCSAgICAhKGRzYi0+ZHNiZC5kd0ZsYWdzICYgRFNCQ0FQU19TVEFUSUMpKSB7CgkJLyogaWYgdGhpcyBpcyBhIHN0cmVhbWluZyBidWZmZXIsIGl0IHR5cGljYWxseSBtZWFucyB0aGF0CgkJICogd2Ugc2hvdWxkIGRlZmVyIG1peGluZyBwYXN0IHByb2JhYmx5X3ZhbGlkX3RvIGFzIGxvbmcKCQkgKiBhcyB3ZSBjYW4sIHRvIGF2b2lkIHVubmVjZXNzYXJ5IHJlbWl4aW5nICovCgkJLyogdGhlIGhlYXZ5LWxvb2tpbmcgY2FsY3VsYXRpb25zIHNob3VsZG4ndCBiZSB0aGF0IGJhZCwKCQkgKiBhcyBhbnkgZ2FtZSBpc24ndCBsaWtlbHkgdG8gYmUgaGF2ZSBtb3JlIHRoYW4gMSBvciAyCgkJICogc3RyZWFtaW5nIGJ1ZmZlcnMgaW4gdXNlIGF0IGFueSB0aW1lIGFueXdheS4uLiAqLwoJCURXT1JEIHByb2JhYmx5X3ZhbGlkX2xlZnQgPQoJCQkoZHNiLT5wcm9iYWJseV92YWxpZF90byA9PSAoRFdPUkQpLTEpID8gZHNiLT5idWZsZW4gOgoJCQkoKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPCBidWZfd3JpdGVwb3MpID8gZHNiLT5idWZsZW4gOiAwKSArCgkJCWRzYi0+cHJvYmFibHlfdmFsaWRfdG8gLSBidWZfd3JpdGVwb3M7CgkJLyogY2hlY2sgZm9yIGxlYWRpbiBjb25kaXRpb24gKi8KCQlpZiAoKHByb2JhYmx5X3ZhbGlkX2xlZnQgPT0gMCkgJiYKCQkgICAgKGRzYi0+cHJvYmFibHlfdmFsaWRfdG8gPT0gZHNiLT5zdGFydHBvcykgJiYKCQkgICAgZHNiLT5sZWFkaW4pCgkJCXByb2JhYmx5X3ZhbGlkX2xlZnQgPSBkc2ItPmJ1ZmxlbjsKCQlUUkFDRSgic3RyZWFtaW5nIGJ1ZmZlciBwcm9iYWJseV92YWxpZF90bz0lbGQsIHByb2JhYmx5X3ZhbGlkX2xlZnQ9JWxkXG4iLAoJCSAgICAgIGRzYi0+cHJvYmFibHlfdmFsaWRfdG8sIHByb2JhYmx5X3ZhbGlkX2xlZnQpOwoJCS8qIGNoZWNrIHdoZXRoZXIgdGhlIGFwcCdzIHRpbWUgaXMgYWxyZWFkeSB1cCAqLwoJCWlmIChwcm9iYWJseV92YWxpZF9sZWZ0IDwgZHNiLT53cml0ZWxlYWQpIHsKCQkJV0FSTigicHJvYmFibHlfdmFsaWRfdG8gbm93IHdpdGhpbiB3cml0ZWxlYWQsIHBvc3NpYmxlIHN0cmVhbWluZyB1bmRlcnJ1blxuIik7CgkJCS8qIG9uY2Ugd2UgcGFzcyB0aGUgcG9pbnQgb2Ygbm8gcmV0dXJuLAoJCQkgKiBubyByZWFzb24gdG8gaG9sZCBiYWNrIGFueW1vcmUgKi8KCQkJZHNiLT5wcm9iYWJseV92YWxpZF90byA9IChEV09SRCktMTsKCQkJLyogd2UganVzdCBoYXZlIHRvIGdvIGFoZWFkIGFuZCBtaXggd2hhdCB3ZSBoYXZlLAoJCQkgKiB0aGVyZSdzIG5vIHRlbGxpbmcgd2hhdCB0aGUgYXBwIGlzIHRoaW5raW5nIGFueXdheSAqLwoJCX0gZWxzZSB7CgkJCS8qIGFkanVzdCBmb3Igb3VyIGZyZXF1ZW5jeSBhbmQgb3VyIHNhbXBsZSBzaXplICovCgkJCXByb2JhYmx5X3ZhbGlkX2xlZnQgPSBNdWxEaXYocHJvYmFibHlfdmFsaWRfbGVmdCwKCQkJCQkJICAgICAxIDw8IERTT1VORF9GUkVRU0hJRlQsCgkJCQkJCSAgICAgZHNiLT5wd2Z4LT5uQmxvY2tBbGlnbiAqIGRzYi0+ZnJlcUFkanVzdCkgKgoJCQkJICAgICAgICAgICAgICBkc2ItPmRzb3VuZC0+cHdmeC0+bkJsb2NrQWxpZ247CgkJCS8qIGNoZWNrIHdoZXRoZXIgdG8gY2xpcCBtaXhfbGVuICovCgkJCWlmIChwcm9iYWJseV92YWxpZF9sZWZ0IDwgbWl4bGVuKSB7CgkJCQlUUkFDRSgiY2xpcHBpbmcgdG8gcHJvYmFibHlfdmFsaWRfbGVmdD0lbGRcbiIsIHByb2JhYmx5X3ZhbGlkX2xlZnQpOwoJCQkJbWl4bGVuID0gcHJvYmFibHlfdmFsaWRfbGVmdDsKCQkJfQoJCX0KCX0KCS8qIGN1dCBtaXhsZW4gd2l0aCB3aGF0J3MgYWxyZWFkeSBiZWVuIG1peGVkICovCglpZiAobWl4bGVuIDwgcHJpbWFyeV9kb25lKSB7CgkJLyogaHVoPyBhbmQgc3RpbGwgQ2FsY1BsYXlQb3NpdGlvbiBkaWRuJ3QKCQkgKiBkZXRlY3QgYW4gdW5kZXJydW4/ICovCgkJRklYTUUoInByb2JsZW0gd2l0aCB1bmRlcnJ1biBkZXRlY3Rpb24gKG1peGxlbj0lbGQgPCBwcmltYXJ5X2RvbmU9JWxkKVxuIiwgbWl4bGVuLCBwcmltYXJ5X2RvbmUpOwoJCXJldHVybiAwOwoJfQoJbGVuID0gbWl4bGVuIC0gcHJpbWFyeV9kb25lOwoJVFJBQ0UoInJlbWFpbmluZyBtaXhsZW49JWxkXG4iLCBsZW4pOwoKCWlmIChsZW4gPCBkc2ItPmRzb3VuZC0+ZnJhZ2xlbikgewoJCS8qIHNtYWxsZXIgdGhhbiBhIGZyYWdtZW50LCB3YWl0IHVudGlsIGl0IGdldHMgbGFyZ2VyCgkJICogYmVmb3JlIHdlIHRha2UgdGhlIG1peGluZyBvdmVyaGVhZCAqLwoJCVRSQUNFKCJtaXhsZW4gbm90IHdvcnRoIGl0LCBkZWZlcnJpbmcgbWl4aW5nXG4iKTsKCQlzdGlsbF9iZWhpbmQgPSAxOwoJCWdvdG8gcG9zdF9taXg7Cgl9CgoJLyogb2ssIHdlIGtub3cgaG93IG11Y2ggdG8gbWl4LCBsZXQncyBnbyAqLwoJc3RpbGxfYmVoaW5kID0gKGFkdl9kb25lID4gcHJpbWFyeV9kb25lKTsKCXdoaWxlIChsZW4pIHsKCQlzbGVuID0gZHNiLT5kc291bmQtPmJ1ZmxlbiAtIGRzYi0+cHJpbWFyeV9taXhwb3M7CgkJaWYgKHNsZW4gPiBsZW4pIHNsZW4gPSBsZW47CgkJc2xlbiA9IERTT1VORF9NaXhJbkJ1ZmZlcihkc2IsIGRzYi0+cHJpbWFyeV9taXhwb3MsIHNsZW4pOwoKCQlpZiAoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBkc2ItPmRzb3VuZC0+bWl4cG9zKSAmJgoJCSAgICAoZHNiLT5wcmltYXJ5X21peHBvcyArIHNsZW4gPj0gZHNiLT5kc291bmQtPm1peHBvcykpCgkJCXN0aWxsX2JlaGluZCA9IEZBTFNFOwoKCQlkc2ItPnByaW1hcnlfbWl4cG9zICs9IHNsZW47IGxlbiAtPSBzbGVuOwoJCWRzYi0+cHJpbWFyeV9taXhwb3MgJT0gZHNiLT5kc291bmQtPmJ1ZmxlbjsKCgkJaWYgKChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHx8ICFzbGVuKSBicmVhazsKCX0KCVRSQUNFKCJuZXcgcHJpbWFyeV9taXhwb3M9JWxkLCBwcmltYXJ5X2FkdmJhc2U9JWxkXG4iLCBkc2ItPnByaW1hcnlfbWl4cG9zLCBkc2ItPmRzb3VuZC0+bWl4cG9zKTsKCVRSQUNFKCJtaXhlZCBkYXRhIGxlbj0lbGQsIHN0aWxsX2JlaGluZD0lZFxuIiwgbWl4bGVuLWxlbiwgc3RpbGxfYmVoaW5kKTsKCnBvc3RfbWl4OgoJLyogY2hlY2sgaWYgYnVmZmVyIHNob3VsZCBiZSBjb25zaWRlcmVkIGNvbXBsZXRlICovCglpZiAoYnVmX2xlZnQgPCBkc2ItPndyaXRlbGVhZCAmJgoJICAgICEoZHNiLT5wbGF5ZmxhZ3MgJiBEU0JQTEFZX0xPT1BJTkcpKSB7CgkJZHNiLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJZHNiLT5wbGF5cG9zID0gMDsKCQlkc2ItPmxhc3RfcGxheXBvcyA9IDA7CgkJZHNiLT5idWZfbWl4cG9zID0gMDsKCQlkc2ItPmxlYWRpbiA9IEZBTFNFOwoJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgYnVmX2xlZnQpOwoJfQoKCS8qIHJldHVybiBob3cgZmFyIHdlIHRoaW5rIHRoZSBwcmltYXJ5IGJ1ZmZlciBjYW4KCSAqIGFkdmFuY2UgaXRzIHVuZGVycnVuIGRldGVjdG9yLi4uKi8KCWlmIChzdGlsbF9iZWhpbmQpIHJldHVybiAwOwoJaWYgKChtaXhsZW4gLSBsZW4pIDwgcHJpbWFyeV9kb25lKSByZXR1cm4gMDsKCXNsZW4gPSAoKGRzYi0+cHJpbWFyeV9taXhwb3MgPCBkc2ItPmRzb3VuZC0+bWl4cG9zKSA/CgkJZHNiLT5kc291bmQtPmJ1ZmxlbiA6IDApICsgZHNiLT5wcmltYXJ5X21peHBvcyAtCgkJZHNiLT5kc291bmQtPm1peHBvczsKCWlmIChzbGVuID4gbWl4bGVuKSB7CgkJLyogdGhlIHByaW1hcnlfZG9uZSBhbmQgc3RpbGxfYmVoaW5kIGNoZWNrcyBhYm92ZSBzaG91bGQgaGF2ZSB3b3JrZWQgKi8KCQlGSVhNRSgicHJvYmxlbSB3aXRoIGFkdmFuY2VtZW50IGNhbGN1bGF0aW9uIChhZHZsZW49JWxkID4gbWl4bGVuPSVsZClcbiIsIHNsZW4sIG1peGxlbik7CgkJc2xlbiA9IDA7Cgl9CglyZXR1cm4gc2xlbjsKfQoKc3RhdGljIERXT1JEIERTT1VORF9NaXhUb1ByaW1hcnkoSURpcmVjdFNvdW5kSW1wbCAqZHNvdW5kLCBEV09SRCBwbGF5cG9zLCBEV09SRCB3cml0ZXBvcywgRFdPUkQgbWl4bGVuLCBCT09MIHJlY292ZXIpCnsKCUlOVAkJCWksIGxlbiwgbWF4bGVuID0gMDsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwJKmRzYjsKCglUUkFDRSgiKCVsZCwlbGQsJWxkLCVkKVxuIiwgcGxheXBvcywgd3JpdGVwb3MsIG1peGxlbiwgcmVjb3Zlcik7Cglmb3IgKGkgPSAwOyBpIDwgZHNvdW5kLT5ucm9mYnVmZmVyczsgaSsrKSB7CgkJZHNiID0gZHNvdW5kLT5idWZmZXJzW2ldOwoKCQlpZiAoZHNiLT5idWZsZW4gJiYgZHNiLT5zdGF0ZSAmJiAhZHNiLT5od2J1ZikgewoJCQlUUkFDRSgiQ2hlY2tpbmcgJXAsIG1peGxlbj0lbGRcbiIsIGRzYiwgbWl4bGVuKTsKCQkJRW50ZXJDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQkJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RPUFBJTkcpIHsKCQkJCURTT1VORF9NaXhDYW5jZWwoZHNiLCB3cml0ZXBvcywgVFJVRSk7CgkJCQlkc2ItPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQkJCURTT1VORF9DaGVja0V2ZW50KGRzYiwgMCk7CgkJCX0gZWxzZSB7CgkJCQlpZiAoKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHx8IHJlY292ZXIpIHsKCQkJCQlkc2ItPnByaW1hcnlfbWl4cG9zID0gd3JpdGVwb3M7CgkJCQkJZHNiLT5jdm9scGFuID0gZHNiLT52b2xwYW47CgkJCQkJZHNiLT5uZWVkX3JlbWl4ID0gRkFMU0U7CgkJCQl9CgkJCQllbHNlIGlmIChkc2ItPm5lZWRfcmVtaXgpIHsKCQkJCQlEU09VTkRfTWl4Q2FuY2VsKGRzYiwgd3JpdGVwb3MsIFRSVUUpOwoJCQkJCWRzYi0+Y3ZvbHBhbiA9IGRzYi0+dm9scGFuOwoJCQkJCWRzYi0+bmVlZF9yZW1peCA9IEZBTFNFOwoJCQkJfQoJCQkJbGVuID0gRFNPVU5EX01peE9uZShkc2IsIHBsYXlwb3MsIHdyaXRlcG9zLCBtaXhsZW4pOwoJCQkJaWYgKGRzYi0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpCgkJCQkJZHNiLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7CgkJCQltYXhsZW4gPSAobGVuID4gbWF4bGVuKSA/IGxlbiA6IG1heGxlbjsKCQkJfQoJCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKGRzYi0+bG9jaykpOwoJCX0KCX0KCglyZXR1cm4gbWF4bGVuOwp9CgpzdGF0aWMgdm9pZCBEU09VTkRfTWl4UmVzZXQoSURpcmVjdFNvdW5kSW1wbCAqZHNvdW5kLCBEV09SRCB3cml0ZXBvcykKewoJSU5UCQkJaTsKCUlEaXJlY3RTb3VuZEJ1ZmZlckltcGwJKmRzYjsKCWludCBuZmlsbGVyOwoKCVRSQUNFKCIoJWxkKVxuIiwgd3JpdGVwb3MpOwoKCS8qIHRoZSBzb3VuZCBvZiBzaWxlbmNlICovCgluZmlsbGVyID0gZHNvdW5kLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4ID8gMTI4IDogMDsKCgkvKiByZXNldCBhbGwgYnVmZmVyIG1peCBwb3NpdGlvbnMgKi8KCWZvciAoaSA9IDA7IGkgPCBkc291bmQtPm5yb2ZidWZmZXJzOyBpKyspIHsKCQlkc2IgPSBkc291bmQtPmJ1ZmZlcnNbaV07CgoJCWlmIChkc2ItPmJ1ZmxlbiAmJiBkc2ItPnN0YXRlICYmICFkc2ItPmh3YnVmKSB7CgkJCVRSQUNFKCJSZXNldHRpbmcgJXBcbiIsIGRzYik7CgkJCUVudGVyQ3JpdGljYWxTZWN0aW9uKCYoZHNiLT5sb2NrKSk7CgkJCWlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSB7CgkJCQlkc2ItPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQkJfQoJCQllbHNlIGlmIChkc2ItPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSB7CgkJCQkvKiBub3RoaW5nICovCgkJCX0gZWxzZSB7CgkJCQlEU09VTkRfTWl4Q2FuY2VsKGRzYiwgd3JpdGVwb3MsIEZBTFNFKTsKCQkJCWRzYi0+Y3ZvbHBhbiA9IGRzYi0+dm9scGFuOwoJCQkJZHNiLT5uZWVkX3JlbWl4ID0gRkFMU0U7CgkJCX0KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc2ItPmxvY2spKTsKCQl9Cgl9CgoJLyogd2lwZSBvdXQgcHJlbWl4ZWQgZGF0YSAqLwoJaWYgKGRzb3VuZC0+bWl4cG9zIDwgd3JpdGVwb3MpIHsKCQltZW1zZXQoZHNvdW5kLT5idWZmZXIgKyB3cml0ZXBvcywgbmZpbGxlciwgZHNvdW5kLT5idWZsZW4gLSB3cml0ZXBvcyk7CgkJbWVtc2V0KGRzb3VuZC0+YnVmZmVyLCBuZmlsbGVyLCBkc291bmQtPm1peHBvcyk7Cgl9IGVsc2UgewoJCW1lbXNldChkc291bmQtPmJ1ZmZlciArIHdyaXRlcG9zLCBuZmlsbGVyLCBkc291bmQtPm1peHBvcyAtIHdyaXRlcG9zKTsKCX0KCgkvKiByZXNldCBwcmltYXJ5IG1peCBwb3NpdGlvbiAqLwoJZHNvdW5kLT5taXhwb3MgPSB3cml0ZXBvczsKfQoKc3RhdGljIHZvaWQgRFNPVU5EX0NoZWNrUmVzZXQoSURpcmVjdFNvdW5kSW1wbCAqZHNvdW5kLCBEV09SRCB3cml0ZXBvcykKewoJVFJBQ0UoIiglcCwlbGQpXG4iLGRzb3VuZCx3cml0ZXBvcyk7CglpZiAoZHNvdW5kLT5uZWVkX3JlbWl4KSB7CgkJRFNPVU5EX01peFJlc2V0KGRzb3VuZCwgd3JpdGVwb3MpOwoJCWRzb3VuZC0+bmVlZF9yZW1peCA9IEZBTFNFOwoJCS8qIG1heGltaXplIEhhbGYtTGlmZSBwZXJmb3JtYW5jZSAqLwoJCWRzb3VuZC0+cHJlYnVmID0gZHNfc25kX3F1ZXVlX21pbjsKCQlkc291bmQtPnByZWNvdW50ID0gMDsKCX0gZWxzZSB7CgkJZHNvdW5kLT5wcmVjb3VudCsrOwoJCWlmIChkc291bmQtPnByZWNvdW50ID49IDQpIHsKCQkJaWYgKGRzb3VuZC0+cHJlYnVmIDwgZHNfc25kX3F1ZXVlX21heCkKCQkJCWRzb3VuZC0+cHJlYnVmKys7CgkJCWRzb3VuZC0+cHJlY291bnQgPSAwOwoJCX0KCX0KCVRSQUNFKCJwcmVtaXggYWRqdXN0OiAlZFxuIiwgZHNvdW5kLT5wcmVidWYpOwp9Cgp2b2lkIERTT1VORF9XYXZlUXVldWUoSURpcmVjdFNvdW5kSW1wbCAqZHNvdW5kLCBEV09SRCBtaXhxKQp7CglUUkFDRSgiKCVwLCVsZClcbiIsZHNvdW5kLG1peHEpOwoJaWYgKG1peHEgKyBkc291bmQtPnB3cXVldWUgPiBkc19oZWxfcXVldWUpIG1peHEgPSBkc19oZWxfcXVldWUgLSBkc291bmQtPnB3cXVldWU7CglUUkFDRSgicXVldWVpbmcgJWxkIGJ1ZmZlcnMsIHN0YXJ0aW5nIGF0ICVkXG4iLCBtaXhxLCBkc291bmQtPnB3d3JpdGUpOwoJZm9yICg7IG1peHE7IG1peHEtLSkgewoJCXdhdmVPdXRXcml0ZShkc291bmQtPmh3bywgZHNvdW5kLT5wd2F2ZVtkc291bmQtPnB3d3JpdGVdLCBzaXplb2YoV0FWRUhEUikpOwoJCWRzb3VuZC0+cHd3cml0ZSsrOwoJCWlmIChkc291bmQtPnB3d3JpdGUgPj0gRFNfSEVMX0ZSQUdTKSBkc291bmQtPnB3d3JpdGUgPSAwOwoJCWRzb3VuZC0+cHdxdWV1ZSsrOwoJfQp9CgovKiAjZGVmaW5lIFNZTkNfQ0FMTEJBQ0sgKi8KCnZvaWQgRFNPVU5EX1BlcmZvcm1NaXgoSURpcmVjdFNvdW5kSW1wbCAqZHNvdW5kKQp7CglpbnQgbmZpbGxlcjsKCUJPT0wgZm9yY2VkOwoJSFJFU1VMVCBocmVzOwoKCVRSQUNFKCIoJXApXG4iLCBkc291bmQpOwoKCS8qIHRoZSBzb3VuZCBvZiBzaWxlbmNlICovCgluZmlsbGVyID0gZHNvdW5kLT5wd2Z4LT53Qml0c1BlclNhbXBsZSA9PSA4ID8gMTI4IDogMDsKCgkvKiB3aGV0aGVyIHRoZSBwcmltYXJ5IGlzIGZvcmNlZCB0byBwbGF5IGV2ZW4gd2l0aG91dCBzZWNvbmRhcnkgYnVmZmVycyAqLwoJZm9yY2VkID0gKChkc291bmQtPnN0YXRlID09IFNUQVRFX1BMQVlJTkcpIHx8IChkc291bmQtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSk7CgoJaWYgKGRzb3VuZC0+cHJpb2xldmVsICE9IERTU0NMX1dSSVRFUFJJTUFSWSkgewoJCUJPT0wgcGF1c2VkID0gKChkc291bmQtPnN0YXRlID09IFNUQVRFX1NUT1BQRUQpIHx8IChkc291bmQtPnN0YXRlID09IFNUQVRFX1NUQVJUSU5HKSk7CgkJLyogRklYTUU6IGRvY3VtZW50IHZhcmlhYmxlcyAqLwogCQlEV09SRCBwbGF5cG9zLCB3cml0ZXBvcywgaW5xLCBtYXhxLCBmcmFnOwogCQlpZiAoZHNvdW5kLT5od2J1ZikgewoJCQlocmVzID0gSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKGRzb3VuZC0+aHdidWYsICZwbGF5cG9zLCAmd3JpdGVwb3MpOwoJCQlpZiAoaHJlcykgewoJCQkgICAgV0FSTigiSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uIGZhaWxlZFxuIik7CgkJCSAgICByZXR1cm47CgkJCX0KCQkJLyogV2VsbCwgd2UgKmNvdWxkKiBkbyBKdXN0LUluLVRpbWUgbWl4aW5nIHVzaW5nIHRoZSB3cml0ZXBvcywKCQkJICogYnV0IHRoYXQncyBhIGxpdHRsZSBiaXQgYW1iaXRpb3VzIGFuZCB1bm5lY2Vzc2FyeS4uLiAqLwoJCQkvKiByYXRoZXIgYWRkIG91ciBzYWZldHkgbWFyZ2luIHRvIHRoZSB3cml0ZXBvcywgaWYgd2UncmUgcGxheWluZyAqLwoJCQlpZiAoIXBhdXNlZCkgewoJCQkJd3JpdGVwb3MgKz0gZHNvdW5kLT53cml0ZWxlYWQ7CgkJCQl3cml0ZXBvcyAlPSBkc291bmQtPmJ1ZmxlbjsKCQkJfSBlbHNlIHdyaXRlcG9zID0gcGxheXBvczsKCQl9IGVsc2UgewogCQkJcGxheXBvcyA9IGRzb3VuZC0+cHdwbGF5ICogZHNvdW5kLT5mcmFnbGVuOwogCQkJd3JpdGVwb3MgPSBwbGF5cG9zOwogCQkJaWYgKCFwYXVzZWQpIHsKCSAJCQl3cml0ZXBvcyArPSBkc19oZWxfbWFyZ2luICogZHNvdW5kLT5mcmFnbGVuOwogCQkJCXdyaXRlcG9zICU9IGRzb3VuZC0+YnVmbGVuOwoJIAkJfQoJCX0KCQlUUkFDRSgicHJpbWFyeSBwbGF5cG9zPSVsZCwgd3JpdGVwb3M9JWxkLCBjbHJwb3M9JWxkLCBtaXhwb3M9JWxkLCBidWZsZW49JWxkXG4iLAoJCSAgICAgIHBsYXlwb3Msd3JpdGVwb3MsZHNvdW5kLT5wbGF5cG9zLGRzb3VuZC0+bWl4cG9zLGRzb3VuZC0+YnVmbGVuKTsKCQlhc3NlcnQoZHNvdW5kLT5wbGF5cG9zIDwgZHNvdW5kLT5idWZsZW4pOwoJCS8qIHdpcGUgb3V0IGp1c3QtcGxheWVkIHNvdW5kIGRhdGEgKi8KCQlpZiAocGxheXBvcyA8IGRzb3VuZC0+cGxheXBvcykgewoJCQltZW1zZXQoZHNvdW5kLT5idWZmZXIgKyBkc291bmQtPnBsYXlwb3MsIG5maWxsZXIsIGRzb3VuZC0+YnVmbGVuIC0gZHNvdW5kLT5wbGF5cG9zKTsKCQkJbWVtc2V0KGRzb3VuZC0+YnVmZmVyLCBuZmlsbGVyLCBwbGF5cG9zKTsKCQl9IGVsc2UgewoJCQltZW1zZXQoZHNvdW5kLT5idWZmZXIgKyBkc291bmQtPnBsYXlwb3MsIG5maWxsZXIsIHBsYXlwb3MgLSBkc291bmQtPnBsYXlwb3MpOwoJCX0KCQlkc291bmQtPnBsYXlwb3MgPSBwbGF5cG9zOwoKCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bWl4bG9jaykpOwoKCQkvKiByZXNldCBtaXhpbmcgaWYgbmVjZXNzYXJ5ICovCgkJRFNPVU5EX0NoZWNrUmVzZXQoZHNvdW5kLCB3cml0ZXBvcyk7CgoJCS8qIGNoZWNrIGhvdyBtdWNoIHByZWJ1ZmZlcmluZyBpcyBsZWZ0ICovCgkJaW5xID0gZHNvdW5kLT5taXhwb3M7CgkJaWYgKGlucSA8IHdyaXRlcG9zKQoJCQlpbnEgKz0gZHNvdW5kLT5idWZsZW47CgkJaW5xIC09IHdyaXRlcG9zOwoKCQkvKiBmaW5kIHRoZSBtYXhpbXVtIHdlIGNhbiBwcmVidWZmZXIgKi8KCQlpZiAoIXBhdXNlZCkgewoJCQltYXhxID0gcGxheXBvczsKCQkJaWYgKG1heHEgPCB3cml0ZXBvcykKCQkJCW1heHEgKz0gZHNvdW5kLT5idWZsZW47CgkJCW1heHEgLT0gd3JpdGVwb3M7CgkJfSBlbHNlIG1heHEgPSBkc291bmQtPmJ1ZmxlbjsKCgkJLyogY2xpcCBtYXhxIHRvIGRzb3VuZC0+cHJlYnVmICovCgkJZnJhZyA9IGRzb3VuZC0+cHJlYnVmICogZHNvdW5kLT5mcmFnbGVuOwoJCWlmIChtYXhxID4gZnJhZykgbWF4cSA9IGZyYWc7CgoJCS8qIGNoZWNrIGZvciBjb25zaXN0ZW5jeSAqLwoJCWlmIChpbnEgPiBtYXhxKSB7CgkJCS8qIHRoZSBwbGF5YmFjayBwb3NpdGlvbiBtdXN0IGhhdmUgcGFzc2VkIG91ciBsYXN0CgkJCSAqIG1peGVkIHBvc2l0aW9uLCBpLmUuIGl0J3MgYW4gdW5kZXJydW4sIG9yIHdlIGhhdmUKCQkJICogbm90aGluZyBtb3JlIHRvIHBsYXkgKi8KCQkJVFJBQ0UoInJlYWNoZWQgZW5kIG9mIG1peGVkIGRhdGEgKGlucT0lbGQsIG1heHE9JWxkKVxuIiwgaW5xLCBtYXhxKTsKCQkJaW5xID0gMDsKCQkJLyogc3RvcCB0aGUgcGxheWJhY2sgbm93LCB0byBhbGxvdyBidWZmZXJzIHRvIHJlZmlsbCAqLwoJCQlpZiAoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9QTEFZSU5HKSB7CgkJCQlkc291bmQtPnN0YXRlID0gU1RBVEVfU1RBUlRJTkc7CgkJCX0KCQkJZWxzZSBpZiAoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9TVE9QUElORykgewoJCQkJZHNvdW5kLT5zdGF0ZSA9IFNUQVRFX1NUT1BQRUQ7CgkJCX0KCQkJZWxzZSB7CgkJCQkvKiBob3cgY2FuIHdlIGhhdmUgYW4gdW5kZXJydW4gaWYgd2UgYXJlbid0IHBsYXlpbmc/ICovCgkJCQlXQVJOKCJ1bmV4cGVjdGVkIHByaW1hcnkgc3RhdGUgKCVsZClcbiIsIGRzb3VuZC0+c3RhdGUpOwoJCQl9CiNpZmRlZiBTWU5DX0NBTExCQUNLCgkJCS8qIERTT1VORF9jYWxsYmFjayBtYXkgbmVlZCB0aGlzIGxvY2sgKi8KCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPm1peGxvY2spKTsKI2VuZGlmCgkJCWlmIChEU09VTkRfUHJpbWFyeVN0b3AoZHNvdW5kKSAhPSBEU19PSykKCQkJCVdBUk4oIkRTT1VORF9QcmltYXJ5U3RvcCBmYWlsZWRcbiIpOwojaWZkZWYgU1lOQ19DQUxMQkFDSwoJCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKGRzb3VuZC0+bWl4bG9jaykpOwojZW5kaWYKCQkJaWYgKGRzb3VuZC0+aHdidWYpIHsKCQkJCS8qIHRoZSBTdG9wIGlzIHN1cHBvc2VkIHRvIHJlc2V0IHBsYXkgcG9zaXRpb24gdG8gYmVnaW5uaW5nIG9mIGJ1ZmZlciAqLwoJCQkJLyogdW5mb3J0dW5hdGVseSwgT1NTIGlzIG5vdCBhYmxlIHRvIGRvIHNvLCBzbyBnZXQgY3VycmVudCBwb2ludGVyICovCgkJCQlocmVzID0gSURzRHJpdmVyQnVmZmVyX0dldFBvc2l0aW9uKGRzb3VuZC0+aHdidWYsICZwbGF5cG9zLCBOVUxMKTsKCQkJCWlmIChocmVzKSB7CgkJCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPm1peGxvY2spKTsKCQkJCQlXQVJOKCJJRHNEcml2ZXJCdWZmZXJfR2V0UG9zaXRpb24gZmFpbGVkXG4iKTsKCQkJCQlyZXR1cm47CgkJCQl9CgkJCX0gZWxzZSB7CgkgCQkJcGxheXBvcyA9IGRzb3VuZC0+cHdwbGF5ICogZHNvdW5kLT5mcmFnbGVuOwoJCQl9CgkJCXdyaXRlcG9zID0gcGxheXBvczsKCQkJZHNvdW5kLT5wbGF5cG9zID0gcGxheXBvczsKCQkJZHNvdW5kLT5taXhwb3MgPSB3cml0ZXBvczsKCQkJaW5xID0gMDsKCQkJbWF4cSA9IGRzb3VuZC0+YnVmbGVuOwoJCQlpZiAobWF4cSA+IGZyYWcpIG1heHEgPSBmcmFnOwoJCQltZW1zZXQoZHNvdW5kLT5idWZmZXIsIG5maWxsZXIsIGRzb3VuZC0+YnVmbGVuKTsKCQkJcGF1c2VkID0gVFJVRTsKCQl9CgoJCS8qIGRvIHRoZSBtaXhpbmcgKi8KCQlmcmFnID0gRFNPVU5EX01peFRvUHJpbWFyeShkc291bmQsIHBsYXlwb3MsIHdyaXRlcG9zLCBtYXhxLCBwYXVzZWQpOwoJCWlmIChmb3JjZWQpIGZyYWcgPSBtYXhxIC0gaW5xOwoJCWRzb3VuZC0+bWl4cG9zICs9IGZyYWc7CgkJZHNvdW5kLT5taXhwb3MgJT0gZHNvdW5kLT5idWZsZW47CgoJCWlmIChmcmFnKSB7CgkJCS8qIGJ1ZmZlcnMgaGF2ZSBiZWVuIGZpbGxlZCwgcmVzdGFydCBwbGF5YmFjayAqLwoJCQlpZiAoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9TVEFSVElORykgewoJCQkJZHNvdW5kLT5zdGF0ZSA9IFNUQVRFX1BMQVlJTkc7CgkJCX0KCQkJZWxzZSBpZiAoZHNvdW5kLT5zdGF0ZSA9PSBTVEFURV9TVE9QUEVEKSB7CgkJCQkvKiB0aGUgZHNvdW5kIGlzIHN1cHBvc2VkIHRvIHBsYXkgaWYgdGhlcmUncyBzb21ldGhpbmcgdG8gcGxheQoJCQkJICogZXZlbiBpZiBpdCBpcyByZXBvcnRlZCBhcyBzdG9wcGVkLCBzbyBkb24ndCBsZXQgdGhpcyBjb25mdXNlIHlvdSAqLwoJCQkJZHNvdW5kLT5zdGF0ZSA9IFNUQVRFX1NUT1BQSU5HOwoJCQl9CgkJCUxlYXZlQ3JpdGljYWxTZWN0aW9uKCYoZHNvdW5kLT5taXhsb2NrKSk7CgkJCWlmIChwYXVzZWQpIHsKCQkJCWlmIChEU09VTkRfUHJpbWFyeVBsYXkoZHNvdW5kKSAhPSBEU19PSykKCQkJCQlXQVJOKCJEU09VTkRfUHJpbWFyeVBsYXkgZmFpbGVkXG4iKTsKCQkJCWVsc2UKCQkJCQlUUkFDRSgic3RhcnRpbmcgcGxheWJhY2tcbiIpOwoJCQl9CgkJfQoJCWVsc2UKCQkJTGVhdmVDcml0aWNhbFNlY3Rpb24oJihkc291bmQtPm1peGxvY2spKTsKCX0gZWxzZSB7CgkJLyogaW4gdGhlIERTU0NMX1dSSVRFUFJJTUFSWSBtb2RlLCB0aGUgYXBwIGlzIHRvdGFsbHkgaW4gY2hhcmdlLi4uICovCgkJaWYgKGRzb3VuZC0+c3RhdGUgPT0gU1RBVEVfU1RBUlRJTkcpIHsKCQkJaWYgKERTT1VORF9QcmltYXJ5UGxheShkc291bmQpICE9IERTX09LKQoJCQkJV0FSTigiRFNPVU5EX1ByaW1hcnlQbGF5IGZhaWxlZFxuIik7CgkJCWVsc2UKCQkJCWRzb3VuZC0+c3RhdGUgPSBTVEFURV9QTEFZSU5HOwoJCX0KCQllbHNlIGlmIChkc291bmQtPnN0YXRlID09IFNUQVRFX1NUT1BQSU5HKSB7CgkJCWlmIChEU09VTkRfUHJpbWFyeVN0b3AoZHNvdW5kKSAhPSBEU19PSykKCQkJCVdBUk4oIkRTT1VORF9QcmltYXJ5U3RvcCBmYWlsZWRcbiIpOwoJCQllbHNlCgkJCQlkc291bmQtPnN0YXRlID0gU1RBVEVfU1RPUFBFRDsKCQl9Cgl9Cn0KCnZvaWQgQ0FMTEJBQ0sgRFNPVU5EX3RpbWVyKFVJTlQgdGltZXJJRCwgVUlOVCBtc2csIERXT1JEIGR3VXNlciwgRFdPUkQgZHcxLCBEV09SRCBkdzIpCnsKICAgICAgICBJRGlyZWN0U291bmRJbXBsKiBUaGlzID0gKElEaXJlY3RTb3VuZEltcGwqKWR3VXNlcjsKCURXT1JEIHN0YXJ0X3RpbWUgPSAgR2V0VGlja0NvdW50KCk7CiAgICAgICAgRFdPUkQgZW5kX3RpbWU7CglUUkFDRSgiKCVkLCVkLDB4JWx4LDB4JWx4LDB4JWx4KVxuIix0aW1lcklELG1zZyxkd1VzZXIsZHcxLGR3Mik7CiAgICAgICAgVFJBQ0UoImVudGVyaW5nIGF0ICVsZFxuIiwgc3RhcnRfdGltZSk7CgoJaWYgKGRzb3VuZCAhPSBUaGlzKSB7CgkJRVJSKCJkc291bmQgZGllZCB3aXRob3V0IGtpbGxpbmcgdXM/XG4iKTsKCQl0aW1lS2lsbEV2ZW50KHRpbWVySUQpOwoJCXRpbWVFbmRQZXJpb2QoRFNfVElNRV9SRVMpOwoJCXJldHVybjsKCX0KCglSdGxBY3F1aXJlUmVzb3VyY2VTaGFyZWQoJihUaGlzLT5idWZmZXJfbGlzdF9sb2NrKSwgVFJVRSk7CgoJaWYgKFRoaXMtPnJlZikKCQlEU09VTkRfUGVyZm9ybU1peChUaGlzKTsKCglSdGxSZWxlYXNlUmVzb3VyY2UoJihUaGlzLT5idWZmZXJfbGlzdF9sb2NrKSk7CgoJZW5kX3RpbWUgPSBHZXRUaWNrQ291bnQoKTsKCVRSQUNFKCJjb21wbGV0ZWQgcHJvY2Vzc2luZyBhdCAlbGQsIGR1cmF0aW9uID0gJWxkXG4iLCBlbmRfdGltZSwgZW5kX3RpbWUgLSBzdGFydF90aW1lKTsKfQoKdm9pZCBDQUxMQkFDSyBEU09VTkRfY2FsbGJhY2soSFdBVkVPVVQgaHdvLCBVSU5UIG1zZywgRFdPUkQgZHdVc2VyLCBEV09SRCBkdzEsIERXT1JEIGR3MikKewogICAgICAgIElEaXJlY3RTb3VuZEltcGwqIFRoaXMgPSAoSURpcmVjdFNvdW5kSW1wbCopZHdVc2VyOwoJVFJBQ0UoIiglcCwleCwlbHgsJWx4LCVseClcbiIsaHdvLG1zZyxkd1VzZXIsZHcxLGR3Mik7CglUUkFDRSgiZW50ZXJpbmcgYXQgJWxkLCBtc2c9JTA4eCglcylcbiIsIEdldFRpY2tDb3VudCgpLCBtc2csIAoJCW1zZz09TU1fV09NX0RPTkUgPyAiTU1fV09NX0RPTkUiIDogbXNnPT1NTV9XT01fQ0xPU0UgPyAiTU1fV09NX0NMT1NFIiA6IAoJCW1zZz09TU1fV09NX09QRU4gPyAiTU1fV09NX09QRU4iIDogIlVOS05PV04iKTsKCWlmIChtc2cgPT0gTU1fV09NX0RPTkUpIHsKCQlEV09SRCBpbnEsIG1peHEsIGZyYWdsZW4sIGJ1ZmxlbiwgcHdwbGF5LCBwbGF5cG9zLCBtaXhwb3M7CgkJaWYgKFRoaXMtPnB3cXVldWUgPT0gKERXT1JEKS0xKSB7CgkJCVRSQUNFKCJjb21wbGV0ZWQgZHVlIHRvIHJlc2V0XG4iKTsKCQkJcmV0dXJuOwoJCX0KLyogaXQgY291bGQgYmUgYSBiYWQgaWRlYSB0byBlbnRlciBjcml0aWNhbCBzZWN0aW9uIGhlcmUuLi4gaWYgdGhlcmUncyBsb2NrIGNvbnRlbnRpb24sCiAqIHRoZSByZXN1bHRpbmcgc2NoZWR1bGluZyBkZWxheXMgbWlnaHQgb2JzdHJ1Y3QgdGhlIHdpbm1tIHBsYXllciB0aHJlYWQgKi8KI2lmZGVmIFNZTkNfQ0FMTEJBQ0sKCQlFbnRlckNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPm1peGxvY2spKTsKI2VuZGlmCgkJLyogcmV0cmlldmUgY3VycmVudCB2YWx1ZXMgKi8KCQlmcmFnbGVuID0gVGhpcy0+ZnJhZ2xlbjsKCQlidWZsZW4gPSBUaGlzLT5idWZsZW47CgkJcHdwbGF5ID0gVGhpcy0+cHdwbGF5OwoJCXBsYXlwb3MgPSBwd3BsYXkgKiBmcmFnbGVuOwoJCW1peHBvcyA9IFRoaXMtPm1peHBvczsKCQkvKiBjaGVjayByZW1haW5pbmcgbWl4ZWQgZGF0YSAqLwoJCWlucSA9ICgobWl4cG9zIDwgcGxheXBvcykgPyBidWZsZW4gOiAwKSArIG1peHBvcyAtIHBsYXlwb3M7CgkJbWl4cSA9IGlucSAvIGZyYWdsZW47CgkJaWYgKChpbnEgLSAobWl4cSAqIGZyYWdsZW4pKSA+IDApIG1peHErKzsKCQkvKiBjb21wbGV0ZSB0aGUgcGxheWluZyBidWZmZXIgKi8KCQlUUkFDRSgiZG9uZSBwbGF5aW5nIHByaW1hcnkgcG9zPSVsZFxuIiwgcGxheXBvcyk7CgkJcHdwbGF5Kys7CgkJaWYgKHB3cGxheSA+PSBEU19IRUxfRlJBR1MpIHB3cGxheSA9IDA7CgkJLyogd3JpdGUgbmV3IHZhbHVlcyAqLwoJCVRoaXMtPnB3cGxheSA9IHB3cGxheTsKCQlUaGlzLT5wd3F1ZXVlLS07CgkJLyogcXVldWUgbmV3IGJ1ZmZlciBpZiB3ZSBoYXZlIGRhdGEgZm9yIGl0ICovCgkJaWYgKGlucT4xKSBEU09VTkRfV2F2ZVF1ZXVlKFRoaXMsIGlucS0xKTsKI2lmZGVmIFNZTkNfQ0FMTEJBQ0sKCQlMZWF2ZUNyaXRpY2FsU2VjdGlvbigmKFRoaXMtPm1peGxvY2spKTsKI2VuZGlmCgl9CglUUkFDRSgiY29tcGxldGVkXG4iKTsKfQo=