LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgovKiBUT0RPOgogKiAgLSBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSBpcyBtaXNzaW5nIGZvciB0aGUgSUFWSVN0cmVhbUltcGwKICogIC0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGU6IEZJTkRfSU5ERVggaXNuJ3Qgc3VwcG9ydGVkLgogKiAgLSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdDogZm9ybWF0Y2hhbmdlcyBhcmVuJ3QgcmVhZCBpbi4KICogIC0gSUFWSVN0cmVhbV9mbkRlbGV0ZTogYSBzdHViLgogKiAgLSBJQVZJU3RyZWFtX2ZuU2V0SW5mbzogYSBzdHViLgogKiAgLSBtYWtlIHRocmVhZCBzYWZlCiAqCiAqIEtOT1dOIEJ1Z3M6CiAqICAtIG5hdGl2ZSB2ZXJzaW9uIGNhbiBoYW5ndXAgd2hlbiByZWFkaW5nIGEgZmlsZSBnZW5lcmF0ZWQgd2l0aCB0aGlzIERMTC4KICogICAgV2hlbiBpbmRleCBpcyBtaXNzaW5nIGl0IHdvcmtzLCBidXQgaW5kZXggc2VlbXMgdG8gYmUgb2theS4KICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgInZmdy5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgojaW5jbHVkZSAiZXh0cmFjaHVuay5oIgoKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgojaWZuZGVmIElEWF9QRVJfQkxPQ0sKI2RlZmluZSBJRFhfUEVSX0JMT0NLIDI3MzAKI2VuZGlmCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSogaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUZpbGVfZm5SZWxlYXNlKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUqaWZhY2UsQVZJRklMRUlORk9XKmFmaSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLEFWSVNUUkVBTUlORk9XKmFzaSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgKnNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklGaWxlVnRibCBpYXZpZnQgPSB7CiAgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJQVZJRmlsZV9mbkFkZFJlZiwKICBJQVZJRmlsZV9mblJlbGVhc2UsCiAgSUFWSUZpbGVfZm5JbmZvLAogIElBVklGaWxlX2ZuR2V0U3RyZWFtLAogIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtLAogIElBVklGaWxlX2ZuV3JpdGVEYXRhLAogIElBVklGaWxlX2ZuUmVhZERhdGEsCiAgSUFWSUZpbGVfZm5FbmRSZWNvcmQsCiAgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUqaWZhY2UsQ0xTSUQqcENsYXNzSUQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLERXT1JEIGR3TW9kZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlKmlmYWNlLExQT0xFU1RSKnBwc3pGaWxlTmFtZSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElQZXJzaXN0RmlsZVZ0YmwgaXBlcnNpc3RmdCA9IHsKICBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJUGVyc2lzdEZpbGVfZm5BZGRSZWYsCiAgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZSwKICBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lELAogIElQZXJzaXN0RmlsZV9mbklzRGlydHksCiAgSVBlcnNpc3RGaWxlX2ZuTG9hZCwKICBJUGVyc2lzdEZpbGVfZm5TYXZlLAogIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSxMUEFSQU0gbFBhcmFtMSxMUEFSQU0gbFBhcmFtMik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyAqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsTE9ORyAqc2FtcHdyaXR0ZW4sTE9ORyAqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklTdHJlYW1WdGJsIGlhdmlzdCA9IHsKICBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSVN0cmVhbV9mbkFkZFJlZiwKICBJQVZJU3RyZWFtX2ZuUmVsZWFzZSwKICBJQVZJU3RyZWFtX2ZuQ3JlYXRlLAogIElBVklTdHJlYW1fZm5JbmZvLAogIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlLAogIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0LAogIElBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblJlYWQsCiAgSUFWSVN0cmVhbV9mbldyaXRlLAogIElBVklTdHJlYW1fZm5EZWxldGUsCiAgSUFWSVN0cmVhbV9mblJlYWREYXRhLAogIElBVklTdHJlYW1fZm5Xcml0ZURhdGEsCiAgSUFWSVN0cmVhbV9mblNldEluZm8KfTsKCnR5cGVkZWYgc3RydWN0IF9JQVZJRmlsZUltcGwgSUFWSUZpbGVJbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lQZXJzaXN0RmlsZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSVBlcnNpc3RGaWxlVnRibCAqbHBWdGJsOwoKICAvKiBJUGVyc2lzdEZpbGUgc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7Cn0gSVBlcnNpc3RGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JQVZJU3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJU3RyZWFtVnRibCAqbHBWdGJsOwogIExPTkcJCSAgICByZWY7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7CiAgRFdPUkQgICAgICAgICAgICAgblN0cmVhbTsgICAgICAgLyogdGhlIG4tdGggc3RyZWFtIGluIGZpbGUgKi8KICBBVklTVFJFQU1JTkZPVyAgICBzSW5mbzsKCiAgTFBWT0lEICAgICAgICAgICAgbHBGb3JtYXQ7CiAgRFdPUkQgICAgICAgICAgICAgY2JGb3JtYXQ7CgogIExQVk9JRCAgICAgICAgICAgIGxwSGFuZGxlckRhdGE7CiAgRFdPUkQgICAgICAgICAgICAgY2JIYW5kbGVyRGF0YTsKCiAgRVhUUkFDSFVOS1MgICAgICAgZXh0cmE7CgogIExQRFdPUkQgICAgICAgICAgIGxwQnVmZmVyOwogIERXT1JEICAgICAgICAgICAgIGNiQnVmZmVyOyAgICAgICAvKiBzaXplIG9mIGxwQnVmZmVyICovCiAgRFdPUkQgICAgICAgICAgICAgZHdDdXJyZW50RnJhbWU7IC8qIGZyYW1lL2Jsb2NrIGN1cnJlbnRseSBpbiBscEJ1ZmZlciAqLwoKICBMT05HICAgICAgICAgICAgICBsTGFzdEZyYW1lOyAgICAvKiBsYXN0IGNvcnJlY3QgaW5kZXggaW4gaWR4RnJhbWVzICovCiAgQVZJSU5ERVhFTlRSWSAgICAqaWR4RnJhbWVzOwogIERXT1JEICAgICAgICAgICAgIG5JZHhGcmFtZXM7ICAgICAvKiB1cHBlciBpbmRleCBsaW1pdCBvZiBpZHhGcmFtZXMgKi8KICBBVklJTkRFWEVOVFJZICAgICppZHhGbXRDaGFuZ2VzOwogIERXT1JEICAgICAgICAgICAgIG5JZHhGbXRDaGFuZ2VzOyAvKiB1cHBlciBpbmRleCBsaW1pdCBvZiBpZHhGbXRDaGFuZ2VzICovCn0gSUFWSVN0cmVhbUltcGw7CgpzdHJ1Y3QgX0lBVklGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJRmlsZVZ0YmwgICAgICpscFZ0Ymw7CiAgTE9ORwkJICAgIHJlZjsKCiAgLyogSUFWSUZpbGUgc3R1ZmYuLi4gKi8KICBJUGVyc2lzdEZpbGVJbXBsICBpUGVyc2lzdEZpbGU7CgogIEFWSUZJTEVJTkZPVyAgICAgIGZJbmZvOwogIElBVklTdHJlYW1JbXBsICAgKnBwU3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CgogIEVYVFJBQ0hVTktTICAgICAgIGZpbGVleHRyYTsKCiAgRFdPUkQgICAgICAgICAgICAgZHdNb3ZpQ2h1bmtQb3M7ICAvKiBzb21lIHN0dWZmIGZvciBzYXZpbmcgLi4uICovCiAgRFdPUkQgICAgICAgICAgICAgZHdJZHhDaHVua1BvczsKICBEV09SRCAgICAgICAgICAgICBkd05leHRGcmFtZVBvczsKICBEV09SRCAgICAgICAgICAgICBkd0luaXRpYWxGcmFtZXM7CgogIE1NQ0tJTkZPICAgICAgICAgIGNrTGFzdFJlY29yZDsKICBBVklJTkRFWEVOVFJZICAgICppZHhSZWNvcmRzOyAgICAgIC8qIHdvbid0IGJlIHVwZGF0ZWQgd2hpbGUgbG9hZGluZyAqLwogIERXT1JEICAgICAgICAgICAgIG5JZHhSZWNvcmRzOyAgICAgLyogY3VycmVudCBmaWxsIGxldmVsICovCiAgRFdPUkQgICAgICAgICAgICAgY2JJZHhSZWNvcmRzOyAgICAvKiBzaXplIG9mIGlkeFJlY29yZHMgKi8KCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmIC4uLiAqLwogIEhNTUlPICAgICAgICAgICAgIGhtbWlvOwogIExQV1NUUiAgICAgICAgICAgIHN6RmlsZU5hbWU7CiAgVUlOVCAgICAgICAgICAgICAgdU1vZGU7CiAgQk9PTCAgICAgICAgICAgICAgZkRpcnR5Owp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgY2tpZCwgRFdPUkQgc2l6ZSwKCQkJCURXT1JEIG9mZnNldCwgRFdPUkQgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZFJlY29yZChJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgRFdPUkQgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oSUFWSUZpbGVJbXBsICpwYWYsIERXT1JEIG5yLAoJCQkJCSAgTFBBVklTVFJFQU1JTkZPVyBhc2kpOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX0Rlc3RydWN0QVZJU3RyZWFtKElBVklTdHJlYW1JbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIHNpemUsIERXT1JEIG9mZnNldCk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUGFyc2VJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIEFWSUlOREVYRU5UUlkgKmxwLAoJCQkJICBMT05HIGNvdW50LCBEV09SRCBwb3MsIEJPT0wgKmJBYnNvbHV0ZSk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUmVhZEJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBzdGFydCwKCQkJCSBMUFZPSUQgYnVmZmVyLCBMT05HIHNpemUpOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBMUExPTkcgcG9zLAoJCQkJICAgICAgTFBMT05HIG9mZnNldCk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIFVMT05HICAgQVZJRklMRV9TZWFyY2hTdHJlYW0oSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBmY2NUeXBlLAoJCQkJICAgIExPTkcgbFNraXApOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1VwZGF0ZUluZm8oSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Xcml0ZUJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBibG9jaywKCQkJCSAgRk9VUkNDIGNraWQsIERXT1JEIGZsYWdzLCBMUFZPSUQgYnVmZmVyLAoJCQkJICBMT05HIHNpemUpOwoKSFJFU1VMVCBBVklGSUxFX0NyZWF0ZUFWSUZpbGUoUkVGSUlEIHJpaWQsIExQVk9JRCAqcHB2KQp7CiAgSUFWSUZpbGVJbXBsICpwZmlsZTsKICBIUkVTVUxUICAgICAgIGhyOwoKICBhc3NlcnQocmlpZCAhPSBOVUxMICYmIHBwdiAhPSBOVUxMKTsKCiAgKnBwdiA9IE5VTEw7CgogIHBmaWxlID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihJQVZJRmlsZUltcGwpKTsKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBwZmlsZS0+bHBWdGJsID0gJmlhdmlmdDsKICBwZmlsZS0+cmVmID0gMDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLmxwVnRibCA9ICZpcGVyc2lzdGZ0OwogIHBmaWxlLT5pUGVyc2lzdEZpbGUucGFmID0gcGZpbGU7CgogIGhyID0gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKElBVklGaWxlKilwZmlsZSwgcmlpZCwgcHB2KTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHBmaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSAqaWZhY2UsIFJFRklJRCByZWZpaWQsCgkJCQkJCUxQVk9JRCAqb2JqKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmVmaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklGaWxlLCByZWZpaWQpKSB7CiAgICAqb2JqID0gaWZhY2U7CiAgICBJQVZJRmlsZV9BZGRSZWYoaWZhY2UpOwoKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQoJklJRF9JUGVyc2lzdEZpbGUsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aVBlcnNpc3RGaWxlOwogICAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVkXG4iLCBpZmFjZSwgcmVmKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwogIFVJTlQgaTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAoIXJlZikgewogICAgaWYgKFRoaXMtPmZEaXJ0eSkgewogICAgICAvKiBuZWVkIHRvIHdyaXRlIGhlYWRlcnMgdG8gZmlsZSAqLwogICAgICBBVklGSUxFX1NhdmVGaWxlKFRoaXMpOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IGkrKykgewogICAgICBpZiAoVGhpcy0+cHBTdHJlYW1zW2ldICE9IE5VTEwpIHsKCWlmIChUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiAhPSAwKSB7CiAgICAgICAgICBFUlIoIjogc29tZW9uZSBoYXMgc3RpbGwgJXUgcmVmZXJlbmNlIHRvIHN0cmVhbSAldSAoJXApIVxuIiwKCSAgICAgICBUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiwgaSwgVGhpcy0+cHBTdHJlYW1zW2ldKTsKCX0KCUFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oVGhpcy0+cHBTdHJlYW1zW2ldKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBwU3RyZWFtc1tpXSk7CglUaGlzLT5wcFN0cmVhbXNbaV0gPSBOVUxMOwogICAgICB9CiAgICB9CgogICAgaWYgKFRoaXMtPmlkeFJlY29yZHMgIT0gTlVMTCkgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5pZHhSZWNvcmRzKTsKICAgICAgVGhpcy0+aWR4UmVjb3JkcyAgPSBOVUxMOwogICAgICBUaGlzLT5uSWR4UmVjb3JkcyA9IDA7CiAgICB9CgogICAgaWYgKFRoaXMtPmZpbGVleHRyYS5scCAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmZpbGVleHRyYS5scCk7CiAgICAgIFRoaXMtPmZpbGVleHRyYS5scCA9IE5VTEw7CiAgICAgIFRoaXMtPmZpbGVleHRyYS5jYiA9IDA7CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+c3pGaWxlTmFtZSk7CiAgICBUaGlzLT5zekZpbGVOYW1lID0gTlVMTDsKCiAgICBpZiAoVGhpcy0+aG1taW8gIT0gTlVMTCkgewogICAgICBtbWlvQ2xvc2UoVGhpcy0+aG1taW8sIDApOwogICAgICBUaGlzLT5obW1pbyA9IE5VTEw7CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgfQogIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUgKmlmYWNlLCBMUEFWSUZJTEVJTkZPVyBhZmksCgkJCQkgICAgICBMT05HIHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLGlmYWNlLGFmaSxzaXplKTsKCiAgaWYgKGFmaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIEFWSUZJTEVfVXBkYXRlSW5mbyhUaGlzKTsKCiAgbWVtY3B5KGFmaSwgJlRoaXMtPmZJbmZvLCBtaW4oKERXT1JEKXNpemUsIHNpemVvZihUaGlzLT5mSW5mbykpKTsKCiAgaWYgKChEV09SRClzaXplIDwgc2l6ZW9mKFRoaXMtPmZJbmZvKSkKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuR2V0U3RyZWFtKElBVklGaWxlICppZmFjZSwgUEFWSVNUUkVBTSAqYXZpcywKCQkJCQkgICBEV09SRCBmY2NUeXBlLCBMT05HIGxQYXJhbSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVUxPTkcgblN0cmVhbTsKCiAgVFJBQ0UoIiglcCwlcCwweCUwOFgsJWQpXG4iLCBpZmFjZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBsUGFyYW0gPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgICphdmlzID0gKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwogICAgSUFWSVN0cmVhbV9BZGRSZWYoKmF2aXMpOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBTb3JyeSwgYnV0IHRoZSBzcGVjaWZpZWQgc3RyZWFtIGRvZXNuJ3QgZXhpc3QgKi8KICByZXR1cm4gQVZJRVJSX05PREFUQTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlICppZmFjZSxQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgaWZhY2UsIGF2aXMsIGFzaSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXZpcyA9PSBOVUxMIHx8IGFzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKmF2aXMgPSBOVUxMOwoKICAvKiBEb2VzIHRoZSB1c2VyIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBDYW4gd2UgYWRkIGFub3RoZXIgc3RyZWFtPyAqLwogIG4gPSBUaGlzLT5mSW5mby5kd1N0cmVhbXM7CiAgaWYgKG4gPj0gTUFYX0FWSVNUUkVBTVMgfHwgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkgewogICAgLyogYWxyZWFkeSByZWFjaGVkIG1heCBuciBvZiBzdHJlYW1zCiAgICAgKiBvciBoYXZlIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gZGlzayAqLwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIGNoZWNrIEFWSVNUUkVBTUlORk8gZm9yIHNvbWUgcmVhbGx5IG5lZWRlZCB0aGluZ3MgKi8KICBpZiAoYXNpLT5mY2NUeXBlID09IDAgfHwgYXNpLT5kd1NjYWxlID09IDAgfHwgYXNpLT5kd1JhdGUgPT0gMCkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBub3cgaXQgc2VlbXMgdG8gYmUgc2F2ZSB0byBhZGQgdGhlIHN0cmVhbSAqLwogIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCk7CiAgVGhpcy0+cHBTdHJlYW1zW25dID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksCgkJCQkJCSAgIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKiBpbml0aWFsaXplIHRoZSBuZXcgYWxsb2NhdGVkIHN0cmVhbSAqLwogIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKFRoaXMsIG4sIGFzaSk7CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcysrOwogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIHVwZGF0ZSBvdXIgQVZJRklMRUlORk8gc3RydWN0dXJlICovCiAgQVZJRklMRV9VcGRhdGVJbmZvKFRoaXMpOwoKICAvKiByZXR1cm4gaXQgKi8KICAqYXZpcyA9IChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1tuXTsKICBJQVZJU3RyZWFtX0FkZFJlZigqYXZpcyk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGNraWQsCgkJCQkJICAgTFBWT0lEIGxwRGF0YSwgTE9ORyBzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4WCwlcCwlZClcbiIsIGlmYWNlLCBja2lkLCBscERhdGEsIHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwRGF0YSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICByZXR1cm4gV3JpdGVFeHRyYUNodW5rKCZUaGlzLT5maWxlZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblJlYWREYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgIExQVk9JRCBscERhdGEsIExPTkcgKnNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhYLCVwLCVwKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZmlsZWV4dHJhLCBja2lkLCBscERhdGEsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIG5vIGZyYW1lcyB3cml0dGVuIHRvIGFueSBzdHJlYW0/IC0tIGNvbXB1dGUgc3RhcnQgb2YgJ21vdmknLWNodW5rICovCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcyk7CgogIFRoaXMtPmZJbmZvLmR3RmxhZ3MgIHw9IEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQ7CgogIC8qIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gYW55IHN0cmVhbSwgLi4uICovCiAgaWYgKFRoaXMtPmNrTGFzdFJlY29yZC5kd0ZsYWdzICYgTU1JT19ESVJUWSkgewogICAgLyogY2xvc2UgbGFzdCByZWNvcmQgKi8KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tMYXN0UmVjb3JkLCAwKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICBBVklGSUxFX0FkZFJlY29yZChUaGlzKTsKCiAgICBpZiAoVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSArIDMgKiBzaXplb2YoRFdPUkQpKQogICAgICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplICsgMyAqIHNpemVvZihEV09SRCk7CiAgfQoKICAvKiB3cml0ZSBvdXQgYSBuZXcgcmVjb3JkIGludG8gZmlsZSwgYnV0IGRvbid0IGNsb3NlIGl0ICovCiAgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSAgPSAwOwogIFRoaXMtPmNrTGFzdFJlY29yZC5mY2NUeXBlID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJlRoaXMtPmNrTGFzdFJlY29yZCwgTU1JT19DUkVBVEVMSVNUKSAhPSAwKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgKz0gMyAqIHNpemVvZihEV09SRCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGZjY1R5cGUsCgkJCQkJICAgICAgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFVMT05HIG5TdHJlYW07CgogIFRSQUNFKCIoJXAsMHglMDhYLCVkKVxuIiwgaWZhY2UsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChsUGFyYW0gPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogSGF2ZSB1c2VyIHdyaXRlIHBlcm1pc3Npb25zPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIG5TdHJlYW0gPSBBVklGSUxFX1NlYXJjaFN0cmVhbShUaGlzLCBmY2NUeXBlLCBsUGFyYW0pOwoKICAvKiBEb2VzIHRoZSByZXF1ZXN0ZWQgc3RyZWFtIGV4aXN0PyAqLwogIGlmIChuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICYmCiAgICAgIFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSAhPSBOVUxMKSB7CiAgICAvKiAuLi4gc28gZGVsZXRlIGl0IG5vdyAqLwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dKTsKCiAgICBpZiAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zIC0gblN0cmVhbSA+IDApCiAgICAgIG1lbWNweShUaGlzLT5wcFN0cmVhbXMgKyBuU3RyZWFtLCBUaGlzLT5wcFN0cmVhbXMgKyBuU3RyZWFtICsgMSwKCSAgICAgKFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAtIG5TdHJlYW0pICogc2l6ZW9mKElBVklTdHJlYW1JbXBsKikpOwoKICAgIFRoaXMtPnBwU3RyZWFtc1tUaGlzLT5mSW5mby5kd1N0cmVhbXNdID0gTlVMTDsKICAgIFRoaXMtPmZJbmZvLmR3U3RyZWFtcy0tOwogICAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgICAvKiBUaGlzLT5mSW5mbyB3aWxsIGJlIHVwZGF0ZWQgZnVydGhlciB3aGVuIGFza2VkIGZvciAqLwogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJICAgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgoUEFWSUZJTEUpVGhpcy0+cGFmLCByZWZpaWQsIG9iaik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5BZGRSZWYoSVBlcnNpc3RGaWxlICppZmFjZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gSUFWSUZpbGVfQWRkUmVmKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9SZWxlYXNlKChQQVZJRklMRSlUaGlzLT5wYWYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQlMUENMU0lEIHBDbGFzc0lEKQp7CiAgVFJBQ0UoIiglcCwlcClcbiIsIGlmYWNlLCBwQ2xhc3NJRCk7CgogIGlmIChwQ2xhc3NJRCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgbWVtY3B5KHBDbGFzc0lELCAmQ0xTSURfQVZJRmlsZSwgc2l6ZW9mKENMU0lEX0FWSUZpbGUpKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbklzRGlydHkoSVBlcnNpc3RGaWxlICppZmFjZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gKFRoaXMtPnBhZi0+ZkRpcnR5ID8gU19PSyA6IFNfRkFMU0UpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCSAgTFBDT0xFU1RSIHBzekZpbGVOYW1lLCBEV09SRCBkd01vZGUpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgaW50IGxlbjsKCiAgVFJBQ0UoIiglcCwlcywweCUwOFgpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGR3TW9kZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKICBpZiAoVGhpcy0+cGFmLT5obW1pbyAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogTm8gcmV1c2Ugb2YgdGhpcyBvYmplY3QgZm9yIGFub3RoZXIgZmlsZSEgKi8KCiAgLyogcmVtZWJlciBtb2RlIGFuZCBuYW1lICovCiAgVGhpcy0+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+bHBGb3JtYXQgPT0gTlVMTCkgewogICAgLyogaW5pdGlhbCBmb3JtYXQgKi8KICAgIGlmIChUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zICE9IDApCiAgICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIHVzZXIgaGFzIHVzZWQgQVBJIGluIHdyb25nIHNlcXVuZWNlISAqLwoKICAgIFRoaXMtPmxwRm9ybWF0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGZvcm1hdHNpemUpOwogICAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+Y2JGb3JtYXQgPSBmb3JtYXRzaXplOwoKICAgIG1lbWNweShUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgICAvKiB1cGRhdGUgc29tZSBpbmZvcyBhYm91dCBzdHJlYW0gKi8KICAgIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgICBMT05HIGxEaW07CgogICAgICBsRGltID0gVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCAtIFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdDsKICAgICAgaWYgKGxEaW0gPCBscGJpTmV3LT5iaVdpZHRoKQoJVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCA9IFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdCArIGxwYmlOZXctPmJpV2lkdGg7CiAgICAgIGxEaW0gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSAtIFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wOwogICAgICBpZiAobERpbSA8IGxwYmlOZXctPmJpSGVpZ2h0KQoJVGhpcy0+c0luZm8ucmNGcmFtZS5ib3R0b20gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLnRvcCArIGxwYmlOZXctPmJpSGVpZ2h0OwogICAgfSBlbHNlIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKICAgICAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplID0gKChMUFdBVkVGT1JNQVRFWClUaGlzLT5scEZvcm1hdCktPm5CbG9ja0FsaWduOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlIHsKICAgIE1NQ0tJTkZPICAgICAgICAgICBjazsKICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT2xkID0gKExQQklUTUFQSU5GT0hFQURFUilUaGlzLT5scEZvcm1hdDsKICAgIFJHQlFVQUQgICAgICAgICAgICpyZ2JOZXcgID0gKFJHQlFVQUQqKSgoTFBCWVRFKWxwYmlOZXcgKyBscGJpTmV3LT5iaVNpemUpOwogICAgQVZJUEFMQ0hBTkdFICAgICAgKmxwcGMgPSBOVUxMOwogICAgVUlOVCAgICAgICAgICAgICAgIG47CgogICAgLyogcGVyaGFwcyBmb3JtYXQgY2hhbmdlLCBjaGVjayBpdCAuLi4gKi8KICAgIGlmIChUaGlzLT5jYkZvcm1hdCAhPSBmb3JtYXRzaXplKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIG5vIGZvcm1hdCBjaGFuZ2UsIG9ubHkgdGhlIGluaXRpYWwgb25lICovCiAgICBpZiAobWVtY21wKFRoaXMtPmxwRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CgogICAgLyogY2hlY2sgdGhhdCdzIG9ubHkgdGhlIHBhbGV0dGUsIHdoaWNoIGNoYW5nZXMgKi8KICAgIGlmIChscGJpT2xkLT5iaVNpemUgICAgICAgICE9IGxwYmlOZXctPmJpU2l6ZSB8fAoJbHBiaU9sZC0+YmlXaWR0aCAgICAgICAhPSBscGJpTmV3LT5iaVdpZHRoIHx8CglscGJpT2xkLT5iaUhlaWdodCAgICAgICE9IGxwYmlOZXctPmJpSGVpZ2h0IHx8CglscGJpT2xkLT5iaVBsYW5lcyAgICAgICE9IGxwYmlOZXctPmJpUGxhbmVzIHx8CglscGJpT2xkLT5iaUJpdENvdW50ICAgICE9IGxwYmlOZXctPmJpQml0Q291bnQgfHwKCWxwYmlPbGQtPmJpQ29tcHJlc3Npb24gIT0gbHBiaU5ldy0+YmlDb21wcmVzc2lvbiB8fAoJbHBiaU9sZC0+YmlDbHJVc2VkICAgICAhPSBscGJpTmV3LT5iaUNsclVzZWQpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgVGhpcy0+c0luZm8uZHdGbGFncyB8PSBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVM7CgogICAgLyogc2ltcGx5IHNheSBhbGwgY29sb3JzIGhhdmUgY2hhbmdlZCAqLwogICAgY2suY2tpZCAgID0gTUFLRUFWSUNLSUQoY2t0eXBlUEFMY2hhbmdlLCBUaGlzLT5uU3RyZWFtKTsKICAgIGNrLmNrc2l6ZSA9IDIgKiBzaXplb2YoV09SRCkgKyBscGJpT2xkLT5iaUNsclVzZWQgKiBzaXplb2YoUEFMRVRURUVOVFJZKTsKICAgIGxwcGMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKICAgIGlmIChscHBjID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIGxwcGMtPmJGaXJzdEVudHJ5ID0gMDsKICAgIGxwcGMtPmJOdW1FbnRyaWVzID0gKGxwYmlPbGQtPmJpQ2xyVXNlZCA8IDI1NiA/IGxwYmlPbGQtPmJpQ2xyVXNlZCA6IDApOwogICAgbHBwYy0+d0ZsYWdzICAgICAgPSAwOwogICAgZm9yIChuID0gMDsgbiA8IGxwYmlPbGQtPmJpQ2xyVXNlZDsgbisrKSB7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlUmVkICAgPSByZ2JOZXdbbl0ucmdiUmVkOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUdyZWVuID0gcmdiTmV3W25dLnJnYkdyZWVuOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUJsdWUgID0gcmdiTmV3W25dLnJnYkJsdWU7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlRmxhZ3MgPSAwOwogICAgfQoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpbHBwYywgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MgKz0gY2suY2tzaXplICsgMiAqIHNpemVvZihEV09SRCk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBwYyk7CgogICAgcmV0dXJuIEFWSUZJTEVfQWRkRnJhbWUoVGhpcywgY2t0eXBlUEFMY2hhbmdlLCBuLCBjay5kd0RhdGFPZmZzZXQsIDApOwogIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCUxPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQlMT05HIGJ1ZmZlcnNpemUsIExQTE9ORyBieXRlc3JlYWQsCgkJCQkJTFBMT05HIHNhbXBsZXNyZWFkKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgRFdPUkQgICAgc2l6ZTsKICBIUkVTVUxUICBocjsKCiAgVFJBQ0UoIiglcCwlZCwlZCwlcCwlZCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAogCWJ1ZmZlcnNpemUsIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmICgoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0ID4gc3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsgLyogY291bGRuJ3QgcmVhZCBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtICovCiAgaWYgKFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA8IChEV09SRClzdGFydCkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOyAvKiBzdGFydCBpcyBwYXN0IGVuZCBvZiBzdHJlYW0gKi8KCiAgLyogc2hvdWxkIHdlIHJlYWQgYXMgbXVjaCBhcyBwb3NzaWJsZT8gKi8KICBpZiAoc2FtcGxlcyA9PSAtMSkgewogICAgLyogVXNlciBzaG91bGQga25vdyBob3cgbXVjaCB3ZSBoYXZlIHJlYWQgKi8KICAgIGlmIChieXRlc3JlYWQgPT0gTlVMTCAmJiBzYW1wbGVzcmVhZCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkKICAgICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBlbHNlCiAgICAgIHNhbXBsZXMgPSAxOwogIH0KCiAgLyogbGltaXQgdG8gZW5kIG9mIHN0cmVhbSAqLwogIGlmICgoTE9ORylUaGlzLT5zSW5mby5kd0xlbmd0aCA8IHNhbXBsZXMpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgaWYgKChzdGFydCAtIFRoaXMtPnNJbmZvLmR3U3RhcnQpID4gKFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gc2FtcGxlcykpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGggLSAoc3RhcnQgLSBUaGlzLT5zSW5mby5kd1N0YXJ0KTsKCiAgLyogbm90aGluZyB0byByZWFkPyBUaGVuIGxlYXZlIC4uLiAqLwogIGlmIChzYW1wbGVzID09IDApCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGZpeGVkIHNhbXBsZXNpemUgLS0gd2UgY2FuIHJlYWQgb3ZlciBmcmFtZS9ibG9jayBib3VuZGFyaWVzICovCiAgICBMT05HIGJsb2NrID0gc3RhcnQ7CiAgICBMT05HIG9mZnNldCA9IDA7CgogICAgLyogY29udmVydCBzdGFydCBzYW1wbGUgdG8gYmxvY2ssb2Zmc2V0IHBhaXIgKi8KICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soVGhpcywgJmJsb2NrLCAmb2Zmc2V0KTsKCiAgICAvKiBjb252ZXJ0IHNhbXBsZXMgdG8gYnl0ZXMgKi8KICAgIHNhbXBsZXMgKj0gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwoKICAgIHdoaWxlIChzYW1wbGVzID4gMCAmJiBidWZmZXJzaXplID4gMCkgewogICAgICBpZiAoYmxvY2sgIT0gVGhpcy0+ZHdDdXJyZW50RnJhbWUpIHsKCWhyID0gQVZJRklMRV9SZWFkQmxvY2soVGhpcywgYmxvY2ssIE5VTEwsIDApOwoJaWYgKEZBSUxFRChocikpCgkgIHJldHVybiBocjsKICAgICAgfQoKICAgICAgc2l6ZSA9IG1pbigoRFdPUkQpc2FtcGxlcywgKERXT1JEKWJ1ZmZlcnNpemUpOwogICAgICBzaXplID0gbWluKHNpemUsIFRoaXMtPmNiQnVmZmVyIC0gb2Zmc2V0KTsKICAgICAgbWVtY3B5KGJ1ZmZlciwgKChCWVRFKikmVGhpcy0+bHBCdWZmZXJbMl0pICsgb2Zmc2V0LCBzaXplKTsKCiAgICAgIGJsb2NrKys7CiAgICAgIG9mZnNldCA9IDA7CiAgICAgIGJ1ZmZlciA9ICgoTFBCWVRFKWJ1ZmZlcikrc2l6ZTsKICAgICAgc2FtcGxlcyAgICAtPSBzaXplOwogICAgICBidWZmZXJzaXplIC09IHNpemU7CgogICAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCgkqYnl0ZXNyZWFkICAgKz0gc2l6ZTsKICAgICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCgkqc2FtcGxlc3JlYWQgKz0gc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIH0KCiAgICBpZiAoc2FtcGxlcyA9PSAwKQogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgZWxzZQogICAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0gZWxzZSB7CiAgICAvKiB2YXJpYWJsZSBzYW1wbGVzaXplIC0tIHdlIGNhbiBvbmx5IHJlYWQgb25lIGZ1bGwgZnJhbWUvYmxvY2sgKi8KICAgIGlmIChzYW1wbGVzID4gMSkKICAgICAgc2FtcGxlcyA9IDE7CgogICAgYXNzZXJ0KHN0YXJ0IDw9IFRoaXMtPmxMYXN0RnJhbWUpOwogICAgc2l6ZSA9IFRoaXMtPmlkeEZyYW1lc1tzdGFydF0uZHdDaHVua0xlbmd0aDsKICAgIGlmIChidWZmZXIgIT0gTlVMTCAmJiBidWZmZXJzaXplID49IHNpemUpIHsKICAgICAgaHIgPSBBVklGSUxFX1JlYWRCbG9jayhUaGlzLCBzdGFydCwgYnVmZmVyLCBzaXplKTsKICAgICAgaWYgKEZBSUxFRChocikpCglyZXR1cm4gaHI7CiAgICB9IGVsc2UgaWYgKGJ1ZmZlciAhPSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBzaXplOwogICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAgICpzYW1wbGVzcmVhZCA9IHNhbXBsZXM7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJIExPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQkgTE9ORyBidWZmZXJzaXplLCBEV09SRCBmbGFncywKCQkJCQkgTFBMT05HIHNhbXB3cml0dGVuLAoJCQkJCSBMUExPTkcgYnl0ZXN3cml0dGVuKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgRk9VUkNDICBja2lkOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWQsJWQsJXAsJWQsMHglMDhYLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLAoJYnVmZmVyLCBidWZmZXJzaXplLCBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMICYmIChidWZmZXJzaXplID4gMCB8fCBzYW1wbGVzID4gMCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHdlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBzd2l0Y2ggKFRoaXMtPnNJbmZvLmZjY1R5cGUpIHsKICBjYXNlIHN0cmVhbXR5cGVBVURJTzoKICAgIGNraWQgPSBNQUtFQVZJQ0tJRChja3R5cGVXQVZFYnl0ZXMsIFRoaXMtPm5TdHJlYW0pOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGlmICgoZmxhZ3MgJiBBVklJRl9LRVlGUkFNRSkgJiYgYnVmZmVyc2l6ZSAhPSAwKQogICAgICBja2lkID0gTUFLRUFWSUNLSUQoY2t0eXBlRElCYml0cywgVGhpcy0+blN0cmVhbSk7CiAgICBlbHNlCiAgICAgIGNraWQgPSBNQUtFQVZJQ0tJRChja3R5cGVESUJjb21wcmVzc2VkLCBUaGlzLT5uU3RyZWFtKTsKICAgIGJyZWFrOwogIH07CgogIC8qIGFwcGVuZCB0byBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmIChzdGFydCA9PSAtMSkgewogICAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPT0gLTEpCiAgICAgIHN0YXJ0ID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGVsc2UKICAgICAgc3RhcnQgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICB9IGVsc2UgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPT0gLTEpCiAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ID0gc3RhcnQ7CgogIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgLyogZml4ZWQgc2FtcGxlIHNpemUgLS0gYXVkaW8gbGlrZSAqLwogICAgaWYgKHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gYnVmZmVyc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgICAvKiBDb3VsZG4ndCBza2lwIGF1ZGlvLWxpa2UgZGF0YSAtLSBVc2VyIG11c3Qgc3VwcGx5IGFwcHJvcHJpYXRlIHNpbGVuY2UgKi8KICAgIGlmIChUaGlzLT5zSW5mby5kd0xlbmd0aCAhPSBzdGFydCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICAvKiBDb252ZXJ0IHBvc2l0aW9uIHRvIGZyYW1lL2Jsb2NrICovCiAgICBzdGFydCA9IFRoaXMtPmxMYXN0RnJhbWUgKyAxOwoKICAgIGlmICgoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSVNJTlRFUkxFQVZFRCkgPT0gMCkgewogICAgICBGSVhNRSgiOiBub3QgaW50ZXJsZWF2ZWQsIGNvdWxkIGNvbGxlY3QgYXVkaW8gZGF0YSFcbiIpOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiB2YXJpYWJsZSBzYW1wbGUgc2l6ZSAtLSB2aWRlbyBsaWtlICovCiAgICBpZiAoc2FtcGxlcyA+IDEpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogbXVzdCB3ZSBmaWxsIHVwIHdpdGggZW1wdHkgZnJhbWVzPyAqLwogICAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgIT0gLTEpIHsKICAgICAgRk9VUkNDIGNraWQyID0gTUFLRUFWSUNLSUQoY2t0eXBlRElCY29tcHJlc3NlZCwgVGhpcy0+blN0cmVhbSk7CgogICAgICB3aGlsZSAoc3RhcnQgPiBUaGlzLT5sTGFzdEZyYW1lICsgMSkgewoJaHIgPSBBVklGSUxFX1dyaXRlQmxvY2soVGhpcywgVGhpcy0+bExhc3RGcmFtZSArIDEsIGNraWQyLCAwLCBOVUxMLCAwKTsKCWlmIChGQUlMRUQoaHIpKQoJICByZXR1cm4gaHI7CiAgICAgIH0KICAgIH0KICB9CgogIC8qIHdyaXRlIHRoZSBibG9jayBub3cgKi8KICBociA9IEFWSUZJTEVfV3JpdGVCbG9jayhUaGlzLCBzdGFydCwgY2tpZCwgZmxhZ3MsIGJ1ZmZlciwgYnVmZmVyc2l6ZSk7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICAgKnNhbXB3cml0dGVuID0gc2FtcGxlczsKICAgIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICAgKmJ5dGVzd3JpdHRlbiA9IGJ1ZmZlcnNpemU7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSAgTE9ORyBzYW1wbGVzKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgRklYTUUoIiglcCwlZCwlZCk6IHN0dWJcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3RhcnQgPCAwIHx8IHNhbXBsZXMgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRGVsZXRlIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0/ICovCiAgaWYgKHN0YXJ0ICsgc2FtcGxlcyA8IFRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBEZWxldGUgYWZ0ZXIgZW5kIG9mIHN0cmVhbT8gKi8KICBpZiAoc3RhcnQgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIEZvciB0aGUgcmVzdCB3ZSBuZWVkIHdyaXRlIHBlcm1pc3Npb25zICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiAxLiBvdmVyd3JpdGUgdGhlIGRhdGEgd2l0aCBKVU5LCiAgICoKICAgKiBpZiBJU0lOVEVSTEVBVkVEIHsKICAgKiAgIDIuIGNvbmNhdCBhbGwgbmVpZ2hib3VyZWQgSlVOSy1ibG9ja3MgaW4gdGhpcyByZWNvcmQgdG8gb25lCiAgICogICAzLiBpZiB0aGlzIHJlY29yZCBvbmx5IGNvbnRhaW5zIEpVTksgYW5kIGlzIGF0IGVuZCBzZXQgZHdOZXh0RnJhbWVQb3MKICAgKiAgICAgIHRvIHN0YXJ0IG9mIHRoaXMgcmVjb3JkLCByZXBlYXQgdGhpcy4KICAgKiB9IGVsc2UgewogICAqICAgMi4gY29uY2F0IGFsbCBuZWlnaGJvdXJlZCBKVU5LLWJsb2Nrcy4KICAgKiAgIDMuIGlmIHRoZSBKVU5LIGJsb2NrIGlzIGF0IHRoZSBlbmQsIHRoZW4gc2V0IGR3TmV4dEZyYW1lUG9zIHRvCiAgICogICAgICBzdGFydCBvZiB0aGlzIGJsb2NrLgogICAqIH0KICAgKi8KCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICBMUFZPSUQgbHAsIExQTE9ORyBscHJlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4WCwlcCwlcClcbiIsIGlmYWNlLCBmY2MsIGxwLCBscHJlYWQpOwoKICBpZiAoZmNjID09IGNraWRTVFJFQU1IQU5ETEVSREFUQSkgewogICAgaWYgKFRoaXMtPmxwSGFuZGxlckRhdGEgIT0gTlVMTCAmJiBUaGlzLT5jYkhhbmRsZXJEYXRhID4gMCkgewogICAgICBpZiAobHAgPT0gTlVMTCB8fCAqbHByZWFkIDw9IDApIHsKCSpscHJlYWQgPSBUaGlzLT5jYkhhbmRsZXJEYXRhOwoJcmV0dXJuIEFWSUVSUl9PSzsKICAgICAgfQoKICAgICAgbWVtY3B5KGxwLCBUaGlzLT5scEhhbmRsZXJEYXRhLCBtaW4oVGhpcy0+Y2JIYW5kbGVyRGF0YSwgKmxwcmVhZCkpOwogICAgICBpZiAoKmxwcmVhZCA8IFRoaXMtPmNiSGFuZGxlckRhdGEpCglyZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgfSBlbHNlCiAgICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwogIH0gZWxzZQogICAgcmV0dXJuIFJlYWRFeHRyYUNodW5rKCZUaGlzLT5leHRyYSwgZmNjLCBscCwgbHByZWFkKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgIExQVk9JRCBscCwgTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOHgsJXAsJWQpXG4iLCBpZmFjZSwgZmNjLCBscCwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogbmVlZCB3cml0ZSBwZXJtaXNzaW9uICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBhbHJlYWR5IHdyaXR0ZW4gc29tZXRoaW5nIHRvIHRoaXMgZmlsZT8gKi8KICBpZiAoVGhpcy0+cGFmLT5kd01vdmlDaHVua1BvcyAhPSAwKSB7CiAgICAvKiB0aGUgZGF0YSB3aWxsIGJlIGluc2VydGVkIGJlZm9yZSB0aGUgJ21vdmknIGNodW5rLCBzbyBjaGVjayBmb3IKICAgICAqIGVub3VnaCBzcGFjZSAqLwogICAgRFdPUkQgZHdQb3MgPSBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcy0+cGFmKTsKCiAgICAvKiBja2lkLHNpemUgPT4gMiAqIHNpemVvZihEV09SRCkgKi8KICAgIGR3UG9zICs9IDIgKiBzaXplb2YoRFdPUkQpICsgc2l6ZTsKICAgIGlmIChzaXplID49IFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgLSAyICogc2l6ZW9mKERXT1JEKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogbm90IGVub3VnaCBzcGFjZSBsZWZ0ICovCiAgfQoKICBUaGlzLT5wYWYtPmZEaXJ0eSA9IFRSVUU7CgogIGlmIChmY2MgPT0gY2tpZFNUUkVBTUhBTkRMRVJEQVRBKSB7CiAgICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMKSB7CiAgICAgIEZJWE1FKCI6IGhhbmRsZXIgZGF0YSBhbHJlYWR5IHNldCAtLSBvdmVyd2lydGU/XG4iKTsKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICAgIH0KCiAgICBUaGlzLT5scEhhbmRsZXJEYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgaWYgKFRoaXMtPmxwSGFuZGxlckRhdGEgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5jYkhhbmRsZXJEYXRhID0gc2l6ZTsKICAgIG1lbWNweShUaGlzLT5scEhhbmRsZXJEYXRhLCBscCwgc2l6ZSk7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBmY2MsIGxwLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCSAgIExQQVZJU1RSRUFNSU5GT1cgaW5mbywgTE9ORyBpbmZvbGVuKQp7CiAgRklYTUUoIiglcCwlcCwlZCk6IHN0dWJcbiIsIGlmYWNlLCBpbmZvLCBpbmZvbGVuKTsKCiAgcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgY2tpZCwgRFdPUkQgc2l6ZSwgRFdPUkQgb2Zmc2V0LCBEV09SRCBmbGFncykKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CgogIHN3aXRjaCAoVFdPQ0NGcm9tRk9VUkNDKGNraWQpKSB7CiAgY2FzZSBja3R5cGVESUJiaXRzOgogICAgaWYgKFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX1RSVVNUQ0tUWVBFKQogICAgICBmbGFncyB8PSBBVklJRl9LRVlGUkFNRTsKICAgIGJyZWFrOwogIGNhc2UgY2t0eXBlRElCY29tcHJlc3NlZDoKICAgIGlmIChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19UUlVTVENLVFlQRSkKICAgICAgZmxhZ3MgJj0gfkFWSUlGX0tFWUZSQU1FOwogICAgYnJlYWs7CiAgY2FzZSBja3R5cGVQQUxjaGFuZ2U6CiAgICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSAhPSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgRVJSKCI6IGZvdW5kIHBhbGV0dGUgY2hhbmdlIGluIG5vbi12aWRlbyBzdHJlYW0hXG4iKTsKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CiAgICB9CiAgICBUaGlzLT5zSW5mby5kd0ZsYWdzIHw9IEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUzsKICAgIFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQrKzsKCiAgICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlcyA9PSBOVUxMIHx8IFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgPCBUaGlzLT5uSWR4Rm10Q2hhbmdlcykgewogICAgICBVSU5UIG4gPSBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OwoKICAgICAgVGhpcy0+bklkeEZtdENoYW5nZXMgKz0gMTY7CiAgICAgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzID09IE5VTEwpCglUaGlzLT5pZHhGbXRDaGFuZ2VzID0KCSAgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPm5JZHhGbXRDaGFuZ2VzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgICAgZWxzZQoJVGhpcy0+aWR4Rm10Q2hhbmdlcyA9CgkgIEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPmlkeEZtdENoYW5nZXMsCgkJCSAgIFRoaXMtPm5JZHhGbXRDaGFuZ2VzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgICAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXMgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgICAgVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkICAgICAgICAgID0gVGhpcy0+bExhc3RGcmFtZTsKICAgICAgVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5kd0ZsYWdzICAgICAgID0gMDsKICAgICAgVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5kd0NodW5rT2Zmc2V0ID0gb2Zmc2V0OwogICAgICBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmR3Q2h1bmtMZW5ndGggPSBzaXplOwoKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgY2t0eXBlV0FWRWJ5dGVzOgogICAgaWYgKFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX1RSVVNUQ0tUWVBFKQogICAgICBmbGFncyB8PSBBVklJRl9LRVlGUkFNRTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBXQVJOKCI6IHVua25vd24gVFdPQ0MgMHglMDRYIGZvdW5kXG4iLCBUV09DQ0Zyb21GT1VSQ0MoY2tpZCkpOwogICAgYnJlYWs7CiAgfTsKCiAgLyogZmlyc3QgZnJhbWUgaXMgYWx3YXN5IGEga2V5ZnJhbWUgKi8KICBpZiAoVGhpcy0+bExhc3RGcmFtZSA9PSAtMSkKICAgIGZsYWdzIHw9IEFWSUlGX0tFWUZSQU1FOwoKICBpZiAoVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgc2l6ZSkKICAgIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IHNpemU7CgogIC8qIGdldCBtZW1vcnkgZm9yIGluZGV4ICovCiAgaWYgKFRoaXMtPmlkeEZyYW1lcyA9PSBOVUxMIHx8IFRoaXMtPmxMYXN0RnJhbWUgKyAxID49IFRoaXMtPm5JZHhGcmFtZXMpIHsKICAgIFRoaXMtPm5JZHhGcmFtZXMgKz0gNTEyOwogICAgaWYgKFRoaXMtPmlkeEZyYW1lcyA9PSBOVUxMKQogICAgICBUaGlzLT5pZHhGcmFtZXMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgVGhpcy0+bklkeEZyYW1lcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGVsc2UKCVRoaXMtPmlkeEZyYW1lcyA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPmlkeEZyYW1lcywKCQkJICAgVGhpcy0+bklkeEZyYW1lcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICBpZiAoVGhpcy0+aWR4RnJhbWVzID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIH0KCiAgVGhpcy0+bExhc3RGcmFtZSsrOwogIFRoaXMtPmlkeEZyYW1lc1tUaGlzLT5sTGFzdEZyYW1lXS5ja2lkICAgICAgICAgID0gY2tpZDsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uZHdGbGFncyAgICAgICA9IGZsYWdzOwogIFRoaXMtPmlkeEZyYW1lc1tUaGlzLT5sTGFzdEZyYW1lXS5kd0NodW5rT2Zmc2V0ID0gb2Zmc2V0OwogIFRoaXMtPmlkeEZyYW1lc1tUaGlzLT5sTGFzdEZyYW1lXS5kd0NodW5rTGVuZ3RoID0gc2l6ZTsKCiAgLyogdXBkYXRlIEFWSVNUUkVBTUlORk8gc3RydWN0dXJlIGlmIG5lY2Vzc2FyeSAqLwogIGlmIChUaGlzLT5zSW5mby5kd0xlbmd0aCA8PSBUaGlzLT5sTGFzdEZyYW1lKQogICAgVGhpcy0+c0luZm8uZHdMZW5ndGggPSBUaGlzLT5sTGFzdEZyYW1lICsgMTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRSZWNvcmQoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMICYmIFRoaXMtPnBwU3RyZWFtc1swXSAhPSBOVUxMKTsKCiAgaWYgKFRoaXMtPmlkeFJlY29yZHMgPT0gTlVMTCB8fCBUaGlzLT5jYklkeFJlY29yZHMgPT0gMCkgewogICAgVGhpcy0+Y2JJZHhSZWNvcmRzICs9IDEwMjQgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSk7CiAgICBUaGlzLT5pZHhSZWNvcmRzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPmNiSWR4UmVjb3Jkcyk7CiAgICBpZiAoVGhpcy0+aWR4UmVjb3JkcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICB9CgogIGFzc2VydChUaGlzLT5uSWR4UmVjb3JkcyA8IFRoaXMtPmNiSWR4UmVjb3Jkcy9zaXplb2YoQVZJSU5ERVhFTlRSWSkpOwoKICBUaGlzLT5pZHhSZWNvcmRzW1RoaXMtPm5JZHhSZWNvcmRzXS5ja2lkICAgICAgICAgID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgVGhpcy0+aWR4UmVjb3Jkc1tUaGlzLT5uSWR4UmVjb3Jkc10uZHdGbGFncyAgICAgICA9IEFWSUlGX0xJU1Q7CiAgVGhpcy0+aWR4UmVjb3Jkc1tUaGlzLT5uSWR4UmVjb3Jkc10uZHdDaHVua09mZnNldCA9CiAgICBUaGlzLT5ja0xhc3RSZWNvcmQuZHdEYXRhT2Zmc2V0IC0gMiAqIHNpemVvZihEV09SRCk7CiAgVGhpcy0+aWR4UmVjb3Jkc1tUaGlzLT5uSWR4UmVjb3Jkc10uZHdDaHVua0xlbmd0aCA9CiAgICBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplOwogIFRoaXMtPm5JZHhSZWNvcmRzKys7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBEV09SRCAgIEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBEV09SRCBkd1BvczsKICBEV09SRCBuU3RyZWFtOwoKICAvKiBSSUZGLGhkcmwsbW92aSxhdmloID0+ICgzICogMyArIDIpICogc2l6ZW9mKERXT1JEKSA9IDExICogc2l6ZW9mKERXT1JEKSAqLwogIGR3UG9zID0gMTEgKiBzaXplb2YoRFdPUkQpICsgc2l6ZW9mKE1haW5BVklIZWFkZXIpOwoKICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKICAgIElBVklTdHJlYW1JbXBsICpwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwoKICAgIC8qIHN0cmwsc3RyaCxzdHJmID0+ICgzICsgMiAqIDIpICogc2l6ZW9mKERXT1JEKSA9IDcgKiBzaXplb2YoRFdPUkQpICovCiAgICBkd1BvcyArPSA3ICogc2l6ZW9mKERXT1JEKSArIHNpemVvZihBVklTdHJlYW1IZWFkZXIpOwogICAgZHdQb3MgKz0gKChwU3RyZWFtLT5jYkZvcm1hdCArIDEpICYgfjFVKTsKICAgIGlmIChwU3RyZWFtLT5scEhhbmRsZXJEYXRhICE9IE5VTEwgJiYgcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YSA+IDApCiAgICAgIGR3UG9zICs9IDIgKiBzaXplb2YoRFdPUkQpICsgKChwU3RyZWFtLT5jYkhhbmRsZXJEYXRhICsgMSkgJiB+MVUpOwogICAgaWYgKGxzdHJsZW5XKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkgPiAwKQogICAgICBkd1BvcyArPSAyICogc2l6ZW9mKERXT1JEKSArICgobHN0cmxlblcocFN0cmVhbS0+c0luZm8uc3pOYW1lKSArIDEpICYgfjFVKTsKICB9CgogIGlmIChUaGlzLT5kd01vdmlDaHVua1BvcyA9PSAwKSB7CiAgICBUaGlzLT5kd05leHRGcmFtZVBvcyA9IGR3UG9zOwoKICAgIC8qIHBhZCB0byBtdWx0aXBsZSBvZiBBVklfSEVBREVSU0laRSBvbmx5IGlmIHdlIGFyZSBtb3JlIHRoYW4gOCBieXRlcyBhd2F5IGZyb20gaXQgKi8KICAgIGlmICgoKGR3UG9zICsgQVZJX0hFQURFUlNJWkUpICYgfihBVklfSEVBREVSU0laRSAtIDEpKSAtIGR3UG9zID4gMiAqIHNpemVvZihEV09SRCkpCiAgICAgIFRoaXMtPmR3TmV4dEZyYW1lUG9zID0gKGR3UG9zICsgQVZJX0hFQURFUlNJWkUpICYgfihBVklfSEVBREVSU0laRSAtIDEpOwoKICAgIFRoaXMtPmR3TW92aUNodW5rUG9zID0gVGhpcy0+ZHdOZXh0RnJhbWVQb3MgLSBzaXplb2YoRFdPUkQpOwogIH0KCiAgcmV0dXJuIGR3UG9zOwp9CgpzdGF0aWMgdm9pZCAgICBBVklGSUxFX0NvbnN0cnVjdEFWSVN0cmVhbShJQVZJRmlsZUltcGwgKnBhZiwgRFdPUkQgbnIsIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgSUFWSVN0cmVhbUltcGwgKnBzdHJlYW07CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KHBhZiAhPSBOVUxMKTsKICBhc3NlcnQobnIgPCBNQVhfQVZJU1RSRUFNUyk7CiAgYXNzZXJ0KHBhZi0+cHBTdHJlYW1zW25yXSAhPSBOVUxMKTsKCiAgcHN0cmVhbSA9IHBhZi0+cHBTdHJlYW1zW25yXTsKCiAgcHN0cmVhbS0+bHBWdGJsICAgICAgICAgPSAmaWF2aXN0OwogIHBzdHJlYW0tPnJlZiAgICAgICAgICAgID0gMDsKICBwc3RyZWFtLT5wYWYgICAgICAgICAgICA9IHBhZjsKICBwc3RyZWFtLT5uU3RyZWFtICAgICAgICA9IG5yOwogIHBzdHJlYW0tPmR3Q3VycmVudEZyYW1lID0gKERXT1JEKS0xOwogIHBzdHJlYW0tPmxMYXN0RnJhbWUgICAgPSAtMTsKCiAgaWYgKGFzaSAhPSBOVUxMKSB7CiAgICBtZW1jcHkoJnBzdHJlYW0tPnNJbmZvLCBhc2ksIHNpemVvZihwc3RyZWFtLT5zSW5mbykpOwoKICAgIGlmIChhc2ktPmR3TGVuZ3RoID4gMCkgewogICAgICAvKiBwcmUtYWxsb2NhdGUgbWVtIGZvciBmcmFtZS1pbmRleCBzdHJ1Y3R1cmUgKi8KICAgICAgcHN0cmVhbS0+aWR4RnJhbWVzID0KCUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBhc2ktPmR3TGVuZ3RoICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgICAgaWYgKHBzdHJlYW0tPmlkeEZyYW1lcyAhPSBOVUxMKQoJcHN0cmVhbS0+bklkeEZyYW1lcyA9IGFzaS0+ZHdMZW5ndGg7CiAgICB9CiAgICBpZiAoYXNpLT5kd0Zvcm1hdENoYW5nZUNvdW50ID4gMCkgewogICAgICAvKiBwcmUtYWxsb2NhdGUgbWVtIGZvciBmb3JtYXRjaGFuZ2UtaW5kZXggc3RydWN0dXJlICovCiAgICAgIHBzdHJlYW0tPmlkeEZtdENoYW5nZXMgPQoJSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIGFzaS0+ZHdGb3JtYXRDaGFuZ2VDb3VudCAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGlmIChwc3RyZWFtLT5pZHhGbXRDaGFuZ2VzICE9IE5VTEwpCglwc3RyZWFtLT5uSWR4Rm10Q2hhbmdlcyA9IGFzaS0+ZHdGb3JtYXRDaGFuZ2VDb3VudDsKICAgIH0KCiAgICAvKiBUaGVzZSB2YWx1ZXMgd2lsbCBiZSBjb21wdXRlZCAqLwogICAgcHN0cmVhbS0+c0luZm8uZHdMZW5ndGggICAgICAgICAgICAgID0gMDsKICAgIHBzdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IDA7CiAgICBwc3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ICAgPSAwOwogICAgcHN0cmVhbS0+c0luZm8uZHdFZGl0Q291bnQgICAgICAgICAgID0gMTsKICAgIGlmIChwc3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgPiAwKQogICAgICBTZXRSZWN0RW1wdHkoJnBzdHJlYW0tPnNJbmZvLnJjRnJhbWUpOwogIH0KCiAgcHN0cmVhbS0+c0luZm8uZHdDYXBzID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKfQoKc3RhdGljIHZvaWQgICAgQVZJRklMRV9EZXN0cnVjdEFWSVN0cmVhbShJQVZJU3RyZWFtSW1wbCAqVGhpcykKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CgogIFRoaXMtPmR3Q3VycmVudEZyYW1lID0gKERXT1JEKS0xOwogIFRoaXMtPmxMYXN0RnJhbWUgICAgPSAtMTsKICBUaGlzLT5wYWYgPSBOVUxMOwogIGlmIChUaGlzLT5pZHhGcmFtZXMgIT0gTlVMTCkgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+aWR4RnJhbWVzKTsKICAgIFRoaXMtPmlkeEZyYW1lcyAgPSBOVUxMOwogICAgVGhpcy0+bklkeEZyYW1lcyA9IDA7CiAgfQogIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmlkeEZtdENoYW5nZXMpOwogIFRoaXMtPmlkeEZtdENoYW5nZXMgPSBOVUxMOwogIGlmIChUaGlzLT5scEJ1ZmZlciAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scEJ1ZmZlcik7CiAgICBUaGlzLT5scEJ1ZmZlciA9IE5VTEw7CiAgICBUaGlzLT5jYkJ1ZmZlciA9IDA7CiAgfQogIGlmIChUaGlzLT5scEhhbmRsZXJEYXRhICE9IE5VTEwpIHsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwSGFuZGxlckRhdGEpOwogICAgVGhpcy0+bHBIYW5kbGVyRGF0YSA9IE5VTEw7CiAgICBUaGlzLT5jYkhhbmRsZXJEYXRhID0gMDsKICB9CiAgaWYgKFRoaXMtPmV4dHJhLmxwICE9IE5VTEwpIHsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmV4dHJhLmxwKTsKICAgIFRoaXMtPmV4dHJhLmxwID0gTlVMTDsKICAgIFRoaXMtPmV4dHJhLmNiID0gMDsKICB9CiAgaWYgKFRoaXMtPmxwRm9ybWF0ICE9IE5VTEwpIHsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwRm9ybWF0KTsKICAgIFRoaXMtPmxwRm9ybWF0ID0gTlVMTDsKICAgIFRoaXMtPmNiRm9ybWF0ID0gMDsKICB9Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgTWFpbkFWSUhlYWRlciAgIE1haW5BVklIZHI7CiAgTU1DS0lORk8gICAgICAgIGNrUklGRjsKICBNTUNLSU5GTyAgICAgICAgY2tMSVNUMTsKICBNTUNLSU5GTyAgICAgICAgY2tMSVNUMjsKICBNTUNLSU5GTyAgICAgICAgY2s7CiAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW07CiAgRFdPUkQgICAgICAgICAgIG5TdHJlYW07CiAgSFJFU1VMVCAgICAgICAgIGhyOwoKICBpZiAoVGhpcy0+aG1taW8gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfRklMRU9QRU47CgogIC8qIGluaXRpYWxpemUgc3RyZWFtIHB0cidzICovCiAgbWVtc2V0KFRoaXMtPnBwU3RyZWFtcywgMCwgc2l6ZW9mKFRoaXMtPnBwU3RyZWFtcykpOwoKICAvKiB0cnkgdG8gZ2V0ICJSSUZGIiBjaHVuayAtLSBtdXN0IG5vdCBiZSBhdCBiZWdpbm5pbmcgb2YgZmlsZSEgKi8KICBja1JJRkYuZmNjVHlwZSA9IGZvcm10eXBlQVZJOwogIGlmIChtbWlvRGVzY2VuZChUaGlzLT5obW1pbywgJmNrUklGRiwgTlVMTCwgTU1JT19GSU5EUklGRikgIT0gU19PSykgewogICAgRVJSKCI6IG5vdCBhbiBBVkkhXG4iKTsKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICAvKiBnZXQgIkxJU1QiICJoZHJsIiAqLwogIGNrTElTVDEuZmNjVHlwZSA9IGxpc3R0eXBlQVZJSEVBREVSOwogIGhyID0gRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrTElTVDEsICZja1JJRkYsIE1NSU9fRklORExJU1QpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICAvKiBnZXQgImF2aWgiIGNodW5rICovCiAgY2suY2tpZCA9IGNraWRBVklNQUlOSERSOwogIGhyID0gRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrLCAmY2tMSVNUMSwgTU1JT19GSU5EQ0hVTkspOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICBpZiAoY2suY2tzaXplICE9IHNpemVvZihNYWluQVZJSGRyKSkgewogICAgRVJSKCI6IGludmFsaWQgc2l6ZSBvZiAlZCBmb3IgTWFpbkFWSUhlYWRlciFcbiIsIGNrLmNrc2l6ZSk7CiAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKICB9CiAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpJk1haW5BVklIZHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogY2hlY2sgZm9yIE1BWF9BVklTVFJFQU1TIGxpbWl0ICovCiAgaWYgKE1haW5BVklIZHIuZHdTdHJlYW1zID4gTUFYX0FWSVNUUkVBTVMpIHsKICAgIFdBUk4oImZpbGUgY29udGFpbnMgJXUgc3RyZWFtcywgYnV0IG9ubHkgc3VwcG9ydHMgJWQgLS0gY2hhbmdlIE1BWF9BVklTVFJFQU1TIVxuIiwgTWFpbkFWSUhkci5kd1N0cmVhbXMsIE1BWF9BVklTVFJFQU1TKTsKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfQoKICAvKiBhZGp1c3QgcGVybWlzc2lvbnMgaWYgY29weXJpZ2h0ZWQgbWF0ZXJpYWwgaW4gZmlsZSAqLwogIGlmIChNYWluQVZJSGRyLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19DT1BZUklHSFRFRCkgewogICAgVGhpcy0+dU1vZGUgJj0gfk1NSU9fUldNT0RFOwogICAgVGhpcy0+dU1vZGUgfD0gTU1JT19SRUFEOwogIH0KCiAgLyogY29udmVydCBNYWluQVZJSGVhZGVyIGludG8gQVZJRklMSU5GT1cgKi8KICBtZW1zZXQoJlRoaXMtPmZJbmZvLCAwLCBzaXplb2YoVGhpcy0+ZkluZm8pKTsKICBUaGlzLT5mSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3TWljcm9TZWNQZXJGcmFtZTsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgICAgICAgICAgICAgPSAxMDAwMDAwOwogIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgICAgICA9IE1haW5BVklIZHIuZHdNYXhCeXRlc1BlclNlYzsKICBUaGlzLT5mSW5mby5kd0ZsYWdzICAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3RmxhZ3M7CiAgVGhpcy0+ZkluZm8uZHdDYXBzICAgICAgICAgICAgICAgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3VG90YWxGcmFtZXM7CiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd1N0cmVhbXM7CiAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gTWFpbkFWSUhkci5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgVGhpcy0+ZkluZm8uZHdXaWR0aCAgICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd1dpZHRoOwogIFRoaXMtPmZJbmZvLmR3SGVpZ2h0ICAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdIZWlnaHQ7CiAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQVZJRklMRVRZUEUsIFRoaXMtPmZJbmZvLnN6RmlsZVR5cGUsCgkgICAgICBzaXplb2YoVGhpcy0+ZkluZm8uc3pGaWxlVHlwZSkpOwoKICAvKiBnbyBiYWNrIHRvIGludG8gaGVhZGVyIGxpc3QgKi8KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogZm9yZWFjaCBzdHJlYW0gZXhpc3RzIGEgIkxJU1QiLCJzdHJsIiBjaHVuayAqLwogIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgLyogZ2V0IG5leHQgbmVzdGVkIGNodW5rIGluIHRoaXMgIkxJU1QiLCJzdHJsIiAqLwogICAgaWYgKG1taW9EZXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMiwgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogICAgLyogbmVzdGVkIGNodW5rIG11c3QgYmUgb2YgdHlwZSAiTElTVCIsInN0cmwiIC0tIHdoZW4gbm90IG5vcm1hbGx5IEpVTksgKi8KICAgIGlmIChja0xJU1QyLmNraWQgPT0gRk9VUkNDX0xJU1QgJiYKCWNrTElTVDIuZmNjVHlwZSA9PSBsaXN0dHlwZVNUUkVBTUhFQURFUikgewogICAgICBwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dID0KCUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSUFWSVN0cmVhbUltcGwpKTsKICAgICAgaWYgKHBTdHJlYW0gPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBBVklGSUxFX0NvbnN0cnVjdEFWSVN0cmVhbShUaGlzLCBuU3RyZWFtLCBOVUxMKTsKCiAgICAgIGNrLmNraWQgPSAwOwogICAgICB3aGlsZSAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDIsIDApID09IFNfT0spIHsKCXN3aXRjaCAoY2suY2tpZCkgewoJY2FzZSBja2lkU1RSRUFNSEFORExFUkRBVEE6CgkgIGlmIChwU3RyZWFtLT5scEhhbmRsZXJEYXRhICE9IE5VTEwpCgkgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgkgIHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKCSAgaWYgKHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgPT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCSAgcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YSA9IGNrLmNrc2l6ZTsKCgkgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKXBTdHJlYW0tPmxwSGFuZGxlckRhdGEsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgkgIGJyZWFrOwoJY2FzZSBja2lkU1RSRUFNRk9STUFUOgoJICBpZiAocFN0cmVhbS0+bHBGb3JtYXQgIT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKICAgICAgICAgIGlmIChjay5ja3NpemUgPT0gMCkKICAgICAgICAgICAgYnJlYWs7CgoJICBwU3RyZWFtLT5scEZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjay5ja3NpemUpOwoJICBpZiAocFN0cmVhbS0+bHBGb3JtYXQgPT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCSAgcFN0cmVhbS0+Y2JGb3JtYXQgPSBjay5ja3NpemU7CgoJICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5scEZvcm1hdCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCgkgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCgkgIGlmIChwU3RyZWFtLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewoJICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpID0gKExQQklUTUFQSU5GT0hFQURFUilwU3RyZWFtLT5scEZvcm1hdDsKCgkgICAgLyogc29tZSBjb3JyZWN0aW9ucyB0byB0aGUgdmlkZW8gZm9ybWF0ICovCgkgICAgaWYgKGxwYmktPmJpQ2xyVXNlZCA9PSAwICYmIGxwYmktPmJpQml0Q291bnQgPD0gOCkKCSAgICAgIGxwYmktPmJpQ2xyVXNlZCA9IDF1IDw8IGxwYmktPmJpQml0Q291bnQ7CgkgICAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCICYmIGxwYmktPmJpU2l6ZUltYWdlID09IDApCgkgICAgICBscGJpLT5iaVNpemVJbWFnZSA9IERJQldJRFRIQllURVMoKmxwYmkpICogbHBiaS0+YmlIZWlnaHQ7CgkgICAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gIT0gQklfUkdCICYmIGxwYmktPmJpQml0Q291bnQgPT0gOCkgewoJICAgICAgaWYgKHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gbW1pb0ZPVVJDQygnUicsJ0wnLCdFJywnMCcpIHx8CgkJICBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID09IG1taW9GT1VSQ0MoJ1InLCdMJywnRScsJyAnKSkKCQlscGJpLT5iaUNvbXByZXNzaW9uID0gQklfUkxFODsKCSAgICB9CgkgICAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCICYmCgkJKHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gMCB8fAoJCSBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID09IG1taW9GT1VSQ0MoJ04nLCdPJywnTicsJ0UnKSkpCgkgICAgICBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CgoJICAgIC8qIGluaXQgcmNGcmFtZSBpZiBpdCdzIGVtcHR5ICovCgkgICAgaWYgKElzUmVjdEVtcHR5KCZwU3RyZWFtLT5zSW5mby5yY0ZyYW1lKSkKCSAgICAgIFNldFJlY3QoJnBTdHJlYW0tPnNJbmZvLnJjRnJhbWUsIDAsIDAsIGxwYmktPmJpV2lkdGgsIGxwYmktPmJpSGVpZ2h0KTsKCSAgfQoJICBicmVhazsKCWNhc2UgY2tpZFNUUkVBTUhFQURFUjoKCSAgewoJICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzdHJlYW1UeXBlRm10W10gPSB7JyUnLCc0JywnLicsJzQnLCdoJywncycsMH07CgoJICAgIEFWSVN0cmVhbUhlYWRlciBzdHJlYW1IZHI7CgkgICAgV0NIQVIgICAgICAgICAgIHN6VHlwZVsyNV07CgkgICAgV0NIQVIgICAgICAgICAgIHN0cmVhbU5hbWVGbXRbMjVdOwoJICAgIFVJTlQgICAgICAgICAgICBjb3VudDsKCSAgICBMT05HICAgICAgICAgICAgbiA9IGNrLmNrc2l6ZTsKCgkgICAgaWYgKGNrLmNrc2l6ZSA+IHNpemVvZihzdHJlYW1IZHIpKQoJICAgICAgbiA9IHNpemVvZihzdHJlYW1IZHIpOwoKCSAgICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUikmc3RyZWFtSGRyLCBuKSAhPSBuKQoJICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCgkgICAgcFN0cmVhbS0+c0luZm8uZmNjVHlwZSAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmZjY1R5cGU7CgkgICAgcFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciAgICAgICAgICAgID0gc3RyZWFtSGRyLmZjY0hhbmRsZXI7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdGbGFncyAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3RmxhZ3M7CgkgICAgcFN0cmVhbS0+c0luZm8ud1ByaW9yaXR5ICAgICAgICAgICAgID0gc3RyZWFtSGRyLndQcmlvcml0eTsKCSAgICBwU3RyZWFtLT5zSW5mby53TGFuZ3VhZ2UgICAgICAgICAgICAgPSBzdHJlYW1IZHIud0xhbmd1YWdlOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IHN0cmVhbUhkci5kd0luaXRpYWxGcmFtZXM7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3U2NhbGU7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdSYXRlICAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3UmF0ZTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1N0YXJ0ICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdTdGFydDsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdMZW5ndGg7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0KCSAgICAgIHN0cmVhbUhkci5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdRdWFsaXR5ICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3UXVhbGl0eTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgICAgICAgICAgPSBzdHJlYW1IZHIuZHdTYW1wbGVTaXplOwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUubGVmdCAgICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLmxlZnQ7CgkgICAgcFN0cmVhbS0+c0luZm8ucmNGcmFtZS50b3AgICAgICAgICAgID0gc3RyZWFtSGRyLnJjRnJhbWUudG9wOwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUucmlnaHQgICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLnJpZ2h0OwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUuYm90dG9tICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLmJvdHRvbTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0VkaXRDb3VudCAgICAgICAgICAgPSAwOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgICA9IDA7CgoJICAgIC8qIGdlbmVyYXRlIGRlc2NyaXB0aW9uIGZvciBzdHJlYW0gbGlrZSAiZmlsZW5hbWUuYXZpIFR5cGUgI24iICovCgkgICAgaWYgKHN0cmVhbUhkci5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykKCSAgICAgIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1ZJREVPLCBzelR5cGUsIHNpemVvZihzelR5cGUpKTsKCSAgICBlbHNlIGlmIChzdHJlYW1IZHIuZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCgkgICAgICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19BVURJTywgc3pUeXBlLCBzaXplb2Yoc3pUeXBlKSk7CgkgICAgZWxzZQoJICAgICAgd3NwcmludGZXKHN6VHlwZSwgc3RyZWFtVHlwZUZtdCwgKGNoYXIqKSZzdHJlYW1IZHIuZmNjVHlwZSk7CgoJICAgIC8qIGdldCBjb3VudCBvZiB0aGlzIHN0cmVhbXR5cGUgdXAgdG8gdGhpcyBzdHJlYW0gKi8KCSAgICBjb3VudCA9IDA7CgkgICAgZm9yIChuID0gblN0cmVhbTsgMCA8PSBuOyBuLS0pIHsKCSAgICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbbl0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gc3RyZWFtSGRyLmZjY1R5cGUpCgkJY291bnQrKzsKCSAgICB9CgoJICAgIG1lbXNldChwU3RyZWFtLT5zSW5mby5zek5hbWUsIDAsIHNpemVvZihwU3RyZWFtLT5zSW5mby5zek5hbWUpKTsKCgkgICAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQVZJU1RSRUFNRk9STUFULCBzdHJlYW1OYW1lRm10LCBzaXplb2Yoc3RyZWFtTmFtZUZtdCkpOwoKCSAgICAvKiBGSVhNRTogYXZvaWQgb3ZlcmZsb3cgLS0gYmV0dGVyIHVzZSB3c25wcmludGZXLCB3aGljaCBkb2Vzbid0IGV4aXN0cyAhICovCgkgICAgd3NwcmludGZXKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwgc3RyZWFtTmFtZUZtdCwKCQkgICAgICBBVklGSUxFX0Jhc2VuYW1lVyhUaGlzLT5zekZpbGVOYW1lKSwgc3pUeXBlLCBjb3VudCk7CgkgIH0KCSAgYnJlYWs7CgljYXNlIGNraWRTVFJFQU1OQU1FOgoJICB7IC8qIHN0cmVhbW5hbWUgd2lsbCBiZSBzYXZlZCBhcyBBU0NJSSBzdHJpbmcgKi8KCSAgICBMUFNUUiBzdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKCSAgICBpZiAoc3RyID09IE5VTEwpCgkgICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCgkgICAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpc3RyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCSAgICB7CgkgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIpOwoJICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCSAgICB9CgoJICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzdHIsIC0xLCBwU3RyZWFtLT5zSW5mby5zek5hbWUsCgkJCQlzaXplb2YocFN0cmVhbS0+c0luZm8uc3pOYW1lKS9zaXplb2YocFN0cmVhbS0+c0luZm8uc3pOYW1lWzBdKSk7CgoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cik7CgkgIH0KCSAgYnJlYWs7CgljYXNlIGNraWRBVklQQURESU5HOgoJY2FzZSBtbWlvRk9VUkNDKCdwJywnYScsJ2QnLCdkJyk6CgkgIGJyZWFrOwoJZGVmYXVsdDoKICAgICAgICAgIFdBUk4oIjogZm91bmQgZXh0cmEgY2h1bmsgMHglMDhYXG4iLCBjay5ja2lkKTsKCSAgaHIgPSBSZWFkQ2h1bmtJbnRvRXh0cmEoJnBTdHJlYW0tPmV4dHJhLCBUaGlzLT5obW1pbywgJmNrKTsKCSAgaWYgKEZBSUxFRChocikpCgkgICAgcmV0dXJuIGhyOwoJfTsKCglpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBuZXN0ZWQgY2h1bmtzIGluICJMSVNUIiwiaGRybCIgd2hpY2ggYXJlIG5vdCBvZiB0eXBlICJMSVNUIiwic3RybCIgKi8KICAgICAgaHIgPSBSZWFkQ2h1bmtJbnRvRXh0cmEoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZja0xJU1QyKTsKICAgICAgaWYgKEZBSUxFRChocikpCglyZXR1cm4gaHI7CiAgICB9CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDIsIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICAvKiByZWFkIGFueSBleHRyYSBoZWFkZXJzIGluICJMSVNUIiwiaGRybCIgKi8KICBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssICZja0xJU1QxLCAwKTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBzZWFyY2ggIkxJU1QiLCJtb3ZpIiBjaHVuayBpbiAiUklGRiIsIkFWSSAiICovCiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklNT1ZJRTsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZja0xJU1QxLCAmY2tSSUZGLAoJCQkgICAgICBNTUlPX0ZJTkRMSVNUKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPSBja0xJU1QxLmR3RGF0YU9mZnNldDsKICBUaGlzLT5kd0lkeENodW5rUG9zICA9IGNrTElTVDEuY2tzaXplICsgY2tMSVNUMS5kd0RhdGFPZmZzZXQ7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogdHJ5IHRvIGZpbmQgYW4gaW5kZXggKi8KICBjay5ja2lkID0gY2tpZEFWSU5FV0lOREVYOwogIGhyID0gRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywKCQkJICAgICAgJmNrLCAmY2tSSUZGLCBNTUlPX0ZJTkRDSFVOSyk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgY2suY2tzaXplID4gMCkgewogICAgaWYgKEZBSUxFRChBVklGSUxFX0xvYWRJbmRleChUaGlzLCBjay5ja3NpemUsIGNrTElTVDEuZHdEYXRhT2Zmc2V0KSkpCiAgICAgIFRoaXMtPmZJbmZvLmR3RmxhZ3MgJj0gfkFWSUZJTEVJTkZPX0hBU0lOREVYOwogIH0KCiAgLyogd2hlbiB3ZSBoYXZlbid0IGZvdW5kIGFuIGluZGV4IG9yIGl0J3MgYmFkLCB0aGVuIGJ1aWxkIG9uZQogICAqIGJ5IHBhcnNpbmcgJ21vdmknIGNodW5rICovCiAgaWYgKChUaGlzLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSEFTSU5ERVgpID09IDApIHsKICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5sTGFzdEZyYW1lID0gLTE7CgogICAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBja0xJU1QxLmR3RGF0YU9mZnNldCArIHNpemVvZihEV09SRCksIFNFRUtfU0VUKSA9PSAtMSkgewogICAgICBFUlIoIjogT29wcywgY2FuJ3Qgc2VlayBiYWNrIHRvICdtb3ZpJyBjaHVuayFcbiIpOwogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgfQoKICAgIC8qIHNlZWsgdGhyb3VnaCB0aGUgJ21vdmknIGxpc3QgdW50aWwgZW5kICovCiAgICB3aGlsZSAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDEsIDApID09IFNfT0spIHsKICAgICAgaWYgKGNrLmNraWQgIT0gRk9VUkNDX0xJU1QpIHsKCWlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApID09IFNfT0spIHsKCSAgblN0cmVhbSA9IFN0cmVhbUZyb21GT1VSQ0MoY2suY2tpZCk7CgoJICBpZiAoblN0cmVhbSA+IFRoaXMtPmZJbmZvLmR3U3RyZWFtcykKCSAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCgkgIEFWSUZJTEVfQWRkRnJhbWUoVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLCBjay5ja2lkLCBjay5ja3NpemUsCgkJCSAgIGNrLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpLCAwKTsKCX0gZWxzZSB7CgkgIG5TdHJlYW0gPSBTdHJlYW1Gcm9tRk9VUkNDKGNrLmNraWQpOwoJICBXQVJOKCI6IGZpbGUgc2VlbXMgdG8gYmUgdHJ1bmNhdGVkIVxuIik7CgkgIGlmIChuU3RyZWFtIDw9IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAmJgoJICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd1NhbXBsZVNpemUgPiAwKSB7CgkgICAgY2suY2tzaXplID0gbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfRU5EKTsKCSAgICBpZiAoY2suY2tzaXplICE9IC0xKSB7CgkgICAgICBjay5ja3NpemUgLT0gY2suZHdEYXRhT2Zmc2V0OwoJICAgICAgY2suY2tzaXplICY9IH4oVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd1NhbXBsZVNpemUgLSAxKTsKCgkgICAgICBBVklGSUxFX0FkZEZyYW1lKFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSwgY2suY2tpZCwgY2suY2tzaXplLAoJCQkgICAgICAgY2suZHdEYXRhT2Zmc2V0IC0gMiAqIHNpemVvZihEV09SRCksIDApOwoJICAgIH0KCSAgfQoJfQogICAgICB9CiAgICB9CiAgfQoKICAvKiBmaW5kIG90aGVyIGNodW5rcyAqLwogIEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrUklGRiwgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEluZGV4KElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgc2l6ZSwgRFdPUkQgb2Zmc2V0KQp7CiAgQVZJSU5ERVhFTlRSWSAqbHA7CiAgRFdPUkQgICAgICAgICAgcG9zLCBuOwogIEhSRVNVTFQgICAgICAgIGhyID0gQVZJRVJSX09LOwogIEJPT0wgICAgICAgICAgIGJBYnNvbHV0ZSA9IFRSVUU7CgogIGxwID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIElEWF9QRVJfQkxPQ0sgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIC8qIGFkanVzdCBsaW1pdHMgZm9yIGluZGV4IHRhYmxlcywgc28gdGhhdCBpbnNlcnRpbmcgd2lsbCBiZSBmYXN0ZXIgKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuKyspIHsKICAgIElBVklTdHJlYW1JbXBsICpwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25dOwoKICAgIHBTdHJlYW0tPmxMYXN0RnJhbWUgPSAtMTsKCiAgICBpZiAocFN0cmVhbS0+aWR4RnJhbWVzICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcFN0cmVhbS0+aWR4RnJhbWVzKTsKICAgICAgcFN0cmVhbS0+aWR4RnJhbWVzICA9IE5VTEw7CiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSAwOwogICAgfQoKICAgIGlmIChwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgICBpZiAobiA+IDAgJiYgVGhpcy0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQpIHsKCXBTdHJlYW0tPm5JZHhGcmFtZXMgPSBUaGlzLT5wcFN0cmVhbXNbMF0tPm5JZHhGcmFtZXM7CiAgICAgIH0gZWxzZSBpZiAocFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKSB7CglwU3RyZWFtLT5uSWR4RnJhbWVzID0KCSAgcFN0cmVhbS0+c0luZm8uZHdMZW5ndGggLyBwU3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgICAgIH0KICAgIH0gZWxzZQogICAgICBwU3RyZWFtLT5uSWR4RnJhbWVzID0gcFN0cmVhbS0+c0luZm8uZHdMZW5ndGg7CgogICAgcFN0cmVhbS0+aWR4RnJhbWVzID0KICAgICAgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHBTdHJlYW0tPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgaWYgKHBTdHJlYW0tPmlkeEZyYW1lcyA9PSBOVUxMICYmIHBTdHJlYW0tPm5JZHhGcmFtZXMgPiAwKSB7CiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSAwOwogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIH0KICB9CgogIHBvcyA9IChEV09SRCktMTsKICB3aGlsZSAoc2l6ZSAhPSAwKSB7CiAgICBMT05HIHJlYWQgPSBtaW4oSURYX1BFUl9CTE9DSyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSwgc2l6ZSk7CgogICAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpbHAsIHJlYWQpICE9IHJlYWQpIHsKICAgICAgaHIgPSBBVklFUlJfRklMRVJFQUQ7CiAgICAgIGJyZWFrOwogICAgfQogICAgc2l6ZSAtPSByZWFkOwoKICAgIGlmIChwb3MgPT0gKERXT1JEKS0xKQogICAgICBwb3MgPSBvZmZzZXQgLSBscC0+ZHdDaHVua09mZnNldCArIHNpemVvZihEV09SRCk7CgogICAgQVZJRklMRV9QYXJzZUluZGV4KFRoaXMsIGxwLCByZWFkIC8gc2l6ZW9mKEFWSUlOREVYRU5UUlkpLAoJCSAgICAgICBwb3MsICZiQWJzb2x1dGUpOwogIH0KCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHApOwoKICAvKiBjaGVja2luZyAuLi4gKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuKyspIHsKICAgIElBVklTdHJlYW1JbXBsICpwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25dOwoKICAgIGlmIChwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgPT0gMCAmJgoJcFN0cmVhbS0+c0luZm8uZHdMZW5ndGggIT0gcFN0cmVhbS0+bExhc3RGcmFtZSsxKQogICAgICBFUlIoInN0cmVhbSAldSBsZW5ndGggbWlzbWF0Y2g6IGR3TGVuZ3RoPSV1IGZvdW5kPSVkXG4iLAoJICAgbiwgcFN0cmVhbS0+c0luZm8uZHdMZW5ndGgsIHBTdHJlYW0tPmxMYXN0RnJhbWUpOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1BhcnNlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzLCBBVklJTkRFWEVOVFJZICpscCwKCQkJCSAgTE9ORyBjb3VudCwgRFdPUkQgcG9zLCBCT09MICpiQWJzb2x1dGUpCnsKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGZvciAoOyBjb3VudCA+IDA7IGNvdW50LS0sIGxwKyspIHsKICAgIFdPUkQgblN0cmVhbSA9IFN0cmVhbUZyb21GT1VSQ0MobHAtPmNraWQpOwoKICAgIGlmIChscC0+Y2tpZCA9PSBsaXN0dHlwZUFWSVJFQ09SRCB8fCBuU3RyZWFtID09IDB4N0YpCiAgICAgIGNvbnRpbnVlOyAvKiBza2lwIHRoZXNlICovCgogICAgaWYgKG5TdHJlYW0gPiBUaGlzLT5mSW5mby5kd1N0cmVhbXMpCiAgICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAgIGlmICgqYkFic29sdXRlICYmIGxwLT5kd0NodW5rT2Zmc2V0IDwgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MpCiAgICAgICpiQWJzb2x1dGUgPSBGQUxTRTsKCiAgICBpZiAoKmJBYnNvbHV0ZSkKICAgICAgbHAtPmR3Q2h1bmtPZmZzZXQgKz0gc2l6ZW9mKERXT1JEKTsKICAgIGVsc2UKICAgICAgbHAtPmR3Q2h1bmtPZmZzZXQgKz0gcG9zOwoKICAgIGlmIChGQUlMRUQoQVZJRklMRV9BZGRGcmFtZShUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0sIGxwLT5ja2lkLCBscC0+ZHdDaHVua0xlbmd0aCwgbHAtPmR3Q2h1bmtPZmZzZXQsIGxwLT5kd0ZsYWdzKSkpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9SZWFkQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIHBvcywKCQkJCSBMUFZPSUQgYnVmZmVyLCBMT05HIHNpemUpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBhZi0+aG1taW8gIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3U3RhcnQgPD0gcG9zICYmIHBvcyA8IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKTsKICBhc3NlcnQocG9zIDw9IFRoaXMtPmxMYXN0RnJhbWUpOwoKICAvKiBzaG91bGQgd2UgcmVhZCBhcyBtdWNoIGFzIGJsb2NrIGdpdmVzIHVzPyAqLwogIGlmIChzaXplID09IDAgfHwgc2l6ZSA+IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGgpCiAgICBzaXplID0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aDsKCiAgLyogcmVhZCBpbnRvIG91dCBvd24gYnVmZmVyIG9yIGdpdmVuIG9uZT8gKi8KICBpZiAoYnVmZmVyID09IE5VTEwpIHsKICAgIC8qIHdlIGFsc28gcmVhZCB0aGUgY2h1bmsgKi8KICAgIHNpemUgKz0gMiAqIHNpemVvZihEV09SRCk7CgogICAgLyogY2hlY2sgdGhhdCBidWZmZXIgaXMgYmlnIGVub3VnaCAtLSBkb24ndCB0cnVzdCBkd1N1Z2dlc3RlZEJ1ZmZlclNpemUgKi8KICAgIGlmIChUaGlzLT5scEJ1ZmZlciA9PSBOVUxMIHx8IHNpemUgPCBUaGlzLT5jYkJ1ZmZlcikgewogICAgICBEV09SRCBtYXhTaXplID0gbWF4KHNpemUsIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CgogICAgICBpZiAoVGhpcy0+bHBCdWZmZXIgPT0gTlVMTCkKCVRoaXMtPmxwQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG1heFNpemUpOwogICAgICBlbHNlCglUaGlzLT5scEJ1ZmZlciA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwQnVmZmVyLCBtYXhTaXplKTsKICAgICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgVGhpcy0+Y2JCdWZmZXIgPSBtYXgoc2l6ZSwgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKICAgIH0KCiAgICAvKiBub3cgcmVhZCB0aGUgY29tcGxldGUgY2h1bmsgaW50byBvdXIgYnVmZmVyICovCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgaWYgKG1taW9SZWFkKFRoaXMtPnBhZi0+aG1taW8sIChIUFNUUilUaGlzLT5scEJ1ZmZlciwgc2l6ZSkgIT0gc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgICAvKiBjaGVjayBpZiBpdCB3YXMgdGhlIGNvcnJlY3QgYmxvY2sgd2hpY2ggd2UgaGF2ZSByZWFkICovCiAgICBpZiAoVGhpcy0+bHBCdWZmZXJbMF0gIT0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uY2tpZCB8fAoJVGhpcy0+bHBCdWZmZXJbMV0gIT0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCkgewogICAgICBFUlIoIjogYmxvY2sgJWQgbm90IGZvdW5kIGF0IDB4JTA4WFxuIiwgcG9zLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rT2Zmc2V0KTsKICAgICAgRVJSKCI6IEluZGV4IHNheXM6ICclNC40cycoMHglMDhYKSBzaXplIDB4JTA4WFxuIiwKCSAgKGNoYXIqKSZUaGlzLT5pZHhGcmFtZXNbcG9zXS5ja2lkLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5ja2lkLAoJICBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoKTsKICAgICAgRVJSKCI6IERhdGEgIHNheXM6ICclNC40cycoMHglMDhYKSBzaXplIDB4JTA4WFxuIiwKCSAgKGNoYXIqKSZUaGlzLT5scEJ1ZmZlclswXSwgVGhpcy0+bHBCdWZmZXJbMF0sIFRoaXMtPmxwQnVmZmVyWzFdKTsKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIH0KICB9IGVsc2UgewogICAgaWYgKG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgaWYgKG1taW9SZWFkKFRoaXMtPnBhZi0+aG1taW8sIChIUFNUUilidWZmZXIsIHNpemUpICE9IHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBMUExPTkcgcG9zLAoJCQkJICAgICAgTFBMT05HIG9mZnNldCkKewogIExPTkcgYmxvY2s7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KHBvcyAhPSBOVUxMKTsKICBhc3NlcnQob2Zmc2V0ICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCk7CiAgYXNzZXJ0KCpwb3MgPj0gVGhpcy0+c0luZm8uZHdTdGFydCk7CgogIC8qIGNvbnZlcnQgc3RhcnQgc2FtcGxlIHRvIHN0YXJ0IGJ5dGVzICovCiAgKCpvZmZzZXQpICA9ICgqcG9zKSAtIFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgKCpvZmZzZXQpICo9IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgLyogY29udmVydCBieXRlcyB0byBibG9jayBudW1iZXIgKi8KICBmb3IgKGJsb2NrID0gMDsgYmxvY2sgPD0gVGhpcy0+bExhc3RGcmFtZTsgYmxvY2srKykgewogICAgaWYgKFRoaXMtPmlkeEZyYW1lc1tibG9ja10uZHdDaHVua0xlbmd0aCA8PSAqb2Zmc2V0KQogICAgICAoKm9mZnNldCkgLT0gVGhpcy0+aWR4RnJhbWVzW2Jsb2NrXS5kd0NodW5rTGVuZ3RoOwogICAgZWxzZQogICAgICBicmVhazsKICB9CgogICpwb3MgPSBibG9jazsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNYWluQVZJSGVhZGVyICAgTWFpbkFWSUhkcjsKICBJQVZJU3RyZWFtSW1wbCogcFN0cmVhbTsKICBNTUNLSU5GTyAgICAgICAgY2tSSUZGOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QxOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QyOwogIE1NQ0tJTkZPICAgICAgICBjazsKICBEV09SRCAgICAgICAgICAgblN0cmVhbTsKICBEV09SRCAgICAgICAgICAgZHdQb3M7CiAgSFJFU1VMVCAgICAgICAgIGhyOwoKICAvKiBpbml0aWFsaXplIHNvbWUgdGhpbmdzICovCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcyk7CgogIC8qIHdyaXR0ZW4gb25lIHJlY29yZCB0byBtdWNoPyAqLwogIGlmIChUaGlzLT5ja0xhc3RSZWNvcmQuZHdGbGFncyAmIE1NSU9fRElSVFkpIHsKICAgIFRoaXMtPmR3TmV4dEZyYW1lUG9zIC09IDMgKiBzaXplb2YoRFdPUkQpOwogICAgaWYgKFRoaXMtPm5JZHhSZWNvcmRzID4gMCkKICAgICAgVGhpcy0+bklkeFJlY29yZHMtLTsKICB9CgogIEFWSUZJTEVfVXBkYXRlSW5mbyhUaGlzKTsKCiAgYXNzZXJ0KFRoaXMtPmZJbmZvLmR3U2NhbGUgIT0gMCk7CgogIG1lbXNldCgmTWFpbkFWSUhkciwgMCwgc2l6ZW9mKE1haW5BVklIZHIpKTsKICBNYWluQVZJSGRyLmR3TWljcm9TZWNQZXJGcmFtZSAgICA9IE11bERpdihUaGlzLT5mSW5mby5kd1JhdGUsIDEwMDAwMDAsCgkJCQkJICAgIFRoaXMtPmZJbmZvLmR3U2NhbGUpOwogIE1haW5BVklIZHIuZHdNYXhCeXRlc1BlclNlYyAgICAgID0gVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYzsKICBNYWluQVZJSGRyLmR3UGFkZGluZ0dyYW51bGFyaXR5ICA9IEFWSV9IRUFERVJTSVpFOwogIE1haW5BVklIZHIuZHdGbGFncyAgICAgICAgICAgICAgID0gVGhpcy0+ZkluZm8uZHdGbGFnczsKICBNYWluQVZJSGRyLmR3VG90YWxGcmFtZXMgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3TGVuZ3RoOwogIE1haW5BVklIZHIuZHdJbml0aWFsRnJhbWVzICAgICAgID0gMDsKICBNYWluQVZJSGRyLmR3U3RyZWFtcyAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsKICBNYWluQVZJSGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICBNYWluQVZJSGRyLmR3V2lkdGggICAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3V2lkdGg7CiAgTWFpbkFWSUhkci5kd0hlaWdodCAgICAgICAgICAgICAgPSBUaGlzLT5mSW5mby5kd0hlaWdodDsKICBNYWluQVZJSGRyLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IFRoaXMtPmR3SW5pdGlhbEZyYW1lczsKCiAgLyogbm93IGJlZ2luIHdyaXRpbmcgLi4uICovCiAgbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfU0VUKTsKCiAgLyogUklGRiBjaHVuayAqLwogIGNrUklGRi5ja3NpemUgID0gMDsKICBja1JJRkYuZmNjVHlwZSA9IGZvcm10eXBlQVZJOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja1JJRkYsIE1NSU9fQ1JFQVRFUklGRikgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBBVkkgaGVhZGVybGlzdCAqLwogIGNrTElTVDEuY2tzaXplICA9IDA7CiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklIRUFERVI7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDEsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBNYWluQVZJSGVhZGVyICovCiAgY2suY2tpZCAgICA9IGNraWRBVklNQUlOSERSOwogIGNrLmNrc2l6ZSAgPSBzaXplb2YoTWFpbkFWSUhkcik7CiAgY2suZmNjVHlwZSA9IDA7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZNYWluQVZJSGRyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogd3JpdGUgdGhlIGhlYWRlcnMgb2YgZWFjaCBzdHJlYW0gaW50byBhIHNlcGFyYXRlIHN0cmVhbWhlYWRlciBsaXN0ICovCiAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICBBVklTdHJlYW1IZWFkZXIgc3RySGRyOwoKICAgIHBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgogICAgLyogYmVnaW4gdGhlIG5ldyBzdHJlYW1oZWFkZXIgbGlzdCAqLwogICAgY2tMSVNUMi5ja3NpemUgID0gMDsKICAgIGNrTElTVDIuZmNjVHlwZSA9IGxpc3R0eXBlU1RSRUFNSEVBREVSOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDIsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgLyogY3JlYXRlIGFuIEFWSVN0cmVhbUhlYWRlciBmcm9tIHRoZSBBVlNUUkVBTUlORk8gKi8KICAgIHN0ckhkci5mY2NUeXBlICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5mY2NUeXBlOwogICAgc3RySGRyLmZjY0hhbmRsZXIgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXI7CiAgICBzdHJIZHIuZHdGbGFncyAgICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdGbGFnczsKICAgIHN0ckhkci53UHJpb3JpdHkgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby53UHJpb3JpdHk7CiAgICBzdHJIZHIud0xhbmd1YWdlICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8ud0xhbmd1YWdlOwogICAgc3RySGRyLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lczsKICAgIHN0ckhkci5kd1NjYWxlICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1NjYWxlOwogICAgc3RySGRyLmR3UmF0ZSAgICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3UmF0ZTsKICAgIHN0ckhkci5kd1N0YXJ0ICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1N0YXJ0OwogICAgc3RySGRyLmR3TGVuZ3RoICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoOwogICAgc3RySGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IHBTdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICAgIHN0ckhkci5kd1F1YWxpdHkgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1F1YWxpdHk7CiAgICBzdHJIZHIuZHdTYW1wbGVTaXplICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgc3RySGRyLnJjRnJhbWUubGVmdCAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUubGVmdDsKICAgIHN0ckhkci5yY0ZyYW1lLnRvcCAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnRvcDsKICAgIHN0ckhkci5yY0ZyYW1lLnJpZ2h0ICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnJpZ2h0OwogICAgc3RySGRyLnJjRnJhbWUuYm90dG9tICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUuYm90dG9tOwoKICAgIC8qIG5vdyB3cml0ZSB0aGUgQVZJU3RyZWFtSGVhZGVyICovCiAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNSEVBREVSOwogICAgY2suY2tzaXplID0gc2l6ZW9mKHN0ckhkcik7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZzdHJIZHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIC8qIC4uLiB0aGUgaG9wZWZ1bGx5IGV2ZXIgcHJlc2VudCBzdHJlYW1mb3JtYXQgLi4uICovCiAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNRk9STUFUOwogICAgY2suY2tzaXplID0gcFN0cmVhbS0+Y2JGb3JtYXQ7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKHBTdHJlYW0tPmxwRm9ybWF0ICE9IE5VTEwgJiYgY2suY2tzaXplID4gMCkgewogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICAvKiAuLi4gc29tZSBvcHRpb25hbCBleGlzdGluZyBoYW5kbGVyIGRhdGEgLi4uICovCiAgICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgPiAwKSB7CiAgICAgIGNrLmNraWQgICA9IGNraWRTVFJFQU1IQU5ETEVSREFUQTsKICAgICAgY2suY2tzaXplID0gcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YTsKICAgICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5scEhhbmRsZXJEYXRhLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CgogICAgLyogLi4uIHNvbWUgb3B0aW9uYWwgYWRkaXRpb25hbCBleHRyYSBjaHVuayBmb3IgdGhpcyBzdHJlYW0gLi4uICovCiAgICBpZiAocFN0cmVhbS0+ZXh0cmEubHAgIT0gTlVMTCAmJiBwU3RyZWFtLT5leHRyYS5jYiA+IDApIHsKICAgICAgLyogdGhlIGNodW5rIGhlYWRlcihzKSBhcmUgYWxyZWFkeSBpbiB0aGUgc3RydWN1dHVyZSAqLwogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+ZXh0cmEubHAsIHBTdHJlYW0tPmV4dHJhLmNiKSAhPSBwU3RyZWFtLT5leHRyYS5jYikKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfQoKICAgIC8qIC4uLiBhbiBvcHRpb25hbCBuYW1lIGZvciB0aGlzIHN0cmVhbSAuLi4gKi8KICAgIGlmIChsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpID4gMCkgewogICAgICBMUFNUUiBzdHI7CgogICAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNTkFNRTsKICAgICAgY2suY2tzaXplID0gbHN0cmxlblcocFN0cmVhbS0+c0luZm8uc3pOYW1lKSArIDE7CiAgICAgIGlmIChjay5ja3NpemUgJiAxKSAvKiBhbGlnbiAqLwoJY2suY2tzaXplKys7CiAgICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgICAgLyogdGhlIHN0cmVhbW5hbWUgbXVzdCBiZSBzYXZlZCBpbiBBU0NJSSBub3QgVW5pY29kZSAqLwogICAgICBzdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKICAgICAgaWYgKHN0ciA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBwU3RyZWFtLT5zSW5mby5zek5hbWUsIC0xLCBzdHIsCgkJCSAgY2suY2tzaXplLCBOVUxMLCBOVUxMKTsKCiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilzdHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKSB7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIpOwkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICB9CgogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIpOwogICAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CgogICAgLyogY2xvc2Ugc3RyZWFtaGVhZGVyIGxpc3QgZm9yIHRoaXMgc3RyZWFtICovCiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDIsIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0gLyogZm9yICgwIDw9IG5TdHJlYW0gPCBNYWluQVZJSGRyLmR3U3RyZWFtcykgKi8KCiAgLyogY2xvc2UgdGhlIGF2aWhlYWRlciBsaXN0ICovCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIGNoZWNrIGZvciBwYWRkaW5nIHRvIHByZS1ndWVzc2VkICdtb3ZpJy1jaHVuayBwb3NpdGlvbiAqLwogIGR3UG9zID0gY2tMSVNUMS5kd0RhdGFPZmZzZXQgKyBja0xJU1QxLmNrc2l6ZTsKICBpZiAoVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgLSAyICogc2l6ZW9mKERXT1JEKSA+IGR3UG9zKSB7CiAgICBjay5ja2lkICAgPSBja2lkQVZJUEFERElORzsKICAgIGNrLmNrc2l6ZSA9IFRoaXMtPmR3TW92aUNodW5rUG9zIC0gZHdQb3MgLSA0ICogc2l6ZW9mKERXT1JEKTsKICAgIGFzc2VydCgoTE9ORyljay5ja3NpemUgPj0gMCk7CgogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgY2suY2tzaXplLCBTRUVLX0NVUikgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQoKICAvKiBub3cgd3JpdGUgdGhlICdtb3ZpJyBjaHVuayAqLwogIG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd01vdmlDaHVua1BvcyAtIDIgKiBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCk7CiAgY2tMSVNUMS5ja3NpemUgID0gMDsKICBja0xJU1QxLmZjY1R5cGUgPSBsaXN0dHlwZUFWSU1PVklFOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja0xJU1QxLCBNTUlPX0NSRUFURUxJU1QpICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogd3JpdGUgJ2lkeDEnIGNodW5rICovCiAgaHIgPSBBVklGSUxFX1NhdmVJbmRleChUaGlzKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgLyogd3JpdGUgb3B0aW9uYWwgZXh0cmEgZmlsZSBjaHVua3MgKi8KICBpZiAoVGhpcy0+ZmlsZWV4dHJhLmxwICE9IE5VTEwgJiYgVGhpcy0+ZmlsZWV4dHJhLmNiID4gMCkgewogICAgLyogYXMgZm9yIHRoZSBzdHJlYW1zLCBhcmUgdGhlIGNodW5rIGhlYWRlcihzKSBpbiB0aGUgc3RydWN0dXJlICovCiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpVGhpcy0+ZmlsZWV4dHJhLmxwLCBUaGlzLT5maWxlZXh0cmEuY2IpICE9IFRoaXMtPmZpbGVleHRyYS5jYikKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQoKICAvKiBjbG9zZSBSSUZGIGNodW5rICovCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja1JJRkYsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogYWRkIHNvbWUgSlVOSyBhdCBlbmQgZm9yIGJhZCBwYXJzZXJzICovCiAgbWVtc2V0KCZja1JJRkYsIDAsIHNpemVvZihja1JJRkYpKTsKICBtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmY2tSSUZGLCBzaXplb2YoY2tSSUZGKSk7CiAgbW1pb0ZsdXNoKFRoaXMtPmhtbWlvLCAwKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW07CiAgQVZJSU5ERVhFTlRSWSAgIGlkeDsKICBNTUNLSU5GTyAgICAgICAgY2s7CiAgRFdPUkQgICAgICAgICAgIG5TdHJlYW07CiAgTE9ORyAgICAgICAgICAgIG47CgogIGNrLmNraWQgICA9IGNraWRBVklORVdJTkRFWDsKICBjay5ja3NpemUgPSAwOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICBpZiAoVGhpcy0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQpIHsKICAgIC8qIGlzIGludGVybGVhdmVkIC0tIHdyaXRlIGJsb2NrIG9mIGNvcmVzcG9uZGluZyBmcmFtZXMgKi8KICAgIExPTkcgbEluaXRpYWxGcmFtZXMgPSAwOwogICAgTE9ORyBzdGVwc2l6ZTsKICAgIExPTkcgaTsKCiAgICBpZiAoVGhpcy0+cHBTdHJlYW1zWzBdLT5zSW5mby5kd1NhbXBsZVNpemUgPT0gMCkKICAgICAgc3RlcHNpemUgPSAxOwogICAgZWxzZQogICAgICBzdGVwc2l6ZSA9IEFWSVN0cmVhbVRpbWVUb1NhbXBsZSgoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbMF0sIDEwMDAwMDApOwoKICAgIGFzc2VydChzdGVwc2l6ZSA+IDApOwoKICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgICBpZiAobEluaXRpYWxGcmFtZXMgPCBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcykKCWxJbml0aWFsRnJhbWVzID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd0luaXRpYWxGcmFtZXM7CiAgICB9CgogICAgZm9yIChpID0gLWxJbml0aWFsRnJhbWVzOyBpIDwgKExPTkcpVGhpcy0+ZkluZm8uZHdMZW5ndGggLSBsSW5pdGlhbEZyYW1lczsKCSBpICs9IHN0ZXBzaXplKSB7CiAgICAgIERXT1JEIG5GcmFtZSA9IGxJbml0aWFsRnJhbWVzICsgaTsKCiAgICAgIGFzc2VydChuRnJhbWUgPCBUaGlzLT5uSWR4UmVjb3Jkcyk7CgogICAgICBpZHguY2tpZCAgICAgICAgICA9IGxpc3R0eXBlQVZJUkVDT1JEOwogICAgICBpZHguZHdGbGFncyAgICAgICA9IEFWSUlGX0xJU1Q7CiAgICAgIGlkeC5kd0NodW5rTGVuZ3RoID0gVGhpcy0+aWR4UmVjb3Jkc1tuRnJhbWVdLmR3Q2h1bmtMZW5ndGg7CiAgICAgIGlkeC5kd0NodW5rT2Zmc2V0ID0gVGhpcy0+aWR4UmVjb3Jkc1tuRnJhbWVdLmR3Q2h1bmtPZmZzZXQKCS0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewoJcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKCgkvKiBoZWF2ZSB3ZSByZWFjaGVkIHN0YXJ0IG9mIHRoaXMgc3RyZWFtPyAqLwoJaWYgKC0oTE9ORylwU3RyZWFtLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgPiBpKQoJICBjb250aW51ZTsKCglpZiAocFN0cmVhbS0+c0luZm8uZHdJbml0aWFsRnJhbWVzIDwgbEluaXRpYWxGcmFtZXMpCgkgIG5GcmFtZSAtPSAobEluaXRpYWxGcmFtZXMgLSBwU3RyZWFtLT5zSW5mby5kd0luaXRpYWxGcmFtZXMpOwoKCS8qIHJlYWNoZWQgZW5kIG9mIHRoaXMgc3RyZWFtPyAqLwoJaWYgKHBTdHJlYW0tPmxMYXN0RnJhbWUgPD0gbkZyYW1lKQoJICBjb250aW51ZTsKCglpZiAoKHBTdHJlYW0tPnNJbmZvLmR3RmxhZ3MgJiBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVMpICYmCgkgICAgcFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAhPSAwICYmCgkgICAgcFN0cmVhbS0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMKSB7CgkgIERXT1JEIHBvczsKCgkgIGZvciAocG9zID0gMDsgcG9zIDwgcFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsgcG9zKyspIHsKCSAgICBpZiAocFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmNraWQgPT0gbkZyYW1lKSB7CgkgICAgICBpZHguZHdGbGFncyA9IEFWSUlGX05PVElNRTsKCSAgICAgIGlkeC5ja2lkICAgID0gTUFLRUFWSUNLSUQoY2t0eXBlUEFMY2hhbmdlLCBwU3RyZWFtLT5uU3RyZWFtKTsKCSAgICAgIGlkeC5kd0NodW5rTGVuZ3RoID0gcFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmR3Q2h1bmtMZW5ndGg7CgkgICAgICBpZHguZHdDaHVua09mZnNldCA9IHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5kd0NodW5rT2Zmc2V0CgkJLSBUaGlzLT5kd01vdmlDaHVua1BvczsKCgkgICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoJICAgICAgYnJlYWs7CgkgICAgfQoJICB9Cgl9IC8qIGlmIGhhdmUgZm9ybWF0Y2hhbmdlcyAqLwoKCWlkeC5ja2lkICAgICAgICAgID0gcFN0cmVhbS0+aWR4RnJhbWVzW25GcmFtZV0uY2tpZDsKCWlkeC5kd0ZsYWdzICAgICAgID0gcFN0cmVhbS0+aWR4RnJhbWVzW25GcmFtZV0uZHdGbGFnczsKCWlkeC5kd0NodW5rTGVuZ3RoID0gcFN0cmVhbS0+aWR4RnJhbWVzW25GcmFtZV0uZHdDaHVua0xlbmd0aDsKCWlkeC5kd0NodW5rT2Zmc2V0ID0gcFN0cmVhbS0+aWR4RnJhbWVzW25GcmFtZV0uZHdDaHVua09mZnNldAoJICAtIFRoaXMtPmR3TW92aUNodW5rUG9zOwoJaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCSAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgewogICAgLyogbm90IGludGVybGVhdmVkIC0tIHdyaXRlIGluZGV4IGZvciBlYWNoIHN0cmVhbSBhdCBvbmNlICovCiAgICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKICAgICAgcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKCiAgICAgIGZvciAobiA9IDA7IG4gPD0gcFN0cmVhbS0+bExhc3RGcmFtZTsgbisrKSB7CglpZiAoKHBTdHJlYW0tPnNJbmZvLmR3RmxhZ3MgJiBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVMpICYmCgkgICAgKHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgIT0gMCkpIHsKCSAgRFdPUkQgcG9zOwoKCSAgZm9yIChwb3MgPSAwOyBwb3MgPCBwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBwb3MrKykgewoJICAgIGlmIChwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uY2tpZCA9PSBuKSB7CgkgICAgICBpZHguZHdGbGFncyA9IEFWSUlGX05PVElNRTsKCSAgICAgIGlkeC5ja2lkICAgID0gTUFLRUFWSUNLSUQoY2t0eXBlUEFMY2hhbmdlLCBwU3RyZWFtLT5uU3RyZWFtKTsKCSAgICAgIGlkeC5kd0NodW5rTGVuZ3RoID0gcFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmR3Q2h1bmtMZW5ndGg7CgkgICAgICBpZHguZHdDaHVua09mZnNldCA9CgkJcFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmR3Q2h1bmtPZmZzZXQgLSBUaGlzLT5kd01vdmlDaHVua1BvczsKCSAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCgkJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgkgICAgICBicmVhazsKCSAgICB9CgkgIH0KCX0gLyogaWYgaGF2ZSBmb3JtYXRjaGFuZ2VzICovCgoJaWR4LmNraWQgICAgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbl0uY2tpZDsKCWlkeC5kd0ZsYWdzICAgICAgID0gcFN0cmVhbS0+aWR4RnJhbWVzW25dLmR3RmxhZ3M7CglpZHguZHdDaHVua0xlbmd0aCA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5kd0NodW5rTGVuZ3RoOwoJaWR4LmR3Q2h1bmtPZmZzZXQgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbl0uZHdDaHVua09mZnNldAoJICAtIFRoaXMtPmR3TW92aUNodW5rUG9zOwoKCWlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCgkgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICB9CiAgICB9CiAgfSAvKiBpZiBub3QgaW50ZXJsZWF2ZWQgKi8KCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgVUxPTkcgIEFWSUZJTEVfU2VhcmNoU3RyZWFtKElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgZmNjLCBMT05HIGxTa2lwKQp7CiAgVUlOVCBpOwogIFVJTlQgblN0cmVhbTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChsU2tpcCA+PSAwKTsKCiAgaWYgKGZjYyAhPSAwKSB7CiAgICAvKiBzZWFyY2ggdGhlIG51bWJlciBvZiB0aGUgc3BlY2lmaWVkIHN0cmVhbSAqLwogICAgblN0cmVhbSA9IChVTE9ORyktMTsKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IGkrKykgewogICAgICBhc3NlcnQoVGhpcy0+cHBTdHJlYW1zW2ldICE9IE5VTEwpOwoKICAgICAgaWYgKFRoaXMtPnBwU3RyZWFtc1tpXS0+c0luZm8uZmNjVHlwZSA9PSBmY2MpIHsKCWlmIChsU2tpcCA9PSAwKSB7CgkgIG5TdHJlYW0gPSBpOwoJICBicmVhazsKCX0gZWxzZQoJICBsU2tpcC0tOwogICAgICB9CiAgICB9CiAgfSBlbHNlCiAgICBuU3RyZWFtID0gbFNraXA7CgogIHJldHVybiBuU3RyZWFtOwp9CgpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1VwZGF0ZUluZm8oSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgVUlOVCBpOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwoKICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3Q2FwcyAgICAgICAgICAgICAgICA9IEFWSUZJTEVDQVBTX0NBTlJFQUR8QVZJRklMRUNBUFNfQ0FOV1JJVEU7CiAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gMDsKICBUaGlzLT5mSW5mby5kd1dpZHRoICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3SGVpZ2h0ICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZHdJbml0aWFsRnJhbWVzICAgICAgICAgICAgID0gMDsKCiAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICBBVklTVFJFQU1JTkZPVyAqcHNpOwogICAgRFdPUkQgICAgICAgICAgIG47CgogICAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICAgIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbaV0gIT0gTlVMTCk7CgogICAgcHNpID0gJlRoaXMtPnBwU3RyZWFtc1tpXS0+c0luZm87CiAgICBhc3NlcnQocHNpLT5kd1NjYWxlICE9IDApOwogICAgYXNzZXJ0KHBzaS0+ZHdSYXRlICE9IDApOwoKICAgIGlmIChpID09IDApIHsKICAgICAgLyogdXNlIGZpcnN0IHN0cmVhbSB0aW1pbmdzIGFzIGJhc2UgKi8KICAgICAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgPSBwc2ktPmR3U2NhbGU7CiAgICAgIFRoaXMtPmZJbmZvLmR3UmF0ZSAgID0gcHNpLT5kd1JhdGU7CiAgICAgIFRoaXMtPmZJbmZvLmR3TGVuZ3RoID0gcHNpLT5kd0xlbmd0aDsKICAgIH0gZWxzZSB7CiAgICAgIG4gPSBBVklTdHJlYW1TYW1wbGVUb1NhbXBsZSgoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbMF0sCgkJCQkgIChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1tpXSxwc2ktPmR3TGVuZ3RoKTsKICAgICAgaWYgKFRoaXMtPmZJbmZvLmR3TGVuZ3RoIDwgbikKCVRoaXMtPmZJbmZvLmR3TGVuZ3RoID0gbjsKICAgIH0KCiAgICBpZiAoVGhpcy0+ZHdJbml0aWFsRnJhbWVzIDwgcHNpLT5kd0luaXRpYWxGcmFtZXMpCiAgICAgIFRoaXMtPmR3SW5pdGlhbEZyYW1lcyA9IHBzaS0+ZHdJbml0aWFsRnJhbWVzOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPCBwc2ktPmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSkKICAgICAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gcHNpLT5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CgogICAgaWYgKHBzaS0+ZHdTYW1wbGVTaXplICE9IDApIHsKICAgICAgLyogZml4ZWQgc2FtcGxlIHNpemUgLS0gZXhhY3QgY29tcHV0YXRpb24gKi8KICAgICAgVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYyArPSBNdWxEaXYocHNpLT5kd1NhbXBsZVNpemUsIHBzaS0+ZHdSYXRlLAoJCQkJCSAgICAgcHNpLT5kd1NjYWxlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8qIHZhcmlhYmxlIHNhbXBsZSBzaXplIC0tIG9ubHkgdXBwZXIgbGltaXQgKi8KICAgICAgVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYyArPSBNdWxEaXYocHNpLT5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUsCgkJCQkJICAgICBwc2ktPmR3UmF0ZSwgcHNpLT5kd1NjYWxlKTsKCiAgICAgIC8qIHVwZGF0ZSBkaW1lbnNpb25zICovCiAgICAgIG4gPSBwc2ktPnJjRnJhbWUucmlnaHQgLSBwc2ktPnJjRnJhbWUubGVmdDsKICAgICAgaWYgKFRoaXMtPmZJbmZvLmR3V2lkdGggPCBuKQoJVGhpcy0+ZkluZm8uZHdXaWR0aCA9IG47CiAgICAgIG4gPSBwc2ktPnJjRnJhbWUuYm90dG9tIC0gcHNpLT5yY0ZyYW1lLnRvcDsKICAgICAgaWYgKFRoaXMtPmZJbmZvLmR3SGVpZ2h0IDwgbikKCVRoaXMtPmZJbmZvLmR3SGVpZ2h0ID0gbjsKICAgIH0KICB9Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfV3JpdGVCbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgYmxvY2ssCgkJCQkgIEZPVVJDQyBja2lkLCBEV09SRCBmbGFncywgTFBWT0lEIGJ1ZmZlciwKCQkJCSAgTE9ORyBzaXplKQp7CiAgTU1DS0lORk8gY2s7CgogIGNrLmNraWQgICAgPSBja2lkOwogIGNrLmNrc2l6ZSAgPSBzaXplOwogIGNrLmZjY1R5cGUgPSAwOwoKICAvKiBpZiBubyBmcmFtZS9ibG9jayBpcyBhbHJlYWR5IHdyaXR0ZW4sIHdlIG11c3QgY29tcHV0ZSBzdGFydCBvZiBtb3ZpIGNodW5rICovCiAgaWYgKFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgPT0gMCkKICAgIEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChUaGlzLT5wYWYpOwoKICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+cGFmLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIHNpemUgPiAwKSB7CiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPnBhZi0+aG1taW8sIChIUFNUUilidWZmZXIsIHNpemUpICE9IHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KICBpZiAobW1pb0FzY2VuZChUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgVGhpcy0+cGFmLT5mRGlydHkgICAgICAgICA9IFRSVUU7CiAgVGhpcy0+cGFmLT5kd05leHRGcmFtZVBvcyA9IG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIDAsIFNFRUtfQ1VSKTsKCiAgcmV0dXJuIEFWSUZJTEVfQWRkRnJhbWUoVGhpcywgY2tpZCwgc2l6ZSwKCQkJICBjay5kd0RhdGFPZmZzZXQgLSAyICogc2l6ZW9mKERXT1JEKSwgZmxhZ3MpOwp9Cg==