LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCiNpbmNsdWRlICJtc2FjbS5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgojaW5jbHVkZSAiZXh0cmFjaHVuay5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2RlZmluZSBmb3JtdHlwZVdBVkUgICAgbW1pb0ZPVVJDQygnVycsJ0EnLCdWJywnRScpCiNkZWZpbmUgY2tpZFdBVkVGT1JNQVQgIG1taW9GT1VSQ0MoJ2YnLCdtJywndCcsJyAnKQojZGVmaW5lIGNraWRXQVZFRkFDVCAgICBtbWlvRk9VUkNDKCdmJywnYScsJ2MnLCd0JykKI2RlZmluZSBja2lkV0FWRURBVEEgICAgbW1pb0ZPVVJDQygnZCcsJ2EnLCd0JywnYScpCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgojZGVmaW5lIEVORElBTl9TV0FQV09SRCh4KSAgKCgoKHgpID4+IDgpICYgMHhGRikgfCAoKCh4KSAmIDB4RkYpIDw8IDgpKQojZGVmaW5lIEVORElBTl9TV0FQRFdPUkQoeCkgKEVORElBTl9TV0FQV09SRCgoeCA+PiAxNikgJiAweEZGRkYpIHwgXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIEVORElBTl9TV0FQV09SRCh4ICYgMHhGRkZGKSA8PCAxNikKCiNpZmRlZiBXT1JEU19CSUdFTkRJQU4KI2RlZmluZSBCRTJIX1dPUkQoeCkgICh4KQojZGVmaW5lIEJFMkhfRFdPUkQoeCkgKHgpCiNkZWZpbmUgTEUySF9XT1JEKHgpICBFTkRJQU5fU1dBUFdPUkQoeCkKI2RlZmluZSBMRTJIX0RXT1JEKHgpIEVORElBTl9TV0FQRFdPUkQoeCkKI2Vsc2UKI2RlZmluZSBCRTJIX1dPUkQoeCkgIEVORElBTl9TV0FQV09SRCh4KQojZGVmaW5lIEJFMkhfRFdPUkQoeCkgRU5ESUFOX1NXQVBEV09SRCh4KQojZGVmaW5lIExFMkhfV09SRCh4KSAgKHgpCiNkZWZpbmUgTEUySF9EV09SRCh4KSAoeCkKI2VuZGlmCgp0eXBlZGVmIHN0cnVjdCB7CiAgRk9VUkNDICBmY2NUeXBlOwogIERXT1JEICAgb2Zmc2V0OwogIERXT1JEICAgc2l6ZTsKICBJTlQgICAgIGVuY29kaW5nOwogIERXT1JEICAgc2FtcGxlUmF0ZTsKICBEV09SRCAgIGNoYW5uZWxzOwp9IFNVTkFVRElPSEVBREVSOwoKI2RlZmluZSBBVV9FTkNPRElOR19VTEFXXzggICAgICAgICAgICAgICAgIDEKI2RlZmluZSBBVV9FTkNPRElOR19QQ01fOCAgICAgICAgICAgICAgICAgIDIKI2RlZmluZSBBVV9FTkNPRElOR19QQ01fMTYgICAgICAgICAgICAgICAgIDMKI2RlZmluZSBBVV9FTkNPRElOR19QQ01fMjQgICAgICAgICAgICAgICAgIDQKI2RlZmluZSBBVV9FTkNPRElOR19QQ01fMzIgICAgICAgICAgICAgICAgIDUKI2RlZmluZSBBVV9FTkNPRElOR19GTE9BVCAgICAgICAgICAgICAgICAgIDYKI2RlZmluZSBBVV9FTkNPRElOR19ET1VCTEUgICAgICAgICAgICAgICAgIDcKI2RlZmluZSBBVV9FTkNPRElOR19BRFBDTV9HNzIxXzMyICAgICAgICAgMjMKI2RlZmluZSBBVV9FTkNPRElOR19BRFBDTV9HNzIyICAgICAgICAgICAgMjQKI2RlZmluZSBBVV9FTkNPRElOR19BRFBDTV9HNzIzXzI0ICAgICAgICAgMjUKI2RlZmluZSBBVV9FTkNPRElOR19BRFBDTV9HNzIzXzUgICAgICAgICAgMjYKI2RlZmluZSBBVV9FTkNPRElOR19BTEFXXzggICAgICAgICAgICAgICAgMjcKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlKiBpZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuQWRkUmVmKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSppZmFjZSxBVklGSUxFSU5GT1cqYWZpLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsQVZJU1RSRUFNSU5GT1cqYXNpKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5SZWFkRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyAqc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKCnN0cnVjdCBJQ09NX1ZUQUJMRShJQVZJRmlsZSkgaXdhdmZ0ID0gewogIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJQVZJRmlsZV9mbkFkZFJlZiwKICBJQVZJRmlsZV9mblJlbGVhc2UsCiAgSUFWSUZpbGVfZm5JbmZvLAogIElBVklGaWxlX2ZuR2V0U3RyZWFtLAogIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtLAogIElBVklGaWxlX2ZuV3JpdGVEYXRhLAogIElBVklGaWxlX2ZuUmVhZERhdGEsCiAgSUFWSUZpbGVfZm5FbmRSZWNvcmQsCiAgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUqaWZhY2UsQ0xTSUQqcENsYXNzSUQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLERXT1JEIGR3TW9kZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlKmlmYWNlLExQT0xFU1RSKnBwc3pGaWxlTmFtZSk7CgpzdHJ1Y3QgSUNPTV9WVEFCTEUoSVBlcnNpc3RGaWxlKSBpd2F2cGZ0ID0gewogIElDT01fTVNWVEFCTEVfQ09NUEFUX0R1bW15UlRUSVZBTFVFCiAgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSVBlcnNpc3RGaWxlX2ZuQWRkUmVmLAogIElQZXJzaXN0RmlsZV9mblJlbGVhc2UsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRCwKICBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5LAogIElQZXJzaXN0RmlsZV9mbkxvYWQsCiAgSVBlcnNpc3RGaWxlX2ZuU2F2ZSwKICBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkLAogIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUKfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0qaWZhY2UsTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSk7CnN0YXRpYyBMT05HICAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExPTkcgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgKmZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsTE9ORyAqYnl0ZXNyZWFkLExPTkcgKnNhbXBsZXNyZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLExPTkcgKnNhbXB3cml0dGVuLExPTkcgKmJ5dGVzd3JpdHRlbik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HICpscHJlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RydWN0IElDT01fVlRBQkxFKElBVklTdHJlYW0pIGl3YXZzdCA9IHsKICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJQVZJU3RyZWFtX2ZuQWRkUmVmLAogIElBVklTdHJlYW1fZm5SZWxlYXNlLAogIElBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUFWSVN0cmVhbV9mbkluZm8sCiAgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUsCiAgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblNldEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuUmVhZCwKICBJQVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUFWSVN0cmVhbV9mbkRlbGV0ZSwKICBJQVZJU3RyZWFtX2ZuUmVhZERhdGEsCiAgSUFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJQVZJU3RyZWFtX2ZuU2V0SW5mbwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklGaWxlSW1wbCBJQVZJRmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSVBlcnNpc3RGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBJQ09NX1ZGSUVMRChJUGVyc2lzdEZpbGUpOwoKICAvKiBJUGVyc2lzdEZpbGUgc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7Cn0gSVBlcnNpc3RGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JQVZJU3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBJQ09NX1ZGSUVMRChJQVZJU3RyZWFtKTsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKfSBJQVZJU3RyZWFtSW1wbDsKCnN0cnVjdCBfSUFWSUZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIElDT01fVkZJRUxEKElBVklGaWxlKTsKICBEV09SRAkJICAgIHJlZjsKCiAgLyogSUFWSUZpbGUsIElBVklTdHJlYW0gc3R1ZmYuLi4gKi8KICBJUGVyc2lzdEZpbGVJbXBsICBpUGVyc2lzdEZpbGU7CiAgSUFWSVN0cmVhbUltcGwgICAgaUFWSVN0cmVhbTsKCiAgQVZJRklMRUlORk9XICAgICAgZkluZm87CiAgQVZJU1RSRUFNSU5GT1cgICAgc0luZm87CgogIExQV0FWRUZPUk1BVEVYICAgIGxwRm9ybWF0OwogIExPTkcgICAgICAgICAgICAgIGNiRm9ybWF0OwoKICBNTUNLSU5GTyAgICAgICAgICBja0RhdGE7CgogIEVYVFJBQ0hVTktTICAgICAgIGV4dHJhOwoKICAvKiBJUGVyc2lzdEZpbGUgc3R1ZmYgLi4uICovCiAgSE1NSU8gICAgICAgICAgICAgaG1taW87CiAgTFBXU1RSICAgICAgICAgICAgc3pGaWxlTmFtZTsKICBVSU5UICAgICAgICAgICAgICB1TW9kZTsKICBCT09MICAgICAgICAgICAgICBmRGlydHk7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZFN1bkZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwoKSFJFU1VMVCBBVklGSUxFX0NyZWF0ZVdBVkZpbGUoUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgSUFWSUZpbGVJbXBsICpwZmlsZTsKICBIUkVTVUxUICAgICAgIGhyOwoKICBhc3NlcnQocmlpZCAhPSBOVUxMICYmIHBwdiAhPSBOVUxMKTsKCiAgKnBwdiA9IE5VTEw7CgogIHBmaWxlID0gKElBVklGaWxlSW1wbCopTG9jYWxBbGxvYyhMUFRSLCBzaXplb2YoSUFWSUZpbGVJbXBsKSk7CiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcGZpbGUtPmxwVnRibCAgICAgICAgICAgICAgICA9ICZpd2F2ZnQ7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5scFZ0YmwgICA9ICZpd2F2cGZ0OwogIHBmaWxlLT5pQVZJU3RyZWFtLmxwVnRibCAgICAgPSAmaXdhdnN0OwogIHBmaWxlLT5yZWYgPSAwOwogIHBmaWxlLT5pUGVyc2lzdEZpbGUucGFmID0gcGZpbGU7CiAgcGZpbGUtPmlBVklTdHJlYW0ucGFmICAgPSBwZmlsZTsKCiAgaHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZSgoSVVua25vd24qKXBmaWxlLCByaWlkLCBwcHYpOwogIGlmIChGQUlMRUQoaHIpKQogICAgTG9jYWxGcmVlKChITE9DQUwpcGZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlICppZmFjZSwgUkVGSUlEIHJlZmlpZCwKCQkJCQkJTFBWT0lEICpvYmopCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgPT0gMSAmJgoJICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklTdHJlYW0sIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aUFWSVN0cmVhbTsKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQoJklJRF9JUGVyc2lzdEZpbGUsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aVBlcnNpc3RGaWxlOwogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXApXG4iLGlmYWNlKTsKCiAgcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5SZWxlYXNlKElBVklGaWxlICppZmFjZSkKewogIElDT01fVEhJUyhJQVZJRmlsZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIGlmICghLS0oVGhpcy0+cmVmKSkgewogICAgaWYgKFRoaXMtPmZEaXJ0eSkgewogICAgICAvKiBuZWVkIHRvIHdyaXRlIGhlYWRlcnMgdG8gZmlsZSAqLwogICAgICBBVklGSUxFX1NhdmVGaWxlKFRoaXMpOwogICAgfQoKICAgIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMKSB7CiAgICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+bHBGb3JtYXQpOwogICAgICBUaGlzLT5scEZvcm1hdCA9IE5VTEw7CiAgICAgIFRoaXMtPmNiRm9ybWF0ID0gMDsKICAgIH0KICAgIGlmIChUaGlzLT5leHRyYS5scCAhPSBOVUxMKSB7CiAgICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+ZXh0cmEubHApOwogICAgICBUaGlzLT5leHRyYS5scCA9IE5VTEw7CiAgICAgIFRoaXMtPmV4dHJhLmNiID0gMDsKICAgIH0KICAgIGlmIChUaGlzLT5zekZpbGVOYW1lICE9IE5VTEwpIHsKICAgICAgTG9jYWxGcmVlKChITE9DQUwpVGhpcy0+c3pGaWxlTmFtZSk7CiAgICAgIFRoaXMtPnN6RmlsZU5hbWUgPSBOVUxMOwogICAgfQogICAgaWYgKFRoaXMtPmhtbWlvICE9IE5VTEwpIHsKICAgICAgbW1pb0Nsb3NlKFRoaXMtPmhtbWlvLCAwKTsKICAgICAgVGhpcy0+aG1taW8gPSBOVUxMOwogICAgfQoKICAgIExvY2FsRnJlZSgoSExPQ0FMKVRoaXMpOwogICAgcmV0dXJuIDA7CiAgfQogIHJldHVybiBUaGlzLT5yZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUgKmlmYWNlLCBMUEFWSUZJTEVJTkZPVyBhZmksCgkJCQkgICAgICBMT05HIHNpemUpCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLGlmYWNlLGFmaSxzaXplKTsKCiAgaWYgKGFmaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIHVwZGF0ZSBmaWxlIGluZm8gKi8KICBUaGlzLT5mSW5mby5kd0ZsYWdzID0gMDsKICBUaGlzLT5mSW5mby5kd0NhcHMgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkgewogICAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3U2NhbGUgIT0gMCk7CgogICAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICAgICAgICAgICAgID0gMTsKICAgIFRoaXMtPmZJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IFRoaXMtPnNJbmZvLmR3U2NhbGU7CiAgICBUaGlzLT5mSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBUaGlzLT5zSW5mby5kd1JhdGU7CiAgICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICAgIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CiAgICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjID0KICAgICAgTXVsRGl2KFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSxUaGlzLT5zSW5mby5kd1JhdGUsVGhpcy0+c0luZm8uZHdTY2FsZSk7CiAgfQoKICBtZW1jcHkoYWZpLCAmVGhpcy0+ZkluZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPmZJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+ZkluZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGF2aXMgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICphdmlzID0gTlVMTDsKCiAgLyogRG9lcyBvdXIgc3RyZWFtIGV4aXN0cz8gKi8KICBpZiAobFBhcmFtICE9IDAgfHwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID09IDApCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsKICBpZiAoZmNjVHlwZSAhPSAwICYmIGZjY1R5cGUgIT0gc3RyZWFtdHlwZUFVRElPKQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CgogICphdmlzID0gKFBBVklTVFJFQU0pJlRoaXMtPmlBVklTdHJlYW07CiAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlICppZmFjZSxQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBpZmFjZSwgYXZpcywgYXNpKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChhdmlzID09IE5VTEwgfHwgYXNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqYXZpcyA9IE5VTEw7CgogIC8qIFdlIG9ubHkgc3VwcG9ydCBvbmUgYXVkaW8gc3RyZWFtICovCiAgaWYgKFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAhPSAwIHx8IFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIGlmIChhc2ktPmZjY1R5cGUgIT0gc3RyZWFtdHlwZUFVRElPKQogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgLyogRG9lcyB0aGUgdXNlciBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+Y2JGb3JtYXQgPSAwOwogIFRoaXMtPmxwRm9ybWF0ID0gTlVMTDsKCiAgbWVtY3B5KCZUaGlzLT5zSW5mbywgYXNpLCBzaXplb2YoVGhpcy0+c0luZm8pKTsKCiAgLyogbWFrZSBzdXJlIHN0cmVhbWluZm8gaWYgb2theSBmb3IgdXMgKi8KICBUaGlzLT5zSW5mby5mY2NIYW5kbGVyICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0ZsYWdzICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0NhcHMgICAgICAgICAgICAgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBUaGlzLT5zSW5mby5kd1N0YXJ0ICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ID0gMDsKICBtZW1zZXQoJlRoaXMtPnNJbmZvLnJjRnJhbWUsIDAsIHNpemVvZihUaGlzLT5zSW5mby5yY0ZyYW1lKSk7CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9IDE7CiAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgID0gVGhpcy0+c0luZm8uZHdTY2FsZTsKICBUaGlzLT5mSW5mby5kd1JhdGUgICAgPSBUaGlzLT5zSW5mby5kd1JhdGU7CiAgVGhpcy0+ZkluZm8uZHdMZW5ndGggID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CgogIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSAwOwogIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSAwOwoKICAqYXZpcyA9IChQQVZJU1RSRUFNKSZUaGlzLT5pQVZJU3RyZWFtOwogIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGNraWQsCgkJCQkJICAgTFBWT0lEIGxwRGF0YSwgTE9ORyBzaXplKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlbGQpXG4iLCBpZmFjZSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscERhdGEgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBEbyB3ZSBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgcmV0dXJuIFdyaXRlRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblJlYWREYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgIExQVk9JRCBscERhdGEsIExPTkcgKnNpemUpCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSAqaWZhY2UpCnsKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIC8qIFRoaXMgaXMgb25seSBuZWVkZWQgZm9yIGludGVybGVhdmVkIGZpbGVzLgogICAqIFdlIGhhdmUgb25seSBvbmUgc3RyZWFtLCB3aGljaCBjYW4ndCBiZSBpbnRlcmxlYXZlZC4KICAgKi8KICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBmY2NUeXBlLAoJCQkJCSAgICAgIExPTkcgbFBhcmFtKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHdlIG91ciBhdWRpbyBzdHJlYW0/ICovCiAgaWYgKGxQYXJhbSAhPSAwIHx8IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyA9PSAwIHx8CiAgICAgIChmY2NUeXBlICE9IDAgJiYgZmNjVHlwZSAhPSBzdHJlYW10eXBlQVVESU8pKQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CgogIC8qIEhhdmUgdXNlciB3cml0ZSBwZXJtaXNzaW9ucz8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBHbG9iYWxGcmVlUHRyKFRoaXMtPmxwRm9ybWF0KTsKICBUaGlzLT5scEZvcm1hdCA9IE5VTEw7CiAgVGhpcy0+Y2JGb3JtYXQgPSAwOwoKICAvKiB1cGRhdGUgaW5mb3MgKi8KICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ID0gMDsKICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgID0gMDsKCiAgVGhpcy0+c0luZm8uZHdTY2FsZSAgID0gMDsKICBUaGlzLT5zSW5mby5kd1JhdGUgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3TGVuZ3RoICA9IDA7CiAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gMDsKCiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zID0gMDsKICBUaGlzLT5mSW5mby5kd0VkaXRDb3VudCsrOwoKICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJICAgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUNPTV9USElTKElQZXJzaXN0RmlsZUltcGwsaWZhY2UpOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKFBBVklGSUxFKVRoaXMtPnBhZiwgcmVmaWlkLCBvYmopOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuQWRkUmVmKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJQ09NX1RISVMoSVBlcnNpc3RGaWxlSW1wbCxpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJQ09NX1RISVMoSVBlcnNpc3RGaWxlSW1wbCxpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9SZWxlYXNlKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQlMUENMU0lEIHBDbGFzc0lEKQp7CiAgVFJBQ0UoIiglcCwlcClcbiIsIGlmYWNlLCBwQ2xhc3NJRCk7CgogIGlmIChwQ2xhc3NJRCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgbWVtY3B5KHBDbGFzc0lELCAmQ0xTSURfV0FWRmlsZSwgc2l6ZW9mKENMU0lEX1dBVkZpbGUpKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbklzRGlydHkoSVBlcnNpc3RGaWxlICppZmFjZSkKewogIElDT01fVEhJUyhJUGVyc2lzdEZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcClcbiIsIGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIChUaGlzLT5wYWYtPmZEaXJ0eSA/IFNfT0sgOiBTX0ZBTFNFKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkxvYWQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSwgRFdPUkQgZHdNb2RlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJUGVyc2lzdEZpbGVJbXBsKilpZmFjZSktPnBhZjsKCiAgV0NIQVIgd3N6U3RyZWFtRm10WzUwXTsKICBJTlQgICBsZW47CgogIFRSQUNFKCIoJXAsJXMsMHglMDhsWClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSwgZHdNb2RlKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBpZiAoVGhpcy0+aG1taW8gIT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIE5vIHJldXNlIG9mIHRoaXMgb2JqZWN0IGZvciBhbm90aGVyIGZpbGUhICovCgogIC8qIHJlbWViZXIgbW9kZSBhbmQgbmFtZSAqLwogIFRoaXMtPnVNb2RlID0gZHdNb2RlOwoKICBsZW4gPSBsc3RybGVuVyhwc3pGaWxlTmFtZSkgKyAxOwogIFRoaXMtPnN6RmlsZU5hbWUgPSAoTFBXU1RSKUxvY2FsQWxsb2MoTFBUUiwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKFRoaXMtPnN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIGxzdHJjcHlXKFRoaXMtPnN6RmlsZU5hbWUsIHBzekZpbGVOYW1lKTsKCiAgLyogdHJ5IHRvIG9wZW4gdGhlIGZpbGUgKi8KICBUaGlzLT5obW1pbyA9IG1taW9PcGVuVyhUaGlzLT5zekZpbGVOYW1lLCBOVUxMLCBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICBpZiAoVGhpcy0+aG1taW8gPT0gTlVMTCkgewogICAgLyogbW1pb09wZW5XIG5vdCBpbiBuYXRpdmUgRExMcyBvZiBXaW45eCAtLSB0cnkgbW1pb09wZW5BICovCiAgICBMUFNUUiBzekZpbGVOYW1lID0gTG9jYWxBbGxvYyhMUFRSLCBsZW4gKiBzaXplb2YoQ0hBUikpOwogICAgaWYgKHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnN6RmlsZU5hbWUsIC0xLCBzekZpbGVOYW1lLAoJCQlsZW4sIE5VTEwsIE5VTEwpOwoKICAgIFRoaXMtPmhtbWlvID0gbW1pb09wZW5BKHN6RmlsZU5hbWUsIE5VTEwsIE1NSU9fQUxMT0NCVUYgfCBkd01vZGUpOwogICAgTG9jYWxGcmVlKChITE9DQUwpc3pGaWxlTmFtZSk7CiAgICBpZiAoVGhpcy0+aG1taW8gPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFT1BFTjsKICB9CgogIG1lbXNldCgmIFRoaXMtPmZJbmZvLCAwLCBzaXplb2YoVGhpcy0+ZkluZm8pKTsKICBtZW1zZXQoJiBUaGlzLT5zSW5mbywgMCwgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CgogIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1dBVkVGSUxFVFlQRSwgVGhpcy0+ZkluZm8uc3pGaWxlVHlwZSwKCSAgICAgIHNpemVvZihUaGlzLT5mSW5mby5zekZpbGVUeXBlKSk7CiAgaWYgKExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1dBVkVTVFJFQU1GT1JNQVQsCgkJICB3c3pTdHJlYW1GbXQsIHNpemVvZih3c3pTdHJlYW1GbXQpKSA+IDApIHsKICAgIHdzcHJpbnRmVyhUaGlzLT5zSW5mby5zek5hbWUsIHdzelN0cmVhbUZtdCwKCSAgICAgIEFWSUZJTEVfQmFzZW5hbWVXKFRoaXMtPnN6RmlsZU5hbWUpKTsKICB9CgogIC8qIHNob3VsZCB3ZSBjcmVhdGUgYSBuZXcgZmlsZT8gKi8KICBpZiAoZHdNb2RlICYgT0ZfQ1JFQVRFKSB7CiAgICAvKiBub3RoaW5nIG1vcmUgdG8gZG8gKi8KICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gQVZJRklMRV9Mb2FkRmlsZShUaGlzKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSxCT09MIGZSZW1lbWJlcikKewogIFRSQUNFKCIoJXAsJXMsJWQpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGZSZW1lbWJlcik7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCSAgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSkKewogIFRSQUNFKCIoJXAsJXMpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSkpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQlMUE9MRVNUUiAqcHBzekZpbGVOYW1lKQp7CiAgSUNPTV9USElTKElQZXJzaXN0RmlsZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBwc3pGaWxlTmFtZSk7CgogIGlmIChwcHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcHN6RmlsZU5hbWUgPSBOVUxMOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICBpZiAoVGhpcy0+cGFmLT5zekZpbGVOYW1lICE9IE5VTEwpIHsKICAgIGludCBsZW4gPSBsc3RybGVuVyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUpOwoKICAgICpwcHN6RmlsZU5hbWUgPSAoTFBPTEVTVFIpR2xvYmFsQWxsb2NQdHIoR0hORCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoKnBwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBtZW1jcHkoKnBwc3pGaWxlTmFtZSwgVGhpcy0+cGFmLT5zekZpbGVOYW1lLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKFBBVklGSUxFKVRoaXMtPnBhZiwgcmVmaWlkLCBvYmopOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSAqaWZhY2UpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfQWRkUmVmKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0gKmlmYWNlLCBMUEFSQU0gbFBhcmFtMSwKCQkJCQkgIExQQVJBTSBsUGFyYW0yKQp7CiAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgpXG4iLCBpZmFjZSwgbFBhcmFtMSwgbFBhcmFtMik7CgogIC8qIFRoaXMgSUFWSVN0cmVhbSBpbnRlcmZhY2UgbmVlZHMgYW4gV0FWRmlsZSAqLwogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVwLCVsZClcbiIsIGlmYWNlLCBwc2ksIHNpemUpOwoKICBpZiAocHNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgbWVtY3B5KHBzaSwgJlRoaXMtPnBhZi0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnBhZi0+c0luZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5wYWYtPnNJbmZvKSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIExPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICBMT05HIGZsYWdzKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWxkLDB4JTA4bFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIC8qIERvIHdlIGhhdmUgZGF0YT8gKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiAtMTsKCiAgLyogV2UgZG9uJ3QgaGF2ZSBhbiBpbmRleCAqLwogIGlmIChmbGFncyAmIEZJTkRfSU5ERVgpCiAgICByZXR1cm4gLTE7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgewogICAgaWYgKChmbGFncyAmIEZJTkRfTkVYVCkgJiYgcG9zID4gMCkKICAgICAgcG9zID0gLTE7CiAgICBlbHNlCiAgICAgIHBvcyA9IDA7CiAgfQoKICBpZiAoKGZsYWdzICYgRklORF9SRVQpID09IEZJTkRfTEVOR1RIIHx8CiAgICAgIChmbGFncyAmIEZJTkRfUkVUKSA9PSBGSU5EX1NJWkUpCiAgICByZXR1cm4gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogIGlmICgoZmxhZ3MgJiBGSU5EX1JFVCkgPT0gRklORF9PRkZTRVQpCiAgICByZXR1cm4gVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArIHBvcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgcmV0dXJuIHBvczsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgICBMUFZPSUQgZm9ybWF0LCBMT05HICpmb3JtYXRzaXplKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwlbGQsJXAsJXApXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICBpZiAoZm9ybWF0c2l6ZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogb25seSBpbnRlcmVzdGVkIGluIG5lZWRlZCBidWZmZXJzaXplPyAqLwogIGlmIChmb3JtYXQgPT0gTlVMTCB8fCAqZm9ybWF0c2l6ZSA8PSAwKSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPnBhZi0+Y2JGb3JtYXQ7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIGNvcHkgaW5pdGlhbCBmb3JtYXQgKG9ubHkgYXMgbXVjaCBhcyB3aWxsIGZpdCkgKi8KICBtZW1jcHkoZm9ybWF0LCBUaGlzLT5wYWYtPmxwRm9ybWF0LCBtaW4oKmZvcm1hdHNpemUsIFRoaXMtPnBhZi0+Y2JGb3JtYXQpKTsKICBpZiAoKmZvcm1hdHNpemUgPCBUaGlzLT5wYWYtPmNiRm9ybWF0KSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPnBhZi0+Y2JGb3JtYXQ7CiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0KCiAgKmZvcm1hdHNpemUgPSBUaGlzLT5wYWYtPmNiRm9ybWF0OwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgZm9ybWF0c2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlbGQpXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8IGZvcm1hdHNpemUgPD0gc2l6ZW9mKFBDTVdBVkVGT1JNQVQpKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogV2UgY2FuIG9ubHkgZG8gdGhpcyB0byBhbiBlbXB0eSB3YXZlIGZpbGUsIGJ1dCBpZ25vcmUgY2FsbAogICAqIGlmIHN0aWxsIHNhbWUgZm9ybWF0ICovCiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwpIHsKICAgIGlmIChmb3JtYXRzaXplICE9IFRoaXMtPmNiRm9ybWF0IHx8CgltZW1jbXAoZm9ybWF0LCBUaGlzLT5scEZvcm1hdCwgZm9ybWF0c2l6ZSkgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogb25seSBzdXBwb3J0IHN0YXJ0IGF0IHBvc2l0aW9uIDAgKi8KICBpZiAocG9zICE9IDApCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBEbyB3ZSBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogZ2V0IG1lbW9yeSBmb3IgZm9ybWF0IGFuZCBjb3B5IGl0ICovCiAgVGhpcy0+bHBGb3JtYXQgPSAoTFBXQVZFRk9STUFURVgpR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgZm9ybWF0c2l6ZSk7CiAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgVGhpcy0+Y2JGb3JtYXQgPSBmb3JtYXRzaXplOwogIG1lbWNweShUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgLyogdXBkYXRlIGluZm8ncyBhYm91dCAnZGF0YScgY2h1bmsgKi8KICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0ID0gZm9ybWF0c2l6ZSArIDcgKiBzaXplb2YoRFdPUkQpOwogIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSAwOwoKICAvKiBmb3Igbm9uLXBjbSBmb3JtYXQgd2UgbmVlZCBhbHNvIGEgJ2ZhY3QnIGNodW5rICovCiAgaWYgKFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICE9IFdBVkVfRk9STUFUX1BDTSkKICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgKz0gMyAqIHNpemVvZihEV09SRCk7CgogIC8qIHVwZGF0ZSBzdHJlYW0gYW5kIGZpbGUgaW5mbyAqLwogIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1NjYWxlICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdSYXRlICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYzsKICBUaGlzLT5zSW5mby5kd0xlbmd0aCAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IDA7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQlMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJTE9ORyBidWZmZXJzaXplLCBMUExPTkcgYnl0ZXNyZWFkLAoJCQkJCUxQTE9ORyBzYW1wbGVzcmVhZCkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9ICgoSUFWSVN0cmVhbUltcGwqKWlmYWNlKS0+cGFmOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCglidWZmZXJzaXplLCBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gMDsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9IDA7CgogIC8qIHBvc2l0aW9ucyB3aXRob3V0IGRhdGEgKi8KICBpZiAoc3RhcnQgPCAwIHx8IChEV09SRClzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogY2hlY2sgc2FtcGxlcyAqLwogIGlmIChzYW1wbGVzIDwgMCkKICAgIHNhbXBsZXMgPSAwOwogIGlmIChidWZmZXJzaXplID4gMCkgewogICAgaWYgKHNhbXBsZXMgPiAwKQogICAgICBzYW1wbGVzID0gbWluKChEV09SRClzYW1wbGVzLCBidWZmZXJzaXplIC8gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplKTsKICAgIGVsc2UKICAgICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgfQoKICAvKiBsaW1pdCB0byBlbmQgb2Ygc3RyZWFtICovCiAgaWYgKChEV09SRCkoc3RhcnQgKyBzYW1wbGVzKSA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgc2FtcGxlcyA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gc3RhcnQ7CgogIC8qIHJlcXVlc3Qgb25seSB0aGUgc2l6ZXM/ICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMIHx8IGJ1ZmZlcnNpemUgPD0gMCkgewogICAgLyogdGhlbiBJIG5lZWQgYXRsZWFzdCBvbmUgcGFyYW1ldGVyIGZvciBpdCAqLwogICAgaWYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSBzYW1wbGVzOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBub3RoaW5nIHRvIHJlYWQ/ICovCiAgaWYgKHNhbXBsZXMgPT0gMCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIENhbiBJIGF0bGVhc3QgcmVhZCBvbmUgc2FtcGxlPyAqLwogIGlmICgoRFdPUkQpYnVmZmVyc2l6ZSA8IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CgogIGJ1ZmZlcnNpemUgPSBzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwoKICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQKCSAgICAgICArIHN0YXJ0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplLCBTRUVLX1NFVCkgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgYnVmZmVyc2l6ZSkgIT0gYnVmZmVyc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IGJ1ZmZlcnNpemU7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSBzYW1wbGVzOyAgCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJIExPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQkgTE9ORyBidWZmZXJzaXplLCBEV09SRCBmbGFncywKCQkJCQkgTFBMT05HIHNhbXB3cml0dGVuLAoJCQkJCSBMUExPTkcgYnl0ZXN3cml0dGVuKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywKCWJ1ZmZlciwgYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgKnNhbXB3cml0dGVuID0gMDsKICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAqYnl0ZXN3cml0dGVuID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCAmJiAoYnVmZmVyc2l6ZSA+IDAgfHwgc2FtcGxlcyA+IDApKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogSGF2ZSB3ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIDwgMCBtZWFucyAiYXBwZW5kIiAqLwogIGlmIChzdGFydCA8IDApCiAgICBzdGFydCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aDsKCiAgLyogY2hlY2sgYnVmZmVyc2l6ZSAtLSBtdXN0IG11bHRpcGxlIG9mIHNhbXBsZXNpemUgKi8KICBpZiAoYnVmZmVyc2l6ZSAmIH4oVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplIC0gMSkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIGhhdmUgd2UgYW55dGhpbmcgdG8gd3JpdGU/ICovCiAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmZlcnNpemUgPiAwKSB7CiAgICBUaGlzLT5mRGlydHkgPSAxOwoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArCgkJIHN0YXJ0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgYnVmZmVyc2l6ZSkgIT0gYnVmZmVyc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSBtYXgoVGhpcy0+c0luZm8uZHdMZW5ndGgsIChEV09SRClzdGFydCArIHNhbXBsZXMpOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgPSBtYXgoVGhpcy0+Y2tEYXRhLmNrc2l6ZSwKCQkJICAgICAgIHN0YXJ0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICsgYnVmZmVyc2l6ZSk7CgogICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgICAqc2FtcHdyaXR0ZW4gPSBzYW1wbGVzOwogICAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgICAqYnl0ZXN3cml0dGVuID0gYnVmZmVyc2l6ZTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSAgTE9ORyBzYW1wbGVzKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKChJQVZJU3RyZWFtSW1wbCopaWZhY2UpLT5wYWY7CgogIFRSQUNFKCIoJXAsJWxkLCVsZClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3RhcnQgPCAwIHx8IHNhbXBsZXMgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRGVsZXRlIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0/ICovCiAgaWYgKChEV09SRCkoc3RhcnQgKyBzYW1wbGVzKSA8IFRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBEZWxldGUgYWZ0ZXIgZW5kIG9mIHN0cmVhbT8gKi8KICBpZiAoKERXT1JEKXN0YXJ0ID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBGb3IgdGhlIHJlc3Qgd2UgbmVlZCB3cml0ZSBwZXJtaXNzaW9ucyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIGlmICgoRFdPUkQpKHN0YXJ0ICsgc2FtcGxlcykgPj0gVGhpcy0+c0luZm8uZHdMZW5ndGgpIHsKICAgIC8qIGRlbGV0aW9uIGF0IGVuZCAqLwogICAgc2FtcGxlcyA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gc3RhcnQ7CiAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCAtPSBzYW1wbGVzOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgLT0gc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICB9IGVsc2UgaWYgKChEV09SRClzdGFydCA8PSBUaGlzLT5zSW5mby5kd1N0YXJ0KSB7CiAgICAvKiBkZWxldGlvbiBhdCBzdGFydCAqLwogICAgc2FtcGxlcyA9IFRoaXMtPnNJbmZvLmR3U3RhcnQgLSBzdGFydDsKICAgIHN0YXJ0ICAgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCArPSBzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgVGhpcy0+Y2tEYXRhLmNrc2l6ZSAgICAgICAtPSBzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogIH0gZWxzZSB7CiAgICAvKiBkZWxldGlvbiBpbnNpZGUgc3RyZWFtIC0tIG5lZWRzIHBsYXlsaXN0IGFuZCBjdWUncyAqLwogICAgRklYTUUoIjogZGVsZXRpb24gaW5zaWRlIG9mIHN0cmVhbSBub3Qgc3VwcG9ydGVkIVxuIik7CgogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIFRoaXMtPmZEaXJ0eSA9IDE7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgTFBWT0lEIGxwLCBMUExPTkcgbHByZWFkKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlYWREYXRhKChQQVZJRklMRSlUaGlzLT5wYWYsIGZjYywgbHAsIGxwcmVhZCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgICBMUFZPSUQgbHAsIExPTkcgc2l6ZSkKewogIElDT01fVEhJUyhJQVZJU3RyZWFtSW1wbCxpZmFjZSk7CgogIHJldHVybiBJQVZJRmlsZV9Xcml0ZURhdGEoKFBBVklGSUxFKVRoaXMtPnBhZiwgZmNjLCBscCwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkgICBMUEFWSVNUUkVBTUlORk9XIGluZm8sIExPTkcgaW5mb2xlbikKewogIEZJWE1FKCIoJXAsJXAsJWxkKTogc3R1YlxuIiwgaWZhY2UsIGluZm8sIGluZm9sZW4pOwoKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIE1NQ0tJTkZPIGNrUklGRjsKICBNTUNLSU5GTyBjazsKCiAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSAwOyAvKiBqdXN0IHRvIGJlIHN1cmUgKi8KICBUaGlzLT5mRGlydHkgPSBGQUxTRTsKCiAgLyogc2VhcmNoIGZvciBSSUZGIGNodW5rICovCiAgY2tSSUZGLmZjY1R5cGUgPSAwOyAvKiBmaW5kIGFueSAqLwogIGlmIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrUklGRiwgTlVMTCwgTU1JT19GSU5EUklGRikgIT0gU19PSykgewogICAgcmV0dXJuIEFWSUZJTEVfTG9hZFN1bkZpbGUoVGhpcyk7CiAgfQoKICBpZiAoY2tSSUZGLmZjY1R5cGUgIT0gZm9ybXR5cGVXQVZFKQogICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogIC8qIHNlYXJjaCBXQVZFIGZvcm1hdCBjaHVuayAqLwogIGNrLmNraWQgPSBja2lkV0FWRUZPUk1BVDsKICBpZiAoRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssCgkJCSAgICAgJmNrUklGRiwgTU1JT19GSU5EQ0hVTkspICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBnZXQgbWVtb3J5IGZvciBmb3JtYXQgYW5kIHJlYWQgaXQgKi8KICBUaGlzLT5scEZvcm1hdCA9IChMUFdBVkVGT1JNQVRFWClHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBjay5ja3NpemUpOwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICBUaGlzLT5jYkZvcm1hdCA9IGNrLmNrc2l6ZTsKCiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpVGhpcy0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogTm9uLXBjbSBmb3JtYXRzIGhhdmUgYSBmYWN0IGNodW5rLgogICAqIFdlIGRvbid0IG5lZWQgaXQsIHNvIHNpbXBseSBhZGQgaXQgdG8gdGhlIGV4dHJhIGNodW5rcy4KICAgKi8KCiAgLyogZmluZCB0aGUgYmlnIGRhdGEgY2h1bmsgKi8KICBUaGlzLT5ja0RhdGEuY2tpZCA9IGNraWRXQVZFREFUQTsKICBpZiAoRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tEYXRhLAoJCQkgICAgICZja1JJRkYsIE1NSU9fRklORENIVU5LKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgbWVtc2V0KCZUaGlzLT5zSW5mbywgMCwgc2l6ZW9mKFRoaXMtPnNJbmZvKSk7CiAgVGhpcy0+c0luZm8uZmNjVHlwZSAgICAgID0gc3RyZWFtdHlwZUFVRElPOwogIFRoaXMtPnNJbmZvLmR3UmF0ZSAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWM7CiAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplID0KICAgIFRoaXMtPnNJbmZvLmR3U2NhbGUgICAgPSBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggICAgID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZSAvIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5ja0RhdGEuY2tzaXplOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAxOwoKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJlRoaXMtPmNrRGF0YSwgMCkgIT0gU19PSykgewogICAgLyogc2VlbXMgdG8gYmUgdHJ1bmNhdGVkICovCiAgICBXQVJOKCI6IGZpbGUgc2VlbXMgdG8gYmUgdHJ1bmNhdGVkIVxuIik7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICA9IG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX0VORCkgLQogICAgICBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0OwogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSBUaGlzLT5ja0RhdGEuY2tzaXplIC8gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwogICAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tEYXRhLmNrc2l6ZTsKICB9CgogIC8qIGlnbm9yZSBlcnJvcnMgKi8KICBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5leHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrUklGRiwgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZFN1bkZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgU1VOQVVESU9IRUFERVIgYXVoZHI7CgogIG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX1NFVCk7CiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmF1aGRyLCBzaXplb2YoYXVoZHIpKSAhPSBzaXplb2YoYXVoZHIpKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgaWYgKGF1aGRyLmZjY1R5cGUgPT0gMHgwMDY0NzMyRSkgewogICAgLyogaGVhZGVyIGluIGxpdHRsZSBlbmRpYW4gKi8KICAgIFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQgPSBMRTJIX0RXT1JEKGF1aGRyLm9mZnNldCk7CiAgICBUaGlzLT5ja0RhdGEuY2tzaXplICAgICAgID0gTEUySF9EV09SRChhdWhkci5zaXplKTsKCiAgICBhdWhkci5lbmNvZGluZyAgID0gTEUySF9EV09SRChhdWhkci5lbmNvZGluZyk7CiAgICBhdWhkci5zYW1wbGVSYXRlID0gTEUySF9EV09SRChhdWhkci5zYW1wbGVSYXRlKTsKICAgIGF1aGRyLmNoYW5uZWxzICAgPSBMRTJIX0RXT1JEKGF1aGRyLmNoYW5uZWxzKTsKICB9IGVsc2UgaWYgKGF1aGRyLmZjY1R5cGUgPT0gbW1pb0ZPVVJDQygnLicsJ3MnLCduJywnZCcpKSB7CiAgICAvKiBoZWFkZXIgaW4gYmlnIGVuZGlhbiAqLwogICAgVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldCA9IEJFMkhfRFdPUkQoYXVoZHIub2Zmc2V0KTsKICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgICAgICAgPSBCRTJIX0RXT1JEKGF1aGRyLnNpemUpOwoKICAgIGF1aGRyLmVuY29kaW5nICAgPSBCRTJIX0RXT1JEKGF1aGRyLmVuY29kaW5nKTsKICAgIGF1aGRyLnNhbXBsZVJhdGUgPSBCRTJIX0RXT1JEKGF1aGRyLnNhbXBsZVJhdGUpOwogICAgYXVoZHIuY2hhbm5lbHMgICA9IEJFMkhfRFdPUkQoYXVoZHIuY2hhbm5lbHMpOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgaWYgKGF1aGRyLmNoYW5uZWxzIDwgMSkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBnZXQgc2l6ZSBvZiBoZWFkZXIgKi8KICBzd2l0Y2goYXVoZHIuZW5jb2RpbmcpIHsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjFfMzI6CiAgICBUaGlzLT5jYkZvcm1hdCA9IHNpemVvZihHNzIxX0FEUENNV0FWRUZPUk1BVCk7IGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyM18yNDoKICAgIFRoaXMtPmNiRm9ybWF0ID0gc2l6ZW9mKEc3MjNfQURQQ01XQVZFRk9STUFUKTsgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIyOgogIGNhc2UgQVVfRU5DT0RJTkdfQURQQ01fRzcyM181OgogICAgV0FSTigidW5zdXBwb3J0ZWQgU3VuIGF1ZGlvIGZvcm1hdCAlZFxuIiwgYXVoZHIuZW5jb2RpbmcpOwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogRklYTUUgKi8KICBkZWZhdWx0OgogICAgVGhpcy0+Y2JGb3JtYXQgPSBzaXplb2YoV0FWRUZPUk1BVEVYKTsgYnJlYWs7CiAgfTsKCiAgVGhpcy0+bHBGb3JtYXQgPQogICAgKExQV0FWRUZPUk1BVEVYKUdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIFRoaXMtPmNiRm9ybWF0KTsKICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBUaGlzLT5scEZvcm1hdC0+bkNoYW5uZWxzICAgICAgPSBhdWhkci5jaGFubmVsczsKICBUaGlzLT5scEZvcm1hdC0+blNhbXBsZXNQZXJTZWMgPSBhdWhkci5zYW1wbGVSYXRlOwogIHN3aXRjaChhdWhkci5lbmNvZGluZykgewogIGNhc2UgQVVfRU5DT0RJTkdfVUxBV184OgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfTVVMQVc7CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSA4OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19QQ01fODoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX1BDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDg7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX1BDTV8xNjoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX1BDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9IDE2OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19QQ01fMjQ6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9QQ007CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSAyNDsKICAgIGJyZWFrOwogIGNhc2UgQVVfRU5DT0RJTkdfUENNXzMyOgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gMzI7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FMQVdfODoKICAgIFRoaXMtPmxwRm9ybWF0LT53Rm9ybWF0VGFnICAgICA9IFdBVkVfRk9STUFUX0FMQVc7CiAgICBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUgPSA4OwogICAgYnJlYWs7CiAgY2FzZSBBVV9FTkNPRElOR19BRFBDTV9HNzIxXzMyOgogICAgVGhpcy0+bHBGb3JtYXQtPndGb3JtYXRUYWcgICAgID0gV0FWRV9GT1JNQVRfRzcyMV9BRFBDTTsKICAgIFRoaXMtPmxwRm9ybWF0LT53Qml0c1BlclNhbXBsZSA9ICgzKjUqOCk7CiAgICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gICAgPSAxNSoxNSo4OwogICAgVGhpcy0+bHBGb3JtYXQtPmNiU2l6ZSAgICAgICAgID0gc2l6ZW9mKFdPUkQpOwogICAgKChMUEc3MjFfQURQQ01XQVZFRk9STUFUKVRoaXMtPmxwRm9ybWF0KS0+bkF1eEJsb2NrU2l6ZSA9IDA7CiAgICBicmVhazsKICBjYXNlIEFVX0VOQ09ESU5HX0FEUENNX0c3MjNfMjQ6CiAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAgICAgPSBXQVZFX0ZPUk1BVF9HNzIzX0FEUENNOwogICAgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlID0gKDMqNSo4KTsKICAgIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbiAgICA9IDE1KjE1Kjg7CiAgICBUaGlzLT5scEZvcm1hdC0+Y2JTaXplICAgICAgICAgPSAyKnNpemVvZihXT1JEKTsKICAgICgoTFBHNzIzX0FEUENNV0FWRUZPUk1BVClUaGlzLT5scEZvcm1hdCktPmNiRXh0cmFTaXplICAgPSAwOwogICAgKChMUEc3MjNfQURQQ01XQVZFRk9STUFUKVRoaXMtPmxwRm9ybWF0KS0+bkF1eEJsb2NrU2l6ZSA9IDA7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgV0FSTigidW5zdXBwb3J0ZWQgU3VuIGF1ZGlvIGZvcm1hdCAlZFxuIiwgYXVoZHIuZW5jb2RpbmcpOwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9OwoKICBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ24gPQogICAgKFRoaXMtPmxwRm9ybWF0LT5uQ2hhbm5lbHMgKiBUaGlzLT5scEZvcm1hdC0+d0JpdHNQZXJTYW1wbGUpIC8gODsKICBpZiAoVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduID09IDAgJiYgVGhpcy0+bHBGb3JtYXQtPndCaXRzUGVyU2FtcGxlIDwgOCkKICAgIFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbisrOwogIFRoaXMtPmxwRm9ybWF0LT5uQXZnQnl0ZXNQZXJTZWMgPQogICAgVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduICogVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjOwoKICBUaGlzLT5mRGlydHkgPSAwOwoKICBUaGlzLT5zSW5mby5mY2NUeXBlICAgICAgICAgICAgICAgPSBzdHJlYW10eXBlQVVESU87CiAgVGhpcy0+c0luZm8uZmNjSGFuZGxlciAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0ZsYWdzICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLndQcmlvcml0eSAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8ud0xhbmd1YWdlICAgICAgICAgICAgID0gMDsKICBUaGlzLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgICAgICAgPSAwOwogIFRoaXMtPnNJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IFRoaXMtPmxwRm9ybWF0LT5uQmxvY2tBbGlnbjsKICBUaGlzLT5zSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBUaGlzLT5scEZvcm1hdC0+bkF2Z0J5dGVzUGVyU2VjOwogIFRoaXMtPnNJbmZvLmR3U3RhcnQgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+c0luZm8uZHdMZW5ndGggICAgICAgICAgICAgID0KICAgIFRoaXMtPmNrRGF0YS5ja3NpemUgLyBUaGlzLT5scEZvcm1hdC0+bkJsb2NrQWxpZ247CiAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICAgICAgICAgID0gVGhpcy0+bHBGb3JtYXQtPm5CbG9ja0FsaWduOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMgPSAxOwogIFRoaXMtPmZJbmZvLmR3U2NhbGUgICA9IDE7CiAgVGhpcy0+ZkluZm8uZHdSYXRlICAgID0gVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjOwogIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICA9CiAgICBNdWxEaXYoVGhpcy0+Y2tEYXRhLmNrc2l6ZSwgVGhpcy0+bHBGb3JtYXQtPm5TYW1wbGVzUGVyU2VjLAoJICAgVGhpcy0+bHBGb3JtYXQtPm5BdmdCeXRlc1BlclNlYyk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgTU1DS0lORk8gY2tSSUZGOwogIE1NQ0tJTkZPIGNrOwoKICBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19TRVQpOwoKICAvKiBjcmVhdGUgdGhlIFJJRkYgY2h1bmsgd2l0aCBmb3JtdHlwZSBXQVZFICovCiAgY2tSSUZGLmZjY1R5cGUgPSBmb3JtdHlwZVdBVkU7CiAgY2tSSUZGLmNrc2l6ZSAgPSAwOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja1JJRkYsIE1NSU9fQ1JFQVRFUklGRikgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiB0aGUgbmV4dCBjaHVuayBpcyB0aGUgZm9ybWF0ICovCiAgY2suY2tpZCAgID0gY2tpZFdBVkVGT1JNQVQ7CiAgY2suY2tzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwgJiYgVGhpcy0+Y2JGb3JtYXQgPiAwKSB7CiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpVGhpcy0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBmYWN0IGNodW5rIGlzIG5lZWRlZCBmb3Igbm9uLXBjbSB3YXZlZm9ybXMgKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCAmJiBUaGlzLT5jYkZvcm1hdCA+IHNpemVvZihQQ01XQVZFRk9STUFUKSAmJgogICAgICBUaGlzLT5scEZvcm1hdC0+d0Zvcm1hdFRhZyAhPSBXQVZFX0ZPUk1BVF9QQ00pIHsKICAgIFdBVkVGT1JNQVRFWCB3Zng7CiAgICBEV09SRCAgICAgICAgZHdGYWN0TGVuZ3RoOwogICAgSEFDTVNUUkVBTSAgIGhhczsKCiAgICAvKiB0cnkgdG8gb3BlbiBhbiBhcHByb3ByaWF0ZSBhdWRpbyBjb2RlYyB0byBmaWd1cmUgb3V0CiAgICAgKiBkYXRhIGZvciBmYWN0LWNodW5rICovCiAgICB3Zngud0Zvcm1hdFRhZyA9IFdBVkVfRk9STUFUX1BDTTsKICAgIGlmIChhY21Gb3JtYXRTdWdnZXN0KE5VTEwsIFRoaXMtPmxwRm9ybWF0LCAmd2Z4LAoJCQkgc2l6ZW9mKHdmeCksIEFDTV9GT1JNQVRTVUdHRVNURl9XRk9STUFUVEFHKSkgewogICAgICBhY21TdHJlYW1PcGVuKCZoYXMsIE5VTEwsIFRoaXMtPmxwRm9ybWF0LCAmd2Z4LCBOVUxMLAoJCSAgICAwLCAwLCBBQ01fU1RSRUFNT1BFTkZfTk9OUkVBTFRJTUUpOwogICAgICBhY21TdHJlYW1TaXplKGhhcywgVGhpcy0+Y2tEYXRhLmNrc2l6ZSwgJmR3RmFjdExlbmd0aCwKCQkgICAgQUNNX1NUUkVBTVNJWkVGX1NPVVJDRSk7CiAgICAgIGR3RmFjdExlbmd0aCAvPSB3ZngubkJsb2NrQWxpZ247CiAgICAgIGFjbVN0cmVhbUNsb3NlKGhhcywgMCk7CgogICAgICAvKiBjcmV0ZSB0aGUgZmFjdCBjaHVuayAqLwogICAgICBjay5ja2lkICAgPSBja2lkV0FWRUZBQ1Q7CiAgICAgIGNrLmNrc2l6ZSA9IHNpemVvZihkd0ZhY3RMZW5ndGgpOwoKICAgICAgLyogdGVzdCBmb3IgZW5vdWdoIHNwYWNlIGJlZm9yZSBkYXRhIGNodW5rICovCiAgICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19DVVIpID4gVGhpcy0+Y2tEYXRhLmR3RGF0YU9mZnNldAoJICAtIGNrLmNrc2l6ZSAtIDQgKiBzaXplb2YoRFdPUkQpKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmR3RmFjdExlbmd0aCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfSBlbHNlCiAgICAgIEVSUigiOiBmYWN0IGNodW5rIGlzIG5lZWRlZCBmb3Igbm9uLXBjbSBmaWxlcyAtLSBjdXJyZW50bHkgbm8gY29kZWMgZm91bmQsIHNvIHNraXBwZWQhXG4iKTsKICB9CgogIC8qIGlmIGhlcmUgd2FzIGV4dHJhIHN0dWZmLCB3ZSBuZWVkIHRvIGZpbGwgaXQgd2l0aCBKVU5LICovCiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX0NVUikgKyAyICogc2l6ZW9mKERXT1JEKSA8IFRoaXMtPmNrRGF0YS5kd0RhdGFPZmZzZXQpIHsKICAgIGNrLmNraWQgICA9IGNraWRBVklQQURESU5HOwogICAgY2suY2tzaXplID0gMDsKICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5ja0RhdGEuZHdEYXRhT2Zmc2V0CgkJIC0gMiAqIHNpemVvZihEV09SRCksIFNFRUtfU0VUKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CgogIC8qIGNyZXRlIHRoZSBkYXRhIGNodW5rICovCiAgY2suY2tpZCAgID0gY2tpZFdBVkVEQVRBOwogIGNrLmNrc2l6ZSA9IFRoaXMtPmNrRGF0YS5ja3NpemU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5ja0RhdGEuY2tzaXplLCBTRUVLX0NVUikgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHNvbWUgb3B0aW9uYWwgZXh0cmEgY2h1bmtzPyAqLwogIGlmIChUaGlzLT5leHRyYS5scCAhPSBOVUxMICYmIFRoaXMtPmV4dHJhLmNiID4gMCkgewogICAgLyogY2h1bmsgaGVhZGVycyBhcmUgYWxyZWFkeSBpbiBzdHJ1Y3R1cmUgKi8KICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIFRoaXMtPmV4dHJhLmxwLCBUaGlzLT5leHRyYS5jYikgIT0gVGhpcy0+ZXh0cmEuY2IpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY2xvc2UgUklGRiBjaHVuayAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9GbHVzaChUaGlzLT5obW1pbywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICByZXR1cm4gQVZJRVJSX09LOwp9Cg==