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+cGFmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJTFBDTFNJRCBwQ2xhc3NJRCkKewogIFRSQUNFKCIoJXAsJXApXG4iLCBpZmFjZSwgcENsYXNzSUQpOwoKICBpZiAocENsYXNzSUQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwQ2xhc3NJRCA9IENMU0lEX1dBVkZpbGU7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5KElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIChUaGlzLT5wYWYtPmZEaXJ0eSA/IFNfT0sgOiBTX0ZBTFNFKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkxvYWQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSwgRFdPUkQgZHdNb2RlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJUGVyc2lzdEZpbGVJbXBsKilpZmFjZSktPnBhZjsKCiAgV0NIQVIgd3N6U3RyZWFtRm10WzUwXTsKICBJTlQgICBsZW47CgogIFRSQUNFKCIoJXAsJXMsMHglMDhYKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpLCBkd01vZGUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXIgKi8KICBpZiAocHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGlmIChUaGlzLT5obW1pbyAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogTm8gcmV1c2Ugb2YgdGhpcyBvYmplY3QgZm9yIGFub3RoZXIgZmlsZSEgKi8KCiAgLyogcmVtZW1iZXIgbW9kZSBhbmQgbmFtZSAqLwogIFRoaXMtPnVNb2RlID0gZHdNb2RlOwoKICBsZW4gPSBsc3RybGVuVyhwc3pGaWxlTmFtZSkgKyAxOwogIFRoaXMtPnN6RmlsZU5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKFRoaXMtPnN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIGxzdHJjcHlXKFRoaXMtPnN6RmlsZU5hbWUsIHBzekZpbGVOYW1lKTsKCiAgLyogdHJ5IHRvIG9wZW4gdGhlIGZpbGUgKi8KICBUaGlzLT5obW1pbyA9IG1taW9PcGVuVyhUaGlzLT5zekZpbGVOYW1lLCBOVUxMLCBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICBpZiAoVGhpcy0+aG1taW8gPT0gTlVMTCkgewogICAgLyogbW1pb09wZW5XIG5vdCBpbiBuYXRpdmUgRExMcyBvZiBXaW45eCAtLSB0cnkgbW1pb09wZW5BICovCiAgICBMUFNUUiBzekZpbGVOYW1lOwogICAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnN6RmlsZU5hbWUsIC0xLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAwLCBOVUxMLCBOVUxMKTsKICAgIHN6RmlsZU5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKENIQVIpKTsKICAgIGlmIChzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBUaGlzLT5zekZpbGVOYW1lLCAtMSwgc3pGaWxlTmFtZSwKCQkJbGVuLCBOVUxMLCBOVUxMKTsKCiAgICBUaGlzLT5obW1pbyA9IG1taW9PcGVuQShzekZpbGVOYW1lLCBOVUxMLCBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN6RmlsZU5hbWUpOwogICAgaWYgKFRoaXMtPmhtbWlvID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfRklMRU9QRU47CiAgfQoKICBtZW1zZXQoJiBUaGlzLT5mSW5mbywgMCwgc2l6ZW9mKFRoaXMtPmZJbmZvKSk7CiAgbWVtc2V0KCYgVGhpcy0+c0luZm8sIDAsIHNpemVvZihUaGlzLT5zSW5mbykpOwoKICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19XQVZFRklMRVRZUEUsIFRoaXMtPmZJbmZvLnN6RmlsZVR5cGUsCgkgICAgICBzaXplb2YoVGhpcy0+ZkluZm8uc3pGaWxlVHlwZSkvc2l6ZW9mKFRoaXMtPmZJbmZvLnN6RmlsZVR5cGVbMF0pKTsKICBpZiAoTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfV0FWRVNUUkVBTUZPUk1BVCwKCQkgIHdzelN0cmVhbUZtdCwgc2l6ZW9mKHdzelN0cmVhbUZtdCkvc2l6ZW9mKHdzelN0cmVhbUZtdFswXSkpID4gMCkgewogICAgd3NwcmludGZXKFRoaXMtPnNJbmZvLnN6TmFtZSwgd3N6U3RyZWFtRm10LAoJICAgICAgQVZJRklMRV9CYXNlbmFtZVcoVGhpcy0+c3pGaWxlTmFtZSkpOwogIH0KCiAgLyogc2hvdWxkIHdlIGNyZWF0ZSBhIG5ldyBmaWxlPyAqLwogIGlmIChkd01vZGUgJiBPRl9DUkVBVEUpIHsKICAgIC8qIG5vdGhpbmcgbW9yZSB0byBkbyAqLwogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBBVklGSUxFX0xvYWRGaWxlKFRoaXMpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCSAgTFBDT0xFU1RSIHBzekZpbGVOYW1lLEJPT0wgZlJlbWVtYmVyKQp7CiAgVFJBQ0UoIiglcCwlcywlZClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSwgZlJlbWVtYmVyKTsKCiAgLyogV2Ugd3JpdGUgZGlyZWN0bHkgdG8gZGlzaywgc28gbm90aGluZyB0byBkby4gKi8KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJICAgTFBDT0xFU1RSIHBzekZpbGVOYW1lKQp7CiAgVFJBQ0UoIiglcCwlcylcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSk7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQT0xFU1RSICpwcHN6RmlsZU5hbWUpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGlmYWNlLCBwcHN6RmlsZU5hbWUpOwoKICBpZiAocHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBzekZpbGVOYW1lID0gTlVMTDsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgaWYgKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSAhPSBOVUxMKSB7CiAgICBpbnQgbGVuID0gbHN0cmxlblcoVGhpcy0+cGFmLT5zekZpbGVOYW1lKSArIDE7CgogICAgKnBwc3pGaWxlTmFtZSA9IENvVGFza01lbUFsbG9jKGxlbiAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKCpwcHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgc3RyY3B5VygqcHBzekZpbGVOYW1lLCBUaGlzLT5wYWYtPnN6RmlsZU5hbWUpOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkJICBSRUZJSUQgcmVmaWlkLCBMUFZPSUQgKm9iaikKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgoUEFWSUZJTEUpVGhpcy0+cGFmLCByZWZpaWQsIG9iaik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtICppZmFjZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUmVsZWFzZSgoUEFWSUZJTEUpVGhpcy0+cGFmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExQQVJBTSBsUGFyYW0xLAoJCQkJCSAgTFBBUkFNIGxQYXJhbTIpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIGlmYWNlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgLyogVGhpcyBJQVZJU3RyZWFtIGludGVyZmFjZSBuZWVkcyBhbiBXQVZGaWxlICovCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0gKmlmYWNlLExQQVZJU1RSRUFNSU5GT1cgcHNpLAoJCQkJCUxPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBpZmFjZSwgcHNpLCBzaXplKTsKCiAgaWYgKHBzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIG1lbWNweShwc2ksICZUaGlzLT5wYWYtPnNJbmZvLCBtaW4oKERXT1JEKXNpemUsIHNpemVvZihUaGlzLT5wYWYtPnNJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+cGFmLT5zSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVkLDB4JTA4WClcbiIsaWZhY2UscG9zLGZsYWdzKTsKCiAgLyogRG8gd2UgaGF2ZSBkYXRhPyAqLwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIC0xOwoKICAvKiBXZSBkb24ndCBoYXZlIGFuIGluZGV4ICovCiAgaWYgKGZsYWdzICYgRklORF9JTkRFWCkKICAgIHJldHVybiAtMTsKCiAgaWYgKGZsYWdzICYgRklORF9GUk9NX1NUQVJUKSB7CiAgICBwb3MgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgZmxhZ3MgJj0gfihGSU5EX0ZST01fU1RBUlR8RklORF9QUkVWKTsKICAgIGZsYWdzIHw9IEZJTkRfTkVYVDsKICB9CgogIGlmIChmbGFncyAmIEZJTkRfRk9STUFUKSB7CiAgICBpZiAoKGZsYWdzICYgRklORF9ORVhUKSAmJiBwb3MgPiAwKQogICAgICBwb3MgPSAtMTsKICAgIGVsc2UKICAgICAgcG9zID0gMDsKICB9CgogIGlmICgoZmxhZ3MgJiBGSU5EX1JFVCkgPT0gRklORF9MRU5HVEggfHwKICAgICAgKGZsYWdzICYgRklORF9SRVQpID09IEZJTkRfU0laRSkKICAgIHJldHVybiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgaWYgKChmbGFncyAmIEZJTkRfUkVUKSA9PSBGSU5EX09GRlNFVCkKICAgIHJldHVybiBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ICsgcG9zICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwoKICByZXR1cm4gcG9zOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgKmZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVkLCVwLCVwKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKGZvcm1hdHNpemUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIG9ubHkgaW50ZXJlc3RlZCBpbiBuZWVkZWQgYnVmZmVyc2l6ZT8gKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgKmZvcm1hdHNpemUgPD0gMCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5wYWYtPmNiRm9ybWF0OwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBjb3B5IGluaXRpYWwgZm9ybWF0IChvbmx5IGFzIG11Y2ggYXMgd2lsbCBmaXQpICovCiAgbWVtY3B5KGZvcm1hdCwgVGhpcy0+cGFmLT5scEZvcm1hdCwgbWluKCpmb3JtYXRzaXplLCBUaGlzLT5wYWYtPmNiRm9ybWF0KSk7CiAgaWYgKCpmb3JtYXRzaXplIDwgVGhpcy0+cGFmLT5jYkZvcm1hdCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5wYWYtPmNiRm9ybWF0OwogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9CgogICpmb3JtYXRzaXplID0gVGhpcy0+cGFmLT5jYkZvcm1hdDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoKElBVklTdHJlYW1JbXBsKilpZmFjZSktPnBhZjsKCiAgVFJBQ0UoIiglcCwlZCwlcCwlZClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgZm9ybWF0c2l6ZSA8PSBzaXplb2YoUENNV0FWRUZPUk1BVCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBXZSBjYW4gb25seSBkbyB0aGlzIHRvIGFuIGVtcHR5IHdhdmUgZmlsZSwgYnV0IGlnbm9yZSBjYWxsCiAgICogaWYgc3RpbGwgc2FtZSBmb3JtYXQgKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkgewogICAgaWYgKGZvcm1hdHNpemUgIT0gVGhpcy0+Y2JGb3JtYXQgfHwKCW1lbWNtcChmb3JtYXQsIFRoaXMtPmxwRm9ybWF0LCBmb3JtYXRzaXplKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBvbmx5IHN1cHBvcnQgc3RhcnQgYXQgcG9zaXRpb24gMCAqLwogIGlmIChwb3MgIT0gMCkKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBnZXQgbWVtb3J5IGZvciBmb3JtYXQgYW5kIGNvcHkgaXQgKi8KICBUaGlzLT5scEZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBmb3JtYXRzaXplKTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBUaGlzLT5jYkZvcm1hdCA9IGZvcm1hdHNpemU7CiAgbWVtY3B5KFRoaXMtPmxwRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiB1cGRhdGUgaW5mbydzIGFib3V0ICdkYXRhJyBjaHVuayAqLwogIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSBmb3JtYXRzaXplICsgNyAqIHNpemVvZihEV09SRCk7CiAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICA9IDA7CgogIC8qIGZvciBub24tcGNtIGZvcm1hdCB3ZSBuZWVkIGFsc28gYSAnZmFjdCcgY2h1bmsgKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgIT0gV0FWRV9GT1JNQVRfUENNKQogICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArPSAzICogc2l6ZW9mKERXT1JEKTsKCiAgLyogdXBkYXRlIHN0cmVhbSBhbmQgZmlsZSBpbmZvICovCiAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3U2NhbGUgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1JhdGUgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjOwogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gMDsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCUxPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQlMT05HIGJ1ZmZlcnNpemUsIExQTE9ORyBieXRlc3JlYWQsCgkJCQkJTFBMT05HIHNhbXBsZXNyZWFkKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWQsJWQsJXAsJWQsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwKCWJ1ZmZlcnNpemUsIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKCiAgLyogcG9zaXRpb25zIHdpdGhvdXQgZGF0YSAqLwogIGlmIChzdGFydCA8IDAgfHwgKERXT1JEKXN0YXJ0ID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBjaGVjayBzYW1wbGVzICovCiAgaWYgKHNhbXBsZXMgPCAwKQogICAgc2FtcGxlcyA9IDA7CiAgaWYgKGJ1ZmZlcnNpemUgPiAwKSB7CiAgICBpZiAoc2FtcGxlcyA+IDApCiAgICAgIHNhbXBsZXMgPSBtaW4oKERXT1JEKXNhbXBsZXMsIGJ1ZmZlcnNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUpOwogICAgZWxzZQogICAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICB9CgogIC8qIGxpbWl0IHRvIGVuZCBvZiBzdHJlYW0gKi8KICBpZiAoKERXT1JEKShzdGFydCArIHNhbXBsZXMpID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGggLSBzdGFydDsKCiAgLyogcmVxdWVzdCBvbmx5IHRoZSBzaXplcz8gKi8KICBpZiAoYnVmZmVyID09IE5VTEwgfHwgYnVmZmVyc2l6ZSA8PSAwKSB7CiAgICAvKiB0aGVuIEkgbmVlZCBhdCBsZWFzdCBvbmUgcGFyYW1ldGVyIGZvciBpdCAqLwogICAgaWYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSBzYW1wbGVzOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBub3RoaW5nIHRvIHJlYWQ/ICovCiAgaWYgKHNhbXBsZXMgPT0gMCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIENhbiBJIHJlYWQgYXQgbGVhc3Qgb25lIHNhbXBsZT8gKi8KICBpZiAoKERXT1JEKWJ1ZmZlcnNpemUgPCBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwoKICBidWZmZXJzaXplID0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0CgkgICAgICAgKyBzdGFydCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSwgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilidWZmZXIsIGJ1ZmZlcnNpemUpICE9IGJ1ZmZlcnNpemUpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSBidWZmZXJzaXplOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsgIAoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSBMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCQkJIExQTE9ORyBzYW1wd3JpdHRlbiwKCQkJCQkgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVkLCVkLCVwLCVkLDB4JTA4WCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywKCWJ1ZmZlciwgYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgKnNhbXB3cml0dGVuID0gMDsKICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAqYnl0ZXN3cml0dGVuID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCAmJiAoYnVmZmVyc2l6ZSA+IDAgfHwgc2FtcGxlcyA+IDApKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIDwgMCBtZWFucyAiYXBwZW5kIiAqLwogIGlmIChzdGFydCA8IDApCiAgICBzdGFydCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aDsKCiAgLyogY2hlY2sgYnVmZmVyc2l6ZSAtLSBtdXN0IG11bHRpcGxlIG9mIHNhbXBsZXNpemUgKi8KICBpZiAoYnVmZmVyc2l6ZSAmIH4oVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplIC0gMSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIGRvIHdlIGhhdmUgYW55dGhpbmcgdG8gd3JpdGU/ICovCiAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmZlcnNpemUgPiAwKSB7CiAgICBUaGlzLT5mRGlydHkgPSAxOwoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArCgkJIHN0YXJ0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgYnVmZmVyc2l6ZSkgIT0gYnVmZmVyc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSBtYXgoVGhpcy0+c0luZm8uZHdMZW5ndGgsIChEV09SRClzdGFydCArIHNhbXBsZXMpOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgPSBtYXgoVGhpcy0+Y2tEYXRhLmNrc2l6ZSwKCQkJICAgICAgIHN0YXJ0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICsgYnVmZmVyc2l6ZSk7CgogICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgICAqc2FtcHdyaXR0ZW4gPSBzYW1wbGVzOwogICAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgICAqYnl0ZXN3cml0dGVuID0gYnVmZmVyc2l6ZTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSAgTE9ORyBzYW1wbGVzKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWQsJWQpXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN0YXJ0IDwgMCB8fCBzYW1wbGVzIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERlbGV0ZSBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtPyAqLwogIGlmICgoRFdPUkQpKHN0YXJ0ICsgc2FtcGxlcykgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRGVsZXRlIGFmdGVyIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKChEV09SRClzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRm9yIHRoZSByZXN0IHdlIG5lZWQgd3JpdGUgcGVybWlzc2lvbnMgKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBpZiAoKERXT1JEKShzdGFydCArIHNhbXBsZXMpID49IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKSB7CiAgICAvKiBkZWxldGlvbiBhdCBlbmQgKi8KICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aCAtIHN0YXJ0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggLT0gc2FtcGxlczsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgIC09IHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgfSBlbHNlIGlmICgoRFdPUkQpc3RhcnQgPD0gVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgLyogZGVsZXRpb24gYXQgc3RhcnQgKi8KICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd1N0YXJ0IC0gc3RhcnQ7CiAgICBzdGFydCAgID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKz0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgLT0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICB9IGVsc2UgewogICAgLyogZGVsZXRpb24gaW5zaWRlIHN0cmVhbSAtLSBuZWVkcyBwbGF5bGlzdCBhbmQgY3VlJ3MgKi8KICAgIEZJWE1FKCI6IGRlbGV0aW9uIGluc2lkZSBvZiBzdHJlYW0gbm90IHN1cHBvcnRlZCFcbiIpOwoKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfQoKICBUaGlzLT5mRGlydHkgPSAxOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgIExQVk9JRCBscCwgTFBMT05HIGxwcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9SZWFkRGF0YSgoUEFWSUZJTEUpVGhpcy0+cGFmLCBmY2MsIGxwLCBscHJlYWQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICByZXR1cm4gSUFWSUZpbGVfV3JpdGVEYXRhKChQQVZJRklMRSlUaGlzLT5wYWYsIGZjYywgbHAsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJICAgTFBBVklTVFJFQU1JTkZPVyBpbmZvLCBMT05HIGluZm9sZW4pCnsKICBGSVhNRSgiKCVwLCVwLCVkKTogc3R1YlxuIiwgaWZhY2UsIGluZm8sIGluZm9sZW4pOwoKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIE1NQ0tJTkZPIGNrUklGRjsKICBNTUNLSU5GTyBjazsKCiAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSAwOyAvKiBqdXN0IHRvIGJlIHN1cmUgKi8KICBUaGlzLT5mRGlydHkgPSBGQUxTRTsKCiAgLyogc2VhcmNoIGZvciBSSUZGIGNodW5rICovCiAgY2tSSUZGLmZjY1R5cGUgPSAwOyAvKiBmaW5kIGFueSAqLwogIGlmIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrUklGRiwgTlVMTCwgTU1JT19GSU5EUklGRikgIT0gU19PSykgewogICAgcmV0dXJuIEFWSUZJTEVfTG9hZFN1bkZpbGUoVGhpcyk7CiAgfQoKICBpZiAoY2tSSUZGLmZjY1R5cGUgIT0gZm9ybXR5cGVXQVZFKQogICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogIC8qIHNlYXJjaCBXQVZFIGZvcm1hdCBjaHVuayAqLwogIGNrLmNraWQgPSBja2lkV0FWRUZPUk1BVDsKICBpZiAoRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssCgkJCSAgICAgJmNrUklGRiwgTU1JT19GSU5EQ0hVTkspICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBnZXQgbWVtb3J5IGZvciBmb3JtYXQgYW5kIHJlYWQgaXQgKi8KICBUaGlzLT5scEZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjay5ja3NpemUpOwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICBUaGlzLT5jYkZvcm1hdCA9IGNrLmNrc2l6ZTsKCiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpVGhpcy0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogTm9uLXBjbSBmb3JtYXRzIGhhdmUgYSBmYWN0IGNodW5rLgogICAqIFdlIGRvbid0IG5lZWQgaXQsIHNvIHNpbXBseSBhZGQgaXQgdG8gdGhlIGV4dHJhIGNodW5rcy4KICAgKi8KCiAgLyogZmluZCB0aGUgYmlnIGRhdGEgY2h1bmsgKi8KICBUaGlzLT5ja0RhdGEuY2tpZCA9IGNraWRXQVZFREFUQTsKICBpZiAoRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tEYXRhLAoJCQkgICAgICZja1JJRkYsIE1NSU9fRklORENIVU5LKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgbWVtc2V0KCZUaGlzLT5zSW5mbywgMCwgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgVGhpcy0+c0luZm8uZmNjVHlwZSAgICAgID0gc3RyZWFtdHlwZUFVRElPOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWM7CiAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplID0KICAgIFRoaXMtPnNJbmZvLmR3U2NhbGUgICAgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggICAgID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZSAvIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5ja0RhdGEuY2tzaXplOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAxOwoKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJlRoaXMtPmNrRGF0YSwgMCkgIT0gU19PSykgewogICAgLyogc2VlbXMgdG8gYmUgdHJ1bmNhdGVkICovCiAgICBXQVJOKCI6IGZpbGUgc2VlbXMgdG8gYmUgdHJ1bmNhdGVkIVxuIik7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICA9IG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX0VORCkgLQogICAgICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSBUaGlzLT5ja0RhdGEuY2tzaXplIC8gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogICAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKICB9CgogIC8qIGlnbm9yZSBlcnJvcnMgKi8KICBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5leHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrUklGRiwgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZFN1bkZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgU1VOQVVESU9IRUFERVIgYXVoZHI7CgogIG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX1NFVCk7CiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmF1aGRyLCBzaXplb2YoYXVoZHIpKSAhPSBzaXplb2YoYXVoZHIpKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgaWYgKGF1aGRyLmZjY1R5cGUgPT0gMHgwMDY0NzMyRSkgewogICAgLyogaGVhZGVyIGluIGxpdHRsZSBlbmRpYW4gKi8KICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSBMRTJIX0RXT1JEKGF1aGRyLm9mZnNldCk7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgID0gTEUySF9EV09SRChhdWhkci5zaXplKTsKCiAgICBhdWhkci5lbmNvZGluZyAgID0gTEUySF9EV09SRChhdWhkci5lbmNvZGluZyk7CiAgICBhdWhkci5zYW1wbGVSYXRlID0gTEUySF9EV09SRChhdWhkci5zYW1wbGVSYXRlKTsKICAgIGF1aGRyLmNoYW5uZWxzICAgPSBMRTJIX0RXT1JEKGF1aGRyLmNoYW5uZWxzKTsKICB9IGVsc2UgaWYgKGF1aGRyLmZjY1R5cGUgPT0gbW1pb0ZPVVJDQygnLicsJ3MnLCduJywnZCcpKSB7CiAgICAvKiBoZWFkZXIgaW4gYmlnIGVuZGlhbiAqLwogICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IEJFMkhfRFdPUkQoYXVoZHIub2Zmc2V0KTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSBCRTJIX0RXT1JEKGF1aGRyLnNpemUpOwoKICAgIGF1aGRyLmVuY29kaW5nICAgPSBCRTJIX0RXT1JEKGF1aGRyLmVuY29kaW5nKTsKICAgIGF1aGRyLnNhbXBsZVJhdGUgPSBCRTJIX0RXT1JEKGF1aGRyLnNhbXBsZVJhdGUpOwogICAgYXVoZHIuY2hhbm5lbHMgICA9IEJFMkhfRFdPUkQoYXVoZHIuY2hhbm5lbHMpOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgaWYgKGF1aGRyLmNoYW5uZWxzIDwgMSkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBnZXQgc2l6ZSBvZiBoZWFkZXIgKi8KICBzd2l0Y2goYXVoZHIuZW5jb2RpbmcpIHsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjFfMzI6CiAgICBUaGlzLT5jYkZvcm1hdCA9IHNpemVvZihHNzIxX0FEUENNV0FWRUZPUk1BVCk7IGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyM18yNDoKICAgIFRoaXMtPmNiRm9ybWF0ID0gc2l6ZW9mKEc3MjNfQURQQ01XQVZFRk9STUFUKTsgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIyOgogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyM181OgogICAgV0FSTigidW5zdXBwb3J0ZWQgU3VuIGF1ZGlvIGZvcm1hdCAlZFxuIiwgYXVoZHIuZW5jb2RpbmcpOwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogRklYTUUgKi8KICBkZWZhdWx0OgogICAgVGhpcy0+Y2JGb3JtYXQgPSBzaXplb2YoV0FWRUZPUk1BVEVYKTsgYnJlYWs7CiAgfTsKCiAgVGhpcy0+bHBGb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+Y2JGb3JtYXQpOwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIFRoaXMtPmxwRm9ybWF0LT5uQ2hhbm5lbHMgICAgICA9IGF1aGRyLmNoYW5uZWxzOwogIFRoaXMtPmxwRm9ybWF0LT5uU2FtcGxlc1BlclNlYyA9IGF1aGRyLnNhbXBsZVJhdGU7CiAgc3dpdGNoKGF1aGRyLmVuY29kaW5nKSB7CiAgY2FzZSBBVV9FTkNPRElOR19VTEFXXzg6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9NVUxBVzsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDg7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX1BDTV84OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gODsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfUENNXzE2OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gMTY7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX1BDTV8yNDoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX1BDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDI0OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19QQ01fMzI6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSAzMjsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQUxBV184OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfQUxBVzsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDg7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjFfMzI6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9HNzIxX0FEUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gKDMqNSo4KTsKICAgIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbiAgICA9IDE1KjE1Kjg7CiAgICBUaGlzLT5scEZvcm1hdC0+Y2JTaXplICAgICAgICAgPSBzaXplb2YoV09SRCk7CiAgICAoKExQRzcyMV9BRFBDTVdBVkVGT1JNQVQpVGhpcy0+bHBGb3JtYXQpLT5uQXV4QmxvY2tTaXplID0gMDsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyM18yNDoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX0c3MjNfQURQQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSAoMyo1KjgpOwogICAgVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduICAgID0gMTUqMTUqODsKICAgIFRoaXMtPmxwRm9ybWF0LT5jYlNpemUgICAgICAgICA9IDIqc2l6ZW9mKFdPUkQpOwogICAgKChMUEc3MjNfQURQQ01XQVZFRk9STUFUKVRoaXMtPmxwRm9ybWF0KS0+Y2JFeHRyYVNpemUgICA9IDA7CiAgICAoKExQRzcyM19BRFBDTVdBVkVGT1JNQVQpVGhpcy0+bHBGb3JtYXQpLT5uQXV4QmxvY2tTaXplID0gMDsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBXQVJOKCJ1bnN1cHBvcnRlZCBTdW4gYXVkaW8gZm9ybWF0ICVkXG4iLCBhdWhkci5lbmNvZGluZyk7CiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH07CgogIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbiA9CiAgICAoVGhpcy0+bHBGb3JtYXQtPm5DaGFubmVscyAqIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSkgLyA4OwogIGlmIChUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gPT0gMCAmJiBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPCA4KQogICAgVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduKys7CiAgVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYyA9CiAgICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gKiBUaGlzLT5scEZvcm1hdC0+blNhbXBsZXNQZXJTZWM7CgogIFRoaXMtPmZEaXJ0eSA9IDA7CgogIFRoaXMtPnNJbmZvLmZjY1R5cGUgICAgICAgICAgICAgICA9IHN0cmVhbXR5cGVBVURJTzsKICBUaGlzLT5zSW5mby5mY2NIYW5kbGVyICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3RmxhZ3MgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8ud1ByaW9yaXR5ICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby53TGFuZ3VhZ2UgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWM7CiAgVGhpcy0+c0luZm8uZHdTdGFydCAgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPQogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAvIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgICAgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9IDE7CiAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgID0gMTsKICBUaGlzLT5mSW5mby5kd1JhdGUgICAgPSBUaGlzLT5scEZvcm1hdC0+blNhbXBsZXNQZXJTZWM7CiAgVGhpcy0+ZkluZm8uZHdMZW5ndGggID0KICAgIE11bERpdihUaGlzLT5ja0RhdGEuY2tzaXplLCBUaGlzLT5scEZvcm1hdC0+blNhbXBsZXNQZXJTZWMsCgkgICBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShjb25zdCBJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNTUNLSU5GTyBja1JJRkY7CiAgTU1DS0lORk8gY2s7CgogIG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX1NFVCk7CgogIC8qIGNyZWF0ZSB0aGUgUklGRiBjaHVuayB3aXRoIGZvcm10eXBlIFdBVkUgKi8KICBja1JJRkYuZmNjVHlwZSA9IGZvcm10eXBlV0FWRTsKICBja1JJRkYuY2tzaXplICA9IDA7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrUklGRiwgTU1JT19DUkVBVEVSSUZGKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHRoZSBuZXh0IGNodW5rIGlzIHRoZSBmb3JtYXQgKi8KICBjay5ja2lkICAgPSBja2lkV0FWRUZPUk1BVDsKICBjay5ja3NpemUgPSBUaGlzLT5jYkZvcm1hdDsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCAmJiBUaGlzLT5jYkZvcm1hdCA+IDApIHsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilUaGlzLT5scEZvcm1hdCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIGZhY3QgY2h1bmsgaXMgbmVlZGVkIGZvciBub24tcGNtIHdhdmVmb3JtcyAqLwogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMICYmIFRoaXMtPmNiRm9ybWF0ID4gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpICYmCiAgICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkgewogICAgV0FWRUZPUk1BVEVYIHdmeDsKICAgIERXT1JEICAgICAgICBkd0ZhY3RMZW5ndGg7CiAgICBIQUNNU1RSRUFNICAgaGFzOwoKICAgIC8qIHRyeSB0byBvcGVuIGFuIGFwcHJvcHJpYXRlIGF1ZGlvIGNvZGVjIHRvIGZpZ3VyZSBvdXQKICAgICAqIGRhdGEgZm9yIGZhY3QtY2h1bmsgKi8KICAgIHdmeC53Rm9ybWF0VGFnID0gV0FWRV9GT1JNQVRfUENNOwogICAgaWYgKGFjbUZvcm1hdFN1Z2dlc3QoTlVMTCwgVGhpcy0+bHBGb3JtYXQsICZ3ZngsCgkJCSBzaXplb2Yod2Z4KSwgQUNNX0ZPUk1BVFNVR0dFU1RGX1dGT1JNQVRUQUcpKSB7CiAgICAgIGFjbVN0cmVhbU9wZW4oJmhhcywgTlVMTCwgVGhpcy0+bHBGb3JtYXQsICZ3ZngsIE5VTEwsCgkJICAgIDAsIDAsIEFDTV9TVFJFQU1PUEVORl9OT05SRUFMVElNRSk7CiAgICAgIGFjbVN0cmVhbVNpemUoaGFzLCBUaGlzLT5ja0RhdGEuY2tzaXplLCAmZHdGYWN0TGVuZ3RoLAoJCSAgICBBQ01fU1RSRUFNU0laRUZfU09VUkNFKTsKICAgICAgZHdGYWN0TGVuZ3RoIC89IHdmeC5uQmxvY2tBbGlnbjsKICAgICAgYWNtU3RyZWFtQ2xvc2UoaGFzLCAwKTsKCiAgICAgIC8qIGNyZWF0ZSB0aGUgZmFjdCBjaHVuayAqLwogICAgICBjay5ja2lkICAgPSBja2lkV0FWRUZBQ1Q7CiAgICAgIGNrLmNrc2l6ZSA9IHNpemVvZihkd0ZhY3RMZW5ndGgpOwoKICAgICAgLyogdGVzdCBmb3IgZW5vdWdoIHNwYWNlIGJlZm9yZSBkYXRhIGNodW5rICovCiAgICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19DVVIpID4gVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldAoJICAtIGNrLmNrc2l6ZSAtIDQgKiBzaXplb2YoRFdPUkQpKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmR3RmFjdExlbmd0aCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfSBlbHNlCiAgICAgIEVSUigiOiBmYWN0IGNodW5rIGlzIG5lZWRlZCBmb3Igbm9uLXBjbSBmaWxlcyAtLSBjdXJyZW50bHkgbm8gY29kZWMgZm91bmQsIHNvIHNraXBwZWQhXG4iKTsKICB9CgogIC8qIGlmIHRoZXJlIHdhcyBleHRyYSBzdHVmZiwgd2UgbmVlZCB0byBmaWxsIGl0IHdpdGggSlVOSyAqLwogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19DVVIpICsgMiAqIHNpemVvZihEV09SRCkgPCBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0KSB7CiAgICBjay5ja2lkICAgPSBja2lkQVZJUEFERElORzsKICAgIGNrLmNrc2l6ZSA9IDA7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldAoJCSAtIDIgKiBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQoKICAvKiBjcmVhdGUgdGhlIGRhdGEgY2h1bmsgKi8KICBjay5ja2lkICAgPSBja2lkV0FWRURBVEE7CiAgY2suY2tzaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5ja3NpemUsIFNFRUtfQ1VSKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogc29tZSBvcHRpb25hbCBleHRyYSBjaHVua3M/ICovCiAgaWYgKFRoaXMtPmV4dHJhLmxwICE9IE5VTEwgJiYgVGhpcy0+ZXh0cmEuY2IgPiAwKSB7CiAgICAvKiBjaHVuayBoZWFkZXJzIGFyZSBhbHJlYWR5IGluIHN0cnVjdHVyZSAqLwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgVGhpcy0+ZXh0cmEubHAsIFRoaXMtPmV4dHJhLmNiKSAhPSBUaGlzLT5leHRyYS5jYikKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQoKICAvKiBjbG9zZSBSSUZGIGNodW5rICovCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja1JJRkYsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0ZsdXNoKFRoaXMtPmhtbWlvLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIHJldHVybiBBVklFUlJfT0s7Cn0K