LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDUxIEZyYW5rbGluIFN0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxLCBVU0EKICovCgovKiBUT0RPOgogKiAgLSBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSBpcyBtaXNzaW5nIGZvciB0aGUgSUFWSVN0cmVhbUltcGwKICogIC0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGU6IEZJTkRfSU5ERVggaXNuJ3Qgc3VwcG9ydGVkLgogKiAgLSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdDogZm9ybWF0Y2hhbmdlcyBhcmVuJ3QgcmVhZCBpbi4KICogIC0gSUFWSVN0cmVhbV9mbkRlbGV0ZTogYSBzdHViLgogKiAgLSBJQVZJU3RyZWFtX2ZuU2V0SW5mbzogYSBzdHViLgogKiAgLSBtYWtlIHRocmVhZCBzYWZlCiAqCiAqIEtOT1dOIEJ1Z3M6CiAqICAtIG5hdGl2ZSB2ZXJzaW9uIGNhbiBoYW5ndXAgd2hlbiByZWFkaW5nIGEgZmlsZSBnZW5lcmF0ZWQgd2l0aCB0aGlzIERMTC4KICogICAgV2hlbiBpbmRleCBpcyBtaXNzaW5nIGl0IHdvcmtzLCBidXQgaW5kZXggc2VlbXMgdG8gYmUgb2theS4KICovCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2lubmxzLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAibW1zeXN0ZW0uaCIKI2luY2x1ZGUgInZmdy5oIgoKI2luY2x1ZGUgImF2aWZpbGVfcHJpdmF0ZS5oIgojaW5jbHVkZSAiZXh0cmFjaHVuay5oIgoKI2luY2x1ZGUgIndpbmUvdW5pY29kZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgojaWZuZGVmIElEWF9QRVJfQkxPQ0sKI2RlZmluZSBJRFhfUEVSX0JMT0NLIDI3MzAKI2VuZGlmCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSogaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUZpbGVfZm5SZWxlYXNlKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUqaWZhY2UsQVZJRklMRUlORk9XKmFmaSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLEFWSVNUUkVBTUlORk9XKmFzaSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgKnNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklGaWxlVnRibCBpYXZpZnQgPSB7CiAgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJQVZJRmlsZV9mbkFkZFJlZiwKICBJQVZJRmlsZV9mblJlbGVhc2UsCiAgSUFWSUZpbGVfZm5JbmZvLAogIElBVklGaWxlX2ZuR2V0U3RyZWFtLAogIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtLAogIElBVklGaWxlX2ZuV3JpdGVEYXRhLAogIElBVklGaWxlX2ZuUmVhZERhdGEsCiAgSUFWSUZpbGVfZm5FbmRSZWNvcmQsCiAgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0KfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUqaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRChJUGVyc2lzdEZpbGUqaWZhY2UsQ0xTSUQqcENsYXNzSUQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLERXT1JEIGR3TW9kZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlKmlmYWNlLExQT0xFU1RSKnBwc3pGaWxlTmFtZSk7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElQZXJzaXN0RmlsZVZ0YmwgaXBlcnNpc3RmdCA9IHsKICBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZSwKICBJUGVyc2lzdEZpbGVfZm5BZGRSZWYsCiAgSVBlcnNpc3RGaWxlX2ZuUmVsZWFzZSwKICBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lELAogIElQZXJzaXN0RmlsZV9mbklzRGlydHksCiAgSVBlcnNpc3RGaWxlX2ZuTG9hZCwKICBJUGVyc2lzdEZpbGVfZm5TYXZlLAogIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZShJQVZJU3RyZWFtKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSppZmFjZSxMUEFSQU0gbFBhcmFtMSxMUEFSQU0gbFBhcmFtMik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuSW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XICpwc2ksTE9ORyBzaXplKTsKc3RhdGljIExPTkcgICAgV0lOQVBJIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTE9ORyBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyAqZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HIGZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxMT05HICpieXRlc3JlYWQsTE9ORyAqc2FtcGxlc3JlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsRFdPUkQgZmxhZ3MsTE9ORyAqc2FtcHdyaXR0ZW4sTE9ORyAqYnl0ZXN3cml0dGVuKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5EZWxldGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgKmxwcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyppbmZvLExPTkcgaW5mb2xlbik7CgpzdGF0aWMgY29uc3Qgc3RydWN0IElBVklTdHJlYW1WdGJsIGlhdmlzdCA9IHsKICBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSVN0cmVhbV9mbkFkZFJlZiwKICBJQVZJU3RyZWFtX2ZuUmVsZWFzZSwKICBJQVZJU3RyZWFtX2ZuQ3JlYXRlLAogIElBVklTdHJlYW1fZm5JbmZvLAogIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlLAogIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0LAogIElBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblJlYWQsCiAgSUFWSVN0cmVhbV9mbldyaXRlLAogIElBVklTdHJlYW1fZm5EZWxldGUsCiAgSUFWSVN0cmVhbV9mblJlYWREYXRhLAogIElBVklTdHJlYW1fZm5Xcml0ZURhdGEsCiAgSUFWSVN0cmVhbV9mblNldEluZm8KfTsKCnR5cGVkZWYgc3RydWN0IF9JQVZJRmlsZUltcGwgSUFWSUZpbGVJbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lQZXJzaXN0RmlsZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSVBlcnNpc3RGaWxlVnRibCAqbHBWdGJsOwoKICAvKiBJUGVyc2lzdEZpbGUgc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7Cn0gSVBlcnNpc3RGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JQVZJU3RyZWFtSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJU3RyZWFtVnRibCAqbHBWdGJsOwogIExPTkcJCSAgICByZWY7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7CiAgRFdPUkQgICAgICAgICAgICAgblN0cmVhbTsgICAgICAgLyogdGhlIG4tdGggc3RyZWFtIGluIGZpbGUgKi8KICBBVklTVFJFQU1JTkZPVyAgICBzSW5mbzsKCiAgTFBWT0lEICAgICAgICAgICAgbHBGb3JtYXQ7CiAgRFdPUkQgICAgICAgICAgICAgY2JGb3JtYXQ7CgogIExQVk9JRCAgICAgICAgICAgIGxwSGFuZGxlckRhdGE7CiAgRFdPUkQgICAgICAgICAgICAgY2JIYW5kbGVyRGF0YTsKCiAgRVhUUkFDSFVOS1MgICAgICAgZXh0cmE7CgogIExQRFdPUkQgICAgICAgICAgIGxwQnVmZmVyOwogIERXT1JEICAgICAgICAgICAgIGNiQnVmZmVyOyAgICAgICAvKiBzaXplIG9mIGxwQnVmZmVyICovCiAgRFdPUkQgICAgICAgICAgICAgZHdDdXJyZW50RnJhbWU7IC8qIGZyYW1lL2Jsb2NrIGN1cnJlbnRseSBpbiBscEJ1ZmZlciAqLwoKICBMT05HICAgICAgICAgICAgICBsTGFzdEZyYW1lOyAgICAvKiBsYXN0IGNvcnJlY3QgaW5kZXggaW4gaWR4RnJhbWVzICovCiAgQVZJSU5ERVhFTlRSWSAgICAqaWR4RnJhbWVzOwogIERXT1JEICAgICAgICAgICAgIG5JZHhGcmFtZXM7ICAgICAvKiB1cHBlciBpbmRleCBsaW1pdCBvZiBpZHhGcmFtZXMgKi8KICBBVklJTkRFWEVOVFJZICAgICppZHhGbXRDaGFuZ2VzOwogIERXT1JEICAgICAgICAgICAgIG5JZHhGbXRDaGFuZ2VzOyAvKiB1cHBlciBpbmRleCBsaW1pdCBvZiBpZHhGbXRDaGFuZ2VzICovCn0gSUFWSVN0cmVhbUltcGw7CgpzdHJ1Y3QgX0lBVklGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJQVZJRmlsZVZ0YmwgICAgICpscFZ0Ymw7CiAgTE9ORwkJICAgIHJlZjsKCiAgLyogSUFWSUZpbGUgc3R1ZmYuLi4gKi8KICBJUGVyc2lzdEZpbGVJbXBsICBpUGVyc2lzdEZpbGU7CgogIEFWSUZJTEVJTkZPVyAgICAgIGZJbmZvOwogIElBVklTdHJlYW1JbXBsICAgKnBwU3RyZWFtc1tNQVhfQVZJU1RSRUFNU107CgogIEVYVFJBQ0hVTktTICAgICAgIGZpbGVleHRyYTsKCiAgRFdPUkQgICAgICAgICAgICAgZHdNb3ZpQ2h1bmtQb3M7ICAvKiBzb21lIHN0dWZmIGZvciBzYXZpbmcgLi4uICovCiAgRFdPUkQgICAgICAgICAgICAgZHdJZHhDaHVua1BvczsKICBEV09SRCAgICAgICAgICAgICBkd05leHRGcmFtZVBvczsKICBEV09SRCAgICAgICAgICAgICBkd0luaXRpYWxGcmFtZXM7CgogIE1NQ0tJTkZPICAgICAgICAgIGNrTGFzdFJlY29yZDsKICBBVklJTkRFWEVOVFJZICAgICppZHhSZWNvcmRzOyAgICAgIC8qIHdvbid0IGJlIHVwZGF0ZWQgd2hpbGUgbG9hZGluZyAqLwogIERXT1JEICAgICAgICAgICAgIG5JZHhSZWNvcmRzOyAgICAgLyogY3VycmVudCBmaWxsIGxldmVsICovCiAgRFdPUkQgICAgICAgICAgICAgY2JJZHhSZWNvcmRzOyAgICAvKiBzaXplIG9mIGlkeFJlY29yZHMgKi8KCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmIC4uLiAqLwogIEhNTUlPICAgICAgICAgICAgIGhtbWlvOwogIExQV1NUUiAgICAgICAgICAgIHN6RmlsZU5hbWU7CiAgVUlOVCAgICAgICAgICAgICAgdU1vZGU7CiAgQk9PTCAgICAgICAgICAgICAgZkRpcnR5Owp9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRGcmFtZShJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgY2tpZCwgRFdPUkQgc2l6ZSwKCQkJCURXT1JEIG9mZnNldCwgRFdPUkQgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZFJlY29yZChJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgRFdPUkQgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oSUFWSUZpbGVJbXBsICpwYWYsIERXT1JEIG5yLAoJCQkJCSAgY29uc3QgQVZJU1RSRUFNSU5GT1cgKmFzaSk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oSUFWSVN0cmVhbUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEluZGV4KGNvbnN0IElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgc2l6ZSwgRFdPUkQgb2Zmc2V0KTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9QYXJzZUluZGV4KGNvbnN0IElBVklGaWxlSW1wbCAqVGhpcywgQVZJSU5ERVhFTlRSWSAqbHAsCgkJCQkgIExPTkcgY291bnQsIERXT1JEIHBvcywgQk9PTCAqYkFic29sdXRlKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9SZWFkQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIHN0YXJ0LAoJCQkJIExQVk9JRCBidWZmZXIsIExPTkcgc2l6ZSk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soY29uc3QgSUFWSVN0cmVhbUltcGwgKlRoaXMsIExQTE9ORyBwb3MsCgkJCQkgICAgICBMUExPTkcgb2Zmc2V0KTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVJbmRleChjb25zdCBJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgVUxPTkcgICBBVklGSUxFX1NlYXJjaFN0cmVhbShjb25zdCBJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIGZjY1R5cGUsCgkJCQkgICAgTE9ORyBsU2tpcCk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfVXBkYXRlSW5mbyhJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1dyaXRlQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGJsb2NrLAoJCQkJICBGT1VSQ0MgY2tpZCwgRFdPUkQgZmxhZ3MsIExQVk9JRCBidWZmZXIsCgkJCQkgIExPTkcgc2l6ZSk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlQVZJRmlsZShSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICBJQVZJRmlsZUltcGwgKnBmaWxlOwogIEhSRVNVTFQgICAgICAgaHI7CgogIGFzc2VydChyaWlkICE9IE5VTEwgJiYgcHB2ICE9IE5VTEwpOwoKICAqcHB2ID0gTlVMTDsKCiAgcGZpbGUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgc2l6ZW9mKElBVklGaWxlSW1wbCkpOwogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIHBmaWxlLT5scFZ0YmwgPSAmaWF2aWZ0OwogIHBmaWxlLT5yZWYgPSAwOwogIHBmaWxlLT5pUGVyc2lzdEZpbGUubHBWdGJsID0gJmlwZXJzaXN0ZnQ7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5wYWYgPSBwZmlsZTsKCiAgaHIgPSBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgoSUFWSUZpbGUqKXBmaWxlLCByaWlkLCBwcHYpOwogIGlmIChGQUlMRUQoaHIpKQogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcGZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlICppZmFjZSwgUkVGSUlEIHJlZmlpZCwKCQkJCQkJTFBWT0lEICpvYmopCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSUZpbGUsIHJlZmlpZCkpIHsKICAgICpvYmogPSBpZmFjZTsKICAgIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lQZXJzaXN0RmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9ICZUaGlzLT5pUGVyc2lzdEZpbGU7CiAgICBJQVZJRmlsZV9BZGRSZWYoaWZhY2UpOwoKICAgIHJldHVybiBTX09LOwogIH0KCiAgcmV0dXJuIE9MRV9FX0VOVU1fTk9NT1JFOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuQWRkUmVmKElBVklGaWxlICppZmFjZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWRcbiIsIGlmYWNlLCByZWYpOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CiAgVUlOVCBpOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlZFxuIiwgaWZhY2UsIHJlZik7CgogIGlmICghcmVmKSB7CiAgICBpZiAoVGhpcy0+ZkRpcnR5KSB7CiAgICAgIC8qIG5lZWQgdG8gd3JpdGUgaGVhZGVycyB0byBmaWxlICovCiAgICAgIEFWSUZJTEVfU2F2ZUZpbGUoVGhpcyk7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbaV0gIT0gTlVMTCkgewoJaWYgKFRoaXMtPnBwU3RyZWFtc1tpXS0+cmVmICE9IDApIHsKICAgICAgICAgIEVSUigiOiBzb21lb25lIGhhcyBzdGlsbCAldSByZWZlcmVuY2UgdG8gc3RyZWFtICV1ICglcCkhXG4iLAoJICAgICAgIFRoaXMtPnBwU3RyZWFtc1tpXS0+cmVmLCBpLCBUaGlzLT5wcFN0cmVhbXNbaV0pOwoJfQoJQVZJRklMRV9EZXN0cnVjdEFWSVN0cmVhbShUaGlzLT5wcFN0cmVhbXNbaV0pOwoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+cHBTdHJlYW1zW2ldKTsKCVRoaXMtPnBwU3RyZWFtc1tpXSA9IE5VTEw7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoVGhpcy0+aWR4UmVjb3JkcyAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmlkeFJlY29yZHMpOwogICAgICBUaGlzLT5pZHhSZWNvcmRzICA9IE5VTEw7CiAgICAgIFRoaXMtPm5JZHhSZWNvcmRzID0gMDsKICAgIH0KCiAgICBpZiAoVGhpcy0+ZmlsZWV4dHJhLmxwICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+ZmlsZWV4dHJhLmxwKTsKICAgICAgVGhpcy0+ZmlsZWV4dHJhLmxwID0gTlVMTDsKICAgICAgVGhpcy0+ZmlsZWV4dHJhLmNiID0gMDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5zekZpbGVOYW1lKTsKICAgIFRoaXMtPnN6RmlsZU5hbWUgPSBOVUxMOwoKICAgIGlmIChUaGlzLT5obW1pbyAhPSBOVUxMKSB7CiAgICAgIG1taW9DbG9zZShUaGlzLT5obW1pbywgMCk7CiAgICAgIFRoaXMtPmhtbWlvID0gTlVMTDsKICAgIH0KCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICB9CiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSAqaWZhY2UsIExQQVZJRklMRUlORk9XIGFmaSwKCQkJCSAgICAgIExPTkcgc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsaWZhY2UsYWZpLHNpemUpOwoKICBpZiAoYWZpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgQVZJRklMRV9VcGRhdGVJbmZvKFRoaXMpOwoKICBtZW1jcHkoYWZpLCAmVGhpcy0+ZkluZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPmZJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+ZkluZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgIERXT1JEIGZjY1R5cGUsIExPTkcgbFBhcmFtKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBVTE9ORyBuU3RyZWFtOwoKICBUUkFDRSgiKCVwLCVwLDB4JTA4WCwlZClcbiIsIGlmYWNlLCBhdmlzLCBmY2NUeXBlLCBsUGFyYW0pOwoKICBpZiAoYXZpcyA9PSBOVUxMIHx8IGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBuU3RyZWFtID0gQVZJRklMRV9TZWFyY2hTdHJlYW0oVGhpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogRG9lcyB0aGUgcmVxdWVzdGVkIHN0cmVhbSBleGlzdD8gKi8KICBpZiAoblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAmJgogICAgICBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0gIT0gTlVMTCkgewogICAgKmF2aXMgPSAoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CiAgICBJQVZJU3RyZWFtX0FkZFJlZigqYXZpcyk7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIFNvcnJ5LCBidXQgdGhlIHNwZWNpZmllZCBzdHJlYW0gZG9lc24ndCBleGlzdCAqLwogIHJldHVybiBBVklFUlJfTk9EQVRBOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgICAgTFBBVklTVFJFQU1JTkZPVyBhc2kpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIERXT1JEIG47CgogIFRSQUNFKCIoJXAsJXAsJXApXG4iLCBpZmFjZSwgYXZpcywgYXNpKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChhdmlzID09IE5VTEwgfHwgYXNpID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqYXZpcyA9IE5VTEw7CgogIC8qIERvZXMgdGhlIHVzZXIgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIENhbiB3ZSBhZGQgYW5vdGhlciBzdHJlYW0/ICovCiAgbiA9IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsKICBpZiAobiA+PSBNQVhfQVZJU1RSRUFNUyB8fCBUaGlzLT5kd01vdmlDaHVua1BvcyAhPSAwKSB7CiAgICAvKiBhbHJlYWR5IHJlYWNoZWQgbWF4IG5yIG9mIHN0cmVhbXMKICAgICAqIG9yIGhhdmUgYWxyZWFkeSB3cml0dGVuIGZyYW1lcyB0byBkaXNrICovCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogIH0KCiAgLyogY2hlY2sgQVZJU1RSRUFNSU5GTyBmb3Igc29tZSByZWFsbHkgbmVlZGVkIHRoaW5ncyAqLwogIGlmIChhc2ktPmZjY1R5cGUgPT0gMCB8fCBhc2ktPmR3U2NhbGUgPT0gMCB8fCBhc2ktPmR3UmF0ZSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogIC8qIG5vdyBpdCBzZWVtcyB0byBiZSBzYXZlIHRvIGFkZCB0aGUgc3RyZWFtICovCiAgYXNzZXJ0KFRoaXMtPnBwU3RyZWFtc1tuXSA9PSBOVUxMKTsKICBUaGlzLT5wcFN0cmVhbXNbbl0gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKCQkJCQkJICAgc2l6ZW9mKElBVklTdHJlYW1JbXBsKSk7CiAgaWYgKFRoaXMtPnBwU3RyZWFtc1tuXSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIC8qIGluaXRpYWxpemUgdGhlIG5ldyBhbGxvY2F0ZWQgc3RyZWFtICovCiAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oVGhpcywgbiwgYXNpKTsKCiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zKys7CiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgLyogdXBkYXRlIG91ciBBVklGSUxFSU5GTyBzdHJ1Y3R1cmUgKi8KICBBVklGSUxFX1VwZGF0ZUluZm8oVGhpcyk7CgogIC8qIHJldHVybiBpdCAqLwogICphdmlzID0gKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zW25dOwogIElBVklTdHJlYW1fQWRkUmVmKCphdmlzKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlICppZmFjZSwgRFdPUkQgY2tpZCwKCQkJCQkgICBMUFZPSUQgbHBEYXRhLCBMT05HIHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhYLCVwLCVkKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHBEYXRhID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmZpbGVleHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgTFBWT0lEIGxwRGF0YSwgTE9ORyAqc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOFgsJXAsJXApXG4iLCBpZmFjZSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKCiAgcmV0dXJuIFJlYWRFeHRyYUNodW5rKCZUaGlzLT5maWxlZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLGlmYWNlKTsKCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgVGhpcy0+ZkRpcnR5ID0gVFJVRTsKCiAgLyogbm8gZnJhbWVzIHdyaXR0ZW4gdG8gYW55IHN0cmVhbT8gLS0gY29tcHV0ZSBzdGFydCBvZiAnbW92aSctY2h1bmsgKi8KICBpZiAoVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPT0gMCkKICAgIEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChUaGlzKTsKCiAgVGhpcy0+ZkluZm8uZHdGbGFncyAgfD0gQVZJRklMRUlORk9fSVNJTlRFUkxFQVZFRDsKCiAgLyogYWxyZWFkeSB3cml0dGVuIGZyYW1lcyB0byBhbnkgc3RyZWFtLCAuLi4gKi8KICBpZiAoVGhpcy0+Y2tMYXN0UmVjb3JkLmR3RmxhZ3MgJiBNTUlPX0RJUlRZKSB7CiAgICAvKiBjbG9zZSBsYXN0IHJlY29yZCAqLwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZUaGlzLT5ja0xhc3RSZWNvcmQsIDApICE9IDApCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIEFWSUZJTEVfQWRkUmVjb3JkKFRoaXMpOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPCBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplICsgMyAqIHNpemVvZihEV09SRCkpCiAgICAgIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmNrTGFzdFJlY29yZC5ja3NpemUgKyAzICogc2l6ZW9mKERXT1JEKTsKICB9CgogIC8qIHdyaXRlIG91dCBhIG5ldyByZWNvcmQgaW50byBmaWxlLCBidXQgZG9uJ3QgY2xvc2UgaXQgKi8KICBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplICA9IDA7CiAgVGhpcy0+Y2tMYXN0UmVjb3JkLmZjY1R5cGUgPSBsaXN0dHlwZUFWSVJFQ09SRDsKICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tMYXN0UmVjb3JkLCBNTUlPX0NSRUFURUxJU1QpICE9IDApCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBUaGlzLT5kd05leHRGcmFtZVBvcyArPSAzICogc2l6ZW9mKERXT1JEKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlICppZmFjZSwgRFdPUkQgZmNjVHlwZSwKCQkJCQkgICAgICBMT05HIGxQYXJhbSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVUxPTkcgblN0cmVhbTsKCiAgVFJBQ0UoIiglcCwweCUwOFgsJWQpXG4iLCBpZmFjZSwgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHVzZXIgd3JpdGUgcGVybWlzc2lvbnM/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgIC8qIC4uLiBzbyBkZWxldGUgaXQgbm93ICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0pOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgLSBuU3RyZWFtID4gMCkKICAgICAgbWVtY3B5KFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0sIFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0gKyAxLAoJICAgICAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zIC0gblN0cmVhbSkgKiBzaXplb2YoSUFWSVN0cmVhbUltcGwqKSk7CgogICAgVGhpcy0+cHBTdHJlYW1zW1RoaXMtPmZJbmZvLmR3U3RyZWFtc10gPSBOVUxMOwogICAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zLS07CiAgICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAgIC8qIFRoaXMtPmZJbmZvIHdpbGwgYmUgdXBkYXRlZCBmdXJ0aGVyIHdoZW4gYXNrZWQgZm9yICovCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChQQVZJRklMRSlUaGlzLT5wYWYsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQQ0xTSUQgcENsYXNzSUQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBDbGFzc0lEKTsKCiAgaWYgKHBDbGFzc0lEID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBtZW1jcHkocENsYXNzSUQsICZDTFNJRF9BVklGaWxlLCBzaXplb2YoQ0xTSURfQVZJRmlsZSkpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLCBpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiAoVGhpcy0+cGFmLT5mRGlydHkgPyBTX09LIDogU19GQUxTRSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsIERXT1JEIGR3TW9kZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBpbnQgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4WClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSwgZHdNb2RlKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwogIGlmIChUaGlzLT5wYWYtPmhtbWlvICE9IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBObyByZXVzZSBvZiB0aGlzIG9iamVjdCBmb3IgYW5vdGhlciBmaWxlISAqLwoKICAvKiByZW1lYmVyIG1vZGUgYW5kIG5hbWUgKi8KICBUaGlzLT5wYWYtPnVNb2RlID0gZHdNb2RlOwoKICBsZW4gPSBsc3RybGVuVyhwc3pGaWxlTmFtZSkgKyAxOwogIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICBpZiAoVGhpcy0+cGFmLT5zekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICBsc3RyY3B5VyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIHBzekZpbGVOYW1lKTsKCiAgLyogdHJ5IHRvIG9wZW4gdGhlIGZpbGUgKi8KICBUaGlzLT5wYWYtPmhtbWlvID0gbW1pb09wZW5XKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgTlVMTCwKCQkJICAgICAgIE1NSU9fQUxMT0NCVUYgfCBkd01vZGUpOwogIGlmIChUaGlzLT5wYWYtPmhtbWlvID09IE5VTEwpIHsKICAgIC8qIG1taW9PcGVuVyBub3QgaW4gbmF0aXZlIERMTHMgb2YgV2luOXggLS0gdHJ5IG1taW9PcGVuQSAqLwogICAgTFBTVFIgc3pGaWxlTmFtZTsKCiAgICBsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgVGhpcy0+cGFmLT5zekZpbGVOYW1lLCAtMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIDAsIE5VTEwsIE5VTEwpOwogICAgc3pGaWxlTmFtZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBsZW4gKiBzaXplb2YoQ0hBUikpOwogICAgaWYgKHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgLTEsIHN6RmlsZU5hbWUsCgkJCWxlbiwgTlVMTCwgTlVMTCk7CgogICAgVGhpcy0+cGFmLT5obW1pbyA9IG1taW9PcGVuQShzekZpbGVOYW1lLCBOVUxMLCBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN6RmlsZU5hbWUpOwogICAgaWYgKFRoaXMtPnBhZi0+aG1taW8gPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFT1BFTjsKICB9CgogIC8qIHNob3VsZCB3ZSBjcmVhdGUgYSBuZXcgZmlsZT8gKi8KICBpZiAoZHdNb2RlICYgT0ZfQ1JFQVRFKSB7CiAgICBtZW1zZXQoJiBUaGlzLT5wYWYtPmZJbmZvLCAwLCBzaXplb2YoVGhpcy0+cGFmLT5mSW5mbykpOwogICAgVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzID0gQVZJRklMRUlORk9fSEFTSU5ERVggfCBBVklGSUxFSU5GT19UUlVTVENLVFlQRTsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUZJTEVfTG9hZEZpbGUoVGhpcy0+cGFmKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSxCT09MIGZSZW1lbWJlcikKewogIFRSQUNFKCIoJXAsJXMsJWQpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGZSZW1lbWJlcik7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCSAgIExQQ09MRVNUUiBwc3pGaWxlTmFtZSkKewogIFRSQUNFKCIoJXAsJXMpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSkpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQlMUE9MRVNUUiAqcHBzekZpbGVOYW1lKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBpZmFjZSwgcHBzekZpbGVOYW1lKTsKCiAgaWYgKHBwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKnBwc3pGaWxlTmFtZSA9IE5VTEw7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIGlmIChUaGlzLT5wYWYtPnN6RmlsZU5hbWUgIT0gTlVMTCkgewogICAgaW50IGxlbiA9IGxzdHJsZW5XKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSkgKyAxOwoKICAgICpwcHN6RmlsZU5hbWUgPSBDb1Rhc2tNZW1BbGxvYyhsZW4gKiBzaXplb2YoV0NIQVIpKTsKICAgIGlmICgqcHBzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIHN0cmNweVcoKnBwc3pGaWxlTmFtZSwgVGhpcy0+cGFmLT5zekZpbGVOYW1lKTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgaWZhY2UsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJU3RyZWFtLCByZWZpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIElBVklTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CiAgLyogRklYTUU6IElBVklTdHJlYW1pbmcgaW50ZXJmYWNlICovCgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0gKmlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWRcbiIsIGlmYWNlLCByZWYpOwoKICAvKiBhbHNvIGFkZCByZWYgdG8gcGFyZW50LCBzbyB0aGF0IGl0IGRvZXNuJ3Qga2lsbCB1cyAqLwogIGlmIChUaGlzLT5wYWYgIT0gTlVMTCkKICAgIElBVklGaWxlX0FkZFJlZigoUEFWSUZJTEUpVGhpcy0+cGFmKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVkXG4iLCBpZmFjZSwgcmVmKTsKCiAgaWYgKFRoaXMtPnBhZiAhPSBOVUxMKQogICAgSUFWSUZpbGVfUmVsZWFzZSgoUEFWSUZJTEUpVGhpcy0+cGFmKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExQQVJBTSBsUGFyYW0xLAoJCQkJCSAgTFBBUkFNIGxQYXJhbTIpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIGlmYWNlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgLyogVGhpcyBJQVZJU3RyZWFtIGludGVyZmFjZSBuZWVkcyBhbiBBVklGaWxlICovCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0gKmlmYWNlLExQQVZJU1RSRUFNSU5GT1cgcHNpLAoJCQkJCUxPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWQpXG4iLCBpZmFjZSwgcHNpLCBzaXplKTsKCiAgaWYgKHBzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIG1lbWNweShwc2ksICZUaGlzLT5zSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+c0luZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5zSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIExPTkcgb2Zmc2V0ID0gMDsKCiAgVFJBQ0UoIiglcCwlZCwweCUwOFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGNvbnZlcnQgc2FtcGxlcyBpbnRvIGJsb2NrIG51bWJlciB3aXRoIG9mZnNldCAqLwogICAgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhUaGlzLCAmcG9zLCAmb2Zmc2V0KTsKICB9CgogIGlmIChmbGFncyAmIEZJTkRfVFlQRSkgewogICAgaWYgKGZsYWdzICYgRklORF9LRVkpIHsKICAgICAgd2hpbGUgKDAgPD0gcG9zICYmIHBvcyA8PSBUaGlzLT5sTGFzdEZyYW1lKSB7CglpZiAoVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdGbGFncyAmIEFWSUlGX0tFWUZSQU1FKQoJICBnb3RvIFJFVFVSTl9GT1VORDsKCglpZiAoZmxhZ3MgJiBGSU5EX05FWFQpCgkgIHBvcysrOwoJZWxzZQoJICBwb3MtLTsKICAgICAgfTsKICAgIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0FOWSkgewogICAgICB3aGlsZSAoMCA8PSBwb3MgJiYgcG9zIDw9IFRoaXMtPmxMYXN0RnJhbWUpIHsKCWlmIChUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoID4gMCkKCSAgZ290byBSRVRVUk5fRk9VTkQ7CgoJaWYgKGZsYWdzICYgRklORF9ORVhUKQoJICBwb3MrKzsKCWVsc2UKCSAgcG9zLS07CgogICAgICB9OwogICAgfSBlbHNlIGlmICgoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgJiYgVGhpcy0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMICYmCgkgICAgICAgVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgaWYgKGZsYWdzICYgRklORF9ORVhUKSB7CglVTE9ORyBuOwoKCWZvciAobiA9IDA7IG4gPCBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBuKyspCgkgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQgPj0gcG9zKSB7CiAgICAgICAgICAgIHBvcyA9IFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZDsKCSAgICBnb3RvIFJFVFVSTl9GT1VORDsKICAgICAgICAgIH0KICAgICAgfSBlbHNlIHsKCUxPTkcgbjsKCglmb3IgKG4gPSAoTE9ORylUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBuID49IDA7IG4tLSkgewoJICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkIDw9IHBvcykgewogICAgICAgICAgICBwb3MgPSBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQ7CgkgICAgZ290byBSRVRVUk5fRk9VTkQ7CiAgICAgICAgICB9Cgl9CgoJaWYgKHBvcyA+IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQpCgkgIHJldHVybiAwOyAvKiBmb3JtYXQgY2hhbmdlcyBhbHdheXMgZm9yIGZpcnN0IGZyYW1lICovCiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gLTE7CiAgfQoKIFJFVFVSTl9GT1VORDoKICBpZiAocG9zIDwgKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiAtMTsKCiAgc3dpdGNoIChmbGFncyAmIEZJTkRfUkVUKSB7CiAgY2FzZSBGSU5EX0xFTkdUSDoKICAgIC8qIHBoeXNpY2FsIHNpemUgKi8KICAgIHBvcyA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGg7CiAgICBicmVhazsKICBjYXNlIEZJTkRfT0ZGU0VUOgogICAgLyogcGh5c2ljYWwgcG9zaXRpb24gKi8KICAgIHBvcyA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKQogICAgICArIG9mZnNldCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGJyZWFrOwogIGNhc2UgRklORF9TSVpFOgogICAgLyogbG9naWNhbCBzaXplICovCiAgICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplKQogICAgICBwb3MgPSBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBlbHNlCiAgICAgIHBvcyA9IDE7CiAgICBicmVhazsKICBjYXNlIEZJTkRfSU5ERVg6CiAgICBGSVhNRSgiOiBGSU5EX0lOREVYIGZsYWcgaXMgbm90IHN1cHBvcnRlZCFcbiIpOwogICAgLyogVGhpcyBpcyBhbiBpbmRleCBpbiB0aGUgaW5kZXgtdGFibGUgb24gZGlzYy4gKi8KICAgIGJyZWFrOwogIH07IC8qIGVsc2UgbG9naWNhbCBwb3NpdGlvbiAqLwoKICByZXR1cm4gcG9zOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgKmZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVkLCVwLCVwKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKGZvcm1hdHNpemUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIG9ubHkgaW50ZXJlc3RlZCBpbiBuZWVkZWQgYnVmZmVyc2l6ZT8gKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgKmZvcm1hdHNpemUgPD0gMCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogY29weSBpbml0aWFsIGZvcm1hdCAob25seSBhcyBtdWNoIGFzIHdpbGwgZml0KSAqLwogIG1lbWNweShmb3JtYXQsIFRoaXMtPmxwRm9ybWF0LCBtaW4oKihEV09SRCopZm9ybWF0c2l6ZSwgVGhpcy0+Y2JGb3JtYXQpKTsKICBpZiAoKihEV09SRCopZm9ybWF0c2l6ZSA8IFRoaXMtPmNiRm9ybWF0KSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiRm9ybWF0OwogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9CgogIC8qIENvdWxkIGZvcm1hdCBjaGFuZ2U/IFdoZW4geWVzIHdpbGwgaXQgY2hhbmdlPyAqLwogIGlmICgoVGhpcy0+c0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUykgJiYKICAgICAgcG9zID4gVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgTE9ORyBsTGFzdEZtdDsKCiAgICBsTGFzdEZtdCA9IElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKGlmYWNlLCBwb3MsIEZJTkRfRk9STUFUfEZJTkRfUFJFVik7CiAgICBpZiAobExhc3RGbXQgPiAwKSB7CiAgICAgIEZJWE1FKCI6IG5lZWQgdG8gcmVhZCBmb3JtYXRjaGFuZ2UgZm9yICVkIC0tIHVuaW1wbGVtZW50ZWQhXG4iLGxMYXN0Rm10KTsKICAgIH0KICB9CgogICpmb3JtYXRzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyBmb3JtYXRzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlOZXcgPSAoTFBCSVRNQVBJTkZPSEVBREVSKWZvcm1hdDsKCiAgVFJBQ0UoIiglcCwlZCwlcCwlZClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgZm9ybWF0c2l6ZSA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogY2FuIG9ubHkgc2V0IGZvcm1hdCBiZWZvcmUgZnJhbWUgaXMgd3JpdHRlbiEgKi8KICBpZiAoVGhpcy0+bExhc3RGcmFtZSA+IHBvcykKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIC8qIGluaXRpYWwgZm9ybWF0IG9yIGEgZm9ybWF0Y2hhbmdlPyAqLwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKSB7CiAgICAvKiBpbml0aWFsIGZvcm1hdCAqLwogICAgaWYgKFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogdXNlciBoYXMgdXNlZCBBUEkgaW4gd3Jvbmcgc2VxdW5lY2UhICovCgogICAgVGhpcy0+bHBGb3JtYXQgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgZm9ybWF0c2l6ZSk7CiAgICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5jYkZvcm1hdCA9IGZvcm1hdHNpemU7CgogICAgbWVtY3B5KFRoaXMtPmxwRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAgIC8qIHVwZGF0ZSBzb21lIGluZm9zIGFib3V0IHN0cmVhbSAqLwogICAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIExPTkcgbERpbTsKCiAgICAgIGxEaW0gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLnJpZ2h0IC0gVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0OwogICAgICBpZiAobERpbSA8IGxwYmlOZXctPmJpV2lkdGgpCglUaGlzLT5zSW5mby5yY0ZyYW1lLnJpZ2h0ID0gVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0ICsgbHBiaU5ldy0+YmlXaWR0aDsKICAgICAgbERpbSA9IFRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tIC0gVGhpcy0+c0luZm8ucmNGcmFtZS50b3A7CiAgICAgIGlmIChsRGltIDwgbHBiaU5ldy0+YmlIZWlnaHQpCglUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSA9IFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wICsgbHBiaU5ldy0+YmlIZWlnaHQ7CiAgICB9IGVsc2UgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKQogICAgICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgPSAoKExQV0FWRUZPUk1BVEVYKVRoaXMtPmxwRm9ybWF0KS0+bkJsb2NrQWxpZ247CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UgewogICAgTU1DS0lORk8gICAgICAgICAgIGNrOwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPbGQgPSAoTFBCSVRNQVBJTkZPSEVBREVSKVRoaXMtPmxwRm9ybWF0OwogICAgUkdCUVVBRCAgICAgICAgICAgKnJnYk5ldyAgPSAoUkdCUVVBRCopKChMUEJZVEUpbHBiaU5ldyArIGxwYmlOZXctPmJpU2l6ZSk7CiAgICBBVklQQUxDSEFOR0UgICAgICAqbHBwYyA9IE5VTEw7CiAgICBVSU5UICAgICAgICAgICAgICAgbjsKCiAgICAvKiBwZXJoYXBzIGZvcm1hdCBjaGFuZ2UsIGNoZWNrIGl0IC4uLiAqLwogICAgaWYgKFRoaXMtPmNiRm9ybWF0ICE9IGZvcm1hdHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogbm8gZm9ybWF0IGNoYW5nZSwgb25seSB0aGUgaW5pdGlhbCBvbmUgKi8KICAgIGlmIChtZW1jbXAoVGhpcy0+bHBGb3JtYXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSkgPT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgICAvKiBjaGVjayB0aGF0J3Mgb25seSB0aGUgcGFsZXR0ZSwgd2hpY2ggY2hhbmdlcyAqLwogICAgaWYgKGxwYmlPbGQtPmJpU2l6ZSAgICAgICAgIT0gbHBiaU5ldy0+YmlTaXplIHx8CglscGJpT2xkLT5iaVdpZHRoICAgICAgICE9IGxwYmlOZXctPmJpV2lkdGggfHwKCWxwYmlPbGQtPmJpSGVpZ2h0ICAgICAgIT0gbHBiaU5ldy0+YmlIZWlnaHQgfHwKCWxwYmlPbGQtPmJpUGxhbmVzICAgICAgIT0gbHBiaU5ldy0+YmlQbGFuZXMgfHwKCWxwYmlPbGQtPmJpQml0Q291bnQgICAgIT0gbHBiaU5ldy0+YmlCaXRDb3VudCB8fAoJbHBiaU9sZC0+YmlDb21wcmVzc2lvbiAhPSBscGJpTmV3LT5iaUNvbXByZXNzaW9uIHx8CglscGJpT2xkLT5iaUNsclVzZWQgICAgICE9IGxwYmlOZXctPmJpQ2xyVXNlZCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICBUaGlzLT5zSW5mby5kd0ZsYWdzIHw9IEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUzsKCiAgICAvKiBzaW1wbHkgc2F5IGFsbCBjb2xvcnMgaGF2ZSBjaGFuZ2VkICovCiAgICBjay5ja2lkICAgPSBNQUtFQVZJQ0tJRChja3R5cGVQQUxjaGFuZ2UsIFRoaXMtPm5TdHJlYW0pOwogICAgY2suY2tzaXplID0gMiAqIHNpemVvZihXT1JEKSArIGxwYmlPbGQtPmJpQ2xyVXNlZCAqIHNpemVvZihQQUxFVFRFRU5UUlkpOwogICAgbHBwYyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjay5ja3NpemUpOwogICAgaWYgKGxwcGMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgbHBwYy0+YkZpcnN0RW50cnkgPSAwOwogICAgbHBwYy0+Yk51bUVudHJpZXMgPSAobHBiaU9sZC0+YmlDbHJVc2VkIDwgMjU2ID8gbHBiaU9sZC0+YmlDbHJVc2VkIDogMCk7CiAgICBscHBjLT53RmxhZ3MgICAgICA9IDA7CiAgICBmb3IgKG4gPSAwOyBuIDwgbHBiaU9sZC0+YmlDbHJVc2VkOyBuKyspIHsKICAgICAgbHBwYy0+cGVOZXdbbl0ucGVSZWQgICA9IHJnYk5ld1tuXS5yZ2JSZWQ7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlR3JlZW4gPSByZ2JOZXdbbl0ucmdiR3JlZW47CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlQmx1ZSAgPSByZ2JOZXdbbl0ucmdiQmx1ZTsKICAgICAgbHBwYy0+cGVOZXdbbl0ucGVGbGFncyA9IDA7CiAgICB9CgogICAgaWYgKG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MsIFNFRUtfU0VUKSA9PSAtMSB8fAogICAgICAgIG1taW9DcmVhdGVDaHVuayhUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0sgfHwKICAgICAgICBtbWlvV3JpdGUoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKWxwcGMsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplIHx8CiAgICAgICAgbW1pb0FzY2VuZChUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwcGMpOwogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0KCiAgICBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zICs9IGNrLmNrc2l6ZSArIDIgKiBzaXplb2YoRFdPUkQpOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxwcGMpOwoKICAgIHJldHVybiBBVklGSUxFX0FkZEZyYW1lKFRoaXMsIGNrdHlwZVBBTGNoYW5nZSwgbiwgY2suZHdEYXRhT2Zmc2V0LCAwKTsKICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQlMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJTE9ORyBidWZmZXJzaXplLCBMUExPTkcgYnl0ZXNyZWFkLAoJCQkJCUxQTE9ORyBzYW1wbGVzcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIERXT1JEICAgIHNpemU7CiAgSFJFU1VMVCAgaHI7CgogIFRSQUNFKCIoJXAsJWQsJWQsJXAsJWQsJXAsJXApXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMsIGJ1ZmZlciwKIAlidWZmZXJzaXplLCBieXRlc3JlYWQsIHNhbXBsZXNyZWFkKTsKCiAgLyogY2xlYXIgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAqYnl0ZXNyZWFkID0gMDsKICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICpzYW1wbGVzcmVhZCA9IDA7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCA+IHN0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7IC8qIGNvdWxkbid0IHJlYWQgYmVmb3JlIHN0YXJ0IG9mIHN0cmVhbSAqLwogIGlmIChUaGlzLT5zSW5mby5kd1N0YXJ0ICsgVGhpcy0+c0luZm8uZHdMZW5ndGggPCAoRFdPUkQpc3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsgLyogc3RhcnQgaXMgcGFzdCBlbmQgb2Ygc3RyZWFtICovCgogIC8qIHNob3VsZCB3ZSByZWFkIGFzIG11Y2ggYXMgcG9zc2libGU/ICovCiAgaWYgKHNhbXBsZXMgPT0gLTEpIHsKICAgIC8qIFVzZXIgc2hvdWxkIGtub3cgaG93IG11Y2ggd2UgaGF2ZSByZWFkICovCiAgICBpZiAoYnl0ZXNyZWFkID09IE5VTEwgJiYgc2FtcGxlc3JlYWQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApCiAgICAgIHNhbXBsZXMgPSBidWZmZXJzaXplIC8gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgZWxzZQogICAgICBzYW1wbGVzID0gMTsKICB9CgogIC8qIGxpbWl0IHRvIGVuZCBvZiBzdHJlYW0gKi8KICBpZiAoKExPTkcpVGhpcy0+c0luZm8uZHdMZW5ndGggPCBzYW1wbGVzKQogICAgc2FtcGxlcyA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoOwogIGlmICgoc3RhcnQgLSBUaGlzLT5zSW5mby5kd1N0YXJ0KSA+IChUaGlzLT5zSW5mby5kd0xlbmd0aCAtIHNhbXBsZXMpKQogICAgc2FtcGxlcyA9IFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gKHN0YXJ0IC0gVGhpcy0+c0luZm8uZHdTdGFydCk7CgogIC8qIG5vdGhpbmcgdG8gcmVhZD8gVGhlbiBsZWF2ZSAuLi4gKi8KICBpZiAoc2FtcGxlcyA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAvKiBmaXhlZCBzYW1wbGVzaXplIC0tIHdlIGNhbiByZWFkIG92ZXIgZnJhbWUvYmxvY2sgYm91bmRhcmllcyAqLwogICAgTE9ORyBibG9jayA9IHN0YXJ0OwogICAgTE9ORyBvZmZzZXQgPSAwOwoKICAgIC8qIGNvbnZlcnQgc3RhcnQgc2FtcGxlIHRvIGJsb2NrLG9mZnNldCBwYWlyICovCiAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKFRoaXMsICZibG9jaywgJm9mZnNldCk7CgogICAgLyogY29udmVydCBzYW1wbGVzIHRvIGJ5dGVzICovCiAgICBzYW1wbGVzICo9IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgICB3aGlsZSAoc2FtcGxlcyA+IDAgJiYgYnVmZmVyc2l6ZSA+IDApIHsKICAgICAgaWYgKGJsb2NrICE9IFRoaXMtPmR3Q3VycmVudEZyYW1lKSB7CglociA9IEFWSUZJTEVfUmVhZEJsb2NrKFRoaXMsIGJsb2NrLCBOVUxMLCAwKTsKCWlmIChGQUlMRUQoaHIpKQoJICByZXR1cm4gaHI7CiAgICAgIH0KCiAgICAgIHNpemUgPSBtaW4oKERXT1JEKXNhbXBsZXMsIChEV09SRClidWZmZXJzaXplKTsKICAgICAgc2l6ZSA9IG1pbihzaXplLCBUaGlzLT5jYkJ1ZmZlciAtIG9mZnNldCk7CiAgICAgIG1lbWNweShidWZmZXIsICgoQllURSopJlRoaXMtPmxwQnVmZmVyWzJdKSArIG9mZnNldCwgc2l6ZSk7CgogICAgICBibG9jaysrOwogICAgICBvZmZzZXQgPSAwOwogICAgICBidWZmZXIgPSAoKExQQllURSlidWZmZXIpK3NpemU7CiAgICAgIHNhbXBsZXMgICAgLT0gc2l6ZTsKICAgICAgYnVmZmVyc2l6ZSAtPSBzaXplOwoKICAgICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQoJKmJ5dGVzcmVhZCAgICs9IHNpemU7CiAgICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQoJKnNhbXBsZXNyZWFkICs9IHNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICB9CgogICAgaWYgKHNhbXBsZXMgPT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIGVsc2UKICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9IGVsc2UgewogICAgLyogdmFyaWFibGUgc2FtcGxlc2l6ZSAtLSB3ZSBjYW4gb25seSByZWFkIG9uZSBmdWxsIGZyYW1lL2Jsb2NrICovCiAgICBpZiAoc2FtcGxlcyA+IDEpCiAgICAgIHNhbXBsZXMgPSAxOwoKICAgIGFzc2VydChzdGFydCA8PSBUaGlzLT5sTGFzdEZyYW1lKTsKICAgIHNpemUgPSBUaGlzLT5pZHhGcmFtZXNbc3RhcnRdLmR3Q2h1bmtMZW5ndGg7CiAgICBpZiAoYnVmZmVyICE9IE5VTEwgJiYgYnVmZmVyc2l6ZSA+PSBzaXplKSB7CiAgICAgIGhyID0gQVZJRklMRV9SZWFkQmxvY2soVGhpcywgc3RhcnQsIGJ1ZmZlciwgc2l6ZSk7CiAgICAgIGlmIChGQUlMRUQoaHIpKQoJcmV0dXJuIGhyOwogICAgfSBlbHNlIGlmIChidWZmZXIgIT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKCiAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgICAqYnl0ZXNyZWFkID0gc2l6ZTsKICAgIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgICAqc2FtcGxlc3JlYWQgPSBzYW1wbGVzOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSBMT05HIHNhbXBsZXMsIExQVk9JRCBidWZmZXIsCgkJCQkJIExPTkcgYnVmZmVyc2l6ZSwgRFdPUkQgZmxhZ3MsCgkJCQkJIExQTE9ORyBzYW1wd3JpdHRlbiwKCQkJCQkgTFBMT05HIGJ5dGVzd3JpdHRlbikKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEZPVVJDQyAgY2tpZDsKICBIUkVTVUxUIGhyOwoKICBUUkFDRSgiKCVwLCVkLCVkLCVwLCVkLDB4JTA4WCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywKCWJ1ZmZlciwgYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgKnNhbXB3cml0dGVuID0gMDsKICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAqYnl0ZXN3cml0dGVuID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCAmJiAoYnVmZmVyc2l6ZSA+IDAgfHwgc2FtcGxlcyA+IDApKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogSGF2ZSB3ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgc3dpdGNoIChUaGlzLT5zSW5mby5mY2NUeXBlKSB7CiAgY2FzZSBzdHJlYW10eXBlQVVESU86CiAgICBja2lkID0gTUFLRUFWSUNLSUQoY2t0eXBlV0FWRWJ5dGVzLCBUaGlzLT5uU3RyZWFtKTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBpZiAoKGZsYWdzICYgQVZJSUZfS0VZRlJBTUUpICYmIGJ1ZmZlcnNpemUgIT0gMCkKICAgICAgY2tpZCA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmJpdHMsIFRoaXMtPm5TdHJlYW0pOwogICAgZWxzZQogICAgICBja2lkID0gTUFLRUFWSUNLSUQoY2t0eXBlRElCY29tcHJlc3NlZCwgVGhpcy0+blN0cmVhbSk7CiAgICBicmVhazsKICB9OwoKICAvKiBhcHBlbmQgdG8gZW5kIG9mIHN0cmVhbT8gKi8KICBpZiAoc3RhcnQgPT0gLTEpIHsKICAgIGlmIChUaGlzLT5sTGFzdEZyYW1lID09IC0xKQogICAgICBzdGFydCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBlbHNlCiAgICAgIHN0YXJ0ID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgfSBlbHNlIGlmIChUaGlzLT5sTGFzdEZyYW1lID09IC0xKQogICAgVGhpcy0+c0luZm8uZHdTdGFydCA9IHN0YXJ0OwoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGZpeGVkIHNhbXBsZSBzaXplIC0tIGF1ZGlvIGxpa2UgKi8KICAgIGlmIChzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IGJ1ZmZlcnNpemUpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgLyogQ291bGRuJ3Qgc2tpcCBhdWRpby1saWtlIGRhdGEgLS0gVXNlciBtdXN0IHN1cHBseSBhcHByb3ByaWF0ZSBzaWxlbmNlICovCiAgICBpZiAoVGhpcy0+c0luZm8uZHdMZW5ndGggIT0gc3RhcnQpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogQ29udmVydCBwb3NpdGlvbiB0byBmcmFtZS9ibG9jayAqLwogICAgc3RhcnQgPSBUaGlzLT5sTGFzdEZyYW1lICsgMTsKCiAgICBpZiAoKFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQpID09IDApIHsKICAgICAgRklYTUUoIjogbm90IGludGVybGVhdmVkLCBjb3VsZCBjb2xsZWN0IGF1ZGlvIGRhdGEhXG4iKTsKICAgIH0KICB9IGVsc2UgewogICAgLyogdmFyaWFibGUgc2FtcGxlIHNpemUgLS0gdmlkZW8gbGlrZSAqLwogICAgaWYgKHNhbXBsZXMgPiAxKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIG11c3Qgd2UgZmlsbCB1cCB3aXRoIGVtcHR5IGZyYW1lcz8gKi8KICAgIGlmIChUaGlzLT5sTGFzdEZyYW1lICE9IC0xKSB7CiAgICAgIEZPVVJDQyBja2lkMiA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmNvbXByZXNzZWQsIFRoaXMtPm5TdHJlYW0pOwoKICAgICAgd2hpbGUgKHN0YXJ0ID4gVGhpcy0+bExhc3RGcmFtZSArIDEpIHsKCWhyID0gQVZJRklMRV9Xcml0ZUJsb2NrKFRoaXMsIFRoaXMtPmxMYXN0RnJhbWUgKyAxLCBja2lkMiwgMCwgTlVMTCwgMCk7CglpZiAoRkFJTEVEKGhyKSkKCSAgcmV0dXJuIGhyOwogICAgICB9CiAgICB9CiAgfQoKICAvKiB3cml0ZSB0aGUgYmxvY2sgbm93ICovCiAgaHIgPSBBVklGSUxFX1dyaXRlQmxvY2soVGhpcywgc3RhcnQsIGNraWQsIGZsYWdzLCBidWZmZXIsIGJ1ZmZlcnNpemUpOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAgICpzYW1wd3JpdHRlbiA9IHNhbXBsZXM7CiAgICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAgICpieXRlc3dyaXR0ZW4gPSBidWZmZXJzaXplOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgIExPTkcgc2FtcGxlcykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEZJWE1FKCIoJXAsJWQsJWQpOiBzdHViXG4iLCBpZmFjZSwgc3RhcnQsIHNhbXBsZXMpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKHN0YXJ0IDwgMCB8fCBzYW1wbGVzIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERlbGV0ZSBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtPyAqLwogIGlmIChzdGFydCArIHNhbXBsZXMgPCBUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRGVsZXRlIGFmdGVyIGVuZCBvZiBzdHJlYW0/ICovCiAgaWYgKHN0YXJ0ID4gVGhpcy0+c0luZm8uZHdMZW5ndGgpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBGb3IgdGhlIHJlc3Qgd2UgbmVlZCB3cml0ZSBwZXJtaXNzaW9ucyAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogMS4gb3ZlcndyaXRlIHRoZSBkYXRhIHdpdGggSlVOSwogICAqCiAgICogaWYgSVNJTlRFUkxFQVZFRCB7CiAgICogICAyLiBjb25jYXQgYWxsIG5laWdoYm91cmVkIEpVTkstYmxvY2tzIGluIHRoaXMgcmVjb3JkIHRvIG9uZQogICAqICAgMy4gaWYgdGhpcyByZWNvcmQgb25seSBjb250YWlucyBKVU5LIGFuZCBpcyBhdCBlbmQgc2V0IGR3TmV4dEZyYW1lUG9zCiAgICogICAgICB0byBzdGFydCBvZiB0aGlzIHJlY29yZCwgcmVwZWF0IHRoaXMuCiAgICogfSBlbHNlIHsKICAgKiAgIDIuIGNvbmNhdCBhbGwgbmVpZ2hib3VyZWQgSlVOSy1ibG9ja3MuCiAgICogICAzLiBpZiB0aGUgSlVOSyBibG9jayBpcyBhdCB0aGUgZW5kLCB0aGVuIHNldCBkd05leHRGcmFtZVBvcyB0bwogICAqICAgICAgc3RhcnQgb2YgdGhpcyBibG9jay4KICAgKiB9CiAgICovCgogIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZERhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgTFBWT0lEIGxwLCBMUExPTkcgbHByZWFkKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOFgsJXAsJXApXG4iLCBpZmFjZSwgZmNjLCBscCwgbHByZWFkKTsKCiAgaWYgKGZjYyA9PSBja2lkU1RSRUFNSEFORExFUkRBVEEpIHsKICAgIGlmIChUaGlzLT5scEhhbmRsZXJEYXRhICE9IE5VTEwgJiYgVGhpcy0+Y2JIYW5kbGVyRGF0YSA+IDApIHsKICAgICAgaWYgKGxwID09IE5VTEwgfHwgKmxwcmVhZCA8PSAwKSB7CgkqbHByZWFkID0gVGhpcy0+Y2JIYW5kbGVyRGF0YTsKCXJldHVybiBBVklFUlJfT0s7CiAgICAgIH0KCiAgICAgIG1lbWNweShscCwgVGhpcy0+bHBIYW5kbGVyRGF0YSwgbWluKFRoaXMtPmNiSGFuZGxlckRhdGEsICpscHJlYWQpKTsKICAgICAgaWYgKCpscHJlYWQgPCBUaGlzLT5jYkhhbmRsZXJEYXRhKQoJcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIH0gZWxzZQogICAgICByZXR1cm4gQVZJRVJSX05PREFUQTsKICB9IGVsc2UKICAgIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGZjYywgbHAsIGxwcmVhZCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgICBMUFZPSUQgbHAsIExPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDh4LCVwLCVkKVxuIiwgaWZhY2UsIGZjYywgbHAsIHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDw9IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIC8qIG5lZWQgd3JpdGUgcGVybWlzc2lvbiAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogYWxyZWFkeSB3cml0dGVuIHNvbWV0aGluZyB0byB0aGlzIGZpbGU/ICovCiAgaWYgKFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkgewogICAgLyogdGhlIGRhdGEgd2lsbCBiZSBpbnNlcnRlZCBiZWZvcmUgdGhlICdtb3ZpJyBjaHVuaywgc28gY2hlY2sgZm9yCiAgICAgKiBlbm91Z2ggc3BhY2UgKi8KICAgIERXT1JEIGR3UG9zID0gQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KFRoaXMtPnBhZik7CgogICAgLyogY2tpZCxzaXplID0+IDIgKiBzaXplb2YoRFdPUkQpICovCiAgICBkd1BvcyArPSAyICogc2l6ZW9mKERXT1JEKSArIHNpemU7CiAgICBpZiAoc2l6ZSA+PSBUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zIC0gMiAqIHNpemVvZihEV09SRCkpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7IC8qIG5vdCBlbm91Z2ggc3BhY2UgbGVmdCAqLwogIH0KCiAgVGhpcy0+cGFmLT5mRGlydHkgPSBUUlVFOwoKICBpZiAoZmNjID09IGNraWRTVFJFQU1IQU5ETEVSREFUQSkgewogICAgaWYgKFRoaXMtPmxwSGFuZGxlckRhdGEgIT0gTlVMTCkgewogICAgICBGSVhNRSgiOiBoYW5kbGVyIGRhdGEgYWxyZWFkeSBzZXQgLS0gb3ZlcndpcnRlP1xuIik7CiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgICB9CgogICAgVGhpcy0+bHBIYW5kbGVyRGF0YSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplKTsKICAgIGlmIChUaGlzLT5scEhhbmRsZXJEYXRhID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+Y2JIYW5kbGVyRGF0YSA9IHNpemU7CiAgICBtZW1jcHkoVGhpcy0+bHBIYW5kbGVyRGF0YSwgbHAsIHNpemUpOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gV3JpdGVFeHRyYUNodW5rKCZUaGlzLT5leHRyYSwgZmNjLCBscCwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkgICBMUEFWSVNUUkVBTUlORk9XIGluZm8sIExPTkcgaW5mb2xlbikKewogIEZJWE1FKCIoJXAsJXAsJWQpOiBzdHViXG4iLCBpZmFjZSwgaW5mbywgaW5mb2xlbik7CgogIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQWRkRnJhbWUoSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGNraWQsIERXT1JEIHNpemUsIERXT1JEIG9mZnNldCwgRFdPUkQgZmxhZ3MpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwoKICBzd2l0Y2ggKFRXT0NDRnJvbUZPVVJDQyhja2lkKSkgewogIGNhc2UgY2t0eXBlRElCYml0czoKICAgIGlmIChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19UUlVTVENLVFlQRSkKICAgICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CiAgICBicmVhazsKICBjYXNlIGNrdHlwZURJQmNvbXByZXNzZWQ6CiAgICBpZiAoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fVFJVU1RDS1RZUEUpCiAgICAgIGZsYWdzICY9IH5BVklJRl9LRVlGUkFNRTsKICAgIGJyZWFrOwogIGNhc2UgY2t0eXBlUEFMY2hhbmdlOgogICAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgIT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIEVSUigiOiBmb3VuZCBwYWxldHRlIGNoYW5nZSBpbiBub24tdmlkZW8gc3RyZWFtIVxuIik7CiAgICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwogICAgfQogICAgVGhpcy0+c0luZm8uZHdGbGFncyB8PSBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVM7CiAgICBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50Kys7CgogICAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXMgPT0gTlVMTCB8fCBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50IDwgVGhpcy0+bklkeEZtdENoYW5nZXMpIHsKICAgICAgVUlOVCBuID0gVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsKCiAgICAgIFRoaXMtPm5JZHhGbXRDaGFuZ2VzICs9IDE2OwogICAgICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlcyA9PSBOVUxMKQoJVGhpcy0+aWR4Rm10Q2hhbmdlcyA9CgkgIEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5uSWR4Rm10Q2hhbmdlcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGVsc2UKCVRoaXMtPmlkeEZtdENoYW5nZXMgPQoJICBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5pZHhGbXRDaGFuZ2VzLAoJCQkgICBUaGlzLT5uSWR4Rm10Q2hhbmdlcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZCAgICAgICAgICA9IFRoaXMtPmxMYXN0RnJhbWU7CiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uZHdGbGFncyAgICAgICA9IDA7CiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uZHdDaHVua09mZnNldCA9IG9mZnNldDsKICAgICAgVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5kd0NodW5rTGVuZ3RoID0gc2l6ZTsKCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9CiAgICBicmVhazsKICBjYXNlIGNrdHlwZVdBVkVieXRlczoKICAgIGlmIChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19UUlVTVENLVFlQRSkKICAgICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgV0FSTigiOiB1bmtub3duIFRXT0NDIDB4JTA0WCBmb3VuZFxuIiwgVFdPQ0NGcm9tRk9VUkNDKGNraWQpKTsKICAgIGJyZWFrOwogIH07CgogIC8qIGZpcnN0IGZyYW1lIGlzIGFsd2FzeSBhIGtleWZyYW1lICovCiAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPT0gLTEpCiAgICBmbGFncyB8PSBBVklJRl9LRVlGUkFNRTsKCiAgaWYgKFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA8IHNpemUpCiAgICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBzaXplOwoKICAvKiBnZXQgbWVtb3J5IGZvciBpbmRleCAqLwogIGlmIChUaGlzLT5pZHhGcmFtZXMgPT0gTlVMTCB8fCBUaGlzLT5sTGFzdEZyYW1lICsgMSA+PSBUaGlzLT5uSWR4RnJhbWVzKSB7CiAgICBUaGlzLT5uSWR4RnJhbWVzICs9IDUxMjsKICAgIGlmIChUaGlzLT5pZHhGcmFtZXMgPT0gTlVMTCkKICAgICAgVGhpcy0+aWR4RnJhbWVzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBlbHNlCglUaGlzLT5pZHhGcmFtZXMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5pZHhGcmFtZXMsCgkJCSAgIFRoaXMtPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgaWYgKFRoaXMtPmlkeEZyYW1lcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICB9CgogIFRoaXMtPmxMYXN0RnJhbWUrKzsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uY2tpZCAgICAgICAgICA9IGNraWQ7CiAgVGhpcy0+aWR4RnJhbWVzW1RoaXMtPmxMYXN0RnJhbWVdLmR3RmxhZ3MgICAgICAgPSBmbGFnczsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uZHdDaHVua09mZnNldCA9IG9mZnNldDsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uZHdDaHVua0xlbmd0aCA9IHNpemU7CgogIC8qIHVwZGF0ZSBBVklTVFJFQU1JTkZPIHN0cnVjdHVyZSBpZiBuZWNlc3NhcnkgKi8KICBpZiAoVGhpcy0+c0luZm8uZHdMZW5ndGggPD0gVGhpcy0+bExhc3RGcmFtZSkKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gVGhpcy0+bExhc3RGcmFtZSArIDE7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQWRkUmVjb3JkKElBVklGaWxlSW1wbCAqVGhpcykKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCAmJiBUaGlzLT5wcFN0cmVhbXNbMF0gIT0gTlVMTCk7CgogIGlmIChUaGlzLT5pZHhSZWNvcmRzID09IE5VTEwgfHwgVGhpcy0+Y2JJZHhSZWNvcmRzID09IDApIHsKICAgIFRoaXMtPmNiSWR4UmVjb3JkcyArPSAxMDI0ICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpOwogICAgVGhpcy0+aWR4UmVjb3JkcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5jYklkeFJlY29yZHMpOwogICAgaWYgKFRoaXMtPmlkeFJlY29yZHMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgfQoKICBhc3NlcnQoVGhpcy0+bklkeFJlY29yZHMgPCBUaGlzLT5jYklkeFJlY29yZHMvc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKCiAgVGhpcy0+aWR4UmVjb3Jkc1tUaGlzLT5uSWR4UmVjb3Jkc10uY2tpZCAgICAgICAgICA9IGxpc3R0eXBlQVZJUkVDT1JEOwogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmR3RmxhZ3MgICAgICAgPSBBVklJRl9MSVNUOwogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmR3Q2h1bmtPZmZzZXQgPQogICAgVGhpcy0+Y2tMYXN0UmVjb3JkLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpOwogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmR3Q2h1bmtMZW5ndGggPQogICAgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZTsKICBUaGlzLT5uSWR4UmVjb3JkcysrOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgRFdPUkQgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgRFdPUkQgZHdQb3M7CiAgRFdPUkQgblN0cmVhbTsKCiAgLyogUklGRixoZHJsLG1vdmksYXZpaCA9PiAoMyAqIDMgKyAyKSAqIHNpemVvZihEV09SRCkgPSAxMSAqIHNpemVvZihEV09SRCkgKi8KICBkd1BvcyA9IDExICogc2l6ZW9mKERXT1JEKSArIHNpemVvZihNYWluQVZJSGVhZGVyKTsKCiAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICBJQVZJU3RyZWFtSW1wbCAqcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKCiAgICAvKiBzdHJsLHN0cmgsc3RyZiA9PiAoMyArIDIgKiAyKSAqIHNpemVvZihEV09SRCkgPSA3ICogc2l6ZW9mKERXT1JEKSAqLwogICAgZHdQb3MgKz0gNyAqIHNpemVvZihEV09SRCkgKyBzaXplb2YoQVZJU3RyZWFtSGVhZGVyKTsKICAgIGR3UG9zICs9ICgocFN0cmVhbS0+Y2JGb3JtYXQgKyAxKSAmIH4xVSk7CiAgICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgPiAwKQogICAgICBkd1BvcyArPSAyICogc2l6ZW9mKERXT1JEKSArICgocFN0cmVhbS0+Y2JIYW5kbGVyRGF0YSArIDEpICYgfjFVKTsKICAgIGlmIChsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpID4gMCkKICAgICAgZHdQb3MgKz0gMiAqIHNpemVvZihEV09SRCkgKyAoKGxzdHJsZW5XKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkgKyAxKSAmIH4xVSk7CiAgfQoKICBpZiAoVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPT0gMCkgewogICAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgPSBkd1BvczsKCiAgICAvKiBwYWQgdG8gbXVsdGlwbGUgb2YgQVZJX0hFQURFUlNJWkUgb25seSBpZiB3ZSBhcmUgbW9yZSB0aGFuIDggYnl0ZXMgYXdheSBmcm9tIGl0ICovCiAgICBpZiAoKChkd1BvcyArIEFWSV9IRUFERVJTSVpFKSAmIH4oQVZJX0hFQURFUlNJWkUgLSAxKSkgLSBkd1BvcyA+IDIgKiBzaXplb2YoRFdPUkQpKQogICAgICBUaGlzLT5kd05leHRGcmFtZVBvcyA9IChkd1BvcyArIEFWSV9IRUFERVJTSVpFKSAmIH4oQVZJX0hFQURFUlNJWkUgLSAxKTsKCiAgICBUaGlzLT5kd01vdmlDaHVua1BvcyA9IFRoaXMtPmR3TmV4dEZyYW1lUG9zIC0gc2l6ZW9mKERXT1JEKTsKICB9CgogIHJldHVybiBkd1BvczsKfQoKc3RhdGljIHZvaWQgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oSUFWSUZpbGVJbXBsICpwYWYsIERXT1JEIG5yLCBjb25zdCBBVklTVFJFQU1JTkZPVyAqYXNpKQp7CiAgSUFWSVN0cmVhbUltcGwgKnBzdHJlYW07CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KHBhZiAhPSBOVUxMKTsKICBhc3NlcnQobnIgPCBNQVhfQVZJU1RSRUFNUyk7CiAgYXNzZXJ0KHBhZi0+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+aG1taW8sICZjaywgJmNrUklGRiwgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEluZGV4KGNvbnN0IElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgc2l6ZSwgRFdPUkQgb2Zmc2V0KQp7CiAgQVZJSU5ERVhFTlRSWSAqbHA7CiAgRFdPUkQgICAgICAgICAgcG9zLCBuOwogIEhSRVNVTFQgICAgICAgIGhyID0gQVZJRVJSX09LOwogIEJPT0wgICAgICAgICAgIGJBYnNvbHV0ZSA9IFRSVUU7CgogIGxwID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIElEWF9QRVJfQkxPQ0sgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIC8qIGFkanVzdCBsaW1pdHMgZm9yIGluZGV4IHRhYmxlcywgc28gdGhhdCBpbnNlcnRpbmcgd2lsbCBiZSBmYXN0ZXIgKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuKyspIHsKICAgIElBVklTdHJlYW1JbXBsICpwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25dOwoKICAgIHBTdHJlYW0tPmxMYXN0RnJhbWUgPSAtMTsKCiAgICBpZiAocFN0cmVhbS0+aWR4RnJhbWVzICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcFN0cmVhbS0+aWR4RnJhbWVzKTsKICAgICAgcFN0cmVhbS0+aWR4RnJhbWVzICA9IE5VTEw7CiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSAwOwogICAgfQoKICAgIGlmIChwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgICBpZiAobiA+IDAgJiYgVGhpcy0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQpIHsKCXBTdHJlYW0tPm5JZHhGcmFtZXMgPSBUaGlzLT5wcFN0cmVhbXNbMF0tPm5JZHhGcmFtZXM7CiAgICAgIH0gZWxzZSBpZiAocFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKSB7CglwU3RyZWFtLT5uSWR4RnJhbWVzID0KCSAgcFN0cmVhbS0+c0luZm8uZHdMZW5ndGggLyBwU3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgICAgIH0KICAgIH0gZWxzZQogICAgICBwU3RyZWFtLT5uSWR4RnJhbWVzID0gcFN0cmVhbS0+c0luZm8uZHdMZW5ndGg7CgogICAgcFN0cmVhbS0+aWR4RnJhbWVzID0KICAgICAgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHBTdHJlYW0tPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgaWYgKHBTdHJlYW0tPmlkeEZyYW1lcyA9PSBOVUxMICYmIHBTdHJlYW0tPm5JZHhGcmFtZXMgPiAwKSB7CiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSAwOwogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscCk7CiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgfQogIH0KCiAgcG9zID0gKERXT1JEKS0xOwogIHdoaWxlIChzaXplICE9IDApIHsKICAgIExPTkcgcmVhZCA9IG1pbihJRFhfUEVSX0JMT0NLICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpLCBzaXplKTsKCiAgICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilscCwgcmVhZCkgIT0gcmVhZCkgewogICAgICBociA9IEFWSUVSUl9GSUxFUkVBRDsKICAgICAgYnJlYWs7CiAgICB9CiAgICBzaXplIC09IHJlYWQ7CgogICAgaWYgKHBvcyA9PSAoRFdPUkQpLTEpCiAgICAgIHBvcyA9IG9mZnNldCAtIGxwLT5kd0NodW5rT2Zmc2V0ICsgc2l6ZW9mKERXT1JEKTsKCiAgICBBVklGSUxFX1BhcnNlSW5kZXgoVGhpcywgbHAsIHJlYWQgLyBzaXplb2YoQVZJSU5ERVhFTlRSWSksCgkJICAgICAgIHBvcywgJmJBYnNvbHV0ZSk7CiAgfQoKICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBscCk7CgogIC8qIGNoZWNraW5nIC4uLiAqLwogIGZvciAobiA9IDA7IG4gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG4rKykgewogICAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbbl07CgogICAgaWYgKHBTdHJlYW0tPnNJbmZvLmR3U2FtcGxlU2l6ZSA9PSAwICYmCglwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCAhPSBwU3RyZWFtLT5sTGFzdEZyYW1lKzEpCiAgICAgIEVSUigic3RyZWFtICV1IGxlbmd0aCBtaXNtYXRjaDogZHdMZW5ndGg9JXUgZm91bmQ9JWRcbiIsCgkgICBuLCBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCwgcFN0cmVhbS0+bExhc3RGcmFtZSk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUGFyc2VJbmRleChjb25zdCBJQVZJRmlsZUltcGwgKlRoaXMsIEFWSUlOREVYRU5UUlkgKmxwLAoJCQkJICBMT05HIGNvdW50LCBEV09SRCBwb3MsIEJPT0wgKmJBYnNvbHV0ZSkKewogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgZm9yICg7IGNvdW50ID4gMDsgY291bnQtLSwgbHArKykgewogICAgV09SRCBuU3RyZWFtID0gU3RyZWFtRnJvbUZPVVJDQyhscC0+Y2tpZCk7CgogICAgaWYgKGxwLT5ja2lkID09IGxpc3R0eXBlQVZJUkVDT1JEIHx8IG5TdHJlYW0gPT0gMHg3RikKICAgICAgY29udGludWU7IC8qIHNraXAgdGhlc2UgKi8KCiAgICBpZiAoblN0cmVhbSA+IFRoaXMtPmZJbmZvLmR3U3RyZWFtcykKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogICAgaWYgKCpiQWJzb2x1dGUgJiYgbHAtPmR3Q2h1bmtPZmZzZXQgPCBUaGlzLT5kd01vdmlDaHVua1BvcykKICAgICAgKmJBYnNvbHV0ZSA9IEZBTFNFOwoKICAgIGlmICgqYkFic29sdXRlKQogICAgICBscC0+ZHdDaHVua09mZnNldCArPSBzaXplb2YoRFdPUkQpOwogICAgZWxzZQogICAgICBscC0+ZHdDaHVua09mZnNldCArPSBwb3M7CgogICAgaWYgKEZBSUxFRChBVklGSUxFX0FkZEZyYW1lKFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSwgbHAtPmNraWQsIGxwLT5kd0NodW5rTGVuZ3RoLCBscC0+ZHdDaHVua09mZnNldCwgbHAtPmR3RmxhZ3MpKSkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1JlYWRCbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgcG9zLAoJCQkJIExQVk9JRCBidWZmZXIsIExPTkcgc2l6ZSkKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cGFmLT5obW1pbyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+c0luZm8uZHdTdGFydCA8PSBwb3MgJiYgcG9zIDwgVGhpcy0+c0luZm8uZHdMZW5ndGgpOwogIGFzc2VydChwb3MgPD0gVGhpcy0+bExhc3RGcmFtZSk7CgogIC8qIHNob3VsZCB3ZSByZWFkIGFzIG11Y2ggYXMgYmxvY2sgZ2l2ZXMgdXM/ICovCiAgaWYgKHNpemUgPT0gMCB8fCBzaXplID4gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCkKICAgIHNpemUgPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoOwoKICAvKiByZWFkIGludG8gb3V0IG93biBidWZmZXIgb3IgZ2l2ZW4gb25lPyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCkgewogICAgLyogd2UgYWxzbyByZWFkIHRoZSBjaHVuayAqLwogICAgc2l6ZSArPSAyICogc2l6ZW9mKERXT1JEKTsKCiAgICAvKiBjaGVjayB0aGF0IGJ1ZmZlciBpcyBiaWcgZW5vdWdoIC0tIGRvbid0IHRydXN0IGR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSAqLwogICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwgfHwgc2l6ZSA8IFRoaXMtPmNiQnVmZmVyKSB7CiAgICAgIERXT1JEIG1heFNpemUgPSBtYXgoc2l6ZSwgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKCiAgICAgIGlmIChUaGlzLT5scEJ1ZmZlciA9PSBOVUxMKQoJVGhpcy0+bHBCdWZmZXIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbWF4U2l6ZSk7CiAgICAgIGVsc2UKCVRoaXMtPmxwQnVmZmVyID0gSGVhcFJlQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBCdWZmZXIsIG1heFNpemUpOwogICAgICBpZiAoVGhpcy0+bHBCdWZmZXIgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBUaGlzLT5jYkJ1ZmZlciA9IG1heChzaXplLCBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwogICAgfQoKICAgIC8qIG5vdyByZWFkIHRoZSBjb21wbGV0ZSBjaHVuayBpbnRvIG91ciBidWZmZXIgKi8KICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rT2Zmc2V0LCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICBpZiAobW1pb1JlYWQoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKVRoaXMtPmxwQnVmZmVyLCBzaXplKSAhPSBzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAgIC8qIGNoZWNrIGlmIGl0IHdhcyB0aGUgY29ycmVjdCBibG9jayB3aGljaCB3ZSBoYXZlIHJlYWQgKi8KICAgIGlmIChUaGlzLT5scEJ1ZmZlclswXSAhPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5ja2lkIHx8CglUaGlzLT5scEJ1ZmZlclsxXSAhPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoKSB7CiAgICAgIEVSUigiOiBibG9jayAlZCBub3QgZm91bmQgYXQgMHglMDhYXG4iLCBwb3MsIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQpOwogICAgICBFUlIoIjogSW5kZXggc2F5czogJyU0LjRzJygweCUwOFgpIHNpemUgMHglMDhYXG4iLAoJICAoY2hhciopJlRoaXMtPmlkeEZyYW1lc1twb3NdLmNraWQsIFRoaXMtPmlkeEZyYW1lc1twb3NdLmNraWQsCgkgIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGgpOwogICAgICBFUlIoIjogRGF0YSAgc2F5czogJyU0LjRzJygweCUwOFgpIHNpemUgMHglMDhYXG4iLAoJICAoY2hhciopJlRoaXMtPmxwQnVmZmVyWzBdLCBUaGlzLT5scEJ1ZmZlclswXSwgVGhpcy0+bHBCdWZmZXJbMV0pOwogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgfQogIH0gZWxzZSB7CiAgICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICBpZiAobW1pb1JlYWQoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgc2l6ZSkgIT0gc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyB2b2lkIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soY29uc3QgSUFWSVN0cmVhbUltcGwgKlRoaXMsIExQTE9ORyBwb3MsIExQTE9ORyBvZmZzZXQpCnsKICBMT05HIGJsb2NrOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGFzc2VydChwb3MgIT0gTlVMTCk7CiAgYXNzZXJ0KG9mZnNldCAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApOwogIGFzc2VydCgqcG9zID49IFRoaXMtPnNJbmZvLmR3U3RhcnQpOwoKICAvKiBjb252ZXJ0IHN0YXJ0IHNhbXBsZSB0byBzdGFydCBieXRlcyAqLwogICgqb2Zmc2V0KSAgPSAoKnBvcykgLSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICgqb2Zmc2V0KSAqPSBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CgogIC8qIGNvbnZlcnQgYnl0ZXMgdG8gYmxvY2sgbnVtYmVyICovCiAgZm9yIChibG9jayA9IDA7IGJsb2NrIDw9IFRoaXMtPmxMYXN0RnJhbWU7IGJsb2NrKyspIHsKICAgIGlmIChUaGlzLT5pZHhGcmFtZXNbYmxvY2tdLmR3Q2h1bmtMZW5ndGggPD0gKm9mZnNldCkKICAgICAgKCpvZmZzZXQpIC09IFRoaXMtPmlkeEZyYW1lc1tibG9ja10uZHdDaHVua0xlbmd0aDsKICAgIGVsc2UKICAgICAgYnJlYWs7CiAgfQoKICAqcG9zID0gYmxvY2s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgTWFpbkFWSUhlYWRlciAgIE1haW5BVklIZHI7CiAgSUFWSVN0cmVhbUltcGwqIHBTdHJlYW07CiAgTU1DS0lORk8gICAgICAgIGNrUklGRjsKICBNTUNLSU5GTyAgICAgICAgY2tMSVNUMTsKICBNTUNLSU5GTyAgICAgICAgY2tMSVNUMjsKICBNTUNLSU5GTyAgICAgICAgY2s7CiAgRFdPUkQgICAgICAgICAgIG5TdHJlYW07CiAgRFdPUkQgICAgICAgICAgIGR3UG9zOwogIEhSRVNVTFQgICAgICAgICBocjsKCiAgLyogaW5pdGlhbGl6ZSBzb21lIHRoaW5ncyAqLwogIGlmIChUaGlzLT5kd01vdmlDaHVua1BvcyA9PSAwKQogICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KFRoaXMpOwoKICAvKiB3cml0dGVuIG9uZSByZWNvcmQgdG8gbXVjaD8gKi8KICBpZiAoVGhpcy0+Y2tMYXN0UmVjb3JkLmR3RmxhZ3MgJiBNTUlPX0RJUlRZKSB7CiAgICBUaGlzLT5kd05leHRGcmFtZVBvcyAtPSAzICogc2l6ZW9mKERXT1JEKTsKICAgIGlmIChUaGlzLT5uSWR4UmVjb3JkcyA+IDApCiAgICAgIFRoaXMtPm5JZHhSZWNvcmRzLS07CiAgfQoKICBBVklGSUxFX1VwZGF0ZUluZm8oVGhpcyk7CgogIGFzc2VydChUaGlzLT5mSW5mby5kd1NjYWxlICE9IDApOwoKICBtZW1zZXQoJk1haW5BVklIZHIsIDAsIHNpemVvZihNYWluQVZJSGRyKSk7CiAgTWFpbkFWSUhkci5kd01pY3JvU2VjUGVyRnJhbWUgICAgPSBNdWxEaXYoVGhpcy0+ZkluZm8uZHdSYXRlLCAxMDAwMDAwLAoJCQkJCSAgICBUaGlzLT5mSW5mby5kd1NjYWxlKTsKICBNYWluQVZJSGRyLmR3TWF4Qnl0ZXNQZXJTZWMgICAgICA9IFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWM7CiAgTWFpbkFWSUhkci5kd1BhZGRpbmdHcmFudWxhcml0eSAgPSBBVklfSEVBREVSU0laRTsKICBNYWluQVZJSGRyLmR3RmxhZ3MgICAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3RmxhZ3M7CiAgTWFpbkFWSUhkci5kd1RvdGFsRnJhbWVzICAgICAgICAgPSBUaGlzLT5mSW5mby5kd0xlbmd0aDsKICBNYWluQVZJSGRyLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IDA7CiAgTWFpbkFWSUhkci5kd1N0cmVhbXMgICAgICAgICAgICAgPSBUaGlzLT5mSW5mby5kd1N0cmVhbXM7CiAgTWFpbkFWSUhkci5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgTWFpbkFWSUhkci5kd1dpZHRoICAgICAgICAgICAgICAgPSBUaGlzLT5mSW5mby5kd1dpZHRoOwogIE1haW5BVklIZHIuZHdIZWlnaHQgICAgICAgICAgICAgID0gVGhpcy0+ZkluZm8uZHdIZWlnaHQ7CiAgTWFpbkFWSUhkci5kd0luaXRpYWxGcmFtZXMgICAgICAgPSBUaGlzLT5kd0luaXRpYWxGcmFtZXM7CgogIC8qIG5vdyBiZWdpbiB3cml0aW5nIC4uLiAqLwogIG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX1NFVCk7CgogIC8qIFJJRkYgY2h1bmsgKi8KICBja1JJRkYuY2tzaXplICA9IDA7CiAgY2tSSUZGLmZjY1R5cGUgPSBmb3JtdHlwZUFWSTsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCBNTUlPX0NSRUFURVJJRkYpICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogQVZJIGhlYWRlcmxpc3QgKi8KICBja0xJU1QxLmNrc2l6ZSAgPSAwOwogIGNrTElTVDEuZmNjVHlwZSA9IGxpc3R0eXBlQVZJSEVBREVSOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja0xJU1QxLCBNTUlPX0NSRUFURUxJU1QpICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogTWFpbkFWSUhlYWRlciAqLwogIGNrLmNraWQgICAgPSBja2lkQVZJTUFJTkhEUjsKICBjay5ja3NpemUgID0gc2l6ZW9mKE1haW5BVklIZHIpOwogIGNrLmZjY1R5cGUgPSAwOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmTWFpbkFWSUhkciwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHdyaXRlIHRoZSBoZWFkZXJzIG9mIGVhY2ggc3RyZWFtIGludG8gYSBzZXBhcmF0ZSBzdHJlYW1oZWFkZXIgbGlzdCAqLwogIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgQVZJU3RyZWFtSGVhZGVyIHN0ckhkcjsKCiAgICBwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwoKICAgIC8qIGJlZ2luIHRoZSBuZXcgc3RyZWFtaGVhZGVyIGxpc3QgKi8KICAgIGNrTElTVDIuY2tzaXplICA9IDA7CiAgICBja0xJU1QyLmZjY1R5cGUgPSBsaXN0dHlwZVNUUkVBTUhFQURFUjsKICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja0xJU1QyLCBNTUlPX0NSRUFURUxJU1QpICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIC8qIGNyZWF0ZSBhbiBBVklTdHJlYW1IZWFkZXIgZnJvbSB0aGUgQVZTVFJFQU1JTkZPICovCiAgICBzdHJIZHIuZmNjVHlwZSAgICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZmNjVHlwZTsKICAgIHN0ckhkci5mY2NIYW5kbGVyICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyOwogICAgc3RySGRyLmR3RmxhZ3MgICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3RmxhZ3M7CiAgICBzdHJIZHIud1ByaW9yaXR5ICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8ud1ByaW9yaXR5OwogICAgc3RySGRyLndMYW5ndWFnZSAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLndMYW5ndWFnZTsKICAgIHN0ckhkci5kd0luaXRpYWxGcmFtZXMgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd0luaXRpYWxGcmFtZXM7CiAgICBzdHJIZHIuZHdTY2FsZSAgICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdTY2FsZTsKICAgIHN0ckhkci5kd1JhdGUgICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1JhdGU7CiAgICBzdHJIZHIuZHdTdGFydCAgICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdTdGFydDsKICAgIHN0ckhkci5kd0xlbmd0aCAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aDsKICAgIHN0ckhkci5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBwU3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgICBzdHJIZHIuZHdRdWFsaXR5ICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdRdWFsaXR5OwogICAgc3RySGRyLmR3U2FtcGxlU2l6ZSAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIHN0ckhkci5yY0ZyYW1lLmxlZnQgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLmxlZnQ7CiAgICBzdHJIZHIucmNGcmFtZS50b3AgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8ucmNGcmFtZS50b3A7CiAgICBzdHJIZHIucmNGcmFtZS5yaWdodCAgICAgICAgID0gcFN0cmVhbS0+c0luZm8ucmNGcmFtZS5yaWdodDsKICAgIHN0ckhkci5yY0ZyYW1lLmJvdHRvbSAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLmJvdHRvbTsKCiAgICAvKiBub3cgd3JpdGUgdGhlIEFWSVN0cmVhbUhlYWRlciAqLwogICAgY2suY2tpZCAgID0gY2tpZFNUUkVBTUhFQURFUjsKICAgIGNrLmNrc2l6ZSA9IHNpemVvZihzdHJIZHIpOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmc3RySGRyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICAvKiAuLi4gdGhlIGhvcGVmdWxseSBldmVyIHByZXNlbnQgc3RyZWFtZm9ybWF0IC4uLiAqLwogICAgY2suY2tpZCAgID0gY2tpZFNUUkVBTUZPUk1BVDsKICAgIGNrLmNrc2l6ZSA9IHBTdHJlYW0tPmNiRm9ybWF0OwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChwU3RyZWFtLT5scEZvcm1hdCAhPSBOVUxMICYmIGNrLmNrc2l6ZSA+IDApIHsKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKXBTdHJlYW0tPmxwRm9ybWF0LCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfQogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgLyogLi4uIHNvbWUgb3B0aW9uYWwgZXhpc3RpbmcgaGFuZGxlciBkYXRhIC4uLiAqLwogICAgaWYgKHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgIT0gTlVMTCAmJiBwU3RyZWFtLT5jYkhhbmRsZXJEYXRhID4gMCkgewogICAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNSEFORExFUkRBVEE7CiAgICAgIGNrLmNrc2l6ZSA9IHBTdHJlYW0tPmNiSGFuZGxlckRhdGE7CiAgICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+bHBIYW5kbGVyRGF0YSwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfQoKICAgIC8qIC4uLiBzb21lIG9wdGlvbmFsIGFkZGl0aW9uYWwgZXh0cmEgY2h1bmsgZm9yIHRoaXMgc3RyZWFtIC4uLiAqLwogICAgaWYgKHBTdHJlYW0tPmV4dHJhLmxwICE9IE5VTEwgJiYgcFN0cmVhbS0+ZXh0cmEuY2IgPiAwKSB7CiAgICAgIC8qIHRoZSBjaHVuayBoZWFkZXIocykgYXJlIGFscmVhZHkgaW4gdGhlIHN0cnVjdXR1cmUgKi8KICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKXBTdHJlYW0tPmV4dHJhLmxwLCBwU3RyZWFtLT5leHRyYS5jYikgIT0gcFN0cmVhbS0+ZXh0cmEuY2IpCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0KCiAgICAvKiAuLi4gYW4gb3B0aW9uYWwgbmFtZSBmb3IgdGhpcyBzdHJlYW0gLi4uICovCiAgICBpZiAobHN0cmxlblcocFN0cmVhbS0+c0luZm8uc3pOYW1lKSA+IDApIHsKICAgICAgTFBTVFIgc3RyOwoKICAgICAgY2suY2tpZCAgID0gY2tpZFNUUkVBTU5BTUU7CiAgICAgIGNrLmNrc2l6ZSA9IGxzdHJsZW5XKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkgKyAxOwogICAgICBpZiAoY2suY2tzaXplICYgMSkgLyogYWxpZ24gKi8KCWNrLmNrc2l6ZSsrOwogICAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICAgIC8qIHRoZSBzdHJlYW1uYW1lIG11c3QgYmUgc2F2ZWQgaW4gQVNDSUkgbm90IFVuaWNvZGUgKi8KICAgICAgc3RyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGNrLmNrc2l6ZSk7CiAgICAgIGlmIChzdHIgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgcFN0cmVhbS0+c0luZm8uc3pOYW1lLCAtMSwgc3RyLAoJCQkgIGNrLmNrc2l6ZSwgTlVMTCwgTlVMTCk7CgogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpc3RyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkgewoJSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyKTsJCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgfQoKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc3RyKTsKICAgICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfQoKICAgIC8qIGNsb3NlIHN0cmVhbWhlYWRlciBsaXN0IGZvciB0aGlzIHN0cmVhbSAqLwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QyLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9IC8qIGZvciAoMCA8PSBuU3RyZWFtIDwgTWFpbkFWSUhkci5kd1N0cmVhbXMpICovCgogIC8qIGNsb3NlIHRoZSBhdmloZWFkZXIgbGlzdCAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBjaGVjayBmb3IgcGFkZGluZyB0byBwcmUtZ3Vlc3NlZCAnbW92aSctY2h1bmsgcG9zaXRpb24gKi8KICBkd1BvcyA9IGNrTElTVDEuZHdEYXRhT2Zmc2V0ICsgY2tMSVNUMS5ja3NpemU7CiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zIC0gMiAqIHNpemVvZihEV09SRCkgPiBkd1BvcykgewogICAgY2suY2tpZCAgID0gY2tpZEFWSVBBRERJTkc7CiAgICBjay5ja3NpemUgPSBUaGlzLT5kd01vdmlDaHVua1BvcyAtIGR3UG9zIC0gNCAqIHNpemVvZihEV09SRCk7CiAgICBhc3NlcnQoKExPTkcpY2suY2tzaXplID49IDApOwoKICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIGNrLmNrc2l6ZSwgU0VFS19DVVIpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogbm93IHdyaXRlIHRoZSAnbW92aScgY2h1bmsgKi8KICBtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgLSAyICogc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpOwogIGNrTElTVDEuY2tzaXplICA9IDA7CiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklNT1ZJRTsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgTU1JT19DUkVBVEVMSVNUKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIHdyaXRlICdpZHgxJyBjaHVuayAqLwogIGhyID0gQVZJRklMRV9TYXZlSW5kZXgoVGhpcyk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIC8qIHdyaXRlIG9wdGlvbmFsIGV4dHJhIGZpbGUgY2h1bmtzICovCiAgaWYgKFRoaXMtPmZpbGVleHRyYS5scCAhPSBOVUxMICYmIFRoaXMtPmZpbGVleHRyYS5jYiA+IDApIHsKICAgIC8qIGFzIGZvciB0aGUgc3RyZWFtcywgYXJlIHRoZSBjaHVuayBoZWFkZXIocykgaW4gdGhlIHN0cnVjdHVyZSAqLwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKVRoaXMtPmZpbGVleHRyYS5scCwgVGhpcy0+ZmlsZWV4dHJhLmNiKSAhPSBUaGlzLT5maWxlZXh0cmEuY2IpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KCiAgLyogY2xvc2UgUklGRiBjaHVuayAqLwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tSSUZGLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIGFkZCBzb21lIEpVTksgYXQgZW5kIGZvciBiYWQgcGFyc2VycyAqLwogIG1lbXNldCgmY2tSSUZGLCAwLCBzaXplb2YoY2tSSUZGKSk7CiAgbW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmNrUklGRiwgc2l6ZW9mKGNrUklGRikpOwogIG1taW9GbHVzaChUaGlzLT5obW1pbywgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUluZGV4KGNvbnN0IElBVklGaWxlSW1wbCAqVGhpcykKewogIElBVklTdHJlYW1JbXBsICpwU3RyZWFtOwogIEFWSUlOREVYRU5UUlkgICBpZHg7CiAgTU1DS0lORk8gICAgICAgIGNrOwogIERXT1JEICAgICAgICAgICBuU3RyZWFtOwogIExPTkcgICAgICAgICAgICBuOwoKICBjay5ja2lkICAgPSBja2lkQVZJTkVXSU5ERVg7CiAgY2suY2tzaXplID0gMDsKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgaWYgKFRoaXMtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEKSB7CiAgICAvKiBpcyBpbnRlcmxlYXZlZCAtLSB3cml0ZSBibG9jayBvZiBjb3Jlc3BvbmRpbmcgZnJhbWVzICovCiAgICBMT05HIGxJbml0aWFsRnJhbWVzID0gMDsKICAgIExPTkcgc3RlcHNpemU7CiAgICBMT05HIGk7CgogICAgaWYgKFRoaXMtPnBwU3RyZWFtc1swXS0+c0luZm8uZHdTYW1wbGVTaXplID09IDApCiAgICAgIHN0ZXBzaXplID0gMTsKICAgIGVsc2UKICAgICAgc3RlcHNpemUgPSBBVklTdHJlYW1UaW1lVG9TYW1wbGUoKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zWzBdLCAxMDAwMDAwKTsKCiAgICBhc3NlcnQoc3RlcHNpemUgPiAwKTsKCiAgICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKICAgICAgaWYgKGxJbml0aWFsRnJhbWVzIDwgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd0luaXRpYWxGcmFtZXMpCglsSW5pdGlhbEZyYW1lcyA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+c0luZm8uZHdJbml0aWFsRnJhbWVzOwogICAgfQoKICAgIGZvciAoaSA9IC1sSW5pdGlhbEZyYW1lczsgaSA8IChMT05HKVRoaXMtPmZJbmZvLmR3TGVuZ3RoIC0gbEluaXRpYWxGcmFtZXM7CgkgaSArPSBzdGVwc2l6ZSkgewogICAgICBEV09SRCBuRnJhbWUgPSBsSW5pdGlhbEZyYW1lcyArIGk7CgogICAgICBhc3NlcnQobkZyYW1lIDwgVGhpcy0+bklkeFJlY29yZHMpOwoKICAgICAgaWR4LmNraWQgICAgICAgICAgPSBsaXN0dHlwZUFWSVJFQ09SRDsKICAgICAgaWR4LmR3RmxhZ3MgICAgICAgPSBBVklJRl9MSVNUOwogICAgICBpZHguZHdDaHVua0xlbmd0aCA9IFRoaXMtPmlkeFJlY29yZHNbbkZyYW1lXS5kd0NodW5rTGVuZ3RoOwogICAgICBpZHguZHdDaHVua09mZnNldCA9IFRoaXMtPmlkeFJlY29yZHNbbkZyYW1lXS5kd0NodW5rT2Zmc2V0CgktIFRoaXMtPmR3TW92aUNodW5rUG9zOwogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKCXBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgoJLyogaGVhdmUgd2UgcmVhY2hlZCBzdGFydCBvZiB0aGlzIHN0cmVhbT8gKi8KCWlmICgtKExPTkcpcFN0cmVhbS0+c0luZm8uZHdJbml0aWFsRnJhbWVzID4gaSkKCSAgY29udGludWU7CgoJaWYgKHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyA8IGxJbml0aWFsRnJhbWVzKQoJICBuRnJhbWUgLT0gKGxJbml0aWFsRnJhbWVzIC0gcFN0cmVhbS0+c0luZm8uZHdJbml0aWFsRnJhbWVzKTsKCgkvKiByZWFjaGVkIGVuZCBvZiB0aGlzIHN0cmVhbT8gKi8KCWlmIChwU3RyZWFtLT5sTGFzdEZyYW1lIDw9IG5GcmFtZSkKCSAgY29udGludWU7CgoJaWYgKChwU3RyZWFtLT5zSW5mby5kd0ZsYWdzICYgQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTKSAmJgoJICAgIHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgIT0gMCAmJgoJICAgIHBTdHJlYW0tPmlkeEZtdENoYW5nZXMgIT0gTlVMTCkgewoJICBEV09SRCBwb3M7CgoJICBmb3IgKHBvcyA9IDA7IHBvcyA8IHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7IHBvcysrKSB7CgkgICAgaWYgKHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5ja2lkID09IG5GcmFtZSkgewoJICAgICAgaWR4LmR3RmxhZ3MgPSBBVklJRl9OT1RJTUU7CgkgICAgICBpZHguY2tpZCAgICA9IE1BS0VBVklDS0lEKGNrdHlwZVBBTGNoYW5nZSwgcFN0cmVhbS0+blN0cmVhbSk7CgkgICAgICBpZHguZHdDaHVua0xlbmd0aCA9IHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5kd0NodW5rTGVuZ3RoOwoJICAgICAgaWR4LmR3Q2h1bmtPZmZzZXQgPSBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua09mZnNldAoJCS0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CgoJICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCQlyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCSAgICAgIGJyZWFrOwoJICAgIH0KCSAgfQoJfSAvKiBpZiBoYXZlIGZvcm1hdGNoYW5nZXMgKi8KCglpZHguY2tpZCAgICAgICAgICA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuRnJhbWVdLmNraWQ7CglpZHguZHdGbGFncyAgICAgICA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuRnJhbWVdLmR3RmxhZ3M7CglpZHguZHdDaHVua0xlbmd0aCA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuRnJhbWVdLmR3Q2h1bmtMZW5ndGg7CglpZHguZHdDaHVua09mZnNldCA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuRnJhbWVdLmR3Q2h1bmtPZmZzZXQKCSAgLSBUaGlzLT5kd01vdmlDaHVua1BvczsKCWlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCgkgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICB9CiAgICB9CiAgfSBlbHNlIHsKICAgIC8qIG5vdCBpbnRlcmxlYXZlZCAtLSB3cml0ZSBpbmRleCBmb3IgZWFjaCBzdHJlYW0gYXQgb25jZSAqLwogICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICAgIHBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgogICAgICBmb3IgKG4gPSAwOyBuIDw9IHBTdHJlYW0tPmxMYXN0RnJhbWU7IG4rKykgewoJaWYgKChwU3RyZWFtLT5zSW5mby5kd0ZsYWdzICYgQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTKSAmJgoJICAgIChwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ICE9IDApKSB7CgkgIERXT1JEIHBvczsKCgkgIGZvciAocG9zID0gMDsgcG9zIDwgcFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsgcG9zKyspIHsKCSAgICBpZiAocFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmNraWQgPT0gbikgewoJICAgICAgaWR4LmR3RmxhZ3MgPSBBVklJRl9OT1RJTUU7CgkgICAgICBpZHguY2tpZCAgICA9IE1BS0VBVklDS0lEKGNrdHlwZVBBTGNoYW5nZSwgcFN0cmVhbS0+blN0cmVhbSk7CgkgICAgICBpZHguZHdDaHVua0xlbmd0aCA9IHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5kd0NodW5rTGVuZ3RoOwoJICAgICAgaWR4LmR3Q2h1bmtPZmZzZXQgPQoJCXBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5kd0NodW5rT2Zmc2V0IC0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CgkgICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoJICAgICAgYnJlYWs7CgkgICAgfQoJICB9Cgl9IC8qIGlmIGhhdmUgZm9ybWF0Y2hhbmdlcyAqLwoKCWlkeC5ja2lkICAgICAgICAgID0gcFN0cmVhbS0+aWR4RnJhbWVzW25dLmNraWQ7CglpZHguZHdGbGFncyAgICAgICA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5kd0ZsYWdzOwoJaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGcmFtZXNbbl0uZHdDaHVua0xlbmd0aDsKCWlkeC5kd0NodW5rT2Zmc2V0ID0gcFN0cmVhbS0+aWR4RnJhbWVzW25dLmR3Q2h1bmtPZmZzZXQKCSAgLSBUaGlzLT5kd01vdmlDaHVua1BvczsKCglpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgfQogICAgfQogIH0gLyogaWYgbm90IGludGVybGVhdmVkICovCgogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIFVMT05HICBBVklGSUxFX1NlYXJjaFN0cmVhbShjb25zdCBJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIGZjYywgTE9ORyBsU2tpcCkKewogIFVJTlQgaTsKICBVSU5UIG5TdHJlYW07CgogIC8qIHByZS1jb25kaXRpb24gKi8KICBhc3NlcnQobFNraXAgPj0gMCk7CgogIGlmIChmY2MgIT0gMCkgewogICAgLyogc2VhcmNoIHRoZSBudW1iZXIgb2YgdGhlIHNwZWNpZmllZCBzdHJlYW0gKi8KICAgIG5TdHJlYW0gPSAoVUxPTkcpLTE7CiAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBpKyspIHsKICAgICAgYXNzZXJ0KFRoaXMtPnBwU3RyZWFtc1tpXSAhPSBOVUxMKTsKCiAgICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbaV0tPnNJbmZvLmZjY1R5cGUgPT0gZmNjKSB7CglpZiAobFNraXAgPT0gMCkgewoJICBuU3RyZWFtID0gaTsKCSAgYnJlYWs7Cgl9IGVsc2UKCSAgbFNraXAtLTsKICAgICAgfQogICAgfQogIH0gZWxzZQogICAgblN0cmVhbSA9IGxTa2lwOwoKICByZXR1cm4gblN0cmVhbTsKfQoKc3RhdGljIHZvaWQgICAgQVZJRklMRV9VcGRhdGVJbmZvKElBVklGaWxlSW1wbCAqVGhpcykKewogIFVJTlQgaTsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKCiAgVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYyAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd0NhcHMgICAgICAgICAgICAgICAgPSBBVklGSUxFQ0FQU19DQU5SRUFEfEFWSUZJTEVDQVBTX0NBTldSSVRFOwogIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IDA7CiAgVGhpcy0+ZkluZm8uZHdXaWR0aCAgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd0hlaWdodCAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3U2NhbGUgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdSYXRlICAgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmR3SW5pdGlhbEZyYW1lcyAgICAgICAgICAgICA9IDA7CgogIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IGkrKykgewogICAgQVZJU1RSRUFNSU5GT1cgKnBzaTsKICAgIERXT1JEICAgICAgICAgICBuOwoKICAgIC8qIHByZS1jb25kaXRpb25zICovCiAgICBhc3NlcnQoVGhpcy0+cHBTdHJlYW1zW2ldICE9IE5VTEwpOwoKICAgIHBzaSA9ICZUaGlzLT5wcFN0cmVhbXNbaV0tPnNJbmZvOwogICAgYXNzZXJ0KHBzaS0+ZHdTY2FsZSAhPSAwKTsKICAgIGFzc2VydChwc2ktPmR3UmF0ZSAhPSAwKTsKCiAgICBpZiAoaSA9PSAwKSB7CiAgICAgIC8qIHVzZSBmaXJzdCBzdHJlYW0gdGltaW5ncyBhcyBiYXNlICovCiAgICAgIFRoaXMtPmZJbmZvLmR3U2NhbGUgID0gcHNpLT5kd1NjYWxlOwogICAgICBUaGlzLT5mSW5mby5kd1JhdGUgICA9IHBzaS0+ZHdSYXRlOwogICAgICBUaGlzLT5mSW5mby5kd0xlbmd0aCA9IHBzaS0+ZHdMZW5ndGg7CiAgICB9IGVsc2UgewogICAgICBuID0gQVZJU3RyZWFtU2FtcGxlVG9TYW1wbGUoKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zWzBdLAoJCQkJICAoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbaV0scHNpLT5kd0xlbmd0aCk7CiAgICAgIGlmIChUaGlzLT5mSW5mby5kd0xlbmd0aCA8IG4pCglUaGlzLT5mSW5mby5kd0xlbmd0aCA9IG47CiAgICB9CgogICAgaWYgKFRoaXMtPmR3SW5pdGlhbEZyYW1lcyA8IHBzaS0+ZHdJbml0aWFsRnJhbWVzKQogICAgICBUaGlzLT5kd0luaXRpYWxGcmFtZXMgPSBwc2ktPmR3SW5pdGlhbEZyYW1lczsKCiAgICBpZiAoVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgcHNpLT5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpCiAgICAgIFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IHBzaS0+ZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwoKICAgIGlmIChwc2ktPmR3U2FtcGxlU2l6ZSAhPSAwKSB7CiAgICAgIC8qIGZpeGVkIHNhbXBsZSBzaXplIC0tIGV4YWN0IGNvbXB1dGF0aW9uICovCiAgICAgIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgKz0gTXVsRGl2KHBzaS0+ZHdTYW1wbGVTaXplLCBwc2ktPmR3UmF0ZSwKCQkJCQkgICAgIHBzaS0+ZHdTY2FsZSk7CiAgICB9IGVsc2UgewogICAgICAvKiB2YXJpYWJsZSBzYW1wbGUgc2l6ZSAtLSBvbmx5IHVwcGVyIGxpbWl0ICovCiAgICAgIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgKz0gTXVsRGl2KHBzaS0+ZHdTdWdnZXN0ZWRCdWZmZXJTaXplLAoJCQkJCSAgICAgcHNpLT5kd1JhdGUsIHBzaS0+ZHdTY2FsZSk7CgogICAgICAvKiB1cGRhdGUgZGltZW5zaW9ucyAqLwogICAgICBuID0gcHNpLT5yY0ZyYW1lLnJpZ2h0IC0gcHNpLT5yY0ZyYW1lLmxlZnQ7CiAgICAgIGlmIChUaGlzLT5mSW5mby5kd1dpZHRoIDwgbikKCVRoaXMtPmZJbmZvLmR3V2lkdGggPSBuOwogICAgICBuID0gcHNpLT5yY0ZyYW1lLmJvdHRvbSAtIHBzaS0+cmNGcmFtZS50b3A7CiAgICAgIGlmIChUaGlzLT5mSW5mby5kd0hlaWdodCA8IG4pCglUaGlzLT5mSW5mby5kd0hlaWdodCA9IG47CiAgICB9CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1dyaXRlQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGJsb2NrLAoJCQkJICBGT1VSQ0MgY2tpZCwgRFdPUkQgZmxhZ3MsIExQVk9JRCBidWZmZXIsCgkJCQkgIExPTkcgc2l6ZSkKewogIE1NQ0tJTkZPIGNrOwoKICBjay5ja2lkICAgID0gY2tpZDsKICBjay5ja3NpemUgID0gc2l6ZTsKICBjay5mY2NUeXBlID0gMDsKCiAgLyogaWYgbm8gZnJhbWUvYmxvY2sgaXMgYWxyZWFkeSB3cml0dGVuLCB3ZSBtdXN0IGNvbXB1dGUgc3RhcnQgb2YgbW92aSBjaHVuayAqLwogIGlmIChUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcy0+cGFmKTsKCiAgaWYgKG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MsIFNFRUtfU0VUKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPnBhZi0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChidWZmZXIgIT0gTlVMTCAmJiBzaXplID4gMCkgewogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpYnVmZmVyLCBzaXplKSAhPSBzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIFRoaXMtPnBhZi0+ZkRpcnR5ICAgICAgICAgPSBUUlVFOwogIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MgPSBtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCAwLCBTRUVLX0NVUik7CgogIHJldHVybiBBVklGSUxFX0FkZEZyYW1lKFRoaXMsIGNraWQsIHNpemUsCgkJCSAgY2suZHdEYXRhT2Zmc2V0IC0gMiAqIHNpemVvZihEV09SRCksIGZsYWdzKTsKfQo=