LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgInZmdy5oIgojaW5jbHVkZSAibXNhY20uaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKI2luY2x1ZGUgImV4dHJhY2h1bmsuaCIKCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBmb3JtdHlwZVdBVkUgICAgbW1pb0ZPVVJDQygnVycsJ0EnLCdWJywnRScpCiNkZWZpbmUgY2tpZFdBVkVGT1JNQVQgIG1taW9GT1VSQ0MoJ2YnLCdtJywndCcsJyAnKQojZGVmaW5lIGNraWRXQVZFRkFDVCAgICBtbWlvRk9VUkNDKCdmJywnYScsJ2MnLCd0JykKI2RlZmluZSBja2lkV0FWRURBVEEgICAgbW1pb0ZPVVJDQygnZCcsJ2EnLCd0JywnYScpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIEVORElBTl9TV0FQV09SRCh4KSAgKCgoKHgpID4+IDgpICYgMHhGRikgfCAoKCh4KSAmIDB4RkYpIDw8IDgpKQojZGVmaW5lIEVORElBTl9TV0FQRFdPUkQoeCkgKEVORElBTl9TV0FQV09SRCgoeCA+PiAxNikgJiAweEZGRkYpIHwgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVORElBTl9TV0FQV09SRCh4ICYgMHhGRkZGKSA8PCAxNikKCiNpZmRlZiBXT1JEU19CSUdFTkRJQU4KI2RlZmluZSBCRTJIX1dPUkQoeCkgICh4KQojZGVmaW5lIEJFMkhfRFdPUkQoeCkgKHgpCiNkZWZpbmUgTEUySF9XT1JEKHgpICBFTkRJQU5fU1dBUFdPUkQoeCkKI2RlZmluZSBMRTJIX0RXT1JEKHgpIEVORElBTl9TV0FQRFdPUkQoeCkKI2Vsc2UKI2RlZmluZSBCRTJIX1dPUkQoeCkgIEVORElBTl9TV0FQV09SRCh4KQojZGVmaW5lIEJFMkhfRFdPUkQoeCkgRU5ESUFOX1NXQVBEV09SRCh4KQojZGVmaW5lIExFMkhfV09SRCh4KSAgKHgpCiNkZWZpbmUgTEUySF9EV09SRCh4KSAoeCkKI2VuZGlmCgp0eXBlZGVmIHN0cnVjdCB7CiAgRk9VUkNDICBmY2NUeXBlOwogIERXT1JEICAgb2Zmc2V0OwogIERXT1JEICAgc2l6ZTsKICBJTlQgICAgIGVuY29kaW5nOwogIERXT1JEICAgc2FtcGxlUmF0ZTsKICBEV09SRCAgIGNoYW5uZWxzOwp9IFNVTkFVRElPSEVBREVSOwoKI2RlZmluZSBBVV9FTkNPRElOR19VTEFXXzggICAgICAgICAgICAgICAgIDEKI2RlZmluZSBBVV9FTkNPRElOR19QQ01fOCAgICAgICAgICAgICAgICAgIDIKI2RlZmluZSBBVV9FTkNPRElOR19QQ01fMTYgICAgICAgICAgICAgICAgIDMKI2RlZmluZSBBVV9FTkNPRElOR19QQ01fMjQgICAgICAgICAgICAgICAgIDQKI2RlZmluZSBBVV9FTkNPRElOR19QQ01fMzIgICAgICAgICAgICAgICAgIDUKI2RlZmluZSBBVV9FTkNPRElOR19GTE9BVCAgICAgICAgICAgICAgICAgIDYKI2RlZmluZSBBVV9FTkNPRElOR19ET1VCTEUgICAgICAgICAgICAgICAgIDcKI2RlZmluZSBBVV9FTkNPRElOR19BRFBDTV9HNzIxXzMyICAgICAgICAgMjMKI2RlZmluZSBBVV9FTkNPRElOR19BRFBDTV9HNzIyICAgICAgICAgICAgMjQKI2RlZmluZSBBVV9FTkNPRElOR19BRFBDTV9HNzIzXzI0ICAgICAgICAgMjUKI2RlZmluZSBBVV9FTkNPRElOR19BRFBDTV9HNzIzXzUgICAgICAgICAgMjYKI2RlZmluZSBBVV9FTkNPRElOR19BTEFXXzggICAgICAgICAgICAgICAgMjcKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlKiBpZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuQWRkUmVmKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSppZmFjZSxBVklGSUxFSU5GT1cqYWZpLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsQVZJU1RSRUFNSU5GT1cqYXNpKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5SZWFkRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyAqc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUFWSUZpbGVWdGJsIGl3YXZmdCA9IHsKICBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlLAogIElBVklGaWxlX2ZuQWRkUmVmLAogIElBVklGaWxlX2ZuUmVsZWFzZSwKICBJQVZJRmlsZV9mbkluZm8sCiAgSUFWSUZpbGVfZm5HZXRTdHJlYW0sCiAgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0sCiAgSUFWSUZpbGVfZm5Xcml0ZURhdGEsCiAgSUFWSUZpbGVfZm5SZWFkRGF0YSwKICBJQVZJRmlsZV9mbkVuZFJlY29yZCwKICBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElQZXJzaXN0RmlsZSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuQWRkUmVmKElQZXJzaXN0RmlsZSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSppZmFjZSxDTFNJRCpwQ2xhc3NJRCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5KElQZXJzaXN0RmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsRFdPUkQgZHdNb2RlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmUoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSxCT09MIGZSZW1lbWJlcik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZShJUGVyc2lzdEZpbGUqaWZhY2UsTFBPTEVTVFIqcHBzekZpbGVOYW1lKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSVBlcnNpc3RGaWxlVnRibCBpd2F2cGZ0ID0gewogIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlLAogIElQZXJzaXN0RmlsZV9mbkFkZFJlZiwKICBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlLAogIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQsCiAgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eSwKICBJUGVyc2lzdEZpbGVfZm5Mb2FkLAogIElQZXJzaXN0RmlsZV9mblNhdmUsCiAgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZCwKICBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0qaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMT05HIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HICpmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLExPTkcgKmJ5dGVzcmVhZCxMT05HICpzYW1wbGVzcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncyxMT05HICpzYW1wd3JpdHRlbixMT05HICpieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XKmluZm8sTE9ORyBpbmZvbGVuKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUFWSVN0cmVhbVZ0YmwgaXdhdnN0ID0gewogIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJQVZJU3RyZWFtX2ZuQWRkUmVmLAogIElBVklTdHJlYW1fZm5SZWxlYXNlLAogIElBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUFWSVN0cmVhbV9mbkluZm8sCiAgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUsCiAgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblNldEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuUmVhZCwKICBJQVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUFWSVN0cmVhbV9mbkRlbGV0ZSwKICBJQVZJU3RyZWFtX2ZuUmVhZERhdGEsCiAgSUFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJQVZJU3RyZWFtX2ZuU2V0SW5mbwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklGaWxlSW1wbCBJQVZJRmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSVBlcnNpc3RGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJUGVyc2lzdEZpbGVWdGJsICpscFZ0Ymw7CgogIC8qIElQZXJzaXN0RmlsZSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKfSBJUGVyc2lzdEZpbGVJbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklTdHJlYW1JbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElBVklTdHJlYW1WdGJsICpscFZ0Ymw7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7Cn0gSUFWSVN0cmVhbUltcGw7CgpzdHJ1Y3QgX0lBVklGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJRmlsZVZ0YmwgKmxwVnRibDsKICBMT05HCQkgICAgcmVmOwoKICAvKiBJQVZJRmlsZSwgSUFWSVN0cmVhbSBzdHVmZi4uLiAqLwogIElQZXJzaXN0RmlsZUltcGwgIGlQZXJzaXN0RmlsZTsKICBJQVZJU3RyZWFtSW1wbCAgICBpQVZJU3RyZWFtOwoKICBBVklGSUxFSU5GT1cgICAgICBmSW5mbzsKICBBVklTVFJFQU1JTkZPVyAgICBzSW5mbzsKCiAgTFBXQVZFRk9STUFURVggICAgbHBGb3JtYXQ7CiAgTE9ORyAgICAgICAgICAgICAgY2JGb3JtYXQ7CgogIE1NQ0tJTkZPICAgICAgICAgIGNrRGF0YTsKCiAgRVhUUkFDSFVOS1MgICAgICAgZXh0cmE7CgogIC8qIElQZXJzaXN0RmlsZSBzdHVmZiAuLi4gKi8KICBITU1JTyAgICAgICAgICAgICBobW1pbzsKICBMUFdTVFIgICAgICAgICAgICBzekZpbGVOYW1lOwogIFVJTlQgICAgICAgICAgICAgIHVNb2RlOwogIEJPT0wgICAgICAgICAgICAgIGZEaXJ0eTsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkU3VuRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVGaWxlKGNvbnN0IElBVklGaWxlSW1wbCAqVGhpcyk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlV0FWRmlsZShSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICBJQVZJRmlsZUltcGwgKnBmaWxlOwogIEhSRVNVTFQgICAgICAgaHI7CgogIGFzc2VydChyaWlkICE9IE5VTEwgJiYgcHB2ICE9IE5VTEwpOwoKICAqcHB2ID0gTlVMTDsKCiAgcGZpbGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElBVklGaWxlSW1wbCkpOwogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIHBmaWxlLT5scFZ0YmwgICAgICAgICAgICAgICAgPSAmaXdhdmZ0OwogIHBmaWxlLT5pUGVyc2lzdEZpbGUubHBWdGJsICAgPSAmaXdhdnBmdDsKICBwZmlsZS0+aUFWSVN0cmVhbS5scFZ0YmwgICAgID0gJml3YXZzdDsKICBwZmlsZS0+cmVmID0gMDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLnBhZiA9IHBmaWxlOwogIHBmaWxlLT5pQVZJU3RyZWFtLnBhZiAgID0gcGZpbGU7CgogIGhyID0gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKElBVklGaWxlKilwZmlsZSwgcmlpZCwgcHB2KTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBmaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSAqaWZhY2UsIFJFRklJRCByZWZpaWQsCgkJCQkJCUxQVk9JRCAqb2JqKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmVmaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklGaWxlLCByZWZpaWQpKSB7CiAgICAqb2JqID0gaWZhY2U7CiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9PSAxICYmCgkgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pQVZJU3RyZWFtOwogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lQZXJzaXN0RmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pUGVyc2lzdEZpbGU7CiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLGlmYWNlKTsKCiAgcmV0dXJuIEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApXG4iLGlmYWNlKTsKCiAgaWYgKCFyZWYpIHsKICAgIGlmIChUaGlzLT5mRGlydHkpIHsKICAgICAgLyogbmVlZCB0byB3cml0ZSBoZWFkZXJzIHRvIGZpbGUgKi8KICAgICAgQVZJRklMRV9TYXZlRmlsZShUaGlzKTsKICAgIH0KCiAgICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scEZvcm1hdCk7CiAgICAgIFRoaXMtPmxwRm9ybWF0ID0gTlVMTDsKICAgICAgVGhpcy0+Y2JGb3JtYXQgPSAwOwogICAgfQogICAgaWYgKFRoaXMtPmV4dHJhLmxwICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+ZXh0cmEubHApOwogICAgICBUaGlzLT5leHRyYS5scCA9IE5VTEw7CiAgICAgIFRoaXMtPmV4dHJhLmNiID0gMDsKICAgIH0KICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnN6RmlsZU5hbWUpOwogICAgVGhpcy0+c3pGaWxlTmFtZSA9IE5VTEw7CiAgICBpZiAoVGhpcy0+aG1taW8gIT0gTlVMTCkgewogICAgICBtbWlvQ2xvc2UoVGhpcy0+aG1taW8sIDApOwogICAgICBUaGlzLT5obW1pbyA9IE5VTEw7CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgICByZXR1cm4gMDsKICB9CiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSAqaWZhY2UsIExQQVZJRklMRUlORk9XIGFmaSwKCQkJCSAgICAgIExPTkcgc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsaWZhY2UsYWZpLHNpemUpOwoKICBpZiAoYWZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogdXBkYXRlIGZpbGUgaW5mbyAqLwogIFRoaXMtPmZJbmZvLmR3RmxhZ3MgPSAwOwogIFRoaXMtPmZJbmZvLmR3Q2FwcyAgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMKSB7CiAgICBhc3NlcnQoVGhpcy0+c0luZm8uZHdTY2FsZSAhPSAwKTsKCiAgICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgICAgICAgICAgICAgPSAxOwogICAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gVGhpcy0+c0luZm8uZHdTY2FsZTsKICAgIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IFRoaXMtPnNJbmZvLmR3UmF0ZTsKICAgIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogICAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKICAgIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgPQogICAgICBNdWxEaXYoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplLFRoaXMtPnNJbmZvLmR3UmF0ZSxUaGlzLT5zSW5mby5kd1NjYWxlKTsKICB9CgogIG1lbWNweShhZmksICZUaGlzLT5mSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+ZkluZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5mSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsMHglMDhYLCVkKVxuIiwgaWZhY2UsIGF2aXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChhdmlzID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqYXZpcyA9IE5VTEw7CgogIC8qIERvZXMgb3VyIHN0cmVhbSBleGlzdHM/ICovCiAgaWYgKGxQYXJhbSAhPSAwIHx8IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CiAgaWYgKGZjY1R5cGUgIT0gMCAmJiBmY2NUeXBlICE9IHN0cmVhbXR5cGVBVURJTykKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwoKICAqYXZpcyA9IChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtOwogIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsUEFWSVNUUkVBTSAqYXZpcywKCQkJCQkgICAgICBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGlmYWNlLCBhdmlzLCBhc2kpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBhc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICphdmlzID0gTlVMTDsKCiAgLyogV2Ugb25seSBzdXBwb3J0IG9uZSBhdWRpbyBzdHJlYW0gKi8KICBpZiAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zICE9IDAgfHwgVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgaWYgKGFzaS0+ZmNjVHlwZSAhPSBzdHJlYW10eXBlQVVESU8pCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBEb2VzIHRoZSB1c2VyIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBUaGlzLT5jYkZvcm1hdCA9IDA7CiAgVGhpcy0+bHBGb3JtYXQgPSBOVUxMOwoKICBtZW1jcHkoJlRoaXMtPnNJbmZvLCBhc2ksIHNpemVvZihUaGlzLT5zSW5mbykpOwoKICAvKiBtYWtlIHN1cmUgc3RyZWFtaW5mbyBpZiBva2F5IGZvciB1cyAqLwogIFRoaXMtPnNJbmZvLmZjY0hhbmRsZXIgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3RmxhZ3MgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3Q2FwcyAgICAgICAgICAgICAgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwogIFRoaXMtPnNJbmZvLmR3U3RhcnQgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgPSAwOwogIG1lbXNldCgmVGhpcy0+c0luZm8ucmNGcmFtZSwgMCwgc2l6ZW9mKFRoaXMtPnNJbmZvLnJjRnJhbWUpKTsKCiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID0gMTsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgPSBUaGlzLT5zSW5mby5kd1NjYWxlOwogIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICA9IFRoaXMtPnNJbmZvLmR3UmF0ZTsKICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKCiAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IDA7CiAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IDA7CgogICphdmlzID0gKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW07CiAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgICBMUFZPSUQgbHBEYXRhLCBMT05HIHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhYLCVwLCVkKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHBEYXRhID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBja2lkLCBscERhdGEsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5SZWFkRGF0YShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGNraWQsCgkJCQkJICBMUFZPSUQgbHBEYXRhLCBMT05HICpzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4WCwlcCwlcClcbiIsIGlmYWNlLCBja2lkLCBscERhdGEsIHNpemUpOwoKICByZXR1cm4gUmVhZEV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBja2lkLCBscERhdGEsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUgKmlmYWNlKQp7CiAgVFJBQ0UoIiglcClcbiIsaWZhY2UpOwoKICAvKiBUaGlzIGlzIG9ubHkgbmVlZGVkIGZvciBpbnRlcmxlYXZlZCBmaWxlcy4KICAgKiBXZSBoYXZlIG9ubHkgb25lIHN0cmVhbSwgd2hpY2ggY2FuJ3QgYmUgaW50ZXJsZWF2ZWQuCiAgICovCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlICppZmFjZSwgRFdPUkQgZmNjVHlwZSwKCQkJCQkgICAgICBMT05HIGxQYXJhbSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOFgsJWQpXG4iLCBpZmFjZSwgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEbyB3ZSBoYXZlIG91ciBhdWRpbyBzdHJlYW0/ICovCiAgaWYgKGxQYXJhbSAhPSAwIHx8IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9PSAwIHx8CiAgICAgIChmY2NUeXBlICE9IDAgJiYgZmNjVHlwZSAhPSBzdHJlYW10eXBlQVVESU8pKQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CgogIC8qIEhhdmUgdXNlciB3cml0ZSBwZXJtaXNzaW9ucz8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scEZvcm1hdCk7CiAgVGhpcy0+bHBGb3JtYXQgPSBOVUxMOwogIFRoaXMtPmNiRm9ybWF0ID0gMDsKCiAgLyogdXBkYXRlIGluZm9zICovCiAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IDA7CiAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IDA7CgogIFRoaXMtPnNJbmZvLmR3U2NhbGUgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdSYXRlICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0xlbmd0aCAgPSAwOwogIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IDA7CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9IDA7CiAgVGhpcy0+ZkluZm8uZHdFZGl0Q291bnQrKzsKCiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCSAgICBSRUZJSUQgcmVmaWlkLCBMUFZPSUQgKm9iaikKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKFBBVklGSUxFKVRoaXMtPnBhZiwgcmVmaWlkLCBvYmopOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuQWRkUmVmKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX0FkZFJlZigoUEFWSUZJTEUpVGhpcy0+cGFmKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mblJlbGVhc2UoSVBlcnNpc3RGaWxlICppZmFjZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUmVsZWFzZSgoUEFWSUZJTEUpVGhpcy0+cGFmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJTFBDTFNJRCBwQ2xhc3NJRCkKewogIFRSQUNFKCIoJXAsJXApXG4iLCBpZmFjZSwgcENsYXNzSUQpOwoKICBpZiAocENsYXNzSUQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIG1lbWNweShwQ2xhc3NJRCwgJkNMU0lEX1dBVkZpbGUsIHNpemVvZihDTFNJRF9XQVZGaWxlKSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5KElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIChUaGlzLT5wYWYtPmZEaXJ0eSA/IFNfT0sgOiBTX0ZBTFNFKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkxvYWQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSwgRFdPUkQgZHdNb2RlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJUGVyc2lzdEZpbGVJbXBsKilpZmFjZSktPnBhZjsKCiAgV0NIQVIgd3N6U3RyZWFtRm10WzUwXTsKICBJTlQgICBsZW47CgogIFRSQUNFKCIoJXAsJXMsMHglMDhYKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpLCBkd01vZGUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXIgKi8KICBpZiAocHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGlmIChUaGlzLT5obW1pbyAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogTm8gcmV1c2Ugb2YgdGhpcyBvYmplY3QgZm9yIGFub3RoZXIgZmlsZSEgKi8KCiAgLyogcmVtZWJlciBtb2RlIGFuZCBuYW1lICovCiAgVGhpcy0+dU1vZGUgPSBkd01vZGU7CgogIGxlbiA9IGxzdHJsZW5XKHBzekZpbGVOYW1lKSArIDE7CiAgVGhpcy0+c3pGaWxlTmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICBpZiAoVGhpcy0+c3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgbHN0cmNweVcoVGhpcy0+c3pGaWxlTmFtZSwgcHN6RmlsZU5hbWUpOwoKICAvKiB0cnkgdG8gb3BlbiB0aGUgZmlsZSAqLwogIFRoaXMtPmhtbWlvID0gbW1pb09wZW5XKFRoaXMtPnN6RmlsZU5hbWUsIE5VTEwsIE1NSU9fQUxMT0NCVUYgfCBkd01vZGUpOwogIGlmIChUaGlzLT5obW1pbyA9PSBOVUxMKSB7CiAgICAvKiBtbWlvT3Blblcgbm90IGluIG5hdGl2ZSBETExzIG9mIFdpbjl4IC0tIHRyeSBtbWlvT3BlbkEgKi8KICAgIExQU1RSIHN6RmlsZU5hbWU7CiAgICBsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgVGhpcy0+c3pGaWxlTmFtZSwgLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogICAgc3pGaWxlTmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKiBzaXplb2YoQ0hBUikpOwogICAgaWYgKHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnN6RmlsZU5hbWUsIC0xLCBzekZpbGVOYW1lLAoJCQlsZW4sIE5VTEwsIE5VTEwpOwoKICAgIFRoaXMtPmhtbWlvID0gbW1pb09wZW5BKHN6RmlsZU5hbWUsIE5VTEwsIE1NSU9fQUxMT0NCVUYgfCBkd01vZGUpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3pGaWxlTmFtZSk7CiAgICBpZiAoVGhpcy0+aG1taW8gPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFT1BFTjsKICB9CgogIG1lbXNldCgmIFRoaXMtPmZJbmZvLCAwLCBzaXplb2YoVGhpcy0+ZkluZm8pKTsKICBtZW1zZXQoJiBUaGlzLT5zSW5mbywgMCwgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CgogIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1dBVkVGSUxFVFlQRSwgVGhpcy0+ZkluZm8uc3pGaWxlVHlwZSwKCSAgICAgIHNpemVvZihUaGlzLT5mSW5mby5zekZpbGVUeXBlKSk7CiAgaWYgKExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1dBVkVTVFJFQU1GT1JNQVQsCgkJICB3c3pTdHJlYW1GbXQsIHNpemVvZih3c3pTdHJlYW1GbXQpKSA+IDApIHsKICAgIHdzcHJpbnRmVyhUaGlzLT5zSW5mby5zek5hbWUsIHdzelN0cmVhbUZtdCwKCSAgICAgIEFWSUZJTEVfQmFzZW5hbWVXKFRoaXMtPnN6RmlsZU5hbWUpKTsKICB9CgogIC8qIHNob3VsZCB3ZSBjcmVhdGUgYSBuZXcgZmlsZT8gKi8KICBpZiAoZHdNb2RlICYgT0ZfQ1JFQVRFKSB7CiAgICAvKiBub3RoaW5nIG1vcmUgdG8gZG8gKi8KICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gQVZJRklMRV9Mb2FkRmlsZShUaGlzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSxCT09MIGZSZW1lbWJlcikKewogIFRSQUNFKCIoJXAsJXMsJWQpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGZSZW1lbWJlcik7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCSAgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSkKewogIFRSQUNFKCIoJXAsJXMpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSkpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQlMUE9MRVNUUiAqcHBzekZpbGVOYW1lKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBpZmFjZSwgcHBzekZpbGVOYW1lKTsKCiAgaWYgKHBwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwc3pGaWxlTmFtZSA9IE5VTEw7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIGlmIChUaGlzLT5wYWYtPnN6RmlsZU5hbWUgIT0gTlVMTCkgewogICAgaW50IGxlbiA9IGxzdHJsZW5XKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSkgKyAxOwoKICAgICpwcHN6RmlsZU5hbWUgPSBDb1Rhc2tNZW1BbGxvYyhsZW4gKiBzaXplb2YoV0NIQVIpKTsKICAgIGlmICgqcHBzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIHN0cmNweVcoKnBwc3pGaWxlTmFtZSwgVGhpcy0+cGFmLT5zekZpbGVOYW1lKTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKFBBVklGSUxFKVRoaXMtPnBhZiwgcmVmaWlkLCBvYmopOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSAqaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfQWRkUmVmKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0gKmlmYWNlLCBMUEFSQU0gbFBhcmFtMSwKCQkJCQkgIExQQVJBTSBsUGFyYW0yKQp7CiAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgpXG4iLCBpZmFjZSwgbFBhcmFtMSwgbFBhcmFtMik7CgogIC8qIFRoaXMgSUFWSVN0cmVhbSBpbnRlcmZhY2UgbmVlZHMgYW4gV0FWRmlsZSAqLwogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+cGFmLT5zSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+cGFmLT5zSW5mbykpKTsKCiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKFRoaXMtPnBhZi0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgIExPTkcgZmxhZ3MpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoKElBVklTdHJlYW1JbXBsKilpZmFjZSktPnBhZjsKCiAgVFJBQ0UoIiglcCwlZCwweCUwOFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIC8qIERvIHdlIGhhdmUgZGF0YT8gKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiAtMTsKCiAgLyogV2UgZG9uJ3QgaGF2ZSBhbiBpbmRleCAqLwogIGlmIChmbGFncyAmIEZJTkRfSU5ERVgpCiAgICByZXR1cm4gLTE7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgewogICAgaWYgKChmbGFncyAmIEZJTkRfTkVYVCkgJiYgcG9zID4gMCkKICAgICAgcG9zID0gLTE7CiAgICBlbHNlCiAgICAgIHBvcyA9IDA7CiAgfQoKICBpZiAoKGZsYWdzICYgRklORF9SRVQpID09IEZJTkRfTEVOR1RIIHx8CiAgICAgIChmbGFncyAmIEZJTkRfUkVUKSA9PSBGSU5EX1NJWkUpCiAgICByZXR1cm4gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogIGlmICgoZmxhZ3MgJiBGSU5EX1JFVCkgPT0gRklORF9PRkZTRVQpCiAgICByZXR1cm4gVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArIHBvcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgcmV0dXJuIHBvczsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgICBMUFZPSUQgZm9ybWF0LCBMT05HICpmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlZCwlcCwlcClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChmb3JtYXRzaXplID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBvbmx5IGludGVyZXN0ZWQgaW4gbmVlZGVkIGJ1ZmZlcnNpemU/ICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8ICpmb3JtYXRzaXplIDw9IDApIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+cGFmLT5jYkZvcm1hdDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogY29weSBpbml0aWFsIGZvcm1hdCAob25seSBhcyBtdWNoIGFzIHdpbGwgZml0KSAqLwogIG1lbWNweShmb3JtYXQsIFRoaXMtPnBhZi0+bHBGb3JtYXQsIG1pbigqZm9ybWF0c2l6ZSwgVGhpcy0+cGFmLT5jYkZvcm1hdCkpOwogIGlmICgqZm9ybWF0c2l6ZSA8IFRoaXMtPnBhZi0+Y2JGb3JtYXQpIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+cGFmLT5jYkZvcm1hdDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPnBhZi0+Y2JGb3JtYXQ7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWQsJXAsJWQpXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8IGZvcm1hdHNpemUgPD0gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogV2UgY2FuIG9ubHkgZG8gdGhpcyB0byBhbiBlbXB0eSB3YXZlIGZpbGUsIGJ1dCBpZ25vcmUgY2FsbAogICAqIGlmIHN0aWxsIHNhbWUgZm9ybWF0ICovCiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwpIHsKICAgIGlmIChmb3JtYXRzaXplICE9IFRoaXMtPmNiRm9ybWF0IHx8CgltZW1jbXAoZm9ybWF0LCBUaGlzLT5scEZvcm1hdCwgZm9ybWF0c2l6ZSkgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogb25seSBzdXBwb3J0IHN0YXJ0IGF0IHBvc2l0aW9uIDAgKi8KICBpZiAocG9zICE9IDApCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBEbyB3ZSBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogZ2V0IG1lbW9yeSBmb3IgZm9ybWF0IGFuZCBjb3B5IGl0ICovCiAgVGhpcy0+bHBGb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZm9ybWF0c2l6ZSk7CiAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgVGhpcy0+Y2JGb3JtYXQgPSBmb3JtYXRzaXplOwogIG1lbWNweShUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogdXBkYXRlIGluZm8ncyBhYm91dCAnZGF0YScgY2h1bmsgKi8KICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ID0gZm9ybWF0c2l6ZSArIDcgKiBzaXplb2YoRFdPUkQpOwogIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSAwOwoKICAvKiBmb3Igbm9uLXBjbSBmb3JtYXQgd2UgbmVlZCBhbHNvIGEgJ2ZhY3QnIGNodW5rICovCiAgaWYgKFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkKICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKz0gMyAqIHNpemVvZihEV09SRCk7CgogIC8qIHVwZGF0ZSBzdHJlYW0gYW5kIGZpbGUgaW5mbyAqLwogIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1NjYWxlICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdSYXRlICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYzsKICBUaGlzLT5zSW5mby5kd0xlbmd0aCAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IDA7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQlMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJTE9ORyBidWZmZXJzaXplLCBMUExPTkcgYnl0ZXNyZWFkLAoJCQkJCUxQTE9ORyBzYW1wbGVzcmVhZCkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVkLCVkLCVwLCVkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCglidWZmZXJzaXplLCBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gMDsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9IDA7CgogIC8qIHBvc2l0aW9ucyB3aXRob3V0IGRhdGEgKi8KICBpZiAoc3RhcnQgPCAwIHx8IChEV09SRClzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogY2hlY2sgc2FtcGxlcyAqLwogIGlmIChzYW1wbGVzIDwgMCkKICAgIHNhbXBsZXMgPSAwOwogIGlmIChidWZmZXJzaXplID4gMCkgewogICAgaWYgKHNhbXBsZXMgPiAwKQogICAgICBzYW1wbGVzID0gbWluKChEV09SRClzYW1wbGVzLCBidWZmZXJzaXplIC8gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplKTsKICAgIGVsc2UKICAgICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgfQoKICAvKiBsaW1pdCB0byBlbmQgb2Ygc3RyZWFtICovCiAgaWYgKChEV09SRCkoc3RhcnQgKyBzYW1wbGVzKSA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgc2FtcGxlcyA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gc3RhcnQ7CgogIC8qIHJlcXVlc3Qgb25seSB0aGUgc2l6ZXM/ICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMIHx8IGJ1ZmZlcnNpemUgPD0gMCkgewogICAgLyogdGhlbiBJIG5lZWQgYXQgbGVhc3Qgb25lIHBhcmFtZXRlciBmb3IgaXQgKi8KICAgIGlmIChieXRlc3JlYWQgPT0gTlVMTCAmJiBzYW1wbGVzcmVhZCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogbm90aGluZyB0byByZWFkPyAqLwogIGlmIChzYW1wbGVzID09IDApCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBDYW4gSSByZWFkIGF0IGxlYXN0IG9uZSBzYW1wbGU/ICovCiAgaWYgKChEV09SRClidWZmZXJzaXplIDwgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKCiAgYnVmZmVyc2l6ZSA9IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CgogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldAoJICAgICAgICsgc3RhcnQgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUsIFNFRUtfU0VUKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpYnVmZmVyLCBidWZmZXJzaXplKSAhPSBidWZmZXJzaXplKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gYnVmZmVyc2l6ZTsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9IHNhbXBsZXM7ICAKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCSBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkJCSBMUExPTkcgc2FtcHdyaXR0ZW4sCgkJCQkJIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoKElBVklTdHJlYW1JbXBsKilpZmFjZSktPnBhZjsKCiAgVFJBQ0UoIiglcCwlZCwlZCwlcCwlZCwweCUwOFgsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsCglidWZmZXIsIGJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnVmZmVyID09IE5VTEwgJiYgKGJ1ZmZlcnNpemUgPiAwIHx8IHNhbXBsZXMgPiAwKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiA8IDAgbWVhbnMgImFwcGVuZCIgKi8KICBpZiAoc3RhcnQgPCAwKQogICAgc3RhcnQgPSBUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGg7CgogIC8qIGNoZWNrIGJ1ZmZlcnNpemUgLS0gbXVzdCBtdWx0aXBsZSBvZiBzYW1wbGVzaXplICovCiAgaWYgKGJ1ZmZlcnNpemUgJiB+KFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAtIDEpKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBkbyB3ZSBoYXZlIGFueXRoaW5nIHRvIHdyaXRlPyAqLwogIGlmIChidWZmZXIgIT0gTlVMTCAmJiBidWZmZXJzaXplID4gMCkgewogICAgVGhpcy0+ZkRpcnR5ID0gMTsKCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKwoJCSBzdGFydCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilidWZmZXIsIGJ1ZmZlcnNpemUpICE9IGJ1ZmZlcnNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gbWF4KFRoaXMtPnNJbmZvLmR3TGVuZ3RoLCAoRFdPUkQpc3RhcnQgKyBzYW1wbGVzKTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgID0gbWF4KFRoaXMtPmNrRGF0YS5ja3NpemUsCgkJCSAgICAgICBzdGFydCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSArIGJ1ZmZlcnNpemUpOwoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICAgKnNhbXB3cml0dGVuID0gc2FtcGxlczsKICAgIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICAgKmJ5dGVzd3JpdHRlbiA9IGJ1ZmZlcnNpemU7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgIExPTkcgc2FtcGxlcykKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVkLCVkKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzdGFydCA8IDAgfHwgc2FtcGxlcyA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEZWxldGUgYmVmb3JlIHN0YXJ0IG9mIHN0cmVhbT8gKi8KICBpZiAoKERXT1JEKShzdGFydCArIHNhbXBsZXMpIDwgVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIERlbGV0ZSBhZnRlciBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmICgoRFdPUkQpc3RhcnQgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIEZvciB0aGUgcmVzdCB3ZSBuZWVkIHdyaXRlIHBlcm1pc3Npb25zICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgaWYgKChEV09SRCkoc3RhcnQgKyBzYW1wbGVzKSA+PSBUaGlzLT5zSW5mby5kd0xlbmd0aCkgewogICAgLyogZGVsZXRpb24gYXQgZW5kICovCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGggLSBzdGFydDsKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC09IHNhbXBsZXM7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICAtPSBzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogIH0gZWxzZSBpZiAoKERXT1JEKXN0YXJ0IDw9IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgIC8qIGRlbGV0aW9uIGF0IHN0YXJ0ICovCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdTdGFydCAtIHN0YXJ0OwogICAgc3RhcnQgICA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ICs9IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgIC09IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgfSBlbHNlIHsKICAgIC8qIGRlbGV0aW9uIGluc2lkZSBzdHJlYW0gLS0gbmVlZHMgcGxheWxpc3QgYW5kIGN1ZSdzICovCiAgICBGSVhNRSgiOiBkZWxldGlvbiBpbnNpZGUgb2Ygc3RyZWFtIG5vdCBzdXBwb3J0ZWQhXG4iKTsKCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgVGhpcy0+ZkRpcnR5ID0gMTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICBMUFZPSUQgbHAsIExQTE9ORyBscHJlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUmVhZERhdGEoKFBBVklGSUxFKVRoaXMtPnBhZiwgZmNjLCBscCwgbHByZWFkKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgIExQVk9JRCBscCwgTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgcmV0dXJuIElBVklGaWxlX1dyaXRlRGF0YSgoUEFWSUZJTEUpVGhpcy0+cGFmLCBmY2MsIGxwLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCSAgIExQQVZJU1RSRUFNSU5GT1cgaW5mbywgTE9ORyBpbmZvbGVuKQp7CiAgRklYTUUoIiglcCwlcCwlZCk6IHN0dWJcbiIsIGlmYWNlLCBpbmZvLCBpbmZvbGVuKTsKCiAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNTUNLSU5GTyBja1JJRkY7CiAgTU1DS0lORk8gY2s7CgogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gMDsgLyoganVzdCB0byBiZSBzdXJlICovCiAgVGhpcy0+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+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYyk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoY29uc3QgSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgTU1DS0lORk8gY2tSSUZGOwogIE1NQ0tJTkZPIGNrOwoKICBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19TRVQpOwoKICAvKiBjcmVhdGUgdGhlIFJJRkYgY2h1bmsgd2l0aCBmb3JtdHlwZSBXQVZFICovCiAgY2tSSUZGLmZjY1R5cGUgPSBmb3JtdHlwZVdBVkU7CiAgY2tSSUZGLmNrc2l6ZSAgPSAwOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja1JJRkYsIE1NSU9fQ1JFQVRFUklGRikgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiB0aGUgbmV4dCBjaHVuayBpcyB0aGUgZm9ybWF0ICovCiAgY2suY2tpZCAgID0gY2tpZFdBVkVGT1JNQVQ7CiAgY2suY2tzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwgJiYgVGhpcy0+Y2JGb3JtYXQgPiAwKSB7CiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpVGhpcy0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBmYWN0IGNodW5rIGlzIG5lZWRlZCBmb3Igbm9uLXBjbSB3YXZlZm9ybXMgKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCAmJiBUaGlzLT5jYkZvcm1hdCA+IHNpemVvZihQQ01XQVZFRk9STUFUKSAmJgogICAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAhPSBXQVZFX0ZPUk1BVF9QQ00pIHsKICAgIFdBVkVGT1JNQVRFWCB3Zng7CiAgICBEV09SRCAgICAgICAgZHdGYWN0TGVuZ3RoOwogICAgSEFDTVNUUkVBTSAgIGhhczsKCiAgICAvKiB0cnkgdG8gb3BlbiBhbiBhcHByb3ByaWF0ZSBhdWRpbyBjb2RlYyB0byBmaWd1cmUgb3V0CiAgICAgKiBkYXRhIGZvciBmYWN0LWNodW5rICovCiAgICB3Zngud0Zvcm1hdFRhZyA9IFdBVkVfRk9STUFUX1BDTTsKICAgIGlmIChhY21Gb3JtYXRTdWdnZXN0KE5VTEwsIFRoaXMtPmxwRm9ybWF0LCAmd2Z4LAoJCQkgc2l6ZW9mKHdmeCksIEFDTV9GT1JNQVRTVUdHRVNURl9XRk9STUFUVEFHKSkgewogICAgICBhY21TdHJlYW1PcGVuKCZoYXMsIE5VTEwsIFRoaXMtPmxwRm9ybWF0LCAmd2Z4LCBOVUxMLAoJCSAgICAwLCAwLCBBQ01fU1RSRUFNT1BFTkZfTk9OUkVBTFRJTUUpOwogICAgICBhY21TdHJlYW1TaXplKGhhcywgVGhpcy0+Y2tEYXRhLmNrc2l6ZSwgJmR3RmFjdExlbmd0aCwKCQkgICAgQUNNX1NUUkVBTVNJWkVGX1NPVVJDRSk7CiAgICAgIGR3RmFjdExlbmd0aCAvPSB3ZngubkJsb2NrQWxpZ247CiAgICAgIGFjbVN0cmVhbUNsb3NlKGhhcywgMCk7CgogICAgICAvKiBjcmVhdGUgdGhlIGZhY3QgY2h1bmsgKi8KICAgICAgY2suY2tpZCAgID0gY2tpZFdBVkVGQUNUOwogICAgICBjay5ja3NpemUgPSBzaXplb2YoZHdGYWN0TGVuZ3RoKTsKCiAgICAgIC8qIHRlc3QgZm9yIGVub3VnaCBzcGFjZSBiZWZvcmUgZGF0YSBjaHVuayAqLwogICAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfQ1VSKSA+IFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQKCSAgLSBjay5ja3NpemUgLSA0ICogc2l6ZW9mKERXT1JEKSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZkd0ZhY3RMZW5ndGgsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0gZWxzZQogICAgICBFUlIoIjogZmFjdCBjaHVuayBpcyBuZWVkZWQgZm9yIG5vbi1wY20gZmlsZXMgLS0gY3VycmVudGx5IG5vIGNvZGVjIGZvdW5kLCBzbyBza2lwcGVkIVxuIik7CiAgfQoKICAvKiBpZiB0aGVyZSB3YXMgZXh0cmEgc3R1ZmYsIHdlIG5lZWQgdG8gZmlsbCBpdCB3aXRoIEpVTksgKi8KICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfQ1VSKSArIDIgKiBzaXplb2YoRFdPUkQpIDwgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCkgewogICAgY2suY2tpZCAgID0gY2tpZEFWSVBBRERJTkc7CiAgICBjay5ja3NpemUgPSAwOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQKCQkgLSAyICogc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY3JlYXRlIHRoZSBkYXRhIGNodW5rICovCiAgY2suY2tpZCAgID0gY2tpZFdBVkVEQVRBOwogIGNrLmNrc2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5ja0RhdGEuY2tzaXplLCBTRUVLX0NVUikgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHNvbWUgb3B0aW9uYWwgZXh0cmEgY2h1bmtzPyAqLwogIGlmIChUaGlzLT5leHRyYS5scCAhPSBOVUxMICYmIFRoaXMtPmV4dHJhLmNiID4gMCkgewogICAgLyogY2h1bmsgaGVhZGVycyBhcmUgYWxyZWFkeSBpbiBzdHJ1Y3R1cmUgKi8KICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIFRoaXMtPmV4dHJhLmxwLCBUaGlzLT5leHRyYS5jYikgIT0gVGhpcy0+ZXh0cmEuY2IpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY2xvc2UgUklGRiBjaHVuayAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9GbHVzaChUaGlzLT5obW1pbywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICByZXR1cm4gQVZJRVJSX09LOwp9Cg==