LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgovKiBUT0RPOgogKiAgLSBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSBpcyBtaXNzaW5nIGZvciB0aGUgSUFWSVN0cmVhbUltcGwKICogIC0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGU6IEZJTkRfSU5ERVggaXNuJ3Qgc3VwcG9ydGVkLgogKiAgLSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdDogZm9ybWF0Y2hhbmdlcyBhcmVuJ3QgcmVhZCBpbi4KICogIC0gSUFWSVN0cmVhbV9mbkRlbGV0ZTogYSBzdHViLgogKiAgLSBJQVZJU3RyZWFtX2ZuU2V0SW5mbzogYSBzdHViLgogKiAgLSBtYWtlIHRocmVhZCBzYWZlCiAqCiAqIEtOT1dOIEJ1Z3M6CiAqICAtIG5hdGl2ZSB2ZXJzaW9uIGNhbiBoYW5ndXAgd2hlbiByZWFkaW5nIGEgZmlsZSBnZW5lcmF0ZWQgd2l0aCB0aGlzIERMTC4KICogICAgV2hlbiBpbmRleCBpcyBtaXNzaW5nIGl0IHdvcmtzLCBidXQgaW5kZXggc2VlbXMgdG8gYmUgb2theS4KICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgInZmdy5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgojaW5jbHVkZSAiZXh0cmFjaHVuay5oIgoKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgojaWZuZGVmIElEWF9QRVJfQkxPQ0sKI2RlZmluZSBJRFhfUEVSX0JMT0NLIDI3MzAKI2VuZGlmCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSogaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUZpbGVfZm5SZWxlYXNlKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUqaWZhY2UsQVZJRklMRUlORk9XKmFmaSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLEFWSVNUUkVBTUlORk9XKmFzaSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgKnNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklGaWxlVnRibCBpYXZpZnQgPSB7CiAgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJQVZJRmlsZV9mbkFkZFJlZiwKICBJQVZJRmlsZV9mblJlbGVhc2UsCiAgSUFWSUZpbGVfZm5JbmZvLAogIElBVklGaWxlX2ZuR2V0U3RyZWFtLAogIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtLAogIElBVklGaWxlX2ZuV3JpdGVEYXRhLAogIElBVklGaWxlX2ZuUmVhZERhdGEsCiAgSUFWSUZpbGVfZm5FbmRSZWNvcmQsCiAgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUqaWZhY2UsQ0xTSUQqcENsYXNzSUQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLERXT1JEIGR3TW9kZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlKmlmYWNlLExQT0xFU1RSKnBwc3pGaWxlTmFtZSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElQZXJzaXN0RmlsZVZ0YmwgaXBlcnNpc3RmdCA9IHsKICBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJUGVyc2lzdEZpbGVfZm5BZGRSZWYsCiAgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZSwKICBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lELAogIElQZXJzaXN0RmlsZV9mbklzRGlydHksCiAgSVBlcnNpc3RGaWxlX2ZuTG9hZCwKICBJUGVyc2lzdEZpbGVfZm5TYXZlLAogIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSxMUEFSQU0gbFBhcmFtMSxMUEFSQU0gbFBhcmFtMik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyAqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsTE9ORyAqc2FtcHdyaXR0ZW4sTE9ORyAqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklTdHJlYW1WdGJsIGlhdmlzdCA9IHsKICBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSVN0cmVhbV9mbkFkZFJlZiwKICBJQVZJU3RyZWFtX2ZuUmVsZWFzZSwKICBJQVZJU3RyZWFtX2ZuQ3JlYXRlLAogIElBVklTdHJlYW1fZm5JbmZvLAogIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlLAogIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0LAogIElBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblJlYWQsCiAgSUFWSVN0cmVhbV9mbldyaXRlLAogIElBVklTdHJlYW1fZm5EZWxldGUsCiAgSUFWSVN0cmVhbV9mblJlYWREYXRhLAogIElBVklTdHJlYW1fZm5Xcml0ZURhdGEsCiAgSUFWSVN0cmVhbV9mblNldEluZm8KfTsKCnR5cGVkZWYgc3RydWN0IF9JQVZJRmlsZUltcGwgSUFWSUZpbGVJbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lQZXJzaXN0RmlsZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSVBlcnNpc3RGaWxlVnRibCAqbHBWdGJsOwoKICAvKiBJUGVyc2lzdEZpbGUgc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7Cn0gSVBlcnNpc3RGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JQVZJU3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJU3RyZWFtVnRibCAqbHBWdGJsOwogIExPTkcJCSAgICByZWY7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7CiAgRFdPUkQgICAgICAgICAgICAgblN0cmVhbTsgICAgICAgLyogdGhlIG4tdGggc3RyZWFtIGluIGZpbGUgKi8KICBBVklTVFJFQU1JTkZPVyAgICBzSW5mbzsKCiAgTFBWT0lEICAgICAgICAgICAgbHBGb3JtYXQ7CiAgRFdPUkQgICAgICAgICAgICAgY2JGb3JtYXQ7CgogIExQVk9JRCAgICAgICAgICAgIGxwSGFuZGxlckRhdGE7CiAgRFdPUkQgICAgICAgICAgICAgY2JIYW5kbGVyRGF0YTsKCiAgRVhUUkFDSFVOS1MgICAgICAgZXh0cmE7CgogIExQRFdPUkQgICAgICAgICAgIGxwQnVmZmVyOwogIERXT1JEICAgICAgICAgICAgIGNiQnVmZmVyOyAgICAgICAvKiBzaXplIG9mIGxwQnVmZmVyICovCiAgRFdPUkQgICAgICAgICAgICAgZHdDdXJyZW50RnJhbWU7IC8qIGZyYW1lL2Jsb2NrIGN1cnJlbnRseSBpbiBscEJ1ZmZlciAqLwoKICBMT05HICAgICAgICAgICAgICBsTGFzdEZyYW1lOyAgICAvKiBsYXN0IGNvcnJlY3QgaW5kZXggaW4gaWR4RnJhbWVzICovCiAgQVZJSU5ERVhFTlRSWSAgICAqaWR4RnJhbWVzOwogIERXT1JEICAgICAgICAgICAgIG5JZHhGcmFtZXM7ICAgICAvKiB1cHBlciBpbmRleCBsaW1pdCBvZiBpZHhGcmFtZXMgKi8KICBBVklJTkRFWEVOVFJZICAgICppZHhGbXRDaGFuZ2VzOwogIERXT1JEICAgICAgICAgICAgIG5JZHhGbXRDaGFuZ2VzOyAvKiB1cHBlciBpbmRleCBsaW1pdCBvZiBpZHhGbXRDaGFuZ2VzICovCn0gSUFWSVN0cmVhbUltcGw7CgpzdHJ1Y3QgX0lBVklGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJRmlsZVZ0YmwgICAgICpscFZ0Ymw7CiAgTE9ORwkJICAgIHJlZjsKCiAgLyogSUFWSUZpbGUgc3R1ZmYuLi4gKi8KICBJUGVyc2lzdEZpbGVJbXBsICBpUGVyc2lzdEZpbGU7CgogIEFWSUZJTEVJTkZPVyAgICAgIGZJbmZvOwogIElBVklTdHJlYW1JbXBsICAgKnBwU3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CgogIEVYVFJBQ0hVTktTICAgICAgIGZpbGVleHRyYTsKCiAgRFdPUkQgICAgICAgICAgICAgZHdNb3ZpQ2h1bmtQb3M7ICAvKiBzb21lIHN0dWZmIGZvciBzYXZpbmcgLi4uICovCiAgRFdPUkQgICAgICAgICAgICAgZHdJZHhDaHVua1BvczsKICBEV09SRCAgICAgICAgICAgICBkd05leHRGcmFtZVBvczsKICBEV09SRCAgICAgICAgICAgICBkd0luaXRpYWxGcmFtZXM7CgogIE1NQ0tJTkZPICAgICAgICAgIGNrTGFzdFJlY29yZDsKICBBVklJTkRFWEVOVFJZICAgICppZHhSZWNvcmRzOyAgICAgIC8qIHdvbid0IGJlIHVwZGF0ZWQgd2hpbGUgbG9hZGluZyAqLwogIERXT1JEICAgICAgICAgICAgIG5JZHhSZWNvcmRzOyAgICAgLyogY3VycmVudCBmaWxsIGxldmVsICovCiAgRFdPUkQgICAgICAgICAgICAgY2JJZHhSZWNvcmRzOyAgICAvKiBzaXplIG9mIGlkeFJlY29yZHMgKi8KCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmIC4uLiAqLwogIEhNTUlPICAgICAgICAgICAgIGhtbWlvOwogIExQV1NUUiAgICAgICAgICAgIHN6RmlsZU5hbWU7CiAgVUlOVCAgICAgICAgICAgICAgdU1vZGU7CiAgQk9PTCAgICAgICAgICAgICAgZkRpcnR5Owp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgY2tpZCwgRFdPUkQgc2l6ZSwKCQkJCURXT1JEIG9mZnNldCwgRFdPUkQgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZFJlY29yZChJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgRFdPUkQgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oSUFWSUZpbGVJbXBsICpwYWYsIERXT1JEIG5yLAoJCQkJCSAgY29uc3QgQVZJU1RSRUFNSU5GT1cgKmFzaSk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oSUFWSVN0cmVhbUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEluZGV4KGNvbnN0IElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgc2l6ZSwgRFdPUkQgb2Zmc2V0KTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9QYXJzZUluZGV4KGNvbnN0IElBVklGaWxlSW1wbCAqVGhpcywgQVZJSU5ERVhFTlRSWSAqbHAsCgkJCQkgIExPTkcgY291bnQsIERXT1JEIHBvcywgQk9PTCAqYkFic29sdXRlKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9SZWFkQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIHN0YXJ0LAoJCQkJIExQVk9JRCBidWZmZXIsIExPTkcgc2l6ZSk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soY29uc3QgSUFWSVN0cmVhbUltcGwgKlRoaXMsIExQTE9ORyBwb3MsCgkJCQkgICAgICBMUExPTkcgb2Zmc2V0KTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVJbmRleChjb25zdCBJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgVUxPTkcgICBBVklGSUxFX1NlYXJjaFN0cmVhbShjb25zdCBJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIGZjY1R5cGUsCgkJCQkgICAgTE9ORyBsU2tpcCk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfVXBkYXRlSW5mbyhJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1dyaXRlQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGJsb2NrLAoJCQkJICBGT1VSQ0MgY2tpZCwgRFdPUkQgZmxhZ3MsIExQVk9JRCBidWZmZXIsCgkJCQkgIExPTkcgc2l6ZSk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlQVZJRmlsZShSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICBJQVZJRmlsZUltcGwgKnBmaWxlOwogIEhSRVNVTFQgICAgICAgaHI7CgogIGFzc2VydChyaWlkICE9IE5VTEwgJiYgcHB2ICE9IE5VTEwpOwoKICAqcHB2ID0gTlVMTDsKCiAgcGZpbGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElBVklGaWxlSW1wbCkpOwogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIHBmaWxlLT5scFZ0YmwgPSAmaWF2aWZ0OwogIHBmaWxlLT5yZWYgPSAwOwogIHBmaWxlLT5pUGVyc2lzdEZpbGUubHBWdGJsID0gJmlwZXJzaXN0ZnQ7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5wYWYgPSBwZmlsZTsKCiAgaHIgPSBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgoSUFWSUZpbGUqKXBmaWxlLCByaWlkLCBwcHYpOwogIGlmIChGQUlMRUQoaHIpKQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlICppZmFjZSwgUkVGSUlEIHJlZmlpZCwKCQkJCQkJTFBWT0lEICpvYmopCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSUZpbGUsIHJlZmlpZCkpIHsKICAgICpvYmogPSBpZmFjZTsKICAgIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lQZXJzaXN0RmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pUGVyc2lzdEZpbGU7CiAgICBJQVZJRmlsZV9BZGRSZWYoaWZhY2UpOwoKICAgIHJldHVybiBTX09LOwogIH0KCiAgcmV0dXJuIE9MRV9FX0VOVU1fTk9NT1JFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuQWRkUmVmKElBVklGaWxlICppZmFjZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWRcbiIsIGlmYWNlLCByZWYpOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CiAgVUlOVCBpOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlZFxuIiwgaWZhY2UsIHJlZik7CgogIGlmICghcmVmKSB7CiAgICBpZiAoVGhpcy0+ZkRpcnR5KSB7CiAgICAgIC8qIG5lZWQgdG8gd3JpdGUgaGVhZGVycyB0byBmaWxlICovCiAgICAgIEFWSUZJTEVfU2F2ZUZpbGUoVGhpcyk7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbaV0gIT0gTlVMTCkgewoJaWYgKFRoaXMtPnBwU3RyZWFtc1tpXS0+cmVmICE9IDApIHsKICAgICAgICAgIEVSUigiOiBzb21lb25lIGhhcyBzdGlsbCAldSByZWZlcmVuY2UgdG8gc3RyZWFtICV1ICglcCkhXG4iLAoJICAgICAgIFRoaXMtPnBwU3RyZWFtc1tpXS0+cmVmLCBpLCBUaGlzLT5wcFN0cmVhbXNbaV0pOwoJfQoJQVZJRklMRV9EZXN0cnVjdEFWSVN0cmVhbShUaGlzLT5wcFN0cmVhbXNbaV0pOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cHBTdHJlYW1zW2ldKTsKCVRoaXMtPnBwU3RyZWFtc1tpXSA9IE5VTEw7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoVGhpcy0+aWR4UmVjb3JkcyAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmlkeFJlY29yZHMpOwogICAgICBUaGlzLT5pZHhSZWNvcmRzICA9IE5VTEw7CiAgICAgIFRoaXMtPm5JZHhSZWNvcmRzID0gMDsKICAgIH0KCiAgICBpZiAoVGhpcy0+ZmlsZWV4dHJhLmxwICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+ZmlsZWV4dHJhLmxwKTsKICAgICAgVGhpcy0+ZmlsZWV4dHJhLmxwID0gTlVMTDsKICAgICAgVGhpcy0+ZmlsZWV4dHJhLmNiID0gMDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5zekZpbGVOYW1lKTsKICAgIFRoaXMtPnN6RmlsZU5hbWUgPSBOVUxMOwoKICAgIGlmIChUaGlzLT5obW1pbyAhPSBOVUxMKSB7CiAgICAgIG1taW9DbG9zZShUaGlzLT5obW1pbywgMCk7CiAgICAgIFRoaXMtPmhtbWlvID0gTlVMTDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICB9CiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSAqaWZhY2UsIExQQVZJRklMRUlORk9XIGFmaSwKCQkJCSAgICAgIExPTkcgc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsaWZhY2UsYWZpLHNpemUpOwoKICBpZiAoYWZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgQVZJRklMRV9VcGRhdGVJbmZvKFRoaXMpOwoKICBtZW1jcHkoYWZpLCAmVGhpcy0+ZkluZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPmZJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+ZkluZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBVTE9ORyBuU3RyZWFtOwoKICBUUkFDRSgiKCVwLCVwLDB4JTA4WCwlZClcbiIsIGlmYWNlLCBhdmlzLCBmY2NUeXBlLCBsUGFyYW0pOwoKICBpZiAoYXZpcyA9PSBOVUxMIHx8IGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBuU3RyZWFtID0gQVZJRklMRV9TZWFyY2hTdHJlYW0oVGhpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogRG9lcyB0aGUgcmVxdWVzdGVkIHN0cmVhbSBleGlzdD8gKi8KICBpZiAoblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAmJgogICAgICBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0gIT0gTlVMTCkgewogICAgKmF2aXMgPSAoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CiAgICBJQVZJU3RyZWFtX0FkZFJlZigqYXZpcyk7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIFNvcnJ5LCBidXQgdGhlIHNwZWNpZmllZCBzdHJlYW0gZG9lc24ndCBleGlzdCAqLwogIHJldHVybiBBVklFUlJfTk9EQVRBOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgICAgTFBBVklTVFJFQU1JTkZPVyBhc2kpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIERXT1JEIG47CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBpZmFjZSwgYXZpcywgYXNpKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChhdmlzID09IE5VTEwgfHwgYXNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqYXZpcyA9IE5VTEw7CgogIC8qIERvZXMgdGhlIHVzZXIgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIENhbiB3ZSBhZGQgYW5vdGhlciBzdHJlYW0/ICovCiAgbiA9IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsKICBpZiAobiA+PSBNQVhfQVZJU1RSRUFNUyB8fCBUaGlzLT5kd01vdmlDaHVua1BvcyAhPSAwKSB7CiAgICAvKiBhbHJlYWR5IHJlYWNoZWQgbWF4IG5yIG9mIHN0cmVhbXMKICAgICAqIG9yIGhhdmUgYWxyZWFkeSB3cml0dGVuIGZyYW1lcyB0byBkaXNrICovCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgLyogY2hlY2sgQVZJU1RSRUFNSU5GTyBmb3Igc29tZSByZWFsbHkgbmVlZGVkIHRoaW5ncyAqLwogIGlmIChhc2ktPmZjY1R5cGUgPT0gMCB8fCBhc2ktPmR3U2NhbGUgPT0gMCB8fCBhc2ktPmR3UmF0ZSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogIC8qIG5vdyBpdCBzZWVtcyB0byBiZSBzYXZlIHRvIGFkZCB0aGUgc3RyZWFtICovCiAgYXNzZXJ0KFRoaXMtPnBwU3RyZWFtc1tuXSA9PSBOVUxMKTsKICBUaGlzLT5wcFN0cmVhbXNbbl0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKCQkJCQkJICAgc2l6ZW9mKElBVklTdHJlYW1JbXBsKSk7CiAgaWYgKFRoaXMtPnBwU3RyZWFtc1tuXSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIC8qIGluaXRpYWxpemUgdGhlIG5ldyBhbGxvY2F0ZWQgc3RyZWFtICovCiAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oVGhpcywgbiwgYXNpKTsKCiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zKys7CiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgLyogdXBkYXRlIG91ciBBVklGSUxFSU5GTyBzdHJ1Y3R1cmUgKi8KICBBVklGSUxFX1VwZGF0ZUluZm8oVGhpcyk7CgogIC8qIHJldHVybiBpdCAqLwogICphdmlzID0gKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zW25dOwogIElBVklTdHJlYW1fQWRkUmVmKCphdmlzKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgICBMUFZPSUQgbHBEYXRhLCBMT05HIHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhYLCVwLCVkKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHBEYXRhID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmZpbGVleHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgTFBWT0lEIGxwRGF0YSwgTE9ORyAqc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOFgsJXAsJXApXG4iLCBpZmFjZSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKCiAgcmV0dXJuIFJlYWRFeHRyYUNodW5rKCZUaGlzLT5maWxlZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLGlmYWNlKTsKCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgLyogbm8gZnJhbWVzIHdyaXR0ZW4gdG8gYW55IHN0cmVhbT8gLS0gY29tcHV0ZSBzdGFydCBvZiAnbW92aSctY2h1bmsgKi8KICBpZiAoVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPT0gMCkKICAgIEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChUaGlzKTsKCiAgVGhpcy0+ZkluZm8uZHdGbGFncyAgfD0gQVZJRklMRUlORk9fSVNJTlRFUkxFQVZFRDsKCiAgLyogYWxyZWFkeSB3cml0dGVuIGZyYW1lcyB0byBhbnkgc3RyZWFtLCAuLi4gKi8KICBpZiAoVGhpcy0+Y2tMYXN0UmVjb3JkLmR3RmxhZ3MgJiBNTUlPX0RJUlRZKSB7CiAgICAvKiBjbG9zZSBsYXN0IHJlY29yZCAqLwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZUaGlzLT5ja0xhc3RSZWNvcmQsIDApICE9IDApCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIEFWSUZJTEVfQWRkUmVjb3JkKFRoaXMpOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPCBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplICsgMyAqIHNpemVvZihEV09SRCkpCiAgICAgIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmNrTGFzdFJlY29yZC5ja3NpemUgKyAzICogc2l6ZW9mKERXT1JEKTsKICB9CgogIC8qIHdyaXRlIG91dCBhIG5ldyByZWNvcmQgaW50byBmaWxlLCBidXQgZG9uJ3QgY2xvc2UgaXQgKi8KICBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplICA9IDA7CiAgVGhpcy0+Y2tMYXN0UmVjb3JkLmZjY1R5cGUgPSBsaXN0dHlwZUFWSVJFQ09SRDsKICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tMYXN0UmVjb3JkLCBNTUlPX0NSRUFURUxJU1QpICE9IDApCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBUaGlzLT5kd05leHRGcmFtZVBvcyArPSAzICogc2l6ZW9mKERXT1JEKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlICppZmFjZSwgRFdPUkQgZmNjVHlwZSwKCQkJCQkgICAgICBMT05HIGxQYXJhbSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVUxPTkcgblN0cmVhbTsKCiAgVFJBQ0UoIiglcCwweCUwOFgsJWQpXG4iLCBpZmFjZSwgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHVzZXIgd3JpdGUgcGVybWlzc2lvbnM/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgIC8qIC4uLiBzbyBkZWxldGUgaXQgbm93ICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0pOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgLSBuU3RyZWFtID4gMCkKICAgICAgbWVtY3B5KFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0sIFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0gKyAxLAoJICAgICAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zIC0gblN0cmVhbSkgKiBzaXplb2YoSUFWSVN0cmVhbUltcGwqKSk7CgogICAgVGhpcy0+cHBTdHJlYW1zW1RoaXMtPmZJbmZvLmR3U3RyZWFtc10gPSBOVUxMOwogICAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zLS07CiAgICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAgIC8qIFRoaXMtPmZJbmZvIHdpbGwgYmUgdXBkYXRlZCBmdXJ0aGVyIHdoZW4gYXNrZWQgZm9yICovCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChQQVZJRklMRSlUaGlzLT5wYWYsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQQ0xTSUQgcENsYXNzSUQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBDbGFzc0lEKTsKCiAgaWYgKHBDbGFzc0lEID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcENsYXNzSUQgPSBDTFNJRF9BVklGaWxlOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLCBpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiAoVGhpcy0+cGFmLT5mRGlydHkgPyBTX09LIDogU19GQUxTRSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsIERXT1JEIGR3TW9kZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBpbnQgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4WClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSwgZHdNb2RlKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwogIGlmIChUaGlzLT5wYWYtPmhtbWlvICE9IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBObyByZXVzZSBvZiB0aGlzIG9iamVjdCBmb3IgYW5vdGhlciBmaWxlISAqLwoKICAvKiByZW1lbWJlciBtb2RlIGFuZCBuYW1lICovCiAgVGhpcy0+cGFmLT51TW9kZSA9IGR3TW9kZTsKCiAgbGVuID0gbHN0cmxlblcocHN6RmlsZU5hbWUpICsgMTsKICBUaGlzLT5wYWYtPnN6RmlsZU5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgbHN0cmNweVcoVGhpcy0+cGFmLT5zekZpbGVOYW1lLCBwc3pGaWxlTmFtZSk7CgogIC8qIHRyeSB0byBvcGVuIHRoZSBmaWxlICovCiAgVGhpcy0+cGFmLT5obW1pbyA9IG1taW9PcGVuVyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIE5VTEwsCgkJCSAgICAgICBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICBpZiAoVGhpcy0+cGFmLT5obW1pbyA9PSBOVUxMKSB7CiAgICAvKiBtbWlvT3Blblcgbm90IGluIG5hdGl2ZSBETExzIG9mIFdpbjl4IC0tIHRyeSBtbWlvT3BlbkEgKi8KICAgIExQU1RSIHN6RmlsZU5hbWU7CgogICAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAwLCBOVUxMLCBOVUxMKTsKICAgIHN6RmlsZU5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKENIQVIpKTsKICAgIGlmIChzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIC0xLCBzekZpbGVOYW1lLAoJCQlsZW4sIE5VTEwsIE5VTEwpOwoKICAgIFRoaXMtPnBhZi0+aG1taW8gPSBtbWlvT3BlbkEoc3pGaWxlTmFtZSwgTlVMTCwgTU1JT19BTExPQ0JVRiB8IGR3TW9kZSk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzekZpbGVOYW1lKTsKICAgIGlmIChUaGlzLT5wYWYtPmhtbWlvID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfRklMRU9QRU47CiAgfQoKICAvKiBzaG91bGQgd2UgY3JlYXRlIGEgbmV3IGZpbGU/ICovCiAgaWYgKGR3TW9kZSAmIE9GX0NSRUFURSkgewogICAgbWVtc2V0KCYgVGhpcy0+cGFmLT5mSW5mbywgMCwgc2l6ZW9mKFRoaXMtPnBhZi0+ZkluZm8pKTsKICAgIFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyA9IEFWSUZJTEVJTkZPX0hBU0lOREVYIHwgQVZJRklMRUlORk9fVFJVU1RDS1RZUEU7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBBVklGSUxFX0xvYWRGaWxlKFRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpCnsKICBUUkFDRSgiKCVwLCVzLCVkKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpLCBmUmVtZW1iZXIpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICBMUENPTEVTVFIgcHN6RmlsZU5hbWUpCnsKICBUUkFDRSgiKCVwLCVzKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpKTsKCiAgLyogV2Ugd3JpdGUgZGlyZWN0bHkgdG8gZGlzaywgc28gbm90aGluZyB0byBkby4gKi8KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJTFBPTEVTVFIgKnBwc3pGaWxlTmFtZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBwc3pGaWxlTmFtZSk7CgogIGlmIChwcHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcHN6RmlsZU5hbWUgPSBOVUxMOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICBpZiAoVGhpcy0+cGFmLT5zekZpbGVOYW1lICE9IE5VTEwpIHsKICAgIGludCBsZW4gPSBsc3RybGVuVyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUpICsgMTsKCiAgICAqcHBzekZpbGVOYW1lID0gQ29UYXNrTWVtQWxsb2MobGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoKnBwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBzdHJjcHlXKCpwcHN6RmlsZU5hbWUsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSk7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCQkgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICBJQVZJU3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQogIC8qIEZJWE1FOiBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSAqLwoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtICppZmFjZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVkXG4iLCBpZmFjZSwgcmVmKTsKCiAgLyogYWxzbyBhZGQgcmVmIHRvIHBhcmVudCwgc28gdGhhdCBpdCBkb2Vzbid0IGtpbGwgdXMgKi8KICBpZiAoVGhpcy0+cGFmICE9IE5VTEwpCiAgICBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7CgogIHJldHVybiByZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlZFxuIiwgaWZhY2UsIHJlZik7CgogIGlmIChUaGlzLT5wYWYgIT0gTlVMTCkKICAgIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7CgogIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0gKmlmYWNlLCBMUEFSQU0gbFBhcmFtMSwKCQkJCQkgIExQQVJBTSBsUGFyYW0yKQp7CiAgVFJBQ0UoIiglcCwweCUwOGxYLDB4JTA4bFgpXG4iLCBpZmFjZSwgbFBhcmFtMSwgbFBhcmFtMik7CgogIC8qIFRoaXMgSUFWSVN0cmVhbSBpbnRlcmZhY2UgbmVlZHMgYW4gQVZJRmlsZSAqLwogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtICppZmFjZSxMUEFWSVNUUkVBTUlORk9XIHBzaSwKCQkJCQlMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnNJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgIExPTkcgZmxhZ3MpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBMT05HIG9mZnNldCA9IDA7CgogIFRSQUNFKCIoJXAsJWQsMHglMDhYKVxuIixpZmFjZSxwb3MsZmxhZ3MpOwoKICBpZiAoZmxhZ3MgJiBGSU5EX0ZST01fU1RBUlQpIHsKICAgIHBvcyA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBmbGFncyAmPSB+KEZJTkRfRlJPTV9TVEFSVHxGSU5EX1BSRVYpOwogICAgZmxhZ3MgfD0gRklORF9ORVhUOwogIH0KCiAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAvKiBjb252ZXJ0IHNhbXBsZXMgaW50byBibG9jayBudW1iZXIgd2l0aCBvZmZzZXQgKi8KICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soVGhpcywgJnBvcywgJm9mZnNldCk7CiAgfQoKICBpZiAoZmxhZ3MgJiBGSU5EX1RZUEUpIHsKICAgIGlmIChmbGFncyAmIEZJTkRfS0VZKSB7CiAgICAgIHdoaWxlICgwIDw9IHBvcyAmJiBwb3MgPD0gVGhpcy0+bExhc3RGcmFtZSkgewoJaWYgKFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3RmxhZ3MgJiBBVklJRl9LRVlGUkFNRSkKCSAgZ290byBSRVRVUk5fRk9VTkQ7CgoJaWYgKGZsYWdzICYgRklORF9ORVhUKQoJICBwb3MrKzsKCWVsc2UKCSAgcG9zLS07CiAgICAgIH07CiAgICB9IGVsc2UgaWYgKGZsYWdzICYgRklORF9BTlkpIHsKICAgICAgd2hpbGUgKDAgPD0gcG9zICYmIHBvcyA8PSBUaGlzLT5sTGFzdEZyYW1lKSB7CglpZiAoVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCA+IDApCgkgIGdvdG8gUkVUVVJOX0ZPVU5EOwoKCWlmIChmbGFncyAmIEZJTkRfTkVYVCkKCSAgcG9zKys7CgllbHNlCgkgIHBvcy0tOwoKICAgICAgfTsKICAgIH0gZWxzZSBpZiAoKGZsYWdzICYgRklORF9GT1JNQVQpICYmIFRoaXMtPmlkeEZtdENoYW5nZXMgIT0gTlVMTCAmJgoJICAgICAgIFRoaXMtPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIGlmIChmbGFncyAmIEZJTkRfTkVYVCkgewoJVUxPTkcgbjsKCglmb3IgKG4gPSAwOyBuIDwgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsgbisrKQoJICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkID49IHBvcykgewogICAgICAgICAgICBwb3MgPSBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQ7CgkgICAgZ290byBSRVRVUk5fRk9VTkQ7CiAgICAgICAgICB9CiAgICAgIH0gZWxzZSB7CglMT05HIG47CgoJZm9yIChuID0gKExPTkcpVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsgbiA+PSAwOyBuLS0pIHsKCSAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZCA8PSBwb3MpIHsKICAgICAgICAgICAgcG9zID0gVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkOwoJICAgIGdvdG8gUkVUVVJOX0ZPVU5EOwogICAgICAgICAgfQoJfQoKCWlmIChwb3MgPiAoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0KQoJICByZXR1cm4gMDsgLyogZm9ybWF0IGNoYW5nZXMgYWx3YXlzIGZvciBmaXJzdCBmcmFtZSAqLwogICAgICB9CiAgICB9CgogICAgcmV0dXJuIC0xOwogIH0KCiBSRVRVUk5fRk9VTkQ6CiAgaWYgKHBvcyA8IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gLTE7CgogIHN3aXRjaCAoZmxhZ3MgJiBGSU5EX1JFVCkgewogIGNhc2UgRklORF9MRU5HVEg6CiAgICAvKiBwaHlzaWNhbCBzaXplICovCiAgICBwb3MgPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoOwogICAgYnJlYWs7CiAgY2FzZSBGSU5EX09GRlNFVDoKICAgIC8qIHBoeXNpY2FsIHBvc2l0aW9uICovCiAgICBwb3MgPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rT2Zmc2V0ICsgMiAqIHNpemVvZihEV09SRCkKICAgICAgKyBvZmZzZXQgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBicmVhazsKICBjYXNlIEZJTkRfU0laRToKICAgIC8qIGxvZ2ljYWwgc2l6ZSAqLwogICAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSkKICAgICAgcG9zID0gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgZWxzZQogICAgICBwb3MgPSAxOwogICAgYnJlYWs7CiAgY2FzZSBGSU5EX0lOREVYOgogICAgRklYTUUoIjogRklORF9JTkRFWCBmbGFnIGlzIG5vdCBzdXBwb3J0ZWQhXG4iKTsKICAgIC8qIFRoaXMgaXMgYW4gaW5kZXggaW4gdGhlIGluZGV4LXRhYmxlIG9uIGRpc2MuICovCiAgICBicmVhazsKICB9OyAvKiBlbHNlIGxvZ2ljYWwgcG9zaXRpb24gKi8KCiAgcmV0dXJuIHBvczsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgICBMUFZPSUQgZm9ybWF0LCBMT05HICpmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlZCwlcCwlcClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChmb3JtYXRzaXplID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBvbmx5IGludGVyZXN0ZWQgaW4gbmVlZGVkIGJ1ZmZlcnNpemU/ICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8ICpmb3JtYXRzaXplIDw9IDApIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIGNvcHkgaW5pdGlhbCBmb3JtYXQgKG9ubHkgYXMgbXVjaCBhcyB3aWxsIGZpdCkgKi8KICBtZW1jcHkoZm9ybWF0LCBUaGlzLT5scEZvcm1hdCwgbWluKCooRFdPUkQqKWZvcm1hdHNpemUsIFRoaXMtPmNiRm9ybWF0KSk7CiAgaWYgKCooRFdPUkQqKWZvcm1hdHNpemUgPCBUaGlzLT5jYkZvcm1hdCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQoKICAvKiBDb3VsZCBmb3JtYXQgY2hhbmdlPyBXaGVuIHllcyB3aWxsIGl0IGNoYW5nZT8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3RmxhZ3MgJiBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVMpICYmCiAgICAgIHBvcyA+IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgIExPTkcgbExhc3RGbXQ7CgogICAgbExhc3RGbXQgPSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShpZmFjZSwgcG9zLCBGSU5EX0ZPUk1BVHxGSU5EX1BSRVYpOwogICAgaWYgKGxMYXN0Rm10ID4gMCkgewogICAgICBGSVhNRSgiOiBuZWVkIHRvIHJlYWQgZm9ybWF0Y2hhbmdlIGZvciAlZCAtLSB1bmltcGxlbWVudGVkIVxuIixsTGFzdEZtdCk7CiAgICB9CiAgfQoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiRm9ybWF0OwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgZm9ybWF0c2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIExQQklUTUFQSU5GT0hFQURFUiBscGJpTmV3ID0gKExQQklUTUFQSU5GT0hFQURFUilmb3JtYXQ7CgogIFRSQUNFKCIoJXAsJWQsJXAsJWQpXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8IGZvcm1hdHNpemUgPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIGNhbiBvbmx5IHNldCBmb3JtYXQgYmVmb3JlIGZyYW1lIGlzIHdyaXR0ZW4hICovCiAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPiBwb3MpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBpbml0aWFsIGZvcm1hdCBvciBhIGZvcm1hdGNoYW5nZT8gKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkgewogICAgLyogaW5pdGlhbCBmb3JtYXQgKi8KICAgIGlmIChUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zICE9IDApCiAgICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIHVzZXIgaGFzIHVzZWQgQVBJIGluIHdyb25nIHNlcXVlbmNlISAqLwoKICAgIFRoaXMtPmxwRm9ybWF0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGZvcm1hdHNpemUpOwogICAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+Y2JGb3JtYXQgPSBmb3JtYXRzaXplOwoKICAgIG1lbWNweShUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgICAvKiB1cGRhdGUgc29tZSBpbmZvcyBhYm91dCBzdHJlYW0gKi8KICAgIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgICBMT05HIGxEaW07CgogICAgICBsRGltID0gVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCAtIFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdDsKICAgICAgaWYgKGxEaW0gPCBscGJpTmV3LT5iaVdpZHRoKQoJVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCA9IFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdCArIGxwYmlOZXctPmJpV2lkdGg7CiAgICAgIGxEaW0gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSAtIFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wOwogICAgICBpZiAobERpbSA8IGxwYmlOZXctPmJpSGVpZ2h0KQoJVGhpcy0+c0luZm8ucmNGcmFtZS5ib3R0b20gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLnRvcCArIGxwYmlOZXctPmJpSGVpZ2h0OwogICAgfSBlbHNlIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKICAgICAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplID0gKChMUFdBVkVGT1JNQVRFWClUaGlzLT5scEZvcm1hdCktPm5CbG9ja0FsaWduOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlIHsKICAgIE1NQ0tJTkZPICAgICAgICAgICBjazsKICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT2xkID0gKExQQklUTUFQSU5GT0hFQURFUilUaGlzLT5scEZvcm1hdDsKICAgIFJHQlFVQUQgICAgICAgICAgICpyZ2JOZXcgID0gKFJHQlFVQUQqKSgoTFBCWVRFKWxwYmlOZXcgKyBscGJpTmV3LT5iaVNpemUpOwogICAgQVZJUEFMQ0hBTkdFICAgICAgKmxwcGMgPSBOVUxMOwogICAgVUlOVCAgICAgICAgICAgICAgIG47CgogICAgLyogcGVyaGFwcyBmb3JtYXQgY2hhbmdlLCBjaGVjayBpdCAuLi4gKi8KICAgIGlmIChUaGlzLT5jYkZvcm1hdCAhPSBmb3JtYXRzaXplKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIG5vIGZvcm1hdCBjaGFuZ2UsIG9ubHkgdGhlIGluaXRpYWwgb25lICovCiAgICBpZiAobWVtY21wKFRoaXMtPmxwRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CgogICAgLyogY2hlY2sgdGhhdCdzIG9ubHkgdGhlIHBhbGV0dGUsIHdoaWNoIGNoYW5nZXMgKi8KICAgIGlmIChscGJpT2xkLT5iaVNpemUgICAgICAgICE9IGxwYmlOZXctPmJpU2l6ZSB8fAoJbHBiaU9sZC0+YmlXaWR0aCAgICAgICAhPSBscGJpTmV3LT5iaVdpZHRoIHx8CglscGJpT2xkLT5iaUhlaWdodCAgICAgICE9IGxwYmlOZXctPmJpSGVpZ2h0IHx8CglscGJpT2xkLT5iaVBsYW5lcyAgICAgICE9IGxwYmlOZXctPmJpUGxhbmVzIHx8CglscGJpT2xkLT5iaUJpdENvdW50ICAgICE9IGxwYmlOZXctPmJpQml0Q291bnQgfHwKCWxwYmlPbGQtPmJpQ29tcHJlc3Npb24gIT0gbHBiaU5ldy0+YmlDb21wcmVzc2lvbiB8fAoJbHBiaU9sZC0+YmlDbHJVc2VkICAgICAhPSBscGJpTmV3LT5iaUNsclVzZWQpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgVGhpcy0+c0luZm8uZHdGbGFncyB8PSBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVM7CgogICAgLyogc2ltcGx5IHNheSBhbGwgY29sb3JzIGhhdmUgY2hhbmdlZCAqLwogICAgY2suY2tpZCAgID0gTUFLRUFWSUNLSUQoY2t0eXBlUEFMY2hhbmdlLCBUaGlzLT5uU3RyZWFtKTsKICAgIGNrLmNrc2l6ZSA9IDIgKiBzaXplb2YoV09SRCkgKyBscGJpT2xkLT5iaUNsclVzZWQgKiBzaXplb2YoUEFMRVRURUVOVFJZKTsKICAgIGxwcGMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKICAgIGlmIChscHBjID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIGxwcGMtPmJGaXJzdEVudHJ5ID0gMDsKICAgIGxwcGMtPmJOdW1FbnRyaWVzID0gKGxwYmlPbGQtPmJpQ2xyVXNlZCA8IDI1NiA/IGxwYmlPbGQtPmJpQ2xyVXNlZCA6IDApOwogICAgbHBwYy0+d0ZsYWdzICAgICAgPSAwOwogICAgZm9yIChuID0gMDsgbiA8IGxwYmlPbGQtPmJpQ2xyVXNlZDsgbisrKSB7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlUmVkICAgPSByZ2JOZXdbbl0ucmdiUmVkOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUdyZWVuID0gcmdiTmV3W25dLnJnYkdyZWVuOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUJsdWUgID0gcmdiTmV3W25dLnJnYkJsdWU7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlRmxhZ3MgPSAwOwogICAgfQoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEgfHwKICAgICAgICBtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LIHx8CiAgICAgICAgbW1pb1dyaXRlKFRoaXMtPnBhZi0+aG1taW8sIChIUFNUUilscHBjLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSB8fAogICAgICAgIG1taW9Bc2NlbmQoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscHBjKTsKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CgogICAgVGhpcy0+cGFmLT5kd05leHRGcmFtZVBvcyArPSBjay5ja3NpemUgKyAyICogc2l6ZW9mKERXT1JEKTsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscHBjKTsKCiAgICByZXR1cm4gQVZJRklMRV9BZGRGcmFtZShUaGlzLCBja3R5cGVQQUxjaGFuZ2UsIG4sIGNrLmR3RGF0YU9mZnNldCwgMCk7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCUxPTkcgYnVmZmVyc2l6ZSwgTFBMT05HIGJ5dGVzcmVhZCwKCQkJCQlMUExPTkcgc2FtcGxlc3JlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBEV09SRCAgICBzaXplOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVkLCVkLCVwLCVkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCiAJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQgPiBzdGFydCkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOyAvKiBjb3VsZG4ndCByZWFkIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0gKi8KICBpZiAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKERXT1JEKXN0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7IC8qIHN0YXJ0IGlzIHBhc3QgZW5kIG9mIHN0cmVhbSAqLwoKICAvKiBzaG91bGQgd2UgcmVhZCBhcyBtdWNoIGFzIHBvc3NpYmxlPyAqLwogIGlmIChzYW1wbGVzID09IC0xKSB7CiAgICAvKiBVc2VyIHNob3VsZCBrbm93IGhvdyBtdWNoIHdlIGhhdmUgcmVhZCAqLwogICAgaWYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKQogICAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGVsc2UKICAgICAgc2FtcGxlcyA9IDE7CiAgfQoKICAvKiBsaW1pdCB0byBlbmQgb2Ygc3RyZWFtICovCiAgaWYgKChMT05HKVRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgc2FtcGxlcykKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICBpZiAoKHN0YXJ0IC0gVGhpcy0+c0luZm8uZHdTdGFydCkgPiAoVGhpcy0+c0luZm8uZHdMZW5ndGggLSBzYW1wbGVzKSkKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aCAtIChzdGFydCAtIFRoaXMtPnNJbmZvLmR3U3RhcnQpOwoKICAvKiBub3RoaW5nIHRvIHJlYWQ/IFRoZW4gbGVhdmUgLi4uICovCiAgaWYgKHNhbXBsZXMgPT0gMCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgLyogZml4ZWQgc2FtcGxlc2l6ZSAtLSB3ZSBjYW4gcmVhZCBvdmVyIGZyYW1lL2Jsb2NrIGJvdW5kYXJpZXMgKi8KICAgIExPTkcgYmxvY2sgPSBzdGFydDsKICAgIExPTkcgb2Zmc2V0ID0gMDsKCiAgICAvKiBjb252ZXJ0IHN0YXJ0IHNhbXBsZSB0byBibG9jayxvZmZzZXQgcGFpciAqLwogICAgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhUaGlzLCAmYmxvY2ssICZvZmZzZXQpOwoKICAgIC8qIGNvbnZlcnQgc2FtcGxlcyB0byBieXRlcyAqLwogICAgc2FtcGxlcyAqPSBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CgogICAgd2hpbGUgKHNhbXBsZXMgPiAwICYmIGJ1ZmZlcnNpemUgPiAwKSB7CiAgICAgIGlmIChibG9jayAhPSBUaGlzLT5kd0N1cnJlbnRGcmFtZSkgewoJaHIgPSBBVklGSUxFX1JlYWRCbG9jayhUaGlzLCBibG9jaywgTlVMTCwgMCk7CglpZiAoRkFJTEVEKGhyKSkKCSAgcmV0dXJuIGhyOwogICAgICB9CgogICAgICBzaXplID0gbWluKChEV09SRClzYW1wbGVzLCAoRFdPUkQpYnVmZmVyc2l6ZSk7CiAgICAgIHNpemUgPSBtaW4oc2l6ZSwgVGhpcy0+Y2JCdWZmZXIgLSBvZmZzZXQpOwogICAgICBtZW1jcHkoYnVmZmVyLCAoKEJZVEUqKSZUaGlzLT5scEJ1ZmZlclsyXSkgKyBvZmZzZXQsIHNpemUpOwoKICAgICAgYmxvY2srKzsKICAgICAgb2Zmc2V0ID0gMDsKICAgICAgYnVmZmVyID0gKChMUEJZVEUpYnVmZmVyKStzaXplOwogICAgICBzYW1wbGVzICAgIC09IHNpemU7CiAgICAgIGJ1ZmZlcnNpemUgLT0gc2l6ZTsKCiAgICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKCSpieXRlc3JlYWQgICArPSBzaXplOwogICAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKCSpzYW1wbGVzcmVhZCArPSBzaXplIC8gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgfQoKICAgIGlmIChzYW1wbGVzID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICBlbHNlCiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfSBlbHNlIHsKICAgIC8qIHZhcmlhYmxlIHNhbXBsZXNpemUgLS0gd2UgY2FuIG9ubHkgcmVhZCBvbmUgZnVsbCBmcmFtZS9ibG9jayAqLwogICAgaWYgKHNhbXBsZXMgPiAxKQogICAgICBzYW1wbGVzID0gMTsKCiAgICBhc3NlcnQoc3RhcnQgPD0gVGhpcy0+bExhc3RGcmFtZSk7CiAgICBzaXplID0gVGhpcy0+aWR4RnJhbWVzW3N0YXJ0XS5kd0NodW5rTGVuZ3RoOwogICAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmZlcnNpemUgPj0gc2l6ZSkgewogICAgICBociA9IEFWSUZJTEVfUmVhZEJsb2NrKFRoaXMsIHN0YXJ0LCBidWZmZXIsIHNpemUpOwogICAgICBpZiAoRkFJTEVEKGhyKSkKCXJldHVybiBocjsKICAgIH0gZWxzZSBpZiAoYnVmZmVyICE9IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CgogICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IHNpemU7CiAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCSBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkJCSBMUExPTkcgc2FtcHdyaXR0ZW4sCgkJCQkJIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBGT1VSQ0MgIGNraWQ7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlZCwlZCwlcCwlZCwweCUwOFgsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsCglidWZmZXIsIGJ1ZmZlcnNpemUsIGZsYWdzLCBzYW1wd3JpdHRlbiwgYnl0ZXN3cml0dGVuKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICpzYW1wd3JpdHRlbiA9IDA7CiAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgKmJ5dGVzd3JpdHRlbiA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYnVmZmVyID09IE5VTEwgJiYgKGJ1ZmZlcnNpemUgPiAwIHx8IHNhbXBsZXMgPiAwKSkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIEhhdmUgd2Ugd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIHN3aXRjaCAoVGhpcy0+c0luZm8uZmNjVHlwZSkgewogIGNhc2Ugc3RyZWFtdHlwZUFVRElPOgogICAgY2tpZCA9IE1BS0VBVklDS0lEKGNrdHlwZVdBVkVieXRlcywgVGhpcy0+blN0cmVhbSk7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgaWYgKChmbGFncyAmIEFWSUlGX0tFWUZSQU1FKSAmJiBidWZmZXJzaXplICE9IDApCiAgICAgIGNraWQgPSBNQUtFQVZJQ0tJRChja3R5cGVESUJiaXRzLCBUaGlzLT5uU3RyZWFtKTsKICAgIGVsc2UKICAgICAgY2tpZCA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmNvbXByZXNzZWQsIFRoaXMtPm5TdHJlYW0pOwogICAgYnJlYWs7CiAgfTsKCiAgLyogYXBwZW5kIHRvIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKHN0YXJ0ID09IC0xKSB7CiAgICBpZiAoVGhpcy0+bExhc3RGcmFtZSA9PSAtMSkKICAgICAgc3RhcnQgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgZWxzZQogICAgICBzdGFydCA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogIH0gZWxzZSBpZiAoVGhpcy0+bExhc3RGcmFtZSA9PSAtMSkKICAgIFRoaXMtPnNJbmZvLmR3U3RhcnQgPSBzdGFydDsKCiAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAvKiBmaXhlZCBzYW1wbGUgc2l6ZSAtLSBhdWRpbyBsaWtlICovCiAgICBpZiAoc2FtcGxlcyAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSBidWZmZXJzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIC8qIENvdWxkbid0IHNraXAgYXVkaW8tbGlrZSBkYXRhIC0tIFVzZXIgbXVzdCBzdXBwbHkgYXBwcm9wcmlhdGUgc2lsZW5jZSAqLwogICAgaWYgKFRoaXMtPnNJbmZvLmR3TGVuZ3RoICE9IHN0YXJ0KQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIENvbnZlcnQgcG9zaXRpb24gdG8gZnJhbWUvYmxvY2sgKi8KICAgIHN0YXJ0ID0gVGhpcy0+bExhc3RGcmFtZSArIDE7CgogICAgaWYgKChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEKSA9PSAwKSB7CiAgICAgIEZJWE1FKCI6IG5vdCBpbnRlcmxlYXZlZCwgY291bGQgY29sbGVjdCBhdWRpbyBkYXRhIVxuIik7CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIHZhcmlhYmxlIHNhbXBsZSBzaXplIC0tIHZpZGVvIGxpa2UgKi8KICAgIGlmIChzYW1wbGVzID4gMSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICAvKiBtdXN0IHdlIGZpbGwgdXAgd2l0aCBlbXB0eSBmcmFtZXM/ICovCiAgICBpZiAoVGhpcy0+bExhc3RGcmFtZSAhPSAtMSkgewogICAgICBGT1VSQ0MgY2tpZDIgPSBNQUtFQVZJQ0tJRChja3R5cGVESUJjb21wcmVzc2VkLCBUaGlzLT5uU3RyZWFtKTsKCiAgICAgIHdoaWxlIChzdGFydCA+IFRoaXMtPmxMYXN0RnJhbWUgKyAxKSB7CglociA9IEFWSUZJTEVfV3JpdGVCbG9jayhUaGlzLCBUaGlzLT5sTGFzdEZyYW1lICsgMSwgY2tpZDIsIDAsIE5VTEwsIDApOwoJaWYgKEZBSUxFRChocikpCgkgIHJldHVybiBocjsKICAgICAgfQogICAgfQogIH0KCiAgLyogd3JpdGUgdGhlIGJsb2NrIG5vdyAqLwogIGhyID0gQVZJRklMRV9Xcml0ZUJsb2NrKFRoaXMsIHN0YXJ0LCBja2lkLCBmbGFncywgYnVmZmVyLCBidWZmZXJzaXplKTsKICBpZiAoU1VDQ0VFREVEKGhyKSkgewogICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgICAqc2FtcHdyaXR0ZW4gPSBzYW1wbGVzOwogICAgaWYgKGJ5dGVzd3JpdHRlbiAhPSBOVUxMKQogICAgICAqYnl0ZXN3cml0dGVuID0gYnVmZmVyc2l6ZTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJICBMT05HIHNhbXBsZXMpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBGSVhNRSgiKCVwLCVkLCVkKTogc3R1YlxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzdGFydCA8IDAgfHwgc2FtcGxlcyA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEZWxldGUgYmVmb3JlIHN0YXJ0IG9mIHN0cmVhbT8gKi8KICBpZiAoc3RhcnQgKyBzYW1wbGVzIDwgVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIERlbGV0ZSBhZnRlciBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmIChzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRm9yIHRoZSByZXN0IHdlIG5lZWQgd3JpdGUgcGVybWlzc2lvbnMgKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIDEuIG92ZXJ3cml0ZSB0aGUgZGF0YSB3aXRoIEpVTksKICAgKgogICAqIGlmIElTSU5URVJMRUFWRUQgewogICAqICAgMi4gY29uY2F0IGFsbCBuZWlnaGJvdXJlZCBKVU5LLWJsb2NrcyBpbiB0aGlzIHJlY29yZCB0byBvbmUKICAgKiAgIDMuIGlmIHRoaXMgcmVjb3JkIG9ubHkgY29udGFpbnMgSlVOSyBhbmQgaXMgYXQgZW5kIHNldCBkd05leHRGcmFtZVBvcwogICAqICAgICAgdG8gc3RhcnQgb2YgdGhpcyByZWNvcmQsIHJlcGVhdCB0aGlzLgogICAqIH0gZWxzZSB7CiAgICogICAyLiBjb25jYXQgYWxsIG5laWdoYm91cmVkIEpVTkstYmxvY2tzLgogICAqICAgMy4gaWYgdGhlIEpVTksgYmxvY2sgaXMgYXQgdGhlIGVuZCwgdGhlbiBzZXQgZHdOZXh0RnJhbWVQb3MgdG8KICAgKiAgICAgIHN0YXJ0IG9mIHRoaXMgYmxvY2suCiAgICogfQogICAqLwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgIExQVk9JRCBscCwgTFBMT05HIGxwcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhYLCVwLCVwKVxuIiwgaWZhY2UsIGZjYywgbHAsIGxwcmVhZCk7CgogIGlmIChmY2MgPT0gY2tpZFNUUkVBTUhBTkRMRVJEQVRBKSB7CiAgICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIFRoaXMtPmNiSGFuZGxlckRhdGEgPiAwKSB7CiAgICAgIGlmIChscCA9PSBOVUxMIHx8ICpscHJlYWQgPD0gMCkgewoJKmxwcmVhZCA9IFRoaXMtPmNiSGFuZGxlckRhdGE7CglyZXR1cm4gQVZJRVJSX09LOwogICAgICB9CgogICAgICBtZW1jcHkobHAsIFRoaXMtPmxwSGFuZGxlckRhdGEsIG1pbihUaGlzLT5jYkhhbmRsZXJEYXRhLCAqbHByZWFkKSk7CiAgICAgIGlmICgqbHByZWFkIDwgVGhpcy0+Y2JIYW5kbGVyRGF0YSkKCXJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9IGVsc2UKICAgICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7CiAgfSBlbHNlCiAgICByZXR1cm4gUmVhZEV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBmY2MsIGxwLCBscHJlYWQpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICAgTFBWT0lEIGxwLCBMT05HIHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4eCwlcCwlZClcbiIsIGlmYWNlLCBmY2MsIGxwLCBzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBuZWVkIHdyaXRlIHBlcm1pc3Npb24gKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIGFscmVhZHkgd3JpdHRlbiBzb21ldGhpbmcgdG8gdGhpcyBmaWxlPyAqLwogIGlmIChUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zICE9IDApIHsKICAgIC8qIHRoZSBkYXRhIHdpbGwgYmUgaW5zZXJ0ZWQgYmVmb3JlIHRoZSAnbW92aScgY2h1bmssIHNvIGNoZWNrIGZvcgogICAgICogZW5vdWdoIHNwYWNlICovCiAgICBEV09SRCBkd1BvcyA9IEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChUaGlzLT5wYWYpOwoKICAgIC8qIGNraWQsc2l6ZSA9PiAyICogc2l6ZW9mKERXT1JEKSAqLwogICAgZHdQb3MgKz0gMiAqIHNpemVvZihEV09SRCkgKyBzaXplOwogICAgaWYgKHNpemUgPj0gVGhpcy0+cGFmLT5kd01vdmlDaHVua1BvcyAtIDIgKiBzaXplb2YoRFdPUkQpKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBub3QgZW5vdWdoIHNwYWNlIGxlZnQgKi8KICB9CgogIFRoaXMtPnBhZi0+ZkRpcnR5ID0gVFJVRTsKCiAgaWYgKGZjYyA9PSBja2lkU1RSRUFNSEFORExFUkRBVEEpIHsKICAgIGlmIChUaGlzLT5scEhhbmRsZXJEYXRhICE9IE5VTEwpIHsKICAgICAgRklYTUUoIjogaGFuZGxlciBkYXRhIGFscmVhZHkgc2V0IC0tIG92ZXJ3aXJ0ZT9cbiIpOwogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogICAgfQoKICAgIFRoaXMtPmxwSGFuZGxlckRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZSk7CiAgICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPmNiSGFuZGxlckRhdGEgPSBzaXplOwogICAgbWVtY3B5KFRoaXMtPmxwSGFuZGxlckRhdGEsIGxwLCBzaXplKTsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIFdyaXRlRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGZjYywgbHAsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJICAgTFBBVklTVFJFQU1JTkZPVyBpbmZvLCBMT05HIGluZm9sZW4pCnsKICBGSVhNRSgiKCVwLCVwLCVkKTogc3R1YlxuIiwgaWZhY2UsIGluZm8sIGluZm9sZW4pOwoKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZEZyYW1lKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBja2lkLCBEV09SRCBzaXplLCBEV09SRCBvZmZzZXQsIERXT1JEIGZsYWdzKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKCiAgc3dpdGNoIChUV09DQ0Zyb21GT1VSQ0MoY2tpZCkpIHsKICBjYXNlIGNrdHlwZURJQmJpdHM6CiAgICBpZiAoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fVFJVU1RDS1RZUEUpCiAgICAgIGZsYWdzIHw9IEFWSUlGX0tFWUZSQU1FOwogICAgYnJlYWs7CiAgY2FzZSBja3R5cGVESUJjb21wcmVzc2VkOgogICAgaWYgKFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX1RSVVNUQ0tUWVBFKQogICAgICBmbGFncyAmPSB+QVZJSUZfS0VZRlJBTUU7CiAgICBicmVhazsKICBjYXNlIGNrdHlwZVBBTGNoYW5nZToKICAgIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlICE9IHN0cmVhbXR5cGVWSURFTykgewogICAgICBFUlIoIjogZm91bmQgcGFsZXR0ZSBjaGFuZ2UgaW4gbm9uLXZpZGVvIHN0cmVhbSFcbiIpOwogICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKICAgIH0KICAgIFRoaXMtPnNJbmZvLmR3RmxhZ3MgfD0gQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTOwogICAgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCsrOwoKICAgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzID09IE5VTEwgfHwgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCA8IFRoaXMtPm5JZHhGbXRDaGFuZ2VzKSB7CiAgICAgIFVJTlQgbiA9IFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7CgogICAgICBUaGlzLT5uSWR4Rm10Q2hhbmdlcyArPSAxNjsKICAgICAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXMgPT0gTlVMTCkKCVRoaXMtPmlkeEZtdENoYW5nZXMgPQoJICBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgVGhpcy0+bklkeEZtdENoYW5nZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBlbHNlCglUaGlzLT5pZHhGbXRDaGFuZ2VzID0KCSAgSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgVGhpcy0+aWR4Rm10Q2hhbmdlcywKCQkJICAgVGhpcy0+bklkeEZtdENoYW5nZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlcyA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgICBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQgICAgICAgICAgPSBUaGlzLT5sTGFzdEZyYW1lOwogICAgICBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmR3RmxhZ3MgICAgICAgPSAwOwogICAgICBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmR3Q2h1bmtPZmZzZXQgPSBvZmZzZXQ7CiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uZHdDaHVua0xlbmd0aCA9IHNpemU7CgogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBja3R5cGVXQVZFYnl0ZXM6CiAgICBpZiAoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fVFJVU1RDS1RZUEUpCiAgICAgIGZsYWdzIHw9IEFWSUlGX0tFWUZSQU1FOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIFdBUk4oIjogdW5rbm93biBUV09DQyAweCUwNFggZm91bmRcbiIsIFRXT0NDRnJvbUZPVVJDQyhja2lkKSk7CiAgICBicmVhazsKICB9OwoKICAvKiBmaXJzdCBmcmFtZSBpcyBhbHdheXMgYSBrZXlmcmFtZSAqLwogIGlmIChUaGlzLT5sTGFzdEZyYW1lID09IC0xKQogICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CgogIGlmIChUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPCBzaXplKQogICAgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gc2l6ZTsKCiAgLyogZ2V0IG1lbW9yeSBmb3IgaW5kZXggKi8KICBpZiAoVGhpcy0+aWR4RnJhbWVzID09IE5VTEwgfHwgVGhpcy0+bExhc3RGcmFtZSArIDEgPj0gVGhpcy0+bklkeEZyYW1lcykgewogICAgVGhpcy0+bklkeEZyYW1lcyArPSA1MTI7CiAgICBpZiAoVGhpcy0+aWR4RnJhbWVzID09IE5VTEwpCiAgICAgIFRoaXMtPmlkeEZyYW1lcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5uSWR4RnJhbWVzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgICAgZWxzZQoJVGhpcy0+aWR4RnJhbWVzID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgVGhpcy0+aWR4RnJhbWVzLAoJCQkgICBUaGlzLT5uSWR4RnJhbWVzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgIGlmIChUaGlzLT5pZHhGcmFtZXMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgfQoKICBUaGlzLT5sTGFzdEZyYW1lKys7CiAgVGhpcy0+aWR4RnJhbWVzW1RoaXMtPmxMYXN0RnJhbWVdLmNraWQgICAgICAgICAgPSBja2lkOwogIFRoaXMtPmlkeEZyYW1lc1tUaGlzLT5sTGFzdEZyYW1lXS5kd0ZsYWdzICAgICAgID0gZmxhZ3M7CiAgVGhpcy0+aWR4RnJhbWVzW1RoaXMtPmxMYXN0RnJhbWVdLmR3Q2h1bmtPZmZzZXQgPSBvZmZzZXQ7CiAgVGhpcy0+aWR4RnJhbWVzW1RoaXMtPmxMYXN0RnJhbWVdLmR3Q2h1bmtMZW5ndGggPSBzaXplOwoKICAvKiB1cGRhdGUgQVZJU1RSRUFNSU5GTyBzdHJ1Y3R1cmUgaWYgbmVjZXNzYXJ5ICovCiAgaWYgKFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDw9IFRoaXMtPmxMYXN0RnJhbWUpCiAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCA9IFRoaXMtPmxMYXN0RnJhbWUgKyAxOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZFJlY29yZChJQVZJRmlsZUltcGwgKlRoaXMpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwgJiYgVGhpcy0+cHBTdHJlYW1zWzBdICE9IE5VTEwpOwoKICBpZiAoVGhpcy0+aWR4UmVjb3JkcyA9PSBOVUxMIHx8IFRoaXMtPmNiSWR4UmVjb3JkcyA9PSAwKSB7CiAgICBUaGlzLT5jYklkeFJlY29yZHMgKz0gMTAyNCAqIHNpemVvZihBVklJTkRFWEVOVFJZKTsKICAgIFRoaXMtPmlkeFJlY29yZHMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgVGhpcy0+Y2JJZHhSZWNvcmRzKTsKICAgIGlmIChUaGlzLT5pZHhSZWNvcmRzID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIH0KCiAgYXNzZXJ0KFRoaXMtPm5JZHhSZWNvcmRzIDwgVGhpcy0+Y2JJZHhSZWNvcmRzL3NpemVvZihBVklJTkRFWEVOVFJZKSk7CgogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmNraWQgICAgICAgICAgPSBsaXN0dHlwZUFWSVJFQ09SRDsKICBUaGlzLT5pZHhSZWNvcmRzW1RoaXMtPm5JZHhSZWNvcmRzXS5kd0ZsYWdzICAgICAgID0gQVZJSUZfTElTVDsKICBUaGlzLT5pZHhSZWNvcmRzW1RoaXMtPm5JZHhSZWNvcmRzXS5kd0NodW5rT2Zmc2V0ID0KICAgIFRoaXMtPmNrTGFzdFJlY29yZC5kd0RhdGFPZmZzZXQgLSAyICogc2l6ZW9mKERXT1JEKTsKICBUaGlzLT5pZHhSZWNvcmRzW1RoaXMtPm5JZHhSZWNvcmRzXS5kd0NodW5rTGVuZ3RoID0KICAgIFRoaXMtPmNrTGFzdFJlY29yZC5ja3NpemU7CiAgVGhpcy0+bklkeFJlY29yZHMrKzsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIERXT1JEICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KElBVklGaWxlSW1wbCAqVGhpcykKewogIERXT1JEIGR3UG9zOwogIERXT1JEIG5TdHJlYW07CgogIC8qIFJJRkYsaGRybCxtb3ZpLGF2aWggPT4gKDMgKiAzICsgMikgKiBzaXplb2YoRFdPUkQpID0gMTEgKiBzaXplb2YoRFdPUkQpICovCiAgZHdQb3MgPSAxMSAqIHNpemVvZihEV09SRCkgKyBzaXplb2YoTWFpbkFWSUhlYWRlcik7CgogIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgogICAgLyogc3RybCxzdHJoLHN0cmYgPT4gKDMgKyAyICogMikgKiBzaXplb2YoRFdPUkQpID0gNyAqIHNpemVvZihEV09SRCkgKi8KICAgIGR3UG9zICs9IDcgKiBzaXplb2YoRFdPUkQpICsgc2l6ZW9mKEFWSVN0cmVhbUhlYWRlcik7CiAgICBkd1BvcyArPSAoKHBTdHJlYW0tPmNiRm9ybWF0ICsgMSkgJiB+MVUpOwogICAgaWYgKHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgIT0gTlVMTCAmJiBwU3RyZWFtLT5jYkhhbmRsZXJEYXRhID4gMCkKICAgICAgZHdQb3MgKz0gMiAqIHNpemVvZihEV09SRCkgKyAoKHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgKyAxKSAmIH4xVSk7CiAgICBpZiAobHN0cmxlblcocFN0cmVhbS0+c0luZm8uc3pOYW1lKSA+IDApCiAgICAgIGR3UG9zICs9IDIgKiBzaXplb2YoRFdPUkQpICsgKChsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpICsgMSkgJiB+MVUpOwogIH0KCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApIHsKICAgIFRoaXMtPmR3TmV4dEZyYW1lUG9zID0gZHdQb3M7CgogICAgLyogcGFkIHRvIG11bHRpcGxlIG9mIEFWSV9IRUFERVJTSVpFIG9ubHkgaWYgd2UgYXJlIG1vcmUgdGhhbiA4IGJ5dGVzIGF3YXkgZnJvbSBpdCAqLwogICAgaWYgKCgoZHdQb3MgKyBBVklfSEVBREVSU0laRSkgJiB+KEFWSV9IRUFERVJTSVpFIC0gMSkpIC0gZHdQb3MgPiAyICogc2l6ZW9mKERXT1JEKSkKICAgICAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgPSAoZHdQb3MgKyBBVklfSEVBREVSU0laRSkgJiB+KEFWSV9IRUFERVJTSVpFIC0gMSk7CgogICAgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPSBUaGlzLT5kd05leHRGcmFtZVBvcyAtIHNpemVvZihEV09SRCk7CiAgfQoKICByZXR1cm4gZHdQb3M7Cn0KCnN0YXRpYyB2b2lkIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKElBVklGaWxlSW1wbCAqcGFmLCBEV09SRCBuciwgY29uc3QgQVZJU1RSRUFNSU5GT1cgKmFzaSkKewogIElBVklTdHJlYW1JbXBsICpwc3RyZWFtOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChwYWYgIT0gTlVMTCk7CiAgYXNzZXJ0KG5yIDwgTUFYX0FWSVNUUkVBTVMpOwogIGFzc2VydChwYWYtPnBwU3RyZWFtc1tucl0gIT0gTlVMTCk7CgogIHBzdHJlYW0gPSBwYWYtPnBwU3RyZWFtc1tucl07CgogIHBzdHJlYW0tPmxwVnRibCAgICAgICAgID0gJmlhdmlzdDsKICBwc3RyZWFtLT5yZWYgICAgICAgICAgICA9IDA7CiAgcHN0cmVhbS0+cGFmICAgICAgICAgICAgPSBwYWY7CiAgcHN0cmVhbS0+blN0cmVhbSAgICAgICAgPSBucjsKICBwc3RyZWFtLT5kd0N1cnJlbnRGcmFtZSA9IChEV09SRCktMTsKICBwc3RyZWFtLT5sTGFzdEZyYW1lICAgID0gLTE7CgogIGlmIChhc2kgIT0gTlVMTCkgewogICAgbWVtY3B5KCZwc3RyZWFtLT5zSW5mbywgYXNpLCBzaXplb2YocHN0cmVhbS0+c0luZm8pKTsKCiAgICBpZiAoYXNpLT5kd0xlbmd0aCA+IDApIHsKICAgICAgLyogcHJlLWFsbG9jYXRlIG1lbSBmb3IgZnJhbWUtaW5kZXggc3RydWN0dXJlICovCiAgICAgIHBzdHJlYW0tPmlkeEZyYW1lcyA9CglIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgYXNpLT5kd0xlbmd0aCAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGlmIChwc3RyZWFtLT5pZHhGcmFtZXMgIT0gTlVMTCkKCXBzdHJlYW0tPm5JZHhGcmFtZXMgPSBhc2ktPmR3TGVuZ3RoOwogICAgfQogICAgaWYgKGFzaS0+ZHdGb3JtYXRDaGFuZ2VDb3VudCA+IDApIHsKICAgICAgLyogcHJlLWFsbG9jYXRlIG1lbSBmb3IgZm9ybWF0Y2hhbmdlLWluZGV4IHN0cnVjdHVyZSAqLwogICAgICBwc3RyZWFtLT5pZHhGbXRDaGFuZ2VzID0KCUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBhc2ktPmR3Rm9ybWF0Q2hhbmdlQ291bnQgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBpZiAocHN0cmVhbS0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMKQoJcHN0cmVhbS0+bklkeEZtdENoYW5nZXMgPSBhc2ktPmR3Rm9ybWF0Q2hhbmdlQ291bnQ7CiAgICB9CgogICAgLyogVGhlc2UgdmFsdWVzIHdpbGwgYmUgY29tcHV0ZWQgKi8KICAgIHBzdHJlYW0tPnNJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IDA7CiAgICBwc3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSAwOwogICAgcHN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAgID0gMDsKICAgIHBzdHJlYW0tPnNJbmZvLmR3RWRpdENvdW50ICAgICAgICAgICA9IDE7CiAgICBpZiAocHN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplID4gMCkKICAgICAgU2V0UmVjdEVtcHR5KCZwc3RyZWFtLT5zSW5mby5yY0ZyYW1lKTsKICB9CgogIHBzdHJlYW0tPnNJbmZvLmR3Q2FwcyA9IEFWSUZJTEVDQVBTX0NBTlJFQUR8QVZJRklMRUNBUFNfQ0FOV1JJVEU7Cn0KCnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oSUFWSVN0cmVhbUltcGwgKlRoaXMpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwoKICBUaGlzLT5kd0N1cnJlbnRGcmFtZSA9IChEV09SRCktMTsKICBUaGlzLT5sTGFzdEZyYW1lICAgID0gLTE7CiAgVGhpcy0+cGFmID0gTlVMTDsKICBpZiAoVGhpcy0+aWR4RnJhbWVzICE9IE5VTEwpIHsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmlkeEZyYW1lcyk7CiAgICBUaGlzLT5pZHhGcmFtZXMgID0gTlVMTDsKICAgIFRoaXMtPm5JZHhGcmFtZXMgPSAwOwogIH0KICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5pZHhGbXRDaGFuZ2VzKTsKICBUaGlzLT5pZHhGbXRDaGFuZ2VzID0gTlVMTDsKICBpZiAoVGhpcy0+bHBCdWZmZXIgIT0gTlVMTCkgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBCdWZmZXIpOwogICAgVGhpcy0+bHBCdWZmZXIgPSBOVUxMOwogICAgVGhpcy0+Y2JCdWZmZXIgPSAwOwogIH0KICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scEhhbmRsZXJEYXRhKTsKICAgIFRoaXMtPmxwSGFuZGxlckRhdGEgPSBOVUxMOwogICAgVGhpcy0+Y2JIYW5kbGVyRGF0YSA9IDA7CiAgfQogIGlmIChUaGlzLT5leHRyYS5scCAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5leHRyYS5scCk7CiAgICBUaGlzLT5leHRyYS5scCA9IE5VTEw7CiAgICBUaGlzLT5leHRyYS5jYiA9IDA7CiAgfQogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scEZvcm1hdCk7CiAgICBUaGlzLT5scEZvcm1hdCA9IE5VTEw7CiAgICBUaGlzLT5jYkZvcm1hdCA9IDA7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIE1haW5BVklIZWFkZXIgICBNYWluQVZJSGRyOwogIE1NQ0tJTkZPICAgICAgICBja1JJRkY7CiAgTU1DS0lORk8gICAgICAgIGNrTElTVDE7CiAgTU1DS0lORk8gICAgICAgIGNrTElTVDI7CiAgTU1DS0lORk8gICAgICAgIGNrOwogIElBVklTdHJlYW1JbXBsICpwU3RyZWFtOwogIERXT1JEICAgICAgICAgICBuU3RyZWFtOwogIEhSRVNVTFQgICAgICAgICBocjsKCiAgaWYgKFRoaXMtPmhtbWlvID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVPUEVOOwoKICAvKiBpbml0aWFsaXplIHN0cmVhbSBwdHIncyAqLwogIG1lbXNldChUaGlzLT5wcFN0cmVhbXMsIDAsIHNpemVvZihUaGlzLT5wcFN0cmVhbXMpKTsKCiAgLyogdHJ5IHRvIGdldCAiUklGRiIgY2h1bmsgLS0gbXVzdCBub3QgYmUgYXQgYmVnaW5uaW5nIG9mIGZpbGUhICovCiAgY2tSSUZGLmZjY1R5cGUgPSBmb3JtdHlwZUFWSTsKICBpZiAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZja1JJRkYsIE5VTEwsIE1NSU9fRklORFJJRkYpICE9IFNfT0spIHsKICAgIEVSUigiOiBub3QgYW4gQVZJIVxuIik7CiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIH0KCiAgLyogZ2V0ICJMSVNUIiAiaGRybCIgKi8KICBja0xJU1QxLmZjY1R5cGUgPSBsaXN0dHlwZUFWSUhFQURFUjsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZja0xJU1QxLCAmY2tSSUZGLCBNTUlPX0ZJTkRMSVNUKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgLyogZ2V0ICJhdmloIiBjaHVuayAqLwogIGNrLmNraWQgPSBja2lkQVZJTUFJTkhEUjsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDEsIE1NSU9fRklORENIVU5LKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgaWYgKGNrLmNrc2l6ZSAhPSBzaXplb2YoTWFpbkFWSUhkcikpIHsKICAgIEVSUigiOiBpbnZhbGlkIHNpemUgb2YgJWQgZm9yIE1haW5BVklIZWFkZXIhXG4iLCBjay5ja3NpemUpOwogICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CiAgfQogIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKSZNYWluQVZJSGRyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIGNoZWNrIGZvciBNQVhfQVZJU1RSRUFNUyBsaW1pdCAqLwogIGlmIChNYWluQVZJSGRyLmR3U3RyZWFtcyA+IE1BWF9BVklTVFJFQU1TKSB7CiAgICBXQVJOKCJmaWxlIGNvbnRhaW5zICV1IHN0cmVhbXMsIGJ1dCBvbmx5IHN1cHBvcnRzICVkIC0tIGNoYW5nZSBNQVhfQVZJU1RSRUFNUyFcbiIsIE1haW5BVklIZHIuZHdTdHJlYW1zLCBNQVhfQVZJU1RSRUFNUyk7CiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgLyogYWRqdXN0IHBlcm1pc3Npb25zIGlmIGNvcHlyaWdodGVkIG1hdGVyaWFsIGluIGZpbGUgKi8KICBpZiAoTWFpbkFWSUhkci5kd0ZsYWdzICYgQVZJRklMRUlORk9fQ09QWVJJR0hURUQpIHsKICAgIFRoaXMtPnVNb2RlICY9IH5NTUlPX1JXTU9ERTsKICAgIFRoaXMtPnVNb2RlIHw9IE1NSU9fUkVBRDsKICB9CgogIC8qIGNvbnZlcnQgTWFpbkFWSUhlYWRlciBpbnRvIEFWSUZJTElORk9XICovCiAgbWVtc2V0KCZUaGlzLT5mSW5mbywgMCwgc2l6ZW9mKFRoaXMtPmZJbmZvKSk7CiAgVGhpcy0+ZkluZm8uZHdSYXRlICAgICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd01pY3JvU2VjUGVyRnJhbWU7CiAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gMTAwMDAwMDsKICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICAgICAgPSBNYWluQVZJSGRyLmR3TWF4Qnl0ZXNQZXJTZWM7CiAgVGhpcy0+ZkluZm8uZHdGbGFncyAgICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd0ZsYWdzOwogIFRoaXMtPmZJbmZvLmR3Q2FwcyAgICAgICAgICAgICAgICA9IEFWSUZJTEVDQVBTX0NBTlJFQUR8QVZJRklMRUNBUFNfQ0FOV1JJVEU7CiAgVGhpcy0+ZkluZm8uZHdMZW5ndGggICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd1RvdGFsRnJhbWVzOwogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdTdHJlYW1zOwogIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IE1haW5BVklIZHIuZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwogIFRoaXMtPmZJbmZvLmR3V2lkdGggICAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdXaWR0aDsKICBUaGlzLT5mSW5mby5kd0hlaWdodCAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3SGVpZ2h0OwogIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX0FWSUZJTEVUWVBFLCBUaGlzLT5mSW5mby5zekZpbGVUeXBlLAoJICAgICAgc2l6ZW9mKFRoaXMtPmZJbmZvLnN6RmlsZVR5cGUpL3NpemVvZihUaGlzLT5mSW5mby5zekZpbGVUeXBlWzBdKSk7CgogIC8qIGdvIGJhY2sgdG8gaW50byBoZWFkZXIgbGlzdCAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBmb3JlYWNoIHN0cmVhbSBleGlzdHMgYSAiTElTVCIsInN0cmwiIGNodW5rICovCiAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICAvKiBnZXQgbmV4dCBuZXN0ZWQgY2h1bmsgaW4gdGhpcyAiTElTVCIsInN0cmwiICovCiAgICBpZiAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QyLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgICAvKiBuZXN0ZWQgY2h1bmsgbXVzdCBiZSBvZiB0eXBlICJMSVNUIiwic3RybCIgLS0gd2hlbiBub3Qgbm9ybWFsbHkgSlVOSyAqLwogICAgaWYgKGNrTElTVDIuY2tpZCA9PSBGT1VSQ0NfTElTVCAmJgoJY2tMSVNUMi5mY2NUeXBlID09IGxpc3R0eXBlU1RSRUFNSEVBREVSKSB7CiAgICAgIHBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0gPQoJSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogICAgICBpZiAocFN0cmVhbSA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICAgIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKFRoaXMsIG5TdHJlYW0sIE5VTEwpOwoKICAgICAgY2suY2tpZCA9IDA7CiAgICAgIHdoaWxlIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrLCAmY2tMSVNUMiwgMCkgPT0gU19PSykgewoJc3dpdGNoIChjay5ja2lkKSB7CgljYXNlIGNraWRTVFJFQU1IQU5ETEVSREFUQToKCSAgaWYgKHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgIT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCSAgcFN0cmVhbS0+bHBIYW5kbGVyRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjay5ja3NpemUpOwoJICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSA9PSBOVUxMKQoJICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoJICBwU3RyZWFtLT5jYkhhbmRsZXJEYXRhID0gY2suY2tzaXplOwoKCSAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+bHBIYW5kbGVyRGF0YSwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCgkgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCSAgYnJlYWs7CgljYXNlIGNraWRTVFJFQU1GT1JNQVQ6CgkgIGlmIChwU3RyZWFtLT5scEZvcm1hdCAhPSBOVUxMKQoJICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwogICAgICAgICAgaWYgKGNrLmNrc2l6ZSA9PSAwKQogICAgICAgICAgICBicmVhazsKCgkgIHBTdHJlYW0tPmxwRm9ybWF0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNrLmNrc2l6ZSk7CgkgIGlmIChwU3RyZWFtLT5scEZvcm1hdCA9PSBOVUxMKQoJICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoJICBwU3RyZWFtLT5jYkZvcm1hdCA9IGNrLmNrc2l6ZTsKCgkgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKXBTdHJlYW0tPmxwRm9ybWF0LCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCSAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKCSAgaWYgKHBTdHJlYW0tPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CgkgICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmkgPSAoTFBCSVRNQVBJTkZPSEVBREVSKXBTdHJlYW0tPmxwRm9ybWF0OwoKCSAgICAvKiBzb21lIGNvcnJlY3Rpb25zIHRvIHRoZSB2aWRlbyBmb3JtYXQgKi8KCSAgICBpZiAobHBiaS0+YmlDbHJVc2VkID09IDAgJiYgbHBiaS0+YmlCaXRDb3VudCA8PSA4KQoJICAgICAgbHBiaS0+YmlDbHJVc2VkID0gMXUgPDwgbHBiaS0+YmlCaXRDb3VudDsKCSAgICBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiA9PSBCSV9SR0IgJiYgbHBiaS0+YmlTaXplSW1hZ2UgPT0gMCkKCSAgICAgIGxwYmktPmJpU2l6ZUltYWdlID0gRElCV0lEVEhCWVRFUygqbHBiaSkgKiBscGJpLT5iaUhlaWdodDsKCSAgICBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiAhPSBCSV9SR0IgJiYgbHBiaS0+YmlCaXRDb3VudCA9PSA4KSB7CgkgICAgICBpZiAocFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciA9PSBtbWlvRk9VUkNDKCdSJywnTCcsJ0UnLCcwJykgfHwKCQkgIHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gbW1pb0ZPVVJDQygnUicsJ0wnLCdFJywnICcpKQoJCWxwYmktPmJpQ29tcHJlc3Npb24gPSBCSV9STEU4OwoJICAgIH0KCSAgICBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiA9PSBCSV9SR0IgJiYKCQkocFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciA9PSAwIHx8CgkJIHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gbW1pb0ZPVVJDQygnTicsJ08nLCdOJywnRScpKSkKCSAgICAgIHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPSBjb21wdHlwZURJQjsKCgkgICAgLyogaW5pdCByY0ZyYW1lIGlmIGl0J3MgZW1wdHkgKi8KCSAgICBpZiAoSXNSZWN0RW1wdHkoJnBTdHJlYW0tPnNJbmZvLnJjRnJhbWUpKQoJICAgICAgU2V0UmVjdCgmcFN0cmVhbS0+c0luZm8ucmNGcmFtZSwgMCwgMCwgbHBiaS0+YmlXaWR0aCwgbHBiaS0+YmlIZWlnaHQpOwoJICB9CgkgIGJyZWFrOwoJY2FzZSBja2lkU1RSRUFNSEVBREVSOgoJICB7CgkgICAgc3RhdGljIGNvbnN0IFdDSEFSIHN0cmVhbVR5cGVGbXRbXSA9IHsnJScsJzQnLCcuJywnNCcsJ2gnLCdzJywwfTsKCgkgICAgQVZJU3RyZWFtSGVhZGVyIHN0cmVhbUhkcjsKCSAgICBXQ0hBUiAgICAgICAgICAgc3pUeXBlWzI1XTsKCSAgICBXQ0hBUiAgICAgICAgICAgc3RyZWFtTmFtZUZtdFsyNV07CgkgICAgVUlOVCAgICAgICAgICAgIGNvdW50OwoJICAgIExPTkcgICAgICAgICAgICBuID0gY2suY2tzaXplOwoKCSAgICBpZiAoY2suY2tzaXplID4gc2l6ZW9mKHN0cmVhbUhkcikpCgkgICAgICBuID0gc2l6ZW9mKHN0cmVhbUhkcik7CgoJICAgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKSZzdHJlYW1IZHIsIG4pICE9IG4pCgkgICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKCSAgICBwU3RyZWFtLT5zSW5mby5mY2NUeXBlICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZmNjVHlwZTsKCSAgICBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyICAgICAgICAgICAgPSBzdHJlYW1IZHIuZmNjSGFuZGxlcjsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0ZsYWdzICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdGbGFnczsKCSAgICBwU3RyZWFtLT5zSW5mby53UHJpb3JpdHkgICAgICAgICAgICAgPSBzdHJlYW1IZHIud1ByaW9yaXR5OwoJICAgIHBTdHJlYW0tPnNJbmZvLndMYW5ndWFnZSAgICAgICAgICAgICA9IHN0cmVhbUhkci53TGFuZ3VhZ2U7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdJbml0aWFsRnJhbWVzICAgICAgID0gc3RyZWFtSGRyLmR3SW5pdGlhbEZyYW1lczsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1NjYWxlICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdTY2FsZTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdSYXRlOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3U3RhcnQgICAgICAgICAgICAgICA9IHN0cmVhbUhkci5kd1N0YXJ0OwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IHN0cmVhbUhkci5kd0xlbmd0aDsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPQoJICAgICAgc3RyZWFtSGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1F1YWxpdHkgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdRdWFsaXR5OwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3U2FtcGxlU2l6ZSAgICAgICAgICA9IHN0cmVhbUhkci5kd1NhbXBsZVNpemU7CgkgICAgcFN0cmVhbS0+c0luZm8ucmNGcmFtZS5sZWZ0ICAgICAgICAgID0gc3RyZWFtSGRyLnJjRnJhbWUubGVmdDsKCSAgICBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnRvcCAgICAgICAgICAgPSBzdHJlYW1IZHIucmNGcmFtZS50b3A7CgkgICAgcFN0cmVhbS0+c0luZm8ucmNGcmFtZS5yaWdodCAgICAgICAgID0gc3RyZWFtSGRyLnJjRnJhbWUucmlnaHQ7CgkgICAgcFN0cmVhbS0+c0luZm8ucmNGcmFtZS5ib3R0b20gICAgICAgID0gc3RyZWFtSGRyLnJjRnJhbWUuYm90dG9tOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3RWRpdENvdW50ICAgICAgICAgICA9IDA7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAgID0gMDsKCgkgICAgLyogZ2VuZXJhdGUgZGVzY3JpcHRpb24gZm9yIHN0cmVhbSBsaWtlICJmaWxlbmFtZS5hdmkgVHlwZSAjbiIgKi8KCSAgICBpZiAoc3RyZWFtSGRyLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKQoJICAgICAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfVklERU8sIHN6VHlwZSwgc2l6ZW9mKHN6VHlwZSkvc2l6ZW9mKHN6VHlwZVswXSkpOwoJICAgIGVsc2UgaWYgKHN0cmVhbUhkci5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKCSAgICAgIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX0FVRElPLCBzelR5cGUsIHNpemVvZihzelR5cGUpL3NpemVvZihzelR5cGVbMF0pKTsKCSAgICBlbHNlCgkgICAgICB3c3ByaW50Zlcoc3pUeXBlLCBzdHJlYW1UeXBlRm10LCAoY2hhciopJnN0cmVhbUhkci5mY2NUeXBlKTsKCgkgICAgLyogZ2V0IGNvdW50IG9mIHRoaXMgc3RyZWFtdHlwZSB1cCB0byB0aGlzIHN0cmVhbSAqLwoJICAgIGNvdW50ID0gMDsKCSAgICBmb3IgKG4gPSBuU3RyZWFtOyAwIDw9IG47IG4tLSkgewoJICAgICAgaWYgKFRoaXMtPnBwU3RyZWFtc1tuXS0+c0luZm8uZmNjSGFuZGxlciA9PSBzdHJlYW1IZHIuZmNjVHlwZSkKCQljb3VudCsrOwoJICAgIH0KCgkgICAgbWVtc2V0KHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwgMCwgc2l6ZW9mKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkpOwoKCSAgICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19BVklTVFJFQU1GT1JNQVQsIHN0cmVhbU5hbWVGbXQsIHNpemVvZihzdHJlYW1OYW1lRm10KS9zaXplb2Yoc3RyZWFtTmFtZUZtdFswXSkpOwoKCSAgICAvKiBGSVhNRTogYXZvaWQgb3ZlcmZsb3cgLS0gYmV0dGVyIHVzZSB3c25wcmludGZXLCB3aGljaCBkb2Vzbid0IGV4aXN0cyAhICovCgkgICAgd3NwcmludGZXKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwgc3RyZWFtTmFtZUZtdCwKCQkgICAgICBBVklGSUxFX0Jhc2VuYW1lVyhUaGlzLT5zekZpbGVOYW1lKSwgc3pUeXBlLCBjb3VudCk7CgkgIH0KCSAgYnJlYWs7CgljYXNlIGNraWRTVFJFQU1OQU1FOgoJICB7IC8qIHN0cmVhbW5hbWUgd2lsbCBiZSBzYXZlZCBhcyBBU0NJSSBzdHJpbmcgKi8KCSAgICBMUFNUUiBzdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKCSAgICBpZiAoc3RyID09IE5VTEwpCgkgICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCgkgICAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCBzdHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJICAgIHsKCSAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cik7CgkgICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoJICAgIH0KCgkgICAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIHN0ciwgLTEsIHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwKCQkJCXNpemVvZihwU3RyZWFtLT5zSW5mby5zek5hbWUpL3NpemVvZihwU3RyZWFtLT5zSW5mby5zek5hbWVbMF0pKTsKCgkgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyKTsKCSAgfQoJICBicmVhazsKCWNhc2UgY2tpZEFWSVBBRERJTkc6CgljYXNlIG1taW9GT1VSQ0MoJ3AnLCdhJywnZCcsJ2QnKToKCSAgYnJlYWs7CglkZWZhdWx0OgogICAgICAgICAgV0FSTigiOiBmb3VuZCBleHRyYSBjaHVuayAweCUwOFhcbiIsIGNrLmNraWQpOwoJICBociA9IFJlYWRDaHVua0ludG9FeHRyYSgmcFN0cmVhbS0+ZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2spOwoJICBpZiAoRkFJTEVEKGhyKSkKCSAgICByZXR1cm4gaHI7Cgl9OwoKCWlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCgkgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIC8qIG5lc3RlZCBjaHVua3MgaW4gIkxJU1QiLCJoZHJsIiB3aGljaCBhcmUgbm90IG9mIHR5cGUgIkxJU1QiLCJzdHJsIiAqLwogICAgICBociA9IFJlYWRDaHVua0ludG9FeHRyYSgmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrTElTVDIpOwogICAgICBpZiAoRkFJTEVEKGhyKSkKCXJldHVybiBocjsKICAgIH0KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMiwgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICB9CgogIC8qIHJlYWQgYW55IGV4dHJhIGhlYWRlcnMgaW4gIkxJU1QiLCJoZHJsIiAqLwogIEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDEsIDApOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIHNlYXJjaCAiTElTVCIsIm1vdmkiIGNodW5rIGluICJSSUZGIiwiQVZJICIgKi8KICBja0xJU1QxLmZjY1R5cGUgPSBsaXN0dHlwZUFWSU1PVklFOwogIGhyID0gRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrTElTVDEsICZja1JJRkYsCgkJCSAgICAgIE1NSU9fRklORExJU1QpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICBUaGlzLT5kd01vdmlDaHVua1BvcyA9IGNrTElTVDEuZHdEYXRhT2Zmc2V0OwogIFRoaXMtPmR3SWR4Q2h1bmtQb3MgID0gY2tMSVNUMS5ja3NpemUgKyBja0xJU1QxLmR3RGF0YU9mZnNldDsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiB0cnkgdG8gZmluZCBhbiBpbmRleCAqLwogIGNrLmNraWQgPSBja2lkQVZJTkVXSU5ERVg7CiAgaHIgPSBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLAoJCQkgICAgICAmY2ssICZja1JJRkYsIE1NSU9fRklORENIVU5LKTsKICBpZiAoU1VDQ0VFREVEKGhyKSAmJiBjay5ja3NpemUgPiAwKSB7CiAgICBpZiAoRkFJTEVEKEFWSUZJTEVfTG9hZEluZGV4KFRoaXMsIGNrLmNrc2l6ZSwgY2tMSVNUMS5kd0RhdGFPZmZzZXQpKSkKICAgICAgVGhpcy0+ZkluZm8uZHdGbGFncyAmPSB+QVZJRklMRUlORk9fSEFTSU5ERVg7CiAgfQoKICAvKiB3aGVuIHdlIGhhdmVuJ3QgZm91bmQgYW4gaW5kZXggb3IgaXQncyBiYWQsIHRoZW4gYnVpbGQgb25lCiAgICogYnkgcGFyc2luZyAnbW92aScgY2h1bmsgKi8KICBpZiAoKFRoaXMtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19IQVNJTkRFWCkgPT0gMCkgewogICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKQogICAgICBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPmxMYXN0RnJhbWUgPSAtMTsKCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIGNrTElTVDEuZHdEYXRhT2Zmc2V0ICsgc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpID09IC0xKSB7CiAgICAgIEVSUigiOiBPb3BzLCBjYW4ndCBzZWVrIGJhY2sgdG8gJ21vdmknIGNodW5rIVxuIik7CiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICB9CgogICAgLyogc2VlayB0aHJvdWdoIHRoZSAnbW92aScgbGlzdCB1bnRpbCBlbmQgKi8KICAgIHdoaWxlIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrLCAmY2tMSVNUMSwgMCkgPT0gU19PSykgewogICAgICBpZiAoY2suY2tpZCAhPSBGT1VSQ0NfTElTVCkgewoJaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgPT0gU19PSykgewoJICBuU3RyZWFtID0gU3RyZWFtRnJvbUZPVVJDQyhjay5ja2lkKTsKCgkgIGlmIChuU3RyZWFtID4gVGhpcy0+ZkluZm8uZHdTdHJlYW1zKQoJICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKCSAgQVZJRklMRV9BZGRGcmFtZShUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0sIGNrLmNraWQsIGNrLmNrc2l6ZSwKCQkJICAgY2suZHdEYXRhT2Zmc2V0IC0gMiAqIHNpemVvZihEV09SRCksIDApOwoJfSBlbHNlIHsKCSAgblN0cmVhbSA9IFN0cmVhbUZyb21GT1VSQ0MoY2suY2tpZCk7CgkgIFdBUk4oIjogZmlsZSBzZWVtcyB0byBiZSB0cnVuY2F0ZWQhXG4iKTsKCSAgaWYgKG5TdHJlYW0gPD0gVGhpcy0+ZkluZm8uZHdTdHJlYW1zICYmCgkgICAgICBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPnNJbmZvLmR3U2FtcGxlU2l6ZSA+IDApIHsKCSAgICBjay5ja3NpemUgPSBtbWlvU2VlayhUaGlzLT5obW1pbywgMCwgU0VFS19FTkQpOwoJICAgIGlmIChjay5ja3NpemUgIT0gLTEpIHsKCSAgICAgIGNrLmNrc2l6ZSAtPSBjay5kd0RhdGFPZmZzZXQ7CgkgICAgICBjay5ja3NpemUgJj0gfihUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPnNJbmZvLmR3U2FtcGxlU2l6ZSAtIDEpOwoKCSAgICAgIEFWSUZJTEVfQWRkRnJhbWUoVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLCBjay5ja2lkLCBjay5ja3NpemUsCgkJCSAgICAgICBjay5kd0RhdGFPZmZzZXQgLSAyICogc2l6ZW9mKERXT1JEKSwgMCk7CgkgICAgfQoJICB9Cgl9CiAgICAgIH0KICAgIH0KICB9CgogIC8qIGZpbmQgb3RoZXIgY2h1bmtzICovCiAgRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrLCAmY2tSSUZGLCAwKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkSW5kZXgoY29uc3QgSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBzaXplLCBEV09SRCBvZmZzZXQpCnsKICBBVklJTkRFWEVOVFJZICpscDsKICBEV09SRCAgICAgICAgICBwb3MsIG47CiAgSFJFU1VMVCAgICAgICAgaHIgPSBBVklFUlJfT0s7CiAgQk9PTCAgICAgICAgICAgYkFic29sdXRlID0gVFJVRTsKCiAgbHAgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgSURYX1BFUl9CTE9DSyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogYWRqdXN0IGxpbWl0cyBmb3IgaW5kZXggdGFibGVzLCBzbyB0aGF0IGluc2VydGluZyB3aWxsIGJlIGZhc3RlciAqLwogIGZvciAobiA9IDA7IG4gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG4rKykgewogICAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbbl07CgogICAgcFN0cmVhbS0+bExhc3RGcmFtZSA9IC0xOwoKICAgIGlmIChwU3RyZWFtLT5pZHhGcmFtZXMgIT0gTlVMTCkgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwU3RyZWFtLT5pZHhGcmFtZXMpOwogICAgICBwU3RyZWFtLT5pZHhGcmFtZXMgID0gTlVMTDsKICAgICAgcFN0cmVhbS0+bklkeEZyYW1lcyA9IDA7CiAgICB9CgogICAgaWYgKHBTdHJlYW0tPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAgIGlmIChuID4gMCAmJiBUaGlzLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSVNJTlRFUkxFQVZFRCkgewoJcFN0cmVhbS0+bklkeEZyYW1lcyA9IFRoaXMtPnBwU3RyZWFtc1swXS0+bklkeEZyYW1lczsKICAgICAgfSBlbHNlIGlmIChwU3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpIHsKCXBTdHJlYW0tPm5JZHhGcmFtZXMgPQoJICBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCAvIHBTdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICAgICAgfQogICAgfSBlbHNlCiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aDsKCiAgICBwU3RyZWFtLT5pZHhGcmFtZXMgPQogICAgICBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgcFN0cmVhbS0+bklkeEZyYW1lcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICBpZiAocFN0cmVhbS0+aWR4RnJhbWVzID09IE5VTEwgJiYgcFN0cmVhbS0+bklkeEZyYW1lcyA+IDApIHsKICAgICAgcFN0cmVhbS0+bklkeEZyYW1lcyA9IDA7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwKTsKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICB9CiAgfQoKICBwb3MgPSAoRFdPUkQpLTE7CiAgd2hpbGUgKHNpemUgIT0gMCkgewogICAgTE9ORyByZWFkID0gbWluKElEWF9QRVJfQkxPQ0sgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSksIHNpemUpOwoKICAgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKWxwLCByZWFkKSAhPSByZWFkKSB7CiAgICAgIGhyID0gQVZJRVJSX0ZJTEVSRUFEOwogICAgICBicmVhazsKICAgIH0KICAgIHNpemUgLT0gcmVhZDsKCiAgICBpZiAocG9zID09IChEV09SRCktMSkKICAgICAgcG9zID0gb2Zmc2V0IC0gbHAtPmR3Q2h1bmtPZmZzZXQgKyBzaXplb2YoRFdPUkQpOwoKICAgIEFWSUZJTEVfUGFyc2VJbmRleChUaGlzLCBscCwgcmVhZCAvIHNpemVvZihBVklJTkRFWEVOVFJZKSwKCQkgICAgICAgcG9zLCAmYkFic29sdXRlKTsKICB9CgogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwKTsKCiAgLyogY2hlY2tpbmcgLi4uICovCiAgZm9yIChuID0gMDsgbiA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgbisrKSB7CiAgICBJQVZJU3RyZWFtSW1wbCAqcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuXTsKCiAgICBpZiAocFN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplID09IDAgJiYKCXBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoICE9IHBTdHJlYW0tPmxMYXN0RnJhbWUrMSkKICAgICAgRVJSKCJzdHJlYW0gJXUgbGVuZ3RoIG1pc21hdGNoOiBkd0xlbmd0aD0ldSBmb3VuZD0lZFxuIiwKCSAgIG4sIHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoLCBwU3RyZWFtLT5sTGFzdEZyYW1lKTsKICB9CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9QYXJzZUluZGV4KGNvbnN0IElBVklGaWxlSW1wbCAqVGhpcywgQVZJSU5ERVhFTlRSWSAqbHAsCgkJCQkgIExPTkcgY291bnQsIERXT1JEIHBvcywgQk9PTCAqYkFic29sdXRlKQp7CiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBmb3IgKDsgY291bnQgPiAwOyBjb3VudC0tLCBscCsrKSB7CiAgICBXT1JEIG5TdHJlYW0gPSBTdHJlYW1Gcm9tRk9VUkNDKGxwLT5ja2lkKTsKCiAgICBpZiAobHAtPmNraWQgPT0gbGlzdHR5cGVBVklSRUNPUkQgfHwgblN0cmVhbSA9PSAweDdGKQogICAgICBjb250aW51ZTsgLyogc2tpcCB0aGVzZSAqLwoKICAgIGlmIChuU3RyZWFtID4gVGhpcy0+ZkluZm8uZHdTdHJlYW1zKQogICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCiAgICBpZiAoKmJBYnNvbHV0ZSAmJiBscC0+ZHdDaHVua09mZnNldCA8IFRoaXMtPmR3TW92aUNodW5rUG9zKQogICAgICAqYkFic29sdXRlID0gRkFMU0U7CgogICAgaWYgKCpiQWJzb2x1dGUpCiAgICAgIGxwLT5kd0NodW5rT2Zmc2V0ICs9IHNpemVvZihEV09SRCk7CiAgICBlbHNlCiAgICAgIGxwLT5kd0NodW5rT2Zmc2V0ICs9IHBvczsKCiAgICBpZiAoRkFJTEVEKEFWSUZJTEVfQWRkRnJhbWUoVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLCBscC0+Y2tpZCwgbHAtPmR3Q2h1bmtMZW5ndGgsIGxwLT5kd0NodW5rT2Zmc2V0LCBscC0+ZHdGbGFncykpKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUmVhZEJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBwb3MsCgkJCQkgTFBWT0lEIGJ1ZmZlciwgTE9ORyBzaXplKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5wYWYtPmhtbWlvICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5zSW5mby5kd1N0YXJ0IDw9IHBvcyAmJiBwb3MgPCBUaGlzLT5zSW5mby5kd0xlbmd0aCk7CiAgYXNzZXJ0KHBvcyA8PSBUaGlzLT5sTGFzdEZyYW1lKTsKCiAgLyogc2hvdWxkIHdlIHJlYWQgYXMgbXVjaCBhcyBibG9jayBnaXZlcyB1cz8gKi8KICBpZiAoc2l6ZSA9PSAwIHx8IHNpemUgPiBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoKQogICAgc2l6ZSA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGg7CgogIC8qIHJlYWQgaW50byBvdXQgb3duIGJ1ZmZlciBvciBnaXZlbiBvbmU/ICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMKSB7CiAgICAvKiB3ZSBhbHNvIHJlYWQgdGhlIGNodW5rICovCiAgICBzaXplICs9IDIgKiBzaXplb2YoRFdPUkQpOwoKICAgIC8qIGNoZWNrIHRoYXQgYnVmZmVyIGlzIGJpZyBlbm91Z2ggLS0gZG9uJ3QgdHJ1c3QgZHdTdWdnZXN0ZWRCdWZmZXJTaXplICovCiAgICBpZiAoVGhpcy0+bHBCdWZmZXIgPT0gTlVMTCB8fCBzaXplIDwgVGhpcy0+Y2JCdWZmZXIpIHsKICAgICAgRFdPUkQgbWF4U2l6ZSA9IG1heChzaXplLCBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwoKICAgICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwpCglUaGlzLT5scEJ1ZmZlciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBtYXhTaXplKTsKICAgICAgZWxzZQoJVGhpcy0+bHBCdWZmZXIgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scEJ1ZmZlciwgbWF4U2l6ZSk7CiAgICAgIGlmIChUaGlzLT5scEJ1ZmZlciA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICAgIFRoaXMtPmNiQnVmZmVyID0gbWF4KHNpemUsIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CiAgICB9CgogICAgLyogbm93IHJlYWQgdGhlIGNvbXBsZXRlIGNodW5rIGludG8gb3VyIGJ1ZmZlciAqLwogICAgaWYgKG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQsIFNFRUtfU0VUKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIGlmIChtbWlvUmVhZChUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpVGhpcy0+bHBCdWZmZXIsIHNpemUpICE9IHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogICAgLyogY2hlY2sgaWYgaXQgd2FzIHRoZSBjb3JyZWN0IGJsb2NrIHdoaWNoIHdlIGhhdmUgcmVhZCAqLwogICAgaWYgKFRoaXMtPmxwQnVmZmVyWzBdICE9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmNraWQgfHwKCVRoaXMtPmxwQnVmZmVyWzFdICE9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGgpIHsKICAgICAgRVJSKCI6IGJsb2NrICVkIG5vdCBmb3VuZCBhdCAweCUwOFhcbiIsIHBvcywgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCk7CiAgICAgIEVSUigiOiBJbmRleCBzYXlzOiAnJTQuNHMnKDB4JTA4WCkgc2l6ZSAweCUwOFhcbiIsCgkgIChjaGFyKikmVGhpcy0+aWR4RnJhbWVzW3Bvc10uY2tpZCwgVGhpcy0+aWR4RnJhbWVzW3Bvc10uY2tpZCwKCSAgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCk7CiAgICAgIEVSUigiOiBEYXRhICBzYXlzOiAnJTQuNHMnKDB4JTA4WCkgc2l6ZSAweCUwOFhcbiIsCgkgIChjaGFyKikmVGhpcy0+bHBCdWZmZXJbMF0sIFRoaXMtPmxwQnVmZmVyWzBdLCBUaGlzLT5scEJ1ZmZlclsxXSk7CiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICB9CiAgfSBlbHNlIHsKICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rT2Zmc2V0ICsgMiAqIHNpemVvZihEV09SRCksIFNFRUtfU0VUKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIGlmIChtbWlvUmVhZChUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpYnVmZmVyLCBzaXplKSAhPSBzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIHZvaWQgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhjb25zdCBJQVZJU3RyZWFtSW1wbCAqVGhpcywgTFBMT05HIHBvcywgTFBMT05HIG9mZnNldCkKewogIExPTkcgYmxvY2s7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KHBvcyAhPSBOVUxMKTsKICBhc3NlcnQob2Zmc2V0ICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCk7CiAgYXNzZXJ0KCpwb3MgPj0gVGhpcy0+c0luZm8uZHdTdGFydCk7CgogIC8qIGNvbnZlcnQgc3RhcnQgc2FtcGxlIHRvIHN0YXJ0IGJ5dGVzICovCiAgKCpvZmZzZXQpICA9ICgqcG9zKSAtIFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgKCpvZmZzZXQpICo9IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgLyogY29udmVydCBieXRlcyB0byBibG9jayBudW1iZXIgKi8KICBmb3IgKGJsb2NrID0gMDsgYmxvY2sgPD0gVGhpcy0+bExhc3RGcmFtZTsgYmxvY2srKykgewogICAgaWYgKFRoaXMtPmlkeEZyYW1lc1tibG9ja10uZHdDaHVua0xlbmd0aCA8PSAqb2Zmc2V0KQogICAgICAoKm9mZnNldCkgLT0gVGhpcy0+aWR4RnJhbWVzW2Jsb2NrXS5kd0NodW5rTGVuZ3RoOwogICAgZWxzZQogICAgICBicmVhazsKICB9CgogICpwb3MgPSBibG9jazsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNYWluQVZJSGVhZGVyICAgTWFpbkFWSUhkcjsKICBJQVZJU3RyZWFtSW1wbCogcFN0cmVhbTsKICBNTUNLSU5GTyAgICAgICAgY2tSSUZGOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QxOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QyOwogIE1NQ0tJTkZPICAgICAgICBjazsKICBEV09SRCAgICAgICAgICAgblN0cmVhbTsKICBEV09SRCAgICAgICAgICAgZHdQb3M7CiAgSFJFU1VMVCAgICAgICAgIGhyOwoKICAvKiBpbml0aWFsaXplIHNvbWUgdGhpbmdzICovCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcyk7CgogIC8qIHdyaXR0ZW4gb25lIHJlY29yZCB0byBtdWNoPyAqLwogIGlmIChUaGlzLT5ja0xhc3RSZWNvcmQuZHdGbGFncyAmIE1NSU9fRElSVFkpIHsKICAgIFRoaXMtPmR3TmV4dEZyYW1lUG9zIC09IDMgKiBzaXplb2YoRFdPUkQpOwogICAgaWYgKFRoaXMtPm5JZHhSZWNvcmRzID4gMCkKICAgICAgVGhpcy0+bklkeFJlY29yZHMtLTsKICB9CgogIEFWSUZJTEVfVXBkYXRlSW5mbyhUaGlzKTsKCiAgYXNzZXJ0KFRoaXMtPmZJbmZvLmR3U2NhbGUgIT0gMCk7CgogIG1lbXNldCgmTWFpbkFWSUhkciwgMCwgc2l6ZW9mKE1haW5BVklIZHIpKTsKICBNYWluQVZJSGRyLmR3TWljcm9TZWNQZXJGcmFtZSAgICA9IE11bERpdihUaGlzLT5mSW5mby5kd1JhdGUsIDEwMDAwMDAsCgkJCQkJICAgIFRoaXMtPmZJbmZvLmR3U2NhbGUpOwogIE1haW5BVklIZHIuZHdNYXhCeXRlc1BlclNlYyAgICAgID0gVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYzsKICBNYWluQVZJSGRyLmR3UGFkZGluZ0dyYW51bGFyaXR5ICA9IEFWSV9IRUFERVJTSVpFOwogIE1haW5BVklIZHIuZHdGbGFncyAgICAgICAgICAgICAgID0gVGhpcy0+ZkluZm8uZHdGbGFnczsKICBNYWluQVZJSGRyLmR3VG90YWxGcmFtZXMgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3TGVuZ3RoOwogIE1haW5BVklIZHIuZHdJbml0aWFsRnJhbWVzICAgICAgID0gMDsKICBNYWluQVZJSGRyLmR3U3RyZWFtcyAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsKICBNYWluQVZJSGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICBNYWluQVZJSGRyLmR3V2lkdGggICAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3V2lkdGg7CiAgTWFpbkFWSUhkci5kd0hlaWdodCAgICAgICAgICAgICAgPSBUaGlzLT5mSW5mby5kd0hlaWdodDsKICBNYWluQVZJSGRyLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IFRoaXMtPmR3SW5pdGlhbEZyYW1lczsKCiAgLyogbm93IGJlZ2luIHdyaXRpbmcgLi4uICovCiAgbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfU0VUKTsKCiAgLyogUklGRiBjaHVuayAqLwogIGNrUklGRi5ja3NpemUgID0gMDsKICBja1JJRkYuZmNjVHlwZSA9IGZvcm10eXBlQVZJOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja1JJRkYsIE1NSU9fQ1JFQVRFUklGRikgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBBVkkgaGVhZGVybGlzdCAqLwogIGNrTElTVDEuY2tzaXplICA9IDA7CiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklIRUFERVI7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDEsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBNYWluQVZJSGVhZGVyICovCiAgY2suY2tpZCAgICA9IGNraWRBVklNQUlOSERSOwogIGNrLmNrc2l6ZSAgPSBzaXplb2YoTWFpbkFWSUhkcik7CiAgY2suZmNjVHlwZSA9IDA7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZNYWluQVZJSGRyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogd3JpdGUgdGhlIGhlYWRlcnMgb2YgZWFjaCBzdHJlYW0gaW50byBhIHNlcGFyYXRlIHN0cmVhbWhlYWRlciBsaXN0ICovCiAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICBBVklTdHJlYW1IZWFkZXIgc3RySGRyOwoKICAgIHBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgogICAgLyogYmVnaW4gdGhlIG5ldyBzdHJlYW1oZWFkZXIgbGlzdCAqLwogICAgY2tMSVNUMi5ja3NpemUgID0gMDsKICAgIGNrTElTVDIuZmNjVHlwZSA9IGxpc3R0eXBlU1RSRUFNSEVBREVSOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDIsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgLyogY3JlYXRlIGFuIEFWSVN0cmVhbUhlYWRlciBmcm9tIHRoZSBBVlNUUkVBTUlORk8gKi8KICAgIHN0ckhkci5mY2NUeXBlICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5mY2NUeXBlOwogICAgc3RySGRyLmZjY0hhbmRsZXIgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXI7CiAgICBzdHJIZHIuZHdGbGFncyAgICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdGbGFnczsKICAgIHN0ckhkci53UHJpb3JpdHkgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby53UHJpb3JpdHk7CiAgICBzdHJIZHIud0xhbmd1YWdlICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8ud0xhbmd1YWdlOwogICAgc3RySGRyLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lczsKICAgIHN0ckhkci5kd1NjYWxlICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1NjYWxlOwogICAgc3RySGRyLmR3UmF0ZSAgICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3UmF0ZTsKICAgIHN0ckhkci5kd1N0YXJ0ICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1N0YXJ0OwogICAgc3RySGRyLmR3TGVuZ3RoICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoOwogICAgc3RySGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IHBTdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICAgIHN0ckhkci5kd1F1YWxpdHkgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1F1YWxpdHk7CiAgICBzdHJIZHIuZHdTYW1wbGVTaXplICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgc3RySGRyLnJjRnJhbWUubGVmdCAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUubGVmdDsKICAgIHN0ckhkci5yY0ZyYW1lLnRvcCAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnRvcDsKICAgIHN0ckhkci5yY0ZyYW1lLnJpZ2h0ICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnJpZ2h0OwogICAgc3RySGRyLnJjRnJhbWUuYm90dG9tICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUuYm90dG9tOwoKICAgIC8qIG5vdyB3cml0ZSB0aGUgQVZJU3RyZWFtSGVhZGVyICovCiAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNSEVBREVSOwogICAgY2suY2tzaXplID0gc2l6ZW9mKHN0ckhkcik7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZzdHJIZHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIC8qIC4uLiB0aGUgaG9wZWZ1bGx5IGV2ZXIgcHJlc2VudCBzdHJlYW1mb3JtYXQgLi4uICovCiAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNRk9STUFUOwogICAgY2suY2tzaXplID0gcFN0cmVhbS0+Y2JGb3JtYXQ7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKHBTdHJlYW0tPmxwRm9ybWF0ICE9IE5VTEwgJiYgY2suY2tzaXplID4gMCkgewogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICAvKiAuLi4gc29tZSBvcHRpb25hbCBleGlzdGluZyBoYW5kbGVyIGRhdGEgLi4uICovCiAgICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgPiAwKSB7CiAgICAgIGNrLmNraWQgICA9IGNraWRTVFJFQU1IQU5ETEVSREFUQTsKICAgICAgY2suY2tzaXplID0gcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YTsKICAgICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5scEhhbmRsZXJEYXRhLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CgogICAgLyogLi4uIHNvbWUgb3B0aW9uYWwgYWRkaXRpb25hbCBleHRyYSBjaHVuayBmb3IgdGhpcyBzdHJlYW0gLi4uICovCiAgICBpZiAocFN0cmVhbS0+ZXh0cmEubHAgIT0gTlVMTCAmJiBwU3RyZWFtLT5leHRyYS5jYiA+IDApIHsKICAgICAgLyogdGhlIGNodW5rIGhlYWRlcihzKSBhcmUgYWxyZWFkeSBpbiB0aGUgc3RydWN0dXJlICovCiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5leHRyYS5scCwgcFN0cmVhbS0+ZXh0cmEuY2IpICE9IHBTdHJlYW0tPmV4dHJhLmNiKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CgogICAgLyogLi4uIGFuIG9wdGlvbmFsIG5hbWUgZm9yIHRoaXMgc3RyZWFtIC4uLiAqLwogICAgaWYgKGxzdHJsZW5XKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkgPiAwKSB7CiAgICAgIExQU1RSIHN0cjsKCiAgICAgIGNrLmNraWQgICA9IGNraWRTVFJFQU1OQU1FOwogICAgICBjay5ja3NpemUgPSBsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpICsgMTsKICAgICAgaWYgKGNrLmNrc2l6ZSAmIDEpIC8qIGFsaWduICovCgljay5ja3NpemUrKzsKICAgICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgICAvKiB0aGUgc3RyZWFtbmFtZSBtdXN0IGJlIHNhdmVkIGluIEFTQ0lJIG5vdCBVbmljb2RlICovCiAgICAgIHN0ciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjay5ja3NpemUpOwogICAgICBpZiAoc3RyID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwgLTEsIHN0ciwKCQkJICBjay5ja3NpemUsIE5VTEwsIE5VTEwpOwoKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgc3RyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkgewoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyKTsJCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgfQoKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyKTsKICAgICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfQoKICAgIC8qIGNsb3NlIHN0cmVhbWhlYWRlciBsaXN0IGZvciB0aGlzIHN0cmVhbSAqLwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QyLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9IC8qIGZvciAoMCA8PSBuU3RyZWFtIDwgTWFpbkFWSUhkci5kd1N0cmVhbXMpICovCgogIC8qIGNsb3NlIHRoZSBhdmloZWFkZXIgbGlzdCAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBjaGVjayBmb3IgcGFkZGluZyB0byBwcmUtZ3Vlc3NlZCAnbW92aSctY2h1bmsgcG9zaXRpb24gKi8KICBkd1BvcyA9IGNrTElTVDEuZHdEYXRhT2Zmc2V0ICsgY2tMSVNUMS5ja3NpemU7CiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zIC0gMiAqIHNpemVvZihEV09SRCkgPiBkd1BvcykgewogICAgY2suY2tpZCAgID0gY2tpZEFWSVBBRERJTkc7CiAgICBjay5ja3NpemUgPSBUaGlzLT5kd01vdmlDaHVua1BvcyAtIGR3UG9zIC0gNCAqIHNpemVvZihEV09SRCk7CiAgICBhc3NlcnQoKExPTkcpY2suY2tzaXplID49IDApOwoKICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIGNrLmNrc2l6ZSwgU0VFS19DVVIpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogbm93IHdyaXRlIHRoZSAnbW92aScgY2h1bmsgKi8KICBtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgLSAyICogc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpOwogIGNrTElTVDEuY2tzaXplICA9IDA7CiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklNT1ZJRTsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgTU1JT19DUkVBVEVMSVNUKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHdyaXRlICdpZHgxJyBjaHVuayAqLwogIGhyID0gQVZJRklMRV9TYXZlSW5kZXgoVGhpcyk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIC8qIHdyaXRlIG9wdGlvbmFsIGV4dHJhIGZpbGUgY2h1bmtzICovCiAgaWYgKFRoaXMtPmZpbGVleHRyYS5scCAhPSBOVUxMICYmIFRoaXMtPmZpbGVleHRyYS5jYiA+IDApIHsKICAgIC8qIGFzIGZvciB0aGUgc3RyZWFtcywgYXJlIHRoZSBjaHVuayBoZWFkZXIocykgaW4gdGhlIHN0cnVjdHVyZSAqLwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKVRoaXMtPmZpbGVleHRyYS5scCwgVGhpcy0+ZmlsZWV4dHJhLmNiKSAhPSBUaGlzLT5maWxlZXh0cmEuY2IpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY2xvc2UgUklGRiBjaHVuayAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIGFkZCBzb21lIEpVTksgYXQgZW5kIGZvciBiYWQgcGFyc2VycyAqLwogIG1lbXNldCgmY2tSSUZGLCAwLCBzaXplb2YoY2tSSUZGKSk7CiAgbW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmNrUklGRiwgc2l6ZW9mKGNrUklGRikpOwogIG1taW9GbHVzaChUaGlzLT5obW1pbywgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUluZGV4KGNvbnN0IElBVklGaWxlSW1wbCAqVGhpcykKewogIElBVklTdHJlYW1JbXBsICpwU3RyZWFtOwogIEFWSUlOREVYRU5UUlkgICBpZHg7CiAgTU1DS0lORk8gICAgICAgIGNrOwogIERXT1JEICAgICAgICAgICBuU3RyZWFtOwogIExPTkcgICAgICAgICAgICBuOwoKICBjay5ja2lkICAgPSBja2lkQVZJTkVXSU5ERVg7CiAgY2suY2tzaXplID0gMDsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgaWYgKFRoaXMtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEKSB7CiAgICAvKiBpcyBpbnRlcmxlYXZlZCAtLSB3cml0ZSBibG9jayBvZiBjb3JyZXNwb25kaW5nIGZyYW1lcyAqLwogICAgTE9ORyBsSW5pdGlhbEZyYW1lcyA9IDA7CiAgICBMT05HIHN0ZXBzaXplOwogICAgTE9ORyBpOwoKICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbMF0tPnNJbmZvLmR3U2FtcGxlU2l6ZSA9PSAwKQogICAgICBzdGVwc2l6ZSA9IDE7CiAgICBlbHNlCiAgICAgIHN0ZXBzaXplID0gQVZJU3RyZWFtVGltZVRvU2FtcGxlKChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1swXSwgMTAwMDAwMCk7CgogICAgYXNzZXJ0KHN0ZXBzaXplID4gMCk7CgogICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICAgIGlmIChsSW5pdGlhbEZyYW1lcyA8IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+c0luZm8uZHdJbml0aWFsRnJhbWVzKQoJbEluaXRpYWxGcmFtZXMgPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lczsKICAgIH0KCiAgICBmb3IgKGkgPSAtbEluaXRpYWxGcmFtZXM7IGkgPCAoTE9ORylUaGlzLT5mSW5mby5kd0xlbmd0aCAtIGxJbml0aWFsRnJhbWVzOwoJIGkgKz0gc3RlcHNpemUpIHsKICAgICAgRFdPUkQgbkZyYW1lID0gbEluaXRpYWxGcmFtZXMgKyBpOwoKICAgICAgYXNzZXJ0KG5GcmFtZSA8IFRoaXMtPm5JZHhSZWNvcmRzKTsKCiAgICAgIGlkeC5ja2lkICAgICAgICAgID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgICAgIGlkeC5kd0ZsYWdzICAgICAgID0gQVZJSUZfTElTVDsKICAgICAgaWR4LmR3Q2h1bmtMZW5ndGggPSBUaGlzLT5pZHhSZWNvcmRzW25GcmFtZV0uZHdDaHVua0xlbmd0aDsKICAgICAgaWR4LmR3Q2h1bmtPZmZzZXQgPSBUaGlzLT5pZHhSZWNvcmRzW25GcmFtZV0uZHdDaHVua09mZnNldAoJLSBUaGlzLT5kd01vdmlDaHVua1BvczsKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CglwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwoKCS8qIGhlYXZlIHdlIHJlYWNoZWQgc3RhcnQgb2YgdGhpcyBzdHJlYW0/ICovCglpZiAoLShMT05HKXBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyA+IGkpCgkgIGNvbnRpbnVlOwoKCWlmIChwU3RyZWFtLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgPCBsSW5pdGlhbEZyYW1lcykKCSAgbkZyYW1lIC09IChsSW5pdGlhbEZyYW1lcyAtIHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyk7CgoJLyogcmVhY2hlZCBlbmQgb2YgdGhpcyBzdHJlYW0/ICovCglpZiAocFN0cmVhbS0+bExhc3RGcmFtZSA8PSBuRnJhbWUpCgkgIGNvbnRpbnVlOwoKCWlmICgocFN0cmVhbS0+c0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUykgJiYKCSAgICBwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ICE9IDAgJiYKCSAgICBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzICE9IE5VTEwpIHsKCSAgRFdPUkQgcG9zOwoKCSAgZm9yIChwb3MgPSAwOyBwb3MgPCBwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBwb3MrKykgewoJICAgIGlmIChwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uY2tpZCA9PSBuRnJhbWUpIHsKCSAgICAgIGlkeC5kd0ZsYWdzID0gQVZJSUZfTk9USU1FOwoJICAgICAgaWR4LmNraWQgICAgPSBNQUtFQVZJQ0tJRChja3R5cGVQQUxjaGFuZ2UsIHBTdHJlYW0tPm5TdHJlYW0pOwoJICAgICAgaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua0xlbmd0aDsKCSAgICAgIGlkeC5kd0NodW5rT2Zmc2V0ID0gcFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmR3Q2h1bmtPZmZzZXQKCQktIFRoaXMtPmR3TW92aUNodW5rUG9zOwoKCSAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCgkJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgkgICAgICBicmVhazsKCSAgICB9CgkgIH0KCX0gLyogaWYgaGF2ZSBmb3JtYXRjaGFuZ2VzICovCgoJaWR4LmNraWQgICAgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5ja2lkOwoJaWR4LmR3RmxhZ3MgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5kd0ZsYWdzOwoJaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5kd0NodW5rTGVuZ3RoOwoJaWR4LmR3Q2h1bmtPZmZzZXQgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5kd0NodW5rT2Zmc2V0CgkgIC0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CglpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvKiBub3QgaW50ZXJsZWF2ZWQgLS0gd3JpdGUgaW5kZXggZm9yIGVhY2ggc3RyZWFtIGF0IG9uY2UgKi8KICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgICBwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwoKICAgICAgZm9yIChuID0gMDsgbiA8PSBwU3RyZWFtLT5sTGFzdEZyYW1lOyBuKyspIHsKCWlmICgocFN0cmVhbS0+c0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUykgJiYKCSAgICAocFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAhPSAwKSkgewoJICBEV09SRCBwb3M7CgoJICBmb3IgKHBvcyA9IDA7IHBvcyA8IHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7IHBvcysrKSB7CgkgICAgaWYgKHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5ja2lkID09IG4pIHsKCSAgICAgIGlkeC5kd0ZsYWdzID0gQVZJSUZfTk9USU1FOwoJICAgICAgaWR4LmNraWQgICAgPSBNQUtFQVZJQ0tJRChja3R5cGVQQUxjaGFuZ2UsIHBTdHJlYW0tPm5TdHJlYW0pOwoJICAgICAgaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua0xlbmd0aDsKCSAgICAgIGlkeC5kd0NodW5rT2Zmc2V0ID0KCQlwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua09mZnNldCAtIFRoaXMtPmR3TW92aUNodW5rUG9zOwoJICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCQlyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCSAgICAgIGJyZWFrOwoJICAgIH0KCSAgfQoJfSAvKiBpZiBoYXZlIGZvcm1hdGNoYW5nZXMgKi8KCglpZHguY2tpZCAgICAgICAgICA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5ja2lkOwoJaWR4LmR3RmxhZ3MgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbl0uZHdGbGFnczsKCWlkeC5kd0NodW5rTGVuZ3RoID0gcFN0cmVhbS0+aWR4RnJhbWVzW25dLmR3Q2h1bmtMZW5ndGg7CglpZHguZHdDaHVua09mZnNldCA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5kd0NodW5rT2Zmc2V0CgkgIC0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CgoJaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCSAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIH0KICAgIH0KICB9IC8qIGlmIG5vdCBpbnRlcmxlYXZlZCAqLwoKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBVTE9ORyAgQVZJRklMRV9TZWFyY2hTdHJlYW0oY29uc3QgSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBmY2MsIExPTkcgbFNraXApCnsKICBVSU5UIGk7CiAgVUlOVCBuU3RyZWFtOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KGxTa2lwID49IDApOwoKICBpZiAoZmNjICE9IDApIHsKICAgIC8qIHNlYXJjaCB0aGUgbnVtYmVyIG9mIHRoZSBzcGVjaWZpZWQgc3RyZWFtICovCiAgICBuU3RyZWFtID0gKFVMT05HKS0xOwogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICAgIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbaV0gIT0gTlVMTCk7CgogICAgICBpZiAoVGhpcy0+cHBTdHJlYW1zW2ldLT5zSW5mby5mY2NUeXBlID09IGZjYykgewoJaWYgKGxTa2lwID09IDApIHsKCSAgblN0cmVhbSA9IGk7CgkgIGJyZWFrOwoJfSBlbHNlCgkgIGxTa2lwLS07CiAgICAgIH0KICAgIH0KICB9IGVsc2UKICAgIG5TdHJlYW0gPSBsU2tpcDsKCiAgcmV0dXJuIG5TdHJlYW07Cn0KCnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfVXBkYXRlSW5mbyhJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBVSU5UIGk7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CgogIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdDYXBzICAgICAgICAgICAgICAgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSAwOwogIFRoaXMtPmZJbmZvLmR3V2lkdGggICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdIZWlnaHQgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdMZW5ndGggICAgICAgICAgICAgID0gMDsKICBUaGlzLT5kd0luaXRpYWxGcmFtZXMgICAgICAgICAgICAgPSAwOwoKICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBpKyspIHsKICAgIEFWSVNUUkVBTUlORk9XICpwc2k7CiAgICBEV09SRCAgICAgICAgICAgbjsKCiAgICAvKiBwcmUtY29uZGl0aW9ucyAqLwogICAgYXNzZXJ0KFRoaXMtPnBwU3RyZWFtc1tpXSAhPSBOVUxMKTsKCiAgICBwc2kgPSAmVGhpcy0+cHBTdHJlYW1zW2ldLT5zSW5mbzsKICAgIGFzc2VydChwc2ktPmR3U2NhbGUgIT0gMCk7CiAgICBhc3NlcnQocHNpLT5kd1JhdGUgIT0gMCk7CgogICAgaWYgKGkgPT0gMCkgewogICAgICAvKiB1c2UgZmlyc3Qgc3RyZWFtIHRpbWluZ3MgYXMgYmFzZSAqLwogICAgICBUaGlzLT5mSW5mby5kd1NjYWxlICA9IHBzaS0+ZHdTY2FsZTsKICAgICAgVGhpcy0+ZkluZm8uZHdSYXRlICAgPSBwc2ktPmR3UmF0ZTsKICAgICAgVGhpcy0+ZkluZm8uZHdMZW5ndGggPSBwc2ktPmR3TGVuZ3RoOwogICAgfSBlbHNlIHsKICAgICAgbiA9IEFWSVN0cmVhbVNhbXBsZVRvU2FtcGxlKChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1swXSwKCQkJCSAgKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zW2ldLHBzaS0+ZHdMZW5ndGgpOwogICAgICBpZiAoVGhpcy0+ZkluZm8uZHdMZW5ndGggPCBuKQoJVGhpcy0+ZkluZm8uZHdMZW5ndGggPSBuOwogICAgfQoKICAgIGlmIChUaGlzLT5kd0luaXRpYWxGcmFtZXMgPCBwc2ktPmR3SW5pdGlhbEZyYW1lcykKICAgICAgVGhpcy0+ZHdJbml0aWFsRnJhbWVzID0gcHNpLT5kd0luaXRpYWxGcmFtZXM7CgogICAgaWYgKFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA8IHBzaS0+ZHdTdWdnZXN0ZWRCdWZmZXJTaXplKQogICAgICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBwc2ktPmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKCiAgICBpZiAocHNpLT5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgICAvKiBmaXhlZCBzYW1wbGUgc2l6ZSAtLSBleGFjdCBjb21wdXRhdGlvbiAqLwogICAgICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICs9IE11bERpdihwc2ktPmR3U2FtcGxlU2l6ZSwgcHNpLT5kd1JhdGUsCgkJCQkJICAgICBwc2ktPmR3U2NhbGUpOwogICAgfSBlbHNlIHsKICAgICAgLyogdmFyaWFibGUgc2FtcGxlIHNpemUgLS0gb25seSB1cHBlciBsaW1pdCAqLwogICAgICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICs9IE11bERpdihwc2ktPmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSwKCQkJCQkgICAgIHBzaS0+ZHdSYXRlLCBwc2ktPmR3U2NhbGUpOwoKICAgICAgLyogdXBkYXRlIGRpbWVuc2lvbnMgKi8KICAgICAgbiA9IHBzaS0+cmNGcmFtZS5yaWdodCAtIHBzaS0+cmNGcmFtZS5sZWZ0OwogICAgICBpZiAoVGhpcy0+ZkluZm8uZHdXaWR0aCA8IG4pCglUaGlzLT5mSW5mby5kd1dpZHRoID0gbjsKICAgICAgbiA9IHBzaS0+cmNGcmFtZS5ib3R0b20gLSBwc2ktPnJjRnJhbWUudG9wOwogICAgICBpZiAoVGhpcy0+ZkluZm8uZHdIZWlnaHQgPCBuKQoJVGhpcy0+ZkluZm8uZHdIZWlnaHQgPSBuOwogICAgfQogIH0KfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Xcml0ZUJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBibG9jaywKCQkJCSAgRk9VUkNDIGNraWQsIERXT1JEIGZsYWdzLCBMUFZPSUQgYnVmZmVyLAoJCQkJICBMT05HIHNpemUpCnsKICBNTUNLSU5GTyBjazsKCiAgY2suY2tpZCAgICA9IGNraWQ7CiAgY2suY2tzaXplICA9IHNpemU7CiAgY2suZmNjVHlwZSA9IDA7CgogIC8qIGlmIG5vIGZyYW1lL2Jsb2NrIGlzIGFscmVhZHkgd3JpdHRlbiwgd2UgbXVzdCBjb21wdXRlIHN0YXJ0IG9mIG1vdmkgY2h1bmsgKi8KICBpZiAoVGhpcy0+cGFmLT5kd01vdmlDaHVua1BvcyA9PSAwKQogICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KFRoaXMtPnBhZik7CgogIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAoYnVmZmVyICE9IE5VTEwgJiYgc2l6ZSA+IDApIHsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgc2l6ZSkgIT0gc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQogIGlmIChtbWlvQXNjZW5kKFRoaXMtPnBhZi0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICBUaGlzLT5wYWYtPmZEaXJ0eSAgICAgICAgID0gVFJVRTsKICBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zID0gbW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgMCwgU0VFS19DVVIpOwoKICByZXR1cm4gQVZJRklMRV9BZGRGcmFtZShUaGlzLCBja2lkLCBzaXplLAoJCQkgIGNrLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpLCBmbGFncyk7Cn0K