LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKI2luY2x1ZGUgIm1zYWNtLmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCiNkZWZpbmUgZm9ybXR5cGVXQVZFICAgIG1taW9GT1VSQ0MoJ1cnLCdBJywnVicsJ0UnKQojZGVmaW5lIGNraWRXQVZFRk9STUFUICBtbWlvRk9VUkNDKCdmJywnbScsJ3QnLCcgJykKI2RlZmluZSBja2lkV0FWRUZBQ1QgICAgbW1pb0ZPVVJDQygnZicsJ2EnLCdjJywndCcpCiNkZWZpbmUgY2tpZFdBVkVEQVRBICAgIG1taW9GT1VSQ0MoJ2QnLCdhJywndCcsJ2EnKQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBFTkRJQU5fU1dBUFdPUkQoeCkgICgoKCh4KSA+PiA4KSAmIDB4RkYpIHwgKCgoeCkgJiAweEZGKSA8PCA4KSkKI2RlZmluZSBFTkRJQU5fU1dBUERXT1JEKHgpIChFTkRJQU5fU1dBUFdPUkQoKHggPj4gMTYpICYgMHhGRkZGKSB8IFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBFTkRJQU5fU1dBUFdPUkQoeCAmIDB4RkZGRikgPDwgMTYpCgojaWZkZWYgV09SRFNfQklHRU5ESUFOCiNkZWZpbmUgQkUySF9XT1JEKHgpICAoeCkKI2RlZmluZSBCRTJIX0RXT1JEKHgpICh4KQojZGVmaW5lIExFMkhfV09SRCh4KSAgRU5ESUFOX1NXQVBXT1JEKHgpCiNkZWZpbmUgTEUySF9EV09SRCh4KSBFTkRJQU5fU1dBUERXT1JEKHgpCiNlbHNlCiNkZWZpbmUgQkUySF9XT1JEKHgpICBFTkRJQU5fU1dBUFdPUkQoeCkKI2RlZmluZSBCRTJIX0RXT1JEKHgpIEVORElBTl9TV0FQRFdPUkQoeCkKI2RlZmluZSBMRTJIX1dPUkQoeCkgICh4KQojZGVmaW5lIExFMkhfRFdPUkQoeCkgKHgpCiNlbmRpZgoKdHlwZWRlZiBzdHJ1Y3QgewogIEZPVVJDQyAgZmNjVHlwZTsKICBEV09SRCAgIG9mZnNldDsKICBEV09SRCAgIHNpemU7CiAgSU5UICAgICBlbmNvZGluZzsKICBEV09SRCAgIHNhbXBsZVJhdGU7CiAgRFdPUkQgICBjaGFubmVsczsKfSBTVU5BVURJT0hFQURFUjsKCiNkZWZpbmUgQVVfRU5DT0RJTkdfVUxBV184ICAgICAgICAgICAgICAgICAxCiNkZWZpbmUgQVVfRU5DT0RJTkdfUENNXzggICAgICAgICAgICAgICAgICAyCiNkZWZpbmUgQVVfRU5DT0RJTkdfUENNXzE2ICAgICAgICAgICAgICAgICAzCiNkZWZpbmUgQVVfRU5DT0RJTkdfUENNXzI0ICAgICAgICAgICAgICAgICA0CiNkZWZpbmUgQVVfRU5DT0RJTkdfUENNXzMyICAgICAgICAgICAgICAgICA1CiNkZWZpbmUgQVVfRU5DT0RJTkdfRkxPQVQgICAgICAgICAgICAgICAgICA2CiNkZWZpbmUgQVVfRU5DT0RJTkdfRE9VQkxFICAgICAgICAgICAgICAgICA3CiNkZWZpbmUgQVVfRU5DT0RJTkdfQURQQ01fRzcyMV8zMiAgICAgICAgIDIzCiNkZWZpbmUgQVVfRU5DT0RJTkdfQURQQ01fRzcyMiAgICAgICAgICAgIDI0CiNkZWZpbmUgQVVfRU5DT0RJTkdfQURQQ01fRzcyM18yNCAgICAgICAgIDI1CiNkZWZpbmUgQVVfRU5DT0RJTkdfQURQQ01fRzcyM181ICAgICAgICAgIDI2CiNkZWZpbmUgQVVfRU5DT0RJTkdfQUxBV184ICAgICAgICAgICAgICAgIDI3CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSogaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUZpbGVfZm5SZWxlYXNlKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUqaWZhY2UsQVZJRklMRUlORk9XKmFmaSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLEFWSVNUUkVBTUlORk9XKmFzaSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgKnNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklGaWxlVnRibCBpd2F2ZnQgPSB7CiAgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJQVZJRmlsZV9mbkFkZFJlZiwKICBJQVZJRmlsZV9mblJlbGVhc2UsCiAgSUFWSUZpbGVfZm5JbmZvLAogIElBVklGaWxlX2ZuR2V0U3RyZWFtLAogIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtLAogIElBVklGaWxlX2ZuV3JpdGVEYXRhLAogIElBVklGaWxlX2ZuUmVhZERhdGEsCiAgSUFWSUZpbGVfZm5FbmRSZWNvcmQsCiAgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUqaWZhY2UsQ0xTSUQqcENsYXNzSUQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLERXT1JEIGR3TW9kZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlKmlmYWNlLExQT0xFU1RSKnBwc3pGaWxlTmFtZSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElQZXJzaXN0RmlsZVZ0YmwgaXdhdnBmdCA9IHsKICBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJUGVyc2lzdEZpbGVfZm5BZGRSZWYsCiAgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZSwKICBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lELAogIElQZXJzaXN0RmlsZV9mbklzRGlydHksCiAgSVBlcnNpc3RGaWxlX2ZuTG9hZCwKICBJUGVyc2lzdEZpbGVfZm5TYXZlLAogIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSxMUEFSQU0gbFBhcmFtMSxMUEFSQU0gbFBhcmFtMik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyAqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsTE9ORyAqc2FtcHdyaXR0ZW4sTE9ORyAqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklTdHJlYW1WdGJsIGl3YXZzdCA9IHsKICBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSVN0cmVhbV9mbkFkZFJlZiwKICBJQVZJU3RyZWFtX2ZuUmVsZWFzZSwKICBJQVZJU3RyZWFtX2ZuQ3JlYXRlLAogIElBVklTdHJlYW1fZm5JbmZvLAogIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlLAogIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0LAogIElBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblJlYWQsCiAgSUFWSVN0cmVhbV9mbldyaXRlLAogIElBVklTdHJlYW1fZm5EZWxldGUsCiAgSUFWSVN0cmVhbV9mblJlYWREYXRhLAogIElBVklTdHJlYW1fZm5Xcml0ZURhdGEsCiAgSUFWSVN0cmVhbV9mblNldEluZm8KfTsKCnR5cGVkZWYgc3RydWN0IF9JQVZJRmlsZUltcGwgSUFWSUZpbGVJbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lQZXJzaXN0RmlsZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSVBlcnNpc3RGaWxlVnRibCAqbHBWdGJsOwoKICAvKiBJUGVyc2lzdEZpbGUgc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7Cn0gSVBlcnNpc3RGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JQVZJU3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJU3RyZWFtVnRibCAqbHBWdGJsOwoKICAvKiBJQVZJU3RyZWFtIHN0dWZmICovCiAgSUFWSUZpbGVJbXBsICAgICAqcGFmOwp9IElBVklTdHJlYW1JbXBsOwoKc3RydWN0IF9JQVZJRmlsZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSUZpbGVWdGJsICpscFZ0Ymw7CiAgTE9ORwkJICAgIHJlZjsKCiAgLyogSUFWSUZpbGUsIElBVklTdHJlYW0gc3R1ZmYuLi4gKi8KICBJUGVyc2lzdEZpbGVJbXBsICBpUGVyc2lzdEZpbGU7CiAgSUFWSVN0cmVhbUltcGwgICAgaUFWSVN0cmVhbTsKCiAgQVZJRklMRUlORk9XICAgICAgZkluZm87CiAgQVZJU1RSRUFNSU5GT1cgICAgc0luZm87CgogIExQV0FWRUZPUk1BVEVYICAgIGxwRm9ybWF0OwogIExPTkcgICAgICAgICAgICAgIGNiRm9ybWF0OwoKICBNTUNLSU5GTyAgICAgICAgICBja0RhdGE7CgogIEVYVFJBQ0hVTktTICAgICAgIGV4dHJhOwoKICAvKiBJUGVyc2lzdEZpbGUgc3R1ZmYgLi4uICovCiAgSE1NSU8gICAgICAgICAgICAgaG1taW87CiAgTFBXU1RSICAgICAgICAgICAgc3pGaWxlTmFtZTsKICBVSU5UICAgICAgICAgICAgICB1TW9kZTsKICBCT09MICAgICAgICAgICAgICBmRGlydHk7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZFN1bkZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwoKSFJFU1VMVCBBVklGSUxFX0NyZWF0ZVdBVkZpbGUoUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgSUFWSUZpbGVJbXBsICpwZmlsZTsKICBIUkVTVUxUICAgICAgIGhyOwoKICBhc3NlcnQocmlpZCAhPSBOVUxMICYmIHBwdiAhPSBOVUxMKTsKCiAgKnBwdiA9IE5VTEw7CgogIHBmaWxlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQVZJRmlsZUltcGwpKTsKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBwZmlsZS0+bHBWdGJsICAgICAgICAgICAgICAgID0gJml3YXZmdDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLmxwVnRibCAgID0gJml3YXZwZnQ7CiAgcGZpbGUtPmlBVklTdHJlYW0ubHBWdGJsICAgICA9ICZpd2F2c3Q7CiAgcGZpbGUtPnJlZiA9IDA7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5wYWYgPSBwZmlsZTsKICBwZmlsZS0+aUFWSVN0cmVhbS5wYWYgICA9IHBmaWxlOwoKICBociA9IElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChJQVZJRmlsZSopcGZpbGUsIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwZmlsZSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUgKmlmYWNlLCBSRUZJSUQgcmVmaWlkLAoJCQkJCQlMUFZPSUQgKm9iaikKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgPT0gMSAmJgoJICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUFWSVN0cmVhbTsKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQoJklJRF9JUGVyc2lzdEZpbGUsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aVBlcnNpc3RGaWxlOwogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIHJldHVybiBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIGlmICghcmVmKSB7CiAgICBpZiAoVGhpcy0+ZkRpcnR5KSB7CiAgICAgIC8qIG5lZWQgdG8gd3JpdGUgaGVhZGVycyB0byBmaWxlICovCiAgICAgIEFWSUZJTEVfU2F2ZUZpbGUoVGhpcyk7CiAgICB9CgogICAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBGb3JtYXQpOwogICAgICBUaGlzLT5scEZvcm1hdCA9IE5VTEw7CiAgICAgIFRoaXMtPmNiRm9ybWF0ID0gMDsKICAgIH0KICAgIGlmIChUaGlzLT5leHRyYS5scCAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmV4dHJhLmxwKTsKICAgICAgVGhpcy0+ZXh0cmEubHAgPSBOVUxMOwogICAgICBUaGlzLT5leHRyYS5jYiA9IDA7CiAgICB9CiAgICBpZiAoVGhpcy0+c3pGaWxlTmFtZSAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnN6RmlsZU5hbWUpOwogICAgICBUaGlzLT5zekZpbGVOYW1lID0gTlVMTDsKICAgIH0KICAgIGlmIChUaGlzLT5obW1pbyAhPSBOVUxMKSB7CiAgICAgIG1taW9DbG9zZShUaGlzLT5obW1pbywgMCk7CiAgICAgIFRoaXMtPmhtbWlvID0gTlVMTDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5JbmZvKElBVklGaWxlICppZmFjZSwgTFBBVklGSUxFSU5GT1cgYWZpLAoJCQkJICAgICAgTE9ORyBzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsaWZhY2UsYWZpLHNpemUpOwoKICBpZiAoYWZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogdXBkYXRlIGZpbGUgaW5mbyAqLwogIFRoaXMtPmZJbmZvLmR3RmxhZ3MgPSAwOwogIFRoaXMtPmZJbmZvLmR3Q2FwcyAgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMKSB7CiAgICBhc3NlcnQoVGhpcy0+c0luZm8uZHdTY2FsZSAhPSAwKTsKCiAgICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgICAgICAgICAgICAgPSAxOwogICAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gVGhpcy0+c0luZm8uZHdTY2FsZTsKICAgIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IFRoaXMtPnNJbmZvLmR3UmF0ZTsKICAgIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogICAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKICAgIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgPQogICAgICBNdWxEaXYoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplLFRoaXMtPnNJbmZvLmR3UmF0ZSxUaGlzLT5zSW5mby5kd1NjYWxlKTsKICB9CgogIG1lbWNweShhZmksICZUaGlzLT5mSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+ZkluZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5mSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGF2aXMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICphdmlzID0gTlVMTDsKCiAgLyogRG9lcyBvdXIgc3RyZWFtIGV4aXN0cz8gKi8KICBpZiAobFBhcmFtICE9IDAgfHwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID09IDApCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsKICBpZiAoZmNjVHlwZSAhPSAwICYmIGZjY1R5cGUgIT0gc3RyZWFtdHlwZUFVRElPKQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CgogICphdmlzID0gKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW07CiAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlICppZmFjZSxQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgaWZhY2UsIGF2aXMsIGFzaSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXZpcyA9PSBOVUxMIHx8IGFzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKmF2aXMgPSBOVUxMOwoKICAvKiBXZSBvbmx5IHN1cHBvcnQgb25lIGF1ZGlvIHN0cmVhbSAqLwogIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgIT0gMCB8fCBUaGlzLT5scEZvcm1hdCAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICBpZiAoYXNpLT5mY2NUeXBlICE9IHN0cmVhbXR5cGVBVURJTykKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIC8qIERvZXMgdGhlIHVzZXIgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmNiRm9ybWF0ID0gMDsKICBUaGlzLT5scEZvcm1hdCA9IE5VTEw7CgogIG1lbWNweSgmVGhpcy0+c0luZm8sIGFzaSwgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CgogIC8qIG1ha2Ugc3VyZSBzdHJlYW1pbmZvIGlmIG9rYXkgZm9yIHVzICovCiAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdGbGFncyAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdDYXBzICAgICAgICAgICAgICA9IEFWSUZJTEVDQVBTX0NBTlJFQUR8QVZJRklMRUNBUFNfQ0FOV1JJVEU7CiAgVGhpcy0+c0luZm8uZHdTdGFydCAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdJbml0aWFsRnJhbWVzICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCA9IDA7CiAgbWVtc2V0KCZUaGlzLT5zSW5mby5yY0ZyYW1lLCAwLCBzaXplb2YoVGhpcy0+c0luZm8ucmNGcmFtZSkpOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAxOwogIFRoaXMtPmZJbmZvLmR3U2NhbGUgICA9IFRoaXMtPnNJbmZvLmR3U2NhbGU7CiAgVGhpcy0+ZkluZm8uZHdSYXRlICAgID0gVGhpcy0+c0luZm8uZHdSYXRlOwogIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwoKICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ID0gMDsKICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgID0gMDsKCiAgKmF2aXMgPSAoUEFWSVNUUkVBTSkmVGhpcy0+aUFWSVN0cmVhbTsKICBJQVZJRmlsZV9BZGRSZWYoaWZhY2UpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5Xcml0ZURhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgIExQVk9JRCBscERhdGEsIExPTkcgc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVsZClcbiIsIGlmYWNlLCBja2lkLCBscERhdGEsIHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwRGF0YSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICByZXR1cm4gV3JpdGVFeHRyYUNodW5rKCZUaGlzLT5leHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgTFBWT0lEIGxwRGF0YSwgTE9ORyAqc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSAqaWZhY2UpCnsKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIC8qIFRoaXMgaXMgb25seSBuZWVkZWQgZm9yIGludGVybGVhdmVkIGZpbGVzLgogICAqIFdlIGhhdmUgb25seSBvbmUgc3RyZWFtLCB3aGljaCBjYW4ndCBiZSBpbnRlcmxlYXZlZC4KICAgKi8KICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBmY2NUeXBlLAoJCQkJCSAgICAgIExPTkcgbFBhcmFtKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJWxkKVxuIiwgaWZhY2UsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChsUGFyYW0gPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRG8gd2UgaGF2ZSBvdXIgYXVkaW8gc3RyZWFtPyAqLwogIGlmIChsUGFyYW0gIT0gMCB8fCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPT0gMCB8fAogICAgICAoZmNjVHlwZSAhPSAwICYmIGZjY1R5cGUgIT0gc3RyZWFtdHlwZUFVRElPKSkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwoKICAvKiBIYXZlIHVzZXIgd3JpdGUgcGVybWlzc2lvbnM/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBGb3JtYXQpOwogIFRoaXMtPmxwRm9ybWF0ID0gTlVMTDsKICBUaGlzLT5jYkZvcm1hdCA9IDA7CgogIC8qIHVwZGF0ZSBpbmZvcyAqLwogIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSAwOwogIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSAwOwoKICBUaGlzLT5zSW5mby5kd1NjYWxlICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggID0gMDsKICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSAwOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAwOwogIFRoaXMtPmZJbmZvLmR3RWRpdENvdW50Kys7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChQQVZJRklMRSlUaGlzLT5wYWYsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQQ0xTSUQgcENsYXNzSUQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBDbGFzc0lEKTsKCiAgaWYgKHBDbGFzc0lEID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBtZW1jcHkocENsYXNzSUQsICZDTFNJRF9XQVZGaWxlLCBzaXplb2YoQ0xTSURfV0FWRmlsZSkpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLCBpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiAoVGhpcy0+cGFmLT5mRGlydHkgPyBTX09LIDogU19GQUxTRSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsIERXT1JEIGR3TW9kZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSVBlcnNpc3RGaWxlSW1wbCopaWZhY2UpLT5wYWY7CgogIFdDSEFSIHdzelN0cmVhbUZtdFs1MF07CiAgSU5UICAgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4bFgpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGR3TW9kZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgaWYgKFRoaXMtPmhtbWlvICE9IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBObyByZXVzZSBvZiB0aGlzIG9iamVjdCBmb3IgYW5vdGhlciBmaWxlISAqLwoKICAvKiByZW1lYmVyIG1vZGUgYW5kIG5hbWUgKi8KICBUaGlzLT51TW9kZSA9IGR3TW9kZTsKCiAgbGVuID0gbHN0cmxlblcocHN6RmlsZU5hbWUpICsgMTsKICBUaGlzLT5zekZpbGVOYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbiAqIHNpemVvZihXQ0hBUikpOwogIGlmIChUaGlzLT5zekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICBsc3RyY3B5VyhUaGlzLT5zekZpbGVOYW1lLCBwc3pGaWxlTmFtZSk7CgogIC8qIHRyeSB0byBvcGVuIHRoZSBmaWxlICovCiAgVGhpcy0+aG1taW8gPSBtbWlvT3BlblcoVGhpcy0+c3pGaWxlTmFtZSwgTlVMTCwgTU1JT19BTExPQ0JVRiB8IGR3TW9kZSk7CiAgaWYgKFRoaXMtPmhtbWlvID09IE5VTEwpIHsKICAgIC8qIG1taW9PcGVuVyBub3QgaW4gbmF0aXZlIERMTHMgb2YgV2luOXggLS0gdHJ5IG1taW9PcGVuQSAqLwogICAgTFBTVFIgc3pGaWxlTmFtZTsKICAgIGxlbiA9IFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBUaGlzLT5zekZpbGVOYW1lLCAtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgMCwgTlVMTCwgTlVMTCk7CiAgICBzekZpbGVOYW1lID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGxlbiAqIHNpemVvZihDSEFSKSk7CiAgICBpZiAoc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgVGhpcy0+c3pGaWxlTmFtZSwgLTEsIHN6RmlsZU5hbWUsCgkJCWxlbiwgTlVMTCwgTlVMTCk7CgogICAgVGhpcy0+aG1taW8gPSBtbWlvT3BlbkEoc3pGaWxlTmFtZSwgTlVMTCwgTU1JT19BTExPQ0JVRiB8IGR3TW9kZSk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzekZpbGVOYW1lKTsKICAgIGlmIChUaGlzLT5obW1pbyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVPUEVOOwogIH0KCiAgbWVtc2V0KCYgVGhpcy0+ZkluZm8sIDAsIHNpemVvZihUaGlzLT5mSW5mbykpOwogIG1lbXNldCgmIFRoaXMtPnNJbmZvLCAwLCBzaXplb2YoVGhpcy0+c0luZm8pKTsKCiAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfV0FWRUZJTEVUWVBFLCBUaGlzLT5mSW5mby5zekZpbGVUeXBlLAoJICAgICAgc2l6ZW9mKFRoaXMtPmZJbmZvLnN6RmlsZVR5cGUpKTsKICBpZiAoTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfV0FWRVNUUkVBTUZPUk1BVCwKCQkgIHdzelN0cmVhbUZtdCwgc2l6ZW9mKHdzelN0cmVhbUZtdCkpID4gMCkgewogICAgd3NwcmludGZXKFRoaXMtPnNJbmZvLnN6TmFtZSwgd3N6U3RyZWFtRm10LAoJICAgICAgQVZJRklMRV9CYXNlbmFtZVcoVGhpcy0+c3pGaWxlTmFtZSkpOwogIH0KCiAgLyogc2hvdWxkIHdlIGNyZWF0ZSBhIG5ldyBmaWxlPyAqLwogIGlmIChkd01vZGUgJiBPRl9DUkVBVEUpIHsKICAgIC8qIG5vdGhpbmcgbW9yZSB0byBkbyAqLwogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBBVklGSUxFX0xvYWRGaWxlKFRoaXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCSAgTFBDT0xFU1RSIHBzekZpbGVOYW1lLEJPT0wgZlJlbWVtYmVyKQp7CiAgVFJBQ0UoIiglcCwlcywlZClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSwgZlJlbWVtYmVyKTsKCiAgLyogV2Ugd3JpdGUgZGlyZWN0bHkgdG8gZGlzaywgc28gbm90aGluZyB0byBkby4gKi8KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJICAgTFBDT0xFU1RSIHBzekZpbGVOYW1lKQp7CiAgVFJBQ0UoIiglcCwlcylcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSk7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQT0xFU1RSICpwcHN6RmlsZU5hbWUpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGlmYWNlLCBwcHN6RmlsZU5hbWUpOwoKICBpZiAocHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBzekZpbGVOYW1lID0gTlVMTDsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgaWYgKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSAhPSBOVUxMKSB7CiAgICBpbnQgbGVuID0gbHN0cmxlblcoVGhpcy0+cGFmLT5zekZpbGVOYW1lKSArIDE7CgogICAgKnBwc3pGaWxlTmFtZSA9IENvVGFza01lbUFsbG9jKGxlbiAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKCpwcHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgc3RyY3B5VygqcHBzekZpbGVOYW1lLCBUaGlzLT5wYWYtPnN6RmlsZU5hbWUpOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkJICBSRUZJSUQgcmVmaWlkLCBMUFZPSUQgKm9iaikKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgoUEFWSUZJTEUpVGhpcy0+cGFmLCByZWZpaWQsIG9iaik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtICppZmFjZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUmVsZWFzZSgoUEFWSUZJTEUpVGhpcy0+cGFmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExQQVJBTSBsUGFyYW0xLAoJCQkJCSAgTFBBUkFNIGxQYXJhbTIpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIGlmYWNlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgLyogVGhpcyBJQVZJU3RyZWFtIGludGVyZmFjZSBuZWVkcyBhbiBXQVZGaWxlICovCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0gKmlmYWNlLExQQVZJU1RSRUFNSU5GT1cgcHNpLAoJCQkJCUxPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+cGFmLT5zSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+cGFmLT5zSW5mbykpKTsKCiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKFRoaXMtPnBhZi0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgIExPTkcgZmxhZ3MpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoKElBVklTdHJlYW1JbXBsKilpZmFjZSktPnBhZjsKCiAgVFJBQ0UoIiglcCwlbGQsMHglMDhsWClcbiIsaWZhY2UscG9zLGZsYWdzKTsKCiAgLyogRG8gd2UgaGF2ZSBkYXRhPyAqLwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICAvKiBXZSBkb24ndCBoYXZlIGFuIGluZGV4ICovCiAgaWYgKGZsYWdzICYgRklORF9JTkRFWCkKICAgIHJldHVybiAtMTsKCiAgaWYgKGZsYWdzICYgRklORF9GUk9NX1NUQVJUKSB7CiAgICBwb3MgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgZmxhZ3MgJj0gfihGSU5EX0ZST01fU1RBUlR8RklORF9QUkVWKTsKICAgIGZsYWdzIHw9IEZJTkRfTkVYVDsKICB9CgogIGlmIChmbGFncyAmIEZJTkRfRk9STUFUKSB7CiAgICBpZiAoKGZsYWdzICYgRklORF9ORVhUKSAmJiBwb3MgPiAwKQogICAgICBwb3MgPSAtMTsKICAgIGVsc2UKICAgICAgcG9zID0gMDsKICB9CgogIGlmICgoZmxhZ3MgJiBGSU5EX1JFVCkgPT0gRklORF9MRU5HVEggfHwKICAgICAgKGZsYWdzICYgRklORF9SRVQpID09IEZJTkRfU0laRSkKICAgIHJldHVybiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgaWYgKChmbGFncyAmIEZJTkRfUkVUKSA9PSBGSU5EX09GRlNFVCkKICAgIHJldHVybiBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ICsgcG9zICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwoKICByZXR1cm4gcG9zOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgKmZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlcClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChmb3JtYXRzaXplID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBvbmx5IGludGVyZXN0ZWQgaW4gbmVlZGVkIGJ1ZmZlcnNpemU/ICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8ICpmb3JtYXRzaXplIDw9IDApIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+cGFmLT5jYkZvcm1hdDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogY29weSBpbml0aWFsIGZvcm1hdCAob25seSBhcyBtdWNoIGFzIHdpbGwgZml0KSAqLwogIG1lbWNweShmb3JtYXQsIFRoaXMtPnBhZi0+bHBGb3JtYXQsIG1pbigqZm9ybWF0c2l6ZSwgVGhpcy0+cGFmLT5jYkZvcm1hdCkpOwogIGlmICgqZm9ybWF0c2l6ZSA8IFRoaXMtPnBhZi0+Y2JGb3JtYXQpIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+cGFmLT5jYkZvcm1hdDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPnBhZi0+Y2JGb3JtYXQ7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVsZClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgZm9ybWF0c2l6ZSA8PSBzaXplb2YoUENNV0FWRUZPUk1BVCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBXZSBjYW4gb25seSBkbyB0aGlzIHRvIGFuIGVtcHR5IHdhdmUgZmlsZSwgYnV0IGlnbm9yZSBjYWxsCiAgICogaWYgc3RpbGwgc2FtZSBmb3JtYXQgKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkgewogICAgaWYgKGZvcm1hdHNpemUgIT0gVGhpcy0+Y2JGb3JtYXQgfHwKCW1lbWNtcChmb3JtYXQsIFRoaXMtPmxwRm9ybWF0LCBmb3JtYXRzaXplKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBvbmx5IHN1cHBvcnQgc3RhcnQgYXQgcG9zaXRpb24gMCAqLwogIGlmIChwb3MgIT0gMCkKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBnZXQgbWVtb3J5IGZvciBmb3JtYXQgYW5kIGNvcHkgaXQgKi8KICBUaGlzLT5scEZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBmb3JtYXRzaXplKTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBUaGlzLT5jYkZvcm1hdCA9IGZvcm1hdHNpemU7CiAgbWVtY3B5KFRoaXMtPmxwRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiB1cGRhdGUgaW5mbydzIGFib3V0ICdkYXRhJyBjaHVuayAqLwogIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSBmb3JtYXRzaXplICsgNyAqIHNpemVvZihEV09SRCk7CiAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IDA7CgogIC8qIGZvciBub24tcGNtIGZvcm1hdCB3ZSBuZWVkIGFsc28gYSAnZmFjdCcgY2h1bmsgKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgIT0gV0FWRV9GT1JNQVRfUENNKQogICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArPSAzICogc2l6ZW9mKERXT1JEKTsKCiAgLyogdXBkYXRlIHN0cmVhbSBhbmQgZmlsZSBpbmZvICovCiAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3U2NhbGUgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1JhdGUgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjOwogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gMDsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCUxPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQlMT05HIGJ1ZmZlcnNpemUsIExQTE9ORyBieXRlc3JlYWQsCgkJCQkJTFBMT05HIHNhbXBsZXNyZWFkKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwKCWJ1ZmZlcnNpemUsIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKCiAgLyogcG9zaXRpb25zIHdpdGhvdXQgZGF0YSAqLwogIGlmIChzdGFydCA8IDAgfHwgKERXT1JEKXN0YXJ0ID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBjaGVjayBzYW1wbGVzICovCiAgaWYgKHNhbXBsZXMgPCAwKQogICAgc2FtcGxlcyA9IDA7CiAgaWYgKGJ1ZmZlcnNpemUgPiAwKSB7CiAgICBpZiAoc2FtcGxlcyA+IDApCiAgICAgIHNhbXBsZXMgPSBtaW4oKERXT1JEKXNhbXBsZXMsIGJ1ZmZlcnNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUpOwogICAgZWxzZQogICAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICB9CgogIC8qIGxpbWl0IHRvIGVuZCBvZiBzdHJlYW0gKi8KICBpZiAoKERXT1JEKShzdGFydCArIHNhbXBsZXMpID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGggLSBzdGFydDsKCiAgLyogcmVxdWVzdCBvbmx5IHRoZSBzaXplcz8gKi8KICBpZiAoYnVmZmVyID09IE5VTEwgfHwgYnVmZmVyc2l6ZSA8PSAwKSB7CiAgICAvKiB0aGVuIEkgbmVlZCBhdCBsZWFzdCBvbmUgcGFyYW1ldGVyIGZvciBpdCAqLwogICAgaWYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSBzYW1wbGVzOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBub3RoaW5nIHRvIHJlYWQ/ICovCiAgaWYgKHNhbXBsZXMgPT0gMCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIENhbiBJIHJlYWQgYXQgbGVhc3Qgb25lIHNhbXBsZT8gKi8KICBpZiAoKERXT1JEKWJ1ZmZlcnNpemUgPCBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwoKICBidWZmZXJzaXplID0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0CgkgICAgICAgKyBzdGFydCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSwgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilidWZmZXIsIGJ1ZmZlcnNpemUpICE9IGJ1ZmZlcnNpemUpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSBidWZmZXJzaXplOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsgIAoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSBMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCQkJIExQTE9ORyBzYW1wd3JpdHRlbiwKCQkJCQkgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsCglidWZmZXIsIGJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnVmZmVyID09IE5VTEwgJiYgKGJ1ZmZlcnNpemUgPiAwIHx8IHNhbXBsZXMgPiAwKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiA8IDAgbWVhbnMgImFwcGVuZCIgKi8KICBpZiAoc3RhcnQgPCAwKQogICAgc3RhcnQgPSBUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGg7CgogIC8qIGNoZWNrIGJ1ZmZlcnNpemUgLS0gbXVzdCBtdWx0aXBsZSBvZiBzYW1wbGVzaXplICovCiAgaWYgKGJ1ZmZlcnNpemUgJiB+KFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAtIDEpKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBkbyB3ZSBoYXZlIGFueXRoaW5nIHRvIHdyaXRlPyAqLwogIGlmIChidWZmZXIgIT0gTlVMTCAmJiBidWZmZXJzaXplID4gMCkgewogICAgVGhpcy0+ZkRpcnR5ID0gMTsKCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKwoJCSBzdGFydCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilidWZmZXIsIGJ1ZmZlcnNpemUpICE9IGJ1ZmZlcnNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gbWF4KFRoaXMtPnNJbmZvLmR3TGVuZ3RoLCAoRFdPUkQpc3RhcnQgKyBzYW1wbGVzKTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgID0gbWF4KFRoaXMtPmNrRGF0YS5ja3NpemUsCgkJCSAgICAgICBzdGFydCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSArIGJ1ZmZlcnNpemUpOwoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICAgKnNhbXB3cml0dGVuID0gc2FtcGxlczsKICAgIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICAgKmJ5dGVzd3JpdHRlbiA9IGJ1ZmZlcnNpemU7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgIExPTkcgc2FtcGxlcykKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN0YXJ0IDwgMCB8fCBzYW1wbGVzIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERlbGV0ZSBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtPyAqLwogIGlmICgoRFdPUkQpKHN0YXJ0ICsgc2FtcGxlcykgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRGVsZXRlIGFmdGVyIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKChEV09SRClzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRm9yIHRoZSByZXN0IHdlIG5lZWQgd3JpdGUgcGVybWlzc2lvbnMgKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBpZiAoKERXT1JEKShzdGFydCArIHNhbXBsZXMpID49IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKSB7CiAgICAvKiBkZWxldGlvbiBhdCBlbmQgKi8KICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aCAtIHN0YXJ0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gc2FtcGxlczsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgIC09IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgfSBlbHNlIGlmICgoRFdPUkQpc3RhcnQgPD0gVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgLyogZGVsZXRpb24gYXQgc3RhcnQgKi8KICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd1N0YXJ0IC0gc3RhcnQ7CiAgICBzdGFydCAgID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKz0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgLT0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICB9IGVsc2UgewogICAgLyogZGVsZXRpb24gaW5zaWRlIHN0cmVhbSAtLSBuZWVkcyBwbGF5bGlzdCBhbmQgY3VlJ3MgKi8KICAgIEZJWE1FKCI6IGRlbGV0aW9uIGluc2lkZSBvZiBzdHJlYW0gbm90IHN1cHBvcnRlZCFcbiIpOwoKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfQoKICBUaGlzLT5mRGlydHkgPSAxOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgIExQVk9JRCBscCwgTFBMT05HIGxwcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9SZWFkRGF0YSgoUEFWSUZJTEUpVGhpcy0+cGFmLCBmY2MsIGxwLCBscHJlYWQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICByZXR1cm4gSUFWSUZpbGVfV3JpdGVEYXRhKChQQVZJRklMRSlUaGlzLT5wYWYsIGZjYywgbHAsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJICAgTFBBVklTVFJFQU1JTkZPVyBpbmZvLCBMT05HIGluZm9sZW4pCnsKICBGSVhNRSgiKCVwLCVwLCVsZCk6IHN0dWJcbiIsIGlmYWNlLCBpbmZvLCBpbmZvbGVuKTsKCiAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNTUNLSU5GTyBja1JJRkY7CiAgTU1DS0lORk8gY2s7CgogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gMDsgLyoganVzdCB0byBiZSBzdXJlICovCiAgVGhpcy0+ZkRpcnR5ID0gRkFMU0U7CgogIC8qIHNlYXJjaCBmb3IgUklGRiBjaHVuayAqLwogIGNrUklGRi5mY2NUeXBlID0gMDsgLyogZmluZCBhbnkgKi8KICBpZiAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZja1JJRkYsIE5VTEwsIE1NSU9fRklORFJJRkYpICE9IFNfT0spIHsKICAgIHJldHVybiBBVklGSUxFX0xvYWRTdW5GaWxlKFRoaXMpOwogIH0KCiAgaWYgKGNrUklGRi5mY2NUeXBlICE9IGZvcm10eXBlV0FWRSkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBzZWFyY2ggV0FWRSBmb3JtYXQgY2h1bmsgKi8KICBjay5ja2lkID0gY2tpZFdBVkVGT1JNQVQ7CiAgaWYgKEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmV4dHJhLCBUaGlzLT5obW1pbywgJmNrLAoJCQkgICAgICZja1JJRkYsIE1NSU9fRklORENIVU5LKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogZ2V0IG1lbW9yeSBmb3IgZm9ybWF0IGFuZCByZWFkIGl0ICovCiAgVGhpcy0+bHBGb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgVGhpcy0+Y2JGb3JtYXQgPSBjay5ja3NpemU7CgogIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKVRoaXMtPmxwRm9ybWF0LCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIE5vbi1wY20gZm9ybWF0cyBoYXZlIGEgZmFjdCBjaHVuay4KICAgKiBXZSBkb24ndCBuZWVkIGl0LCBzbyBzaW1wbHkgYWRkIGl0IHRvIHRoZSBleHRyYSBjaHVua3MuCiAgICovCgogIC8qIGZpbmQgdGhlIGJpZyBkYXRhIGNodW5rICovCiAgVGhpcy0+Y2tEYXRhLmNraWQgPSBja2lkV0FWRURBVEE7CiAgaWYgKEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmV4dHJhLCBUaGlzLT5obW1pbywgJlRoaXMtPmNrRGF0YSwKCQkJICAgICAmY2tSSUZGLCBNTUlPX0ZJTkRDSFVOSykgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIG1lbXNldCgmVGhpcy0+c0luZm8sIDAsIHNpemVvZihUaGlzLT5zSW5mbykpOwogIFRoaXMtPnNJbmZvLmZjY1R5cGUgICAgICA9IHN0cmVhbXR5cGVBVURJTzsKICBUaGlzLT5zSW5mby5kd1JhdGUgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjOwogIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSA9CiAgICBUaGlzLT5zSW5mby5kd1NjYWxlICAgID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoICAgICA9IFRoaXMtPmNrRGF0YS5ja3NpemUgLyBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKCiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID0gMTsKCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZUaGlzLT5ja0RhdGEsIDApICE9IFNfT0spIHsKICAgIC8qIHNlZW1zIHRvIGJlIHRydW5jYXRlZCAqLwogICAgV0FSTigiOiBmaWxlIHNlZW1zIHRvIGJlIHRydW5jYXRlZCFcbiIpOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgPSBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19FTkQpIC0KICAgICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldDsKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZSAvIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICAgIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CiAgfQoKICAvKiBpZ25vcmUgZXJyb3JzICovCiAgRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssICZja1JJRkYsIDApOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRTdW5GaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIFNVTkFVRElPSEVBREVSIGF1aGRyOwoKICBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19TRVQpOwogIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKSZhdWhkciwgc2l6ZW9mKGF1aGRyKSkgIT0gc2l6ZW9mKGF1aGRyKSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIGlmIChhdWhkci5mY2NUeXBlID09IDB4MDA2NDczMkUpIHsKICAgIC8qIGhlYWRlciBpbiBsaXR0bGUgZW5kaWFuICovCiAgICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ID0gTEUySF9EV09SRChhdWhkci5vZmZzZXQpOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IExFMkhfRFdPUkQoYXVoZHIuc2l6ZSk7CgogICAgYXVoZHIuZW5jb2RpbmcgICA9IExFMkhfRFdPUkQoYXVoZHIuZW5jb2RpbmcpOwogICAgYXVoZHIuc2FtcGxlUmF0ZSA9IExFMkhfRFdPUkQoYXVoZHIuc2FtcGxlUmF0ZSk7CiAgICBhdWhkci5jaGFubmVscyAgID0gTEUySF9EV09SRChhdWhkci5jaGFubmVscyk7CiAgfSBlbHNlIGlmIChhdWhkci5mY2NUeXBlID09IG1taW9GT1VSQ0MoJy4nLCdzJywnbicsJ2QnKSkgewogICAgLyogaGVhZGVyIGluIGJpZyBlbmRpYW4gKi8KICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSBCRTJIX0RXT1JEKGF1aGRyLm9mZnNldCk7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgID0gQkUySF9EV09SRChhdWhkci5zaXplKTsKCiAgICBhdWhkci5lbmNvZGluZyAgID0gQkUySF9EV09SRChhdWhkci5lbmNvZGluZyk7CiAgICBhdWhkci5zYW1wbGVSYXRlID0gQkUySF9EV09SRChhdWhkci5zYW1wbGVSYXRlKTsKICAgIGF1aGRyLmNoYW5uZWxzICAgPSBCRTJIX0RXT1JEKGF1aGRyLmNoYW5uZWxzKTsKICB9IGVsc2UKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIGlmIChhdWhkci5jaGFubmVscyA8IDEpCiAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCiAgLyogZ2V0IHNpemUgb2YgaGVhZGVyICovCiAgc3dpdGNoKGF1aGRyLmVuY29kaW5nKSB7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIxXzMyOgogICAgVGhpcy0+Y2JGb3JtYXQgPSBzaXplb2YoRzcyMV9BRFBDTVdBVkVGT1JNQVQpOyBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfMjQ6CiAgICBUaGlzLT5jYkZvcm1hdCA9IHNpemVvZihHNzIzX0FEUENNV0FWRUZPUk1BVCk7IGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyMjoKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfNToKICAgIFdBUk4oInVuc3VwcG9ydGVkIFN1biBhdWRpbyBmb3JtYXQgJWRcbiIsIGF1aGRyLmVuY29kaW5nKTsKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIEZJWE1FICovCiAgZGVmYXVsdDoKICAgIFRoaXMtPmNiRm9ybWF0ID0gc2l6ZW9mKFdBVkVGT1JNQVRFWCk7IGJyZWFrOwogIH07CgogIFRoaXMtPmxwRm9ybWF0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmNiRm9ybWF0KTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBUaGlzLT5scEZvcm1hdC0+bkNoYW5uZWxzICAgICAgPSBhdWhkci5jaGFubmVsczsKICBUaGlzLT5scEZvcm1hdC0+blNhbXBsZXNQZXJTZWMgPSBhdWhkci5zYW1wbGVSYXRlOwogIHN3aXRjaChhdWhkci5lbmNvZGluZykgewogIGNhc2UgQVVfRU5DT0RJTkdfVUxBV184OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfTVVMQVc7CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSA4OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19QQ01fODoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX1BDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDg7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX1BDTV8xNjoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX1BDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDE2OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19QQ01fMjQ6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSAyNDsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfUENNXzMyOgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gMzI7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FMQVdfODoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX0FMQVc7CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSA4OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIxXzMyOgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfRzcyMV9BRFBDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9ICgzKjUqOCk7CiAgICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gICAgPSAxNSoxNSo4OwogICAgVGhpcy0+bHBGb3JtYXQtPmNiU2l6ZSAgICAgICAgID0gc2l6ZW9mKFdPUkQpOwogICAgKChMUEc3MjFfQURQQ01XQVZFRk9STUFUKVRoaXMtPmxwRm9ybWF0KS0+bkF1eEJsb2NrU2l6ZSA9IDA7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfMjQ6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9HNzIzX0FEUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gKDMqNSo4KTsKICAgIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbiAgICA9IDE1KjE1Kjg7CiAgICBUaGlzLT5scEZvcm1hdC0+Y2JTaXplICAgICAgICAgPSAyKnNpemVvZihXT1JEKTsKICAgICgoTFBHNzIzX0FEUENNV0FWRUZPUk1BVClUaGlzLT5scEZvcm1hdCktPmNiRXh0cmFTaXplICAgPSAwOwogICAgKChMUEc3MjNfQURQQ01XQVZFRk9STUFUKVRoaXMtPmxwRm9ybWF0KS0+bkF1eEJsb2NrU2l6ZSA9IDA7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgV0FSTigidW5zdXBwb3J0ZWQgU3VuIGF1ZGlvIGZvcm1hdCAlZFxuIiwgYXVoZHIuZW5jb2RpbmcpOwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9OwoKICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gPQogICAgKFRoaXMtPmxwRm9ybWF0LT5uQ2hhbm5lbHMgKiBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUpIC8gODsKICBpZiAoVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduID09IDAgJiYgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlIDwgOCkKICAgIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbisrOwogIFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWMgPQogICAgVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduICogVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjOwoKICBUaGlzLT5mRGlydHkgPSAwOwoKICBUaGlzLT5zSW5mby5mY2NUeXBlICAgICAgICAgICAgICAgPSBzdHJlYW10eXBlQVVESU87CiAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0ZsYWdzICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLndQcmlvcml0eSAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8ud0xhbmd1YWdlICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjOwogIFRoaXMtPnNJbmZvLmR3U3RhcnQgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggICAgICAgICAgICAgID0KICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgLyBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICAgICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAxOwogIFRoaXMtPmZJbmZvLmR3U2NhbGUgICA9IDE7CiAgVGhpcy0+ZkluZm8uZHdSYXRlICAgID0gVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjOwogIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICA9CiAgICBNdWxEaXYoVGhpcy0+Y2tEYXRhLmNrc2l6ZSwgVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjLAoJICAgVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYyk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgTU1DS0lORk8gY2tSSUZGOwogIE1NQ0tJTkZPIGNrOwoKICBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19TRVQpOwoKICAvKiBjcmVhdGUgdGhlIFJJRkYgY2h1bmsgd2l0aCBmb3JtdHlwZSBXQVZFICovCiAgY2tSSUZGLmZjY1R5cGUgPSBmb3JtdHlwZVdBVkU7CiAgY2tSSUZGLmNrc2l6ZSAgPSAwOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja1JJRkYsIE1NSU9fQ1JFQVRFUklGRikgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiB0aGUgbmV4dCBjaHVuayBpcyB0aGUgZm9ybWF0ICovCiAgY2suY2tpZCAgID0gY2tpZFdBVkVGT1JNQVQ7CiAgY2suY2tzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwgJiYgVGhpcy0+Y2JGb3JtYXQgPiAwKSB7CiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpVGhpcy0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBmYWN0IGNodW5rIGlzIG5lZWRlZCBmb3Igbm9uLXBjbSB3YXZlZm9ybXMgKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCAmJiBUaGlzLT5jYkZvcm1hdCA+IHNpemVvZihQQ01XQVZFRk9STUFUKSAmJgogICAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAhPSBXQVZFX0ZPUk1BVF9QQ00pIHsKICAgIFdBVkVGT1JNQVRFWCB3Zng7CiAgICBEV09SRCAgICAgICAgZHdGYWN0TGVuZ3RoOwogICAgSEFDTVNUUkVBTSAgIGhhczsKCiAgICAvKiB0cnkgdG8gb3BlbiBhbiBhcHByb3ByaWF0ZSBhdWRpbyBjb2RlYyB0byBmaWd1cmUgb3V0CiAgICAgKiBkYXRhIGZvciBmYWN0LWNodW5rICovCiAgICB3Zngud0Zvcm1hdFRhZyA9IFdBVkVfRk9STUFUX1BDTTsKICAgIGlmIChhY21Gb3JtYXRTdWdnZXN0KE5VTEwsIFRoaXMtPmxwRm9ybWF0LCAmd2Z4LAoJCQkgc2l6ZW9mKHdmeCksIEFDTV9GT1JNQVRTVUdHRVNURl9XRk9STUFUVEFHKSkgewogICAgICBhY21TdHJlYW1PcGVuKCZoYXMsIE5VTEwsIFRoaXMtPmxwRm9ybWF0LCAmd2Z4LCBOVUxMLAoJCSAgICAwLCAwLCBBQ01fU1RSRUFNT1BFTkZfTk9OUkVBTFRJTUUpOwogICAgICBhY21TdHJlYW1TaXplKGhhcywgVGhpcy0+Y2tEYXRhLmNrc2l6ZSwgJmR3RmFjdExlbmd0aCwKCQkgICAgQUNNX1NUUkVBTVNJWkVGX1NPVVJDRSk7CiAgICAgIGR3RmFjdExlbmd0aCAvPSB3ZngubkJsb2NrQWxpZ247CiAgICAgIGFjbVN0cmVhbUNsb3NlKGhhcywgMCk7CgogICAgICAvKiBjcmVhdGUgdGhlIGZhY3QgY2h1bmsgKi8KICAgICAgY2suY2tpZCAgID0gY2tpZFdBVkVGQUNUOwogICAgICBjay5ja3NpemUgPSBzaXplb2YoZHdGYWN0TGVuZ3RoKTsKCiAgICAgIC8qIHRlc3QgZm9yIGVub3VnaCBzcGFjZSBiZWZvcmUgZGF0YSBjaHVuayAqLwogICAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfQ1VSKSA+IFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQKCSAgLSBjay5ja3NpemUgLSA0ICogc2l6ZW9mKERXT1JEKSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZkd0ZhY3RMZW5ndGgsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0gZWxzZQogICAgICBFUlIoIjogZmFjdCBjaHVuayBpcyBuZWVkZWQgZm9yIG5vbi1wY20gZmlsZXMgLS0gY3VycmVudGx5IG5vIGNvZGVjIGZvdW5kLCBzbyBza2lwcGVkIVxuIik7CiAgfQoKICAvKiBpZiB0aGVyZSB3YXMgZXh0cmEgc3R1ZmYsIHdlIG5lZWQgdG8gZmlsbCBpdCB3aXRoIEpVTksgKi8KICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfQ1VSKSArIDIgKiBzaXplb2YoRFdPUkQpIDwgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCkgewogICAgY2suY2tpZCAgID0gY2tpZEFWSVBBRERJTkc7CiAgICBjay5ja3NpemUgPSAwOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQKCQkgLSAyICogc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY3JlYXRlIHRoZSBkYXRhIGNodW5rICovCiAgY2suY2tpZCAgID0gY2tpZFdBVkVEQVRBOwogIGNrLmNrc2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5ja0RhdGEuY2tzaXplLCBTRUVLX0NVUikgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHNvbWUgb3B0aW9uYWwgZXh0cmEgY2h1bmtzPyAqLwogIGlmIChUaGlzLT5leHRyYS5scCAhPSBOVUxMICYmIFRoaXMtPmV4dHJhLmNiID4gMCkgewogICAgLyogY2h1bmsgaGVhZGVycyBhcmUgYWxyZWFkeSBpbiBzdHJ1Y3R1cmUgKi8KICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIFRoaXMtPmV4dHJhLmxwLCBUaGlzLT5leHRyYS5jYikgIT0gVGhpcy0+ZXh0cmEuY2IpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY2xvc2UgUklGRiBjaHVuayAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9GbHVzaChUaGlzLT5obW1pbywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICByZXR1cm4gQVZJRVJSX09LOwp9Cg==