LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgovKiBUT0RPOgogKiAgLSBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSBpcyBtaXNzaW5nIGZvciB0aGUgSUFWSVN0cmVhbUltcGwKICogIC0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGU6IEZJTkRfSU5ERVggaXNuJ3Qgc3VwcG9ydGVkLgogKiAgLSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdDogZm9ybWF0Y2hhbmdlcyBhcmVuJ3QgcmVhZCBpbi4KICogIC0gSUFWSVN0cmVhbV9mbkRlbGV0ZTogYSBzdHViLgogKiAgLSBJQVZJU3RyZWFtX2ZuU2V0SW5mbzogYSBzdHViLgogKiAgLSBtYWtlIHRocmVhZCBzYWZlCiAqCiAqIEtOT1dOIEJ1Z3M6CiAqICAtIG5hdGl2ZSB2ZXJzaW9uIGNhbiBoYW5ndXAgd2hlbiByZWFkaW5nIGEgZmlsZSBnZW5lcmF0ZWQgd2l0aCB0aGlzIERMTC4KICogICAgV2hlbiBpbmRleCBpcyBtaXNzaW5nIGl0IHdvcmtzLCBidXQgaW5kZXggc2VlbXMgdG8gYmUgb2theS4KICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoYXZpZmlsZSk7CgojaWZuZGVmIElEWF9QRVJfQkxPQ0sKI2RlZmluZSBJRFhfUEVSX0JMT0NLIDI3MzAKI2VuZGlmCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSogaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUZpbGVfZm5SZWxlYXNlKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUqaWZhY2UsQVZJRklMRUlORk9XKmFmaSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5HZXRTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsUEFWSVNUUkVBTSphdmlzLEFWSVNUUkVBTUlORk9XKmFzaSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgKnNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUqaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUqaWZhY2UsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CgpzdHJ1Y3QgSUNPTV9WVEFCTEUoSUFWSUZpbGUpIGlhdmlmdCA9IHsKICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSUZpbGVfZm5BZGRSZWYsCiAgSUFWSUZpbGVfZm5SZWxlYXNlLAogIElBVklGaWxlX2ZuSW5mbywKICBJQVZJRmlsZV9mbkdldFN0cmVhbSwKICBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbSwKICBJQVZJRmlsZV9mbldyaXRlRGF0YSwKICBJQVZJRmlsZV9mblJlYWREYXRhLAogIElBVklGaWxlX2ZuRW5kUmVjb3JkLAogIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSVBlcnNpc3RGaWxlKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5BZGRSZWYoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mblJlbGVhc2UoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQoSVBlcnNpc3RGaWxlKmlmYWNlLENMU0lEKnBDbGFzc0lEKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbklzRGlydHkoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkxvYWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSxEV09SRCBkd01vZGUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZShJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLEJPT0wgZlJlbWVtYmVyKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlKElQZXJzaXN0RmlsZSppZmFjZSxMUE9MRVNUUipwcHN6RmlsZU5hbWUpOwoKc3RydWN0IElDT01fVlRBQkxFKElQZXJzaXN0RmlsZSkgaXBlcnNpc3RmdCA9IHsKICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlLAogIElQZXJzaXN0RmlsZV9mbkFkZFJlZiwKICBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlLAogIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQsCiAgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eSwKICBJUGVyc2lzdEZpbGVfZm5Mb2FkLAogIElQZXJzaXN0RmlsZV9mblNhdmUsCiAgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZCwKICBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0qaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMT05HIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HICpmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLExPTkcgKmJ5dGVzcmVhZCxMT05HICpzYW1wbGVzcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncyxMT05HICpzYW1wd3JpdHRlbixMT05HICpieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XKmluZm8sTE9ORyBpbmZvbGVuKTsKCnN0cnVjdCBJQ09NX1ZUQUJMRShJQVZJU3RyZWFtKSBpYXZpc3QgPSB7CiAgSUNPTV9NU1ZUQUJMRV9DT01QQVRfRHVtbXlSVFRJVkFMVUUKICBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSVN0cmVhbV9mbkFkZFJlZiwKICBJQVZJU3RyZWFtX2ZuUmVsZWFzZSwKICBJQVZJU3RyZWFtX2ZuQ3JlYXRlLAogIElBVklTdHJlYW1fZm5JbmZvLAogIElBVklTdHJlYW1fZm5GaW5kU2FtcGxlLAogIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0LAogIElBVklTdHJlYW1fZm5TZXRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblJlYWQsCiAgSUFWSVN0cmVhbV9mbldyaXRlLAogIElBVklTdHJlYW1fZm5EZWxldGUsCiAgSUFWSVN0cmVhbV9mblJlYWREYXRhLAogIElBVklTdHJlYW1fZm5Xcml0ZURhdGEsCiAgSUFWSVN0cmVhbV9mblNldEluZm8KfTsKCnR5cGVkZWYgc3RydWN0IF9JQVZJRmlsZUltcGwgSUFWSUZpbGVJbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lQZXJzaXN0RmlsZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgSUNPTV9WRklFTEQoSVBlcnNpc3RGaWxlKTsKCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmICovCiAgSUFWSUZpbGVJbXBsICAgICAqcGFmOwp9IElQZXJzaXN0RmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgSUNPTV9WRklFTEQoSUFWSVN0cmVhbSk7CiAgRFdPUkQJCSAgICByZWY7CgogIC8qIElBVklTdHJlYW0gc3R1ZmYgKi8KICBJQVZJRmlsZUltcGwgICAgICpwYWY7CiAgRFdPUkQgICAgICAgICAgICAgblN0cmVhbTsgICAgICAgLyogdGhlIG4tdGggc3RyZWFtIGluIGZpbGUgKi8KICBBVklTVFJFQU1JTkZPVyAgICBzSW5mbzsKCiAgTFBWT0lEICAgICAgICAgICAgbHBGb3JtYXQ7CiAgRFdPUkQgICAgICAgICAgICAgY2JGb3JtYXQ7CgogIExQVk9JRCAgICAgICAgICAgIGxwSGFuZGxlckRhdGE7CiAgRFdPUkQgICAgICAgICAgICAgY2JIYW5kbGVyRGF0YTsKCiAgRVhUUkFDSFVOS1MgICAgICAgZXh0cmE7CgogIExQRFdPUkQgICAgICAgICAgIGxwQnVmZmVyOwogIERXT1JEICAgICAgICAgICAgIGNiQnVmZmVyOyAgICAgICAvKiBzaXplIG9mIGxwQnVmZmVyICovCiAgRFdPUkQgICAgICAgICAgICAgZHdDdXJyZW50RnJhbWU7IC8qIGZyYW1lL2Jsb2NrIGN1cnJlbnRseSBpbiBscEJ1ZmZlciAqLwoKICBMT05HICAgICAgICAgICAgICBsTGFzdEZyYW1lOyAgICAvKiBsYXN0IGNvcnJlY3QgaW5kZXggaW4gaWR4RnJhbWVzICovCiAgQVZJSU5ERVhFTlRSWSAgICAqaWR4RnJhbWVzOwogIERXT1JEICAgICAgICAgICAgIG5JZHhGcmFtZXM7ICAgICAvKiB1cHBlciBpbmRleCBsaW1pdCBvZiBpZHhGcmFtZXMgKi8KICBBVklJTkRFWEVOVFJZICAgICppZHhGbXRDaGFuZ2VzOwogIERXT1JEICAgICAgICAgICAgIG5JZHhGbXRDaGFuZ2VzOyAvKiB1cHBlciBpbmRleCBsaW1pdCBvZiBpZHhGbXRDaGFuZ2VzICovCn0gSUFWSVN0cmVhbUltcGw7CgpzdHJ1Y3QgX0lBVklGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBJQ09NX1ZGSUVMRChJQVZJRmlsZSk7CiAgRFdPUkQJCSAgICByZWY7CgogIC8qIElBVklGaWxlIHN0dWZmLi4uICovCiAgSVBlcnNpc3RGaWxlSW1wbCAgaVBlcnNpc3RGaWxlOwoKICBBVklGSUxFSU5GT1cgICAgICBmSW5mbzsKICBJQVZJU3RyZWFtSW1wbCAgICpwcFN0cmVhbXNbTUFYX0FWSVNUUkVBTVNdOwoKICBFWFRSQUNIVU5LUyAgICAgICBmaWxlZXh0cmE7CgogIERXT1JEICAgICAgICAgICAgIGR3TW92aUNodW5rUG9zOyAgLyogc29tZSBzdHVmZiBmb3Igc2F2aW5nIC4uLiAqLwogIERXT1JEICAgICAgICAgICAgIGR3SWR4Q2h1bmtQb3M7CiAgRFdPUkQgICAgICAgICAgICAgZHdOZXh0RnJhbWVQb3M7CiAgRFdPUkQgICAgICAgICAgICAgZHdJbml0aWFsRnJhbWVzOwoKICBNTUNLSU5GTyAgICAgICAgICBja0xhc3RSZWNvcmQ7CiAgQVZJSU5ERVhFTlRSWSAgICAqaWR4UmVjb3JkczsgICAgICAvKiB3b24ndCBiZSB1cGRhdGVkIHdoaWxlIGxvYWRpbmcgKi8KICBEV09SRCAgICAgICAgICAgICBuSWR4UmVjb3JkczsgICAgIC8qIGN1cnJlbnQgZmlsbCBsZXZlbCAqLwogIERXT1JEICAgICAgICAgICAgIGNiSWR4UmVjb3JkczsgICAgLyogc2l6ZSBvZiBpZHhSZWNvcmRzICovCgogIC8qIElQZXJzaXN0RmlsZSBzdHVmZiAuLi4gKi8KICBITU1JTyAgICAgICAgICAgICBobW1pbzsKICBMUFdTVFIgICAgICAgICAgICBzekZpbGVOYW1lOwogIFVJTlQgICAgICAgICAgICAgIHVNb2RlOwogIEJPT0wgICAgICAgICAgICAgIGZEaXJ0eTsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQWRkRnJhbWUoSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGNraWQsIERXT1JEIHNpemUsCgkJCQlEV09SRCBvZmZzZXQsIERXT1JEIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRSZWNvcmQoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIERXT1JEICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKElBVklGaWxlSW1wbCAqcGFmLCBEV09SRCBuciwKCQkJCQkgIExQQVZJU1RSRUFNSU5GT1cgYXNpKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9EZXN0cnVjdEFWSVN0cmVhbShJQVZJU3RyZWFtSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBzaXplLCBEV09SRCBvZmZzZXQpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1BhcnNlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzLCBBVklJTkRFWEVOVFJZICpscCwKCQkJCSAgTE9ORyBjb3VudCwgRFdPUkQgcG9zLCBCT09MICpiQWJzb2x1dGUpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1JlYWRCbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgc3RhcnQsCgkJCQkgTFBWT0lEIGJ1ZmZlciwgTE9ORyBzaXplKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgTFBMT05HIHBvcywKCQkJCSAgICAgIExQTE9ORyBvZmZzZXQpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVGaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUluZGV4KElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBVTE9ORyAgIEFWSUZJTEVfU2VhcmNoU3RyZWFtKElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgZmNjVHlwZSwKCQkJCSAgICBMT05HIGxTa2lwKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9VcGRhdGVJbmZvKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfV3JpdGVCbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgYmxvY2ssCgkJCQkgIEZPVVJDQyBja2lkLCBEV09SRCBmbGFncywgTFBWT0lEIGJ1ZmZlciwKCQkJCSAgTE9ORyBzaXplKTsKCkhSRVNVTFQgQVZJRklMRV9DcmVhdGVBVklGaWxlKFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogIElBVklGaWxlSW1wbCAqcGZpbGU7CiAgSFJFU1VMVCAgICAgICBocjsKCiAgYXNzZXJ0KHJpaWQgIT0gTlVMTCAmJiBwcHYgIT0gTlVMTCk7CgogICpwcHYgPSBOVUxMOwoKICBwZmlsZSA9IChJQVZJRmlsZUltcGwqKUxvY2FsQWxsb2MoTFBUUiwgc2l6ZW9mKElBVklGaWxlSW1wbCkpOwogIGlmIChwZmlsZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIHBmaWxlLT5scFZ0YmwgPSAmaWF2aWZ0OwogIHBmaWxlLT5yZWYgPSAwOwogIHBmaWxlLT5pUGVyc2lzdEZpbGUubHBWdGJsID0gJmlwZXJzaXN0ZnQ7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5wYWYgPSBwZmlsZTsKCiAgaHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZSgoSVVua25vd24qKXBmaWxlLCByaWlkLCBwcHYpOwogIGlmIChGQUlMRUQoaHIpKQogICAgTG9jYWxGcmVlKChITE9DQUwpcGZpbGUpOwoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlICppZmFjZSwgUkVGSUlEIHJlZmlpZCwKCQkJCQkJTFBWT0lEICpvYmopCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEKCZJSURfSVBlcnNpc3RGaWxlLCByZWZpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPmlQZXJzaXN0RmlsZTsKICAgIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIFRoaXMtPnJlZiArIDEpOwogIHJldHVybiArKyhUaGlzLT5yZWYpOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSAqaWZhY2UpCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKICBVSU5UIGk7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIFRoaXMtPnJlZiAtIDEpOwoKICBpZiAoIS0tKFRoaXMtPnJlZikpIHsKICAgIGlmIChUaGlzLT5mRGlydHkpIHsKICAgICAgLyogbmVlZCB0byB3cml0ZSBoZWFkZXJzIHRvIGZpbGUgKi8KICAgICAgQVZJRklMRV9TYXZlRmlsZShUaGlzKTsKICAgIH0KCiAgICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBpKyspIHsKICAgICAgaWYgKFRoaXMtPnBwU3RyZWFtc1tpXSAhPSBOVUxMKSB7CglpZiAoVGhpcy0+cHBTdHJlYW1zW2ldLT5yZWYgIT0gMCkgewoJICBFUlIoIjogc29tZW9uZSBoYXMgc3RpbGwgJWx1IHJlZmVyZW5jZSB0byBzdHJlYW0gJXUgKCVwKSFcbiIsCgkgICAgICAgVGhpcy0+cHBTdHJlYW1zW2ldLT5yZWYsIGksIFRoaXMtPnBwU3RyZWFtc1tpXSk7Cgl9CglBVklGSUxFX0Rlc3RydWN0QVZJU3RyZWFtKFRoaXMtPnBwU3RyZWFtc1tpXSk7CglMb2NhbEZyZWUoKEhMT0NBTClUaGlzLT5wcFN0cmVhbXNbaV0pOwoJVGhpcy0+cHBTdHJlYW1zW2ldID0gTlVMTDsKICAgICAgfQogICAgfQoKICAgIGlmIChUaGlzLT5pZHhSZWNvcmRzICE9IE5VTEwpIHsKICAgICAgR2xvYmFsRnJlZVB0cihUaGlzLT5pZHhSZWNvcmRzKTsKICAgICAgVGhpcy0+aWR4UmVjb3JkcyAgPSBOVUxMOwogICAgICBUaGlzLT5uSWR4UmVjb3JkcyA9IDA7CiAgICB9CgogICAgaWYgKFRoaXMtPmZpbGVleHRyYS5scCAhPSBOVUxMKSB7CiAgICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+ZmlsZWV4dHJhLmxwKTsKICAgICAgVGhpcy0+ZmlsZWV4dHJhLmxwID0gTlVMTDsKICAgICAgVGhpcy0+ZmlsZWV4dHJhLmNiID0gMDsKICAgIH0KCiAgICBpZiAoVGhpcy0+c3pGaWxlTmFtZSAhPSBOVUxMKSB7CiAgICAgIExvY2FsRnJlZSgoSExPQ0FMKVRoaXMtPnN6RmlsZU5hbWUpOwogICAgICBUaGlzLT5zekZpbGVOYW1lID0gTlVMTDsKICAgIH0KICAgIGlmIChUaGlzLT5obW1pbyAhPSBOVUxMKSB7CiAgICAgIG1taW9DbG9zZShUaGlzLT5obW1pbywgMCk7CiAgICAgIFRoaXMtPmhtbWlvID0gTlVMTDsKICAgIH0KCiAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzKTsKICAgIHJldHVybiAwOwogIH0KICByZXR1cm4gVGhpcy0+cmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5JbmZvKElBVklGaWxlICppZmFjZSwgTFBBVklGSUxFSU5GT1cgYWZpLAoJCQkJICAgICAgTE9ORyBzaXplKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxhZmksc2l6ZSk7CgogIGlmIChhZmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBBVklGSUxFX1VwZGF0ZUluZm8oVGhpcyk7CgogIG1lbWNweShhZmksICZUaGlzLT5mSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+ZkluZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5mSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgVUxPTkcgblN0cmVhbTsKCiAgVFJBQ0UoIiglcCwlcCwweCUwOGxYLCVsZClcbiIsIGlmYWNlLCBhdmlzLCBmY2NUeXBlLCBsUGFyYW0pOwoKICBpZiAoYXZpcyA9PSBOVUxMIHx8IGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBuU3RyZWFtID0gQVZJRklMRV9TZWFyY2hTdHJlYW0oVGhpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogRG9lcyB0aGUgcmVxdWVzdGVkIHN0cmVhbSBleGlzdD8gKi8KICBpZiAoblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAmJgogICAgICBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0gIT0gTlVMTCkgewogICAgKmF2aXMgPSAoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CiAgICBJQVZJU3RyZWFtX0FkZFJlZigqYXZpcyk7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIFNvcnJ5LCBidXQgdGhlIHNwZWNpZmllZCBzdHJlYW0gZG9lc24ndCBleGlzdCAqLwogIHJldHVybiBBVklFUlJfTk9EQVRBOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgICAgTFBBVklTVFJFQU1JTkZPVyBhc2kpCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgRFdPUkQgbjsKCiAgVFJBQ0UoIiglcCwlcCwlcClcbiIsIGlmYWNlLCBhdmlzLCBhc2kpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBhc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICphdmlzID0gTlVMTDsKCiAgLyogRG9lcyB0aGUgdXNlciBoYXZlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogQ2FuIHdlIGFkZCBhbm90aGVyIHN0cmVhbT8gKi8KICBuID0gVGhpcy0+ZkluZm8uZHdTdHJlYW1zOwogIGlmIChuID49IE1BWF9BVklTVFJFQU1TIHx8IFRoaXMtPmR3TW92aUNodW5rUG9zICE9IDApIHsKICAgIC8qIGFscmVhZHkgcmVhY2hlZCBtYXggbnIgb2Ygc3RyZWFtcwogICAgICogb3IgaGF2ZSBhbHJlYWR5IHdyaXR0ZW4gZnJhbWVzIHRvIGRpc2sgKi8KICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfQoKICAvKiBjaGVjayBBVklTVFJFQU1JTkZPIGZvciBzb21lIHJlYWxseSBuZWVkZWQgdGhpbmdzICovCiAgaWYgKGFzaS0+ZmNjVHlwZSA9PSAwIHx8IGFzaS0+ZHdTY2FsZSA9PSAwIHx8IGFzaS0+ZHdSYXRlID09IDApCiAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCiAgLyogbm93IGl0IHNlZW1zIHRvIGJlIHNhdmUgdG8gYWRkIHRoZSBzdHJlYW0gKi8KICBhc3NlcnQoVGhpcy0+cHBTdHJlYW1zW25dID09IE5VTEwpOwogIFRoaXMtPnBwU3RyZWFtc1tuXSA9IChJQVZJU3RyZWFtSW1wbCopTG9jYWxBbGxvYyhMUFRSLAoJCQkJCQkgICBzaXplb2YoSUFWSVN0cmVhbUltcGwpKTsKICBpZiAoVGhpcy0+cHBTdHJlYW1zW25dID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogaW5pdGlhbGl6ZSB0aGUgbmV3IGFsbG9jYXRlZCBzdHJlYW0gKi8KICBBVklGSUxFX0NvbnN0cnVjdEFWSVN0cmVhbShUaGlzLCBuLCBhc2kpOwoKICBUaGlzLT5mSW5mby5kd1N0cmVhbXMrKzsKICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAvKiB1cGRhdGUgb3VyIEFWSUZJTEVJTkZPIHN0cnVjdHVyZSAqLwogIEFWSUZJTEVfVXBkYXRlSW5mbyhUaGlzKTsKCiAgLyogcmV0dXJuIGl0ICovCiAgKmF2aXMgPSAoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbbl07CiAgSUFWSVN0cmVhbV9BZGRSZWYoKmF2aXMpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5Xcml0ZURhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgIExQVk9JRCBscERhdGEsIExPTkcgc2l6ZSkKewogIElDT01fVEhJUyhJQVZJRmlsZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJWxkKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHBEYXRhID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmZpbGVleHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgTFBWT0lEIGxwRGF0YSwgTE9ORyAqc2l6ZSkKewogIElDT01fVEhJUyhJQVZJRmlsZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKCiAgcmV0dXJuIFJlYWRFeHRyYUNodW5rKCZUaGlzLT5maWxlZXh0cmEsIGNraWQsIGxwRGF0YSwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSAqaWZhY2UpCnsKICBJQ09NX1RISVMoSUFWSUZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcClcbiIsaWZhY2UpOwoKICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAvKiBubyBmcmFtZXMgd3JpdHRlbiB0byBhbnkgc3RyZWFtPyAtLSBjb21wdXRlIHN0YXJ0IG9mICdtb3ZpJy1jaHVuayAqLwogIGlmIChUaGlzLT5kd01vdmlDaHVua1BvcyA9PSAwKQogICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KFRoaXMpOwoKICBUaGlzLT5mSW5mby5kd0ZsYWdzICB8PSBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEOwoKICAvKiBhbHJlYWR5IHdyaXR0ZW4gZnJhbWVzIHRvIGFueSBzdHJlYW0sIC4uLiAqLwogIGlmIChUaGlzLT5ja0xhc3RSZWNvcmQuZHdGbGFncyAmIE1NSU9fRElSVFkpIHsKICAgIC8qIGNsb3NlIGxhc3QgcmVjb3JkICovCiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJlRoaXMtPmNrTGFzdFJlY29yZCwgMCkgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgQVZJRklMRV9BZGRSZWNvcmQoVGhpcyk7CgogICAgaWYgKFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA8IFRoaXMtPmNrTGFzdFJlY29yZC5ja3NpemUgKyAzICogc2l6ZW9mKERXT1JEKSkKICAgICAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSArIDMgKiBzaXplb2YoRFdPUkQpOwogIH0KCiAgLyogd3JpdGUgb3V0IGEgbmV3IHJlY29yZCBpbnRvIGZpbGUsIGJ1dCBkb24ndCBjbG9zZSBpdCAqLwogIFRoaXMtPmNrTGFzdFJlY29yZC5ja3NpemUgID0gMDsKICBUaGlzLT5ja0xhc3RSZWNvcmQuZmNjVHlwZSA9IGxpc3R0eXBlQVZJUkVDT1JEOwogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+ZHdOZXh0RnJhbWVQb3MsIFNFRUtfU0VUKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZUaGlzLT5ja0xhc3RSZWNvcmQsIE1NSU9fQ1JFQVRFTElTVCkgIT0gMCkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIFRoaXMtPmR3TmV4dEZyYW1lUG9zICs9IDMgKiBzaXplb2YoRFdPUkQpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5EZWxldGVTdHJlYW0oSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBmY2NUeXBlLAoJCQkJCSAgICAgIExPTkcgbFBhcmFtKQp7CiAgSUNPTV9USElTKElBVklGaWxlSW1wbCxpZmFjZSk7CgogIFVMT05HIG5TdHJlYW07CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHVzZXIgd3JpdGUgcGVybWlzc2lvbnM/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgIC8qIC4uLiBzbyBkZWxldGUgaXQgbm93ICovCiAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0pOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgLSBuU3RyZWFtID4gMCkKICAgICAgbWVtY3B5KFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0sIFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0gKyAxLAoJICAgICAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zIC0gblN0cmVhbSkgKiBzaXplb2YoSUFWSVN0cmVhbUltcGwqKSk7CgogICAgVGhpcy0+cHBTdHJlYW1zW1RoaXMtPmZJbmZvLmR3U3RyZWFtc10gPSBOVUxMOwogICAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zLS07CiAgICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAgIC8qIFRoaXMtPmZJbmZvIHdpbGwgYmUgdXBkYXRlZCBmdXJ0aGVyIHdoZW4gYXNrZWQgZm9yICovCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQ09NX1RISVMoSVBlcnNpc3RGaWxlSW1wbCxpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9RdWVyeUludGVyZmFjZSgoUEFWSUZJTEUpVGhpcy0+cGFmLCByZWZpaWQsIG9iaik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5BZGRSZWYoSVBlcnNpc3RGaWxlICppZmFjZSkKewogIElDT01fVEhJUyhJUGVyc2lzdEZpbGVJbXBsLGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX0FkZFJlZigoUEFWSUZJTEUpVGhpcy0+cGFmKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mblJlbGVhc2UoSVBlcnNpc3RGaWxlICppZmFjZSkKewogIElDT01fVEhJUyhJUGVyc2lzdEZpbGVJbXBsLGlmYWNlKTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQQ0xTSUQgcENsYXNzSUQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBDbGFzc0lEKTsKCiAgaWYgKHBDbGFzc0lEID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBtZW1jcHkocENsYXNzSUQsICZDTFNJRF9BVklGaWxlLCBzaXplb2YoQ0xTSURfQVZJRmlsZSkpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSUNPTV9USElTKElQZXJzaXN0RmlsZUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKVxuIiwgaWZhY2UpOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICByZXR1cm4gKFRoaXMtPnBhZi0+ZkRpcnR5ID8gU19PSyA6IFNfRkFMU0UpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuTG9hZChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCSAgTFBDT0xFU1RSIHBzekZpbGVOYW1lLCBEV09SRCBkd01vZGUpCnsKICBJQ09NX1RISVMoSVBlcnNpc3RGaWxlSW1wbCxpZmFjZSk7CgogIGludCBsZW47CgogIFRSQUNFKCIoJXAsJXMsMHglMDhsWClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSwgZHdNb2RlKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwogIGlmIChUaGlzLT5wYWYtPmhtbWlvICE9IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0VSUk9SOyAvKiBObyByZXVzZSBvZiB0aGlzIG9iamVjdCBmb3IgYW5vdGhlciBmaWxlISAqLwoKICAvKiByZW1lYmVyIG1vZGUgYW5kIG5hbWUgKi8KICBUaGlzLT5wYWYtPnVNb2RlID0gZHdNb2RlOwoKICBsZW4gPSBsc3RybGVuVyhwc3pGaWxlTmFtZSkgKyAxOwogIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSA9IChMUFdTVFIpTG9jYWxBbGxvYyhMUFRSLCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICBpZiAoVGhpcy0+cGFmLT5zekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICBsc3RyY3B5VyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIHBzekZpbGVOYW1lKTsKCiAgLyogdHJ5IHRvIG9wZW4gdGhlIGZpbGUgKi8KICBUaGlzLT5wYWYtPmhtbWlvID0gbW1pb09wZW5XKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgTlVMTCwKCQkJICAgICAgIE1NSU9fQUxMT0NCVUYgfCBkd01vZGUpOwogIGlmIChUaGlzLT5wYWYtPmhtbWlvID09IE5VTEwpIHsKICAgIC8qIG1taW9PcGVuVyBub3QgaW4gbmF0aXZlIERMTHMgb2YgV2luOXggLS0gdHJ5IG1taW9PcGVuQSAqLwogICAgTFBTVFIgc3pGaWxlTmFtZSA9IExvY2FsQWxsb2MoTFBUUiwgbGVuICogc2l6ZW9mKENIQVIpKTsKICAgIGlmIChzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIC0xLCBzekZpbGVOYW1lLAoJCQlsZW4sIE5VTEwsIE5VTEwpOwoKICAgIFRoaXMtPnBhZi0+aG1taW8gPSBtbWlvT3BlbkEoc3pGaWxlTmFtZSwgTlVMTCwgTU1JT19BTExPQ0JVRiB8IGR3TW9kZSk7CiAgICBMb2NhbEZyZWUoKEhMT0NBTClzekZpbGVOYW1lKTsKICAgIGlmIChUaGlzLT5wYWYtPmhtbWlvID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfRklMRU9QRU47CiAgfQoKICAvKiBzaG91bGQgd2UgY3JlYXRlIGEgbmV3IGZpbGU/ICovCiAgaWYgKGR3TW9kZSAmIE9GX0NSRUFURSkgewogICAgbWVtc2V0KCYgVGhpcy0+cGFmLT5mSW5mbywgMCwgc2l6ZW9mKFRoaXMtPnBhZi0+ZkluZm8pKTsKICAgIFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyA9IEFWSUZJTEVJTkZPX0hBU0lOREVYIHwgQVZJRklMRUlORk9fVFJVU1RDS1RZUEU7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBBVklGSUxFX0xvYWRGaWxlKFRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpCnsKICBUUkFDRSgiKCVwLCVzLCVkKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpLCBmUmVtZW1iZXIpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICBMUENPTEVTVFIgcHN6RmlsZU5hbWUpCnsKICBUUkFDRSgiKCVwLCVzKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpKTsKCiAgLyogV2Ugd3JpdGUgZGlyZWN0bHkgdG8gZGlzaywgc28gbm90aGluZyB0byBkby4gKi8KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJTFBPTEVTVFIgKnBwc3pGaWxlTmFtZSkKewogIElDT01fVEhJUyhJUGVyc2lzdEZpbGVJbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGlmYWNlLCBwcHN6RmlsZU5hbWUpOwoKICBpZiAocHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBzekZpbGVOYW1lID0gTlVMTDsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgaWYgKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSAhPSBOVUxMKSB7CiAgICBpbnQgbGVuID0gbHN0cmxlblcoVGhpcy0+cGFmLT5zekZpbGVOYW1lKTsKCiAgICAqcHBzekZpbGVOYW1lID0gKExQT0xFU1RSKUdsb2JhbEFsbG9jUHRyKEdITkQsIGxlbiAqIHNpemVvZihXQ0hBUikpOwogICAgaWYgKCpwcHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogICAgbWVtY3B5KCpwcHN6RmlsZU5hbWUsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCQkgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICBJQVZJU3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQogIC8qIEZJWE1FOiBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSAqLwoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtICppZmFjZSkKewogIElDT01fVEhJUyhJQVZJU3RyZWFtSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIFRoaXMtPnJlZiArIDEpOwoKICAvKiBhbHNvIGFkZCByZWYgdG8gcGFyZW50LCBzbyB0aGF0IGl0IGRvZXNuJ3Qga2lsbCB1cyAqLwogIGlmIChUaGlzLT5wYWYgIT0gTlVMTCkKICAgIElBVklGaWxlX0FkZFJlZigoUEFWSUZJTEUpVGhpcy0+cGFmKTsKCiAgcmV0dXJuICsrKFRoaXMtPnJlZik7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCBUaGlzLT5yZWYgLSAxKTsKCiAgLyogd2UgYmVsb25nIHRvIHRoZSBBVklGaWxlLCB3aGljaCBtdXN0IGZyZWUgdXMhICovCiAgaWYgKFRoaXMtPnJlZiA9PSAwKSB7CiAgICBFUlIoIjogYWxyZWFkeSByZWxlYXNlZCFcbiIpOwogICAgcmV0dXJuIDA7CiAgfQoKICBUaGlzLT5yZWYtLTsKCiAgaWYgKFRoaXMtPnBhZiAhPSBOVUxMKQogICAgSUFWSUZpbGVfUmVsZWFzZSgoUEFWSUZJTEUpVGhpcy0+cGFmKTsKCiAgcmV0dXJuIFRoaXMtPnJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExQQVJBTSBsUGFyYW0xLAoJCQkJCSAgTFBBUkFNIGxQYXJhbTIpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIGlmYWNlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgLyogVGhpcyBJQVZJU3RyZWFtIGludGVyZmFjZSBuZWVkcyBhbiBBVklGaWxlICovCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0gKmlmYWNlLExQQVZJU1RSRUFNSU5GT1cgcHNpLAoJCQkJCUxPTkcgc2l6ZSkKewogIElDT01fVEhJUyhJQVZJU3RyZWFtSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnNJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgIExPTkcgZmxhZ3MpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBMT05HIG9mZnNldCA9IDA7CgogIFRSQUNFKCIoJXAsJWxkLDB4JTA4bFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGNvbnZlcnQgc2FtcGxlcyBpbnRvIGJsb2NrIG51bWJlciB3aXRoIG9mZnNldCAqLwogICAgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhUaGlzLCAmcG9zLCAmb2Zmc2V0KTsKICB9CgogIGlmIChmbGFncyAmIEZJTkRfVFlQRSkgewogICAgaWYgKGZsYWdzICYgRklORF9LRVkpIHsKICAgICAgd2hpbGUgKDAgPD0gcG9zICYmIHBvcyA8PSBUaGlzLT5sTGFzdEZyYW1lKSB7CglpZiAoVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdGbGFncyAmIEFWSUlGX0tFWUZSQU1FKQoJICBnb3RvIFJFVFVSTl9GT1VORDsKCglpZiAoZmxhZ3MgJiBGSU5EX05FWFQpCgkgIHBvcysrOwoJZWxzZQoJICBwb3MtLTsKICAgICAgfTsKICAgIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0FOWSkgewogICAgICB3aGlsZSAoMCA8PSBwb3MgJiYgcG9zIDw9IFRoaXMtPmxMYXN0RnJhbWUpIHsKCWlmIChUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoID4gMCkKCSAgZ290byBSRVRVUk5fRk9VTkQ7CgoJaWYgKGZsYWdzICYgRklORF9ORVhUKQoJICBwb3MrKzsKCWVsc2UKCSAgcG9zLS07CgogICAgICB9OwogICAgfSBlbHNlIGlmICgoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgJiYgVGhpcy0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMICYmCgkgICAgICAgVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgaWYgKGZsYWdzICYgRklORF9ORVhUKSB7CglVTE9ORyBuOwoKCWZvciAobiA9IDA7IG4gPCBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBuKyspCgkgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQgPj0gcG9zKSB7CiAgICAgICAgICAgIHBvcyA9IFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZDsKCSAgICBnb3RvIFJFVFVSTl9GT1VORDsKICAgICAgICAgIH0KICAgICAgfSBlbHNlIHsKCUxPTkcgbjsKCglmb3IgKG4gPSAoTE9ORylUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBuID49IDA7IG4tLSkgewoJICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkIDw9IHBvcykgewogICAgICAgICAgICBwb3MgPSBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQ7CgkgICAgZ290byBSRVRVUk5fRk9VTkQ7CiAgICAgICAgICB9Cgl9CgoJaWYgKHBvcyA+IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQpCgkgIHJldHVybiAwOyAvKiBmb3JtYXQgY2hhbmdlcyBhbHdheXMgZm9yIGZpcnN0IGZyYW1lICovCiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gLTE7CiAgfQoKIFJFVFVSTl9GT1VORDoKICBpZiAocG9zIDwgKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiAtMTsKCiAgc3dpdGNoIChmbGFncyAmIEZJTkRfUkVUKSB7CiAgY2FzZSBGSU5EX0xFTkdUSDoKICAgIC8qIHBoeXNpY2FsIHNpemUgKi8KICAgIHBvcyA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGg7CiAgICBicmVhazsKICBjYXNlIEZJTkRfT0ZGU0VUOgogICAgLyogcGh5c2ljYWwgcG9zaXRpb24gKi8KICAgIHBvcyA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKQogICAgICArIG9mZnNldCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGJyZWFrOwogIGNhc2UgRklORF9TSVpFOgogICAgLyogbG9naWNhbCBzaXplICovCiAgICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplKQogICAgICBwb3MgPSBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBlbHNlCiAgICAgIHBvcyA9IDE7CiAgICBicmVhazsKICBjYXNlIEZJTkRfSU5ERVg6CiAgICBGSVhNRSgiOiBGSU5EX0lOREVYIGZsYWcgaXMgbm90IHN1cHBvcnRlZCFcbiIpOwogICAgLyogVGhpcyBpcyBhbiBpbmRleCBpbiB0aGUgaW5kZXgtdGFibGUgb24gZGlzYy4gKi8KICAgIGJyZWFrOwogIH07IC8qIGVsc2UgbG9naWNhbCBwb3NpdGlvbiAqLwoKICByZXR1cm4gcG9zOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgKmZvcm1hdHNpemUpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlcClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChmb3JtYXRzaXplID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBvbmx5IGludGVyZXN0ZWQgaW4gbmVlZGVkIGJ1ZmZlcnNpemU/ICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8ICpmb3JtYXRzaXplIDw9IDApIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIGNvcHkgaW5pdGlhbCBmb3JtYXQgKG9ubHkgYXMgbXVjaCBhcyB3aWxsIGZpdCkgKi8KICBtZW1jcHkoZm9ybWF0LCBUaGlzLT5scEZvcm1hdCwgbWluKCooRFdPUkQqKWZvcm1hdHNpemUsIFRoaXMtPmNiRm9ybWF0KSk7CiAgaWYgKCooRFdPUkQqKWZvcm1hdHNpemUgPCBUaGlzLT5jYkZvcm1hdCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQoKICAvKiBDb3VsZCBmb3JtYXQgY2hhbmdlPyBXaGVuIHllcyB3aWxsIGl0IGNoYW5nZT8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3RmxhZ3MgJiBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVMpICYmCiAgICAgIHBvcyA+IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgIExPTkcgbExhc3RGbXQ7CgogICAgbExhc3RGbXQgPSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShpZmFjZSwgcG9zLCBGSU5EX0ZPUk1BVHxGSU5EX1BSRVYpOwogICAgaWYgKGxMYXN0Rm10ID4gMCkgewogICAgICBGSVhNRSgiOiBuZWVkIHRvIHJlYWQgZm9ybWF0Y2hhbmdlIGZvciAlbGQgLS0gdW5pbXBsZW1lbnRlZCFcbiIsbExhc3RGbXQpOwogICAgfQogIH0KCiAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU5ldyA9IChMUEJJVE1BUElORk9IRUFERVIpZm9ybWF0OwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlbGQpXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8IGZvcm1hdHNpemUgPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIGNhbiBvbmx5IHNldCBmb3JtYXQgYmVmb3JlIGZyYW1lIGlzIHdyaXR0ZW4hICovCiAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPiBwb3MpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBpbml0aWFsIGZvcm1hdCBvciBhIGZvcm1hdGNoYW5nZT8gKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkgewogICAgLyogaW5pdGlhbCBmb3JtYXQgKi8KICAgIGlmIChUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zICE9IDApCiAgICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIHVzZXIgaGFzIHVzZWQgQVBJIGluIHdyb25nIHNlcXVuZWNlISAqLwoKICAgIFRoaXMtPmxwRm9ybWF0ID0gR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgZm9ybWF0c2l6ZSk7CiAgICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5jYkZvcm1hdCA9IGZvcm1hdHNpemU7CgogICAgbWVtY3B5KFRoaXMtPmxwRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAgIC8qIHVwZGF0ZSBzb21lIGluZm9zIGFib3V0IHN0cmVhbSAqLwogICAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIExPTkcgbERpbTsKCiAgICAgIGxEaW0gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLnJpZ2h0IC0gVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0OwogICAgICBpZiAobERpbSA8IGxwYmlOZXctPmJpV2lkdGgpCglUaGlzLT5zSW5mby5yY0ZyYW1lLnJpZ2h0ID0gVGhpcy0+c0luZm8ucmNGcmFtZS5sZWZ0ICsgbHBiaU5ldy0+YmlXaWR0aDsKICAgICAgbERpbSA9IFRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tIC0gVGhpcy0+c0luZm8ucmNGcmFtZS50b3A7CiAgICAgIGlmIChsRGltIDwgbHBiaU5ldy0+YmlIZWlnaHQpCglUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSA9IFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wICsgbHBiaU5ldy0+YmlIZWlnaHQ7CiAgICB9IGVsc2UgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZUFVRElPKQogICAgICBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgPSAoKExQV0FWRUZPUk1BVEVYKVRoaXMtPmxwRm9ybWF0KS0+bkJsb2NrQWxpZ247CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UgewogICAgTU1DS0lORk8gICAgICAgICAgIGNrOwogICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmlPbGQgPSAoTFBCSVRNQVBJTkZPSEVBREVSKVRoaXMtPmxwRm9ybWF0OwogICAgUkdCUVVBRCAgICAgICAgICAgKnJnYk5ldyAgPSAoUkdCUVVBRCopKChMUEJZVEUpbHBiaU5ldyArIGxwYmlOZXctPmJpU2l6ZSk7CiAgICBBVklQQUxDSEFOR0UgICAgICAqbHBwYyA9IE5VTEw7CiAgICBJTlQgICAgICAgICAgICAgICAgbjsKCiAgICAvKiBwaGVyaGFwcyBmb3JtYXRjaGFuZ2UsIGNoZWNrIGl0IC4uLiAqLwogICAgaWYgKFRoaXMtPmNiRm9ybWF0ICE9IGZvcm1hdHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogbm8gZm9ybWF0Y2hhbmdlLCBvbmx5IHRoZSBpbml0aWFsIG9uZSAqLwogICAgaWYgKG1lbWNtcChUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKSA9PSAwKQogICAgICByZXR1cm4gQVZJRVJSX09LOwoKICAgIC8qIGNoZWNrIHRoYXQncyBvbmx5IHRoZSBwYWxldHRlLCB3aGljaCBjaGFuZ2VzICovCiAgICBpZiAobHBiaU9sZC0+YmlTaXplICAgICAgICAhPSBscGJpTmV3LT5iaVNpemUgfHwKCWxwYmlPbGQtPmJpV2lkdGggICAgICAgIT0gbHBiaU5ldy0+YmlXaWR0aCB8fAoJbHBiaU9sZC0+YmlIZWlnaHQgICAgICAhPSBscGJpTmV3LT5iaUhlaWdodCB8fAoJbHBiaU9sZC0+YmlQbGFuZXMgICAgICAhPSBscGJpTmV3LT5iaVBsYW5lcyB8fAoJbHBiaU9sZC0+YmlCaXRDb3VudCAgICAhPSBscGJpTmV3LT5iaUJpdENvdW50IHx8CglscGJpT2xkLT5iaUNvbXByZXNzaW9uICE9IGxwYmlOZXctPmJpQ29tcHJlc3Npb24gfHwKCWxwYmlPbGQtPmJpQ2xyVXNlZCAgICAgIT0gbHBiaU5ldy0+YmlDbHJVc2VkKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIFRoaXMtPnNJbmZvLmR3RmxhZ3MgfD0gQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTOwoKICAgIC8qIHNpbXBseSBzYXkgYWxsIGNvbG9ycyBoYXZlIGNoYW5nZWQgKi8KICAgIGNrLmNraWQgICA9IE1BS0VBVklDS0lEKGNrdHlwZVBBTGNoYW5nZSwgVGhpcy0+blN0cmVhbSk7CiAgICBjay5ja3NpemUgPSAyICogc2l6ZW9mKFdPUkQpICsgbHBiaU9sZC0+YmlDbHJVc2VkICogc2l6ZW9mKFBBTEVUVEVFTlRSWSk7CiAgICBscHBjID0gKEFWSVBBTENIQU5HRSopR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgY2suY2tzaXplKTsKICAgIGlmIChscHBjID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIGxwcGMtPmJGaXJzdEVudHJ5ID0gMDsKICAgIGxwcGMtPmJOdW1FbnRyaWVzID0gKGxwYmlPbGQtPmJpQ2xyVXNlZCA8IDI1NiA/IGxwYmlPbGQtPmJpQ2xyVXNlZCA6IDApOwogICAgbHBwYy0+d0ZsYWdzICAgICAgPSAwOwogICAgZm9yIChuID0gMDsgbiA8IGxwYmlPbGQtPmJpQ2xyVXNlZDsgbisrKSB7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlUmVkICAgPSByZ2JOZXdbbl0ucmdiUmVkOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUdyZWVuID0gcmdiTmV3W25dLnJnYkdyZWVuOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUJsdWUgID0gcmdiTmV3W25dLnJnYkJsdWU7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlRmxhZ3MgPSAwOwogICAgfQoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpbHBwYywgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MgKz0gY2suY2tzaXplICsgMiAqIHNpemVvZihEV09SRCk7CgogICAgR2xvYmFsRnJlZVB0cihscHBjKTsKCiAgICByZXR1cm4gQVZJRklMRV9BZGRGcmFtZShUaGlzLCBja3R5cGVQQUxjaGFuZ2UsIG4sIGNrLmR3RGF0YU9mZnNldCwgMCk7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCUxPTkcgYnVmZmVyc2l6ZSwgTFBMT05HIGJ5dGVzcmVhZCwKCQkJCQlMUExPTkcgc2FtcGxlc3JlYWQpCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBEV09SRCAgICBzaXplOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCiAJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQgPiBzdGFydCkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOyAvKiBjb3VsZG4ndCByZWFkIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0gKi8KICBpZiAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKERXT1JEKXN0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7IC8qIHN0YXJ0IGlzIHBhc3QgZW5kIG9mIHN0cmVhbSAqLwoKICAvKiBzaG91bGQgd2UgcmVhZCBhcyBtdWNoIGFzIHBvc3NpYmxlPyAqLwogIGlmIChzYW1wbGVzID09IC0xKSB7CiAgICAvKiBVc2VyIHNob3VsZCBrbm93IGhvdyBtdWNoIHdlIGhhdmUgcmVhZCAqLwogICAgaWYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKQogICAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGVsc2UKICAgICAgc2FtcGxlcyA9IDE7CiAgfQoKICAvKiBsaW1pdCB0byBlbmQgb2Ygc3RyZWFtICovCiAgaWYgKChMT05HKVRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgc2FtcGxlcykKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICBpZiAoKHN0YXJ0IC0gVGhpcy0+c0luZm8uZHdTdGFydCkgPiAoVGhpcy0+c0luZm8uZHdMZW5ndGggLSBzYW1wbGVzKSkKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aCAtIChzdGFydCAtIFRoaXMtPnNJbmZvLmR3U3RhcnQpOwoKICAvKiBub3RoaW5nIHRvIHJlYWQ/IFRoZW4gbGVhdmUgLi4uICovCiAgaWYgKHNhbXBsZXMgPT0gMCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgLyogZml4ZWQgc2FtcGxlc2l6ZSAtLSB3ZSBjYW4gcmVhZCBvdmVyIGZyYW1lL2Jsb2NrIGJvdW5kYXJpZXMgKi8KICAgIExPTkcgYmxvY2sgID0gc3RhcnQ7CiAgICBMT05HIG9mZnNldCA9IDA7CgogICAgLyogY29udmVydCBzdGFydCBzYW1wbGUgdG8gYmxvY2ssb2Zmc2V0IHBhaXIgKi8KICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soVGhpcywgJmJsb2NrLCAmb2Zmc2V0KTsKCiAgICAvKiBjb252ZXJ0IHNhbXBsZXMgdG8gYnl0ZXMgKi8KICAgIHNhbXBsZXMgKj0gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwoKICAgIHdoaWxlIChzYW1wbGVzID4gMCAmJiBidWZmZXJzaXplID4gMCkgewogICAgICBpZiAoYmxvY2sgIT0gVGhpcy0+ZHdDdXJyZW50RnJhbWUpIHsKCWhyID0gQVZJRklMRV9SZWFkQmxvY2soVGhpcywgYmxvY2ssIE5VTEwsIDApOwoJaWYgKEZBSUxFRChocikpCgkgIHJldHVybiBocjsKICAgICAgfQoKICAgICAgc2l6ZSA9IG1pbigoRFdPUkQpc2FtcGxlcywgKERXT1JEKWJ1ZmZlcnNpemUpOwogICAgICBzaXplID0gbWluKHNpemUsIFRoaXMtPmNiQnVmZmVyIC0gb2Zmc2V0KTsKICAgICAgbWVtY3B5KGJ1ZmZlciwgKChCWVRFKikmVGhpcy0+bHBCdWZmZXJbMl0pICsgb2Zmc2V0LCBzaXplKTsKCiAgICAgIGJsb2NrKys7CiAgICAgIG9mZnNldCA9IDA7CiAgICAgICgoQllURSopYnVmZmVyKSArPSBzaXplOwogICAgICBzYW1wbGVzICAgIC09IHNpemU7CiAgICAgIGJ1ZmZlcnNpemUgLT0gc2l6ZTsKCiAgICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKCSpieXRlc3JlYWQgICArPSBzaXplOwogICAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKCSpzYW1wbGVzcmVhZCArPSBzaXplIC8gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgfQoKICAgIGlmIChzYW1wbGVzID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICBlbHNlCiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfSBlbHNlIHsKICAgIC8qIHZhcmlhYmxlIHNhbXBsZXNpemUgLS0gd2UgY2FuIG9ubHkgcmVhZCBvbmUgZnVsbCBmcmFtZS9ibG9jayAqLwogICAgaWYgKHNhbXBsZXMgPiAxKQogICAgICBzYW1wbGVzID0gMTsKCiAgICBhc3NlcnQoc3RhcnQgPD0gVGhpcy0+bExhc3RGcmFtZSk7CiAgICBzaXplID0gVGhpcy0+aWR4RnJhbWVzW3N0YXJ0XS5kd0NodW5rTGVuZ3RoOwogICAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmZlcnNpemUgPj0gc2l6ZSkgewogICAgICBociA9IEFWSUZJTEVfUmVhZEJsb2NrKFRoaXMsIHN0YXJ0LCBidWZmZXIsIHNpemUpOwogICAgICBpZiAoRkFJTEVEKGhyKSkKCXJldHVybiBocjsKICAgIH0gZWxzZSBpZiAoYnVmZmVyICE9IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CgogICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IHNpemU7CiAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCSBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkJCSBMUExPTkcgc2FtcHdyaXR0ZW4sCgkJCQkJIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBJQ09NX1RISVMoSUFWSVN0cmVhbUltcGwsaWZhY2UpOwoKICBGT1VSQ0MgIGNraWQ7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLAoJYnVmZmVyLCBidWZmZXJzaXplLCBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMICYmIChidWZmZXJzaXplID4gMCB8fCBzYW1wbGVzID4gMCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHdlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBzd2l0Y2ggKFRoaXMtPnNJbmZvLmZjY1R5cGUpIHsKICBjYXNlIHN0cmVhbXR5cGVBVURJTzoKICAgIGNraWQgPSBNQUtFQVZJQ0tJRChja3R5cGVXQVZFYnl0ZXMsIFRoaXMtPm5TdHJlYW0pOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGlmICgoZmxhZ3MgJiBBVklJRl9LRVlGUkFNRSkgJiYgYnVmZmVyc2l6ZSAhPSAwKQogICAgICBja2lkID0gTUFLRUFWSUNLSUQoY2t0eXBlRElCYml0cywgVGhpcy0+blN0cmVhbSk7CiAgICBlbHNlCiAgICAgIGNraWQgPSBNQUtFQVZJQ0tJRChja3R5cGVESUJjb21wcmVzc2VkLCBUaGlzLT5uU3RyZWFtKTsKICAgIGJyZWFrOwogIH07CgogIC8qIGFwcGVuZCB0byBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmIChzdGFydCA9PSAtMSkgewogICAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPT0gLTEpCiAgICAgIHN0YXJ0ID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGVsc2UKICAgICAgc3RhcnQgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICB9IGVsc2UgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPT0gLTEpCiAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ID0gc3RhcnQ7CgogIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgLyogZml4ZWQgc2FtcGxlIHNpemUgLS0gYXVkaW8gbGlrZSAqLwogICAgaWYgKHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gYnVmZmVyc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgICAvKiBDb3VsZG4ndCBza2lwIGF1ZGlvLWxpa2UgZGF0YSAtLSBVc2VyIG11c3Qgc3VwcGx5IGFwcHJvcHJpYXRlIHNpbGVuY2UgKi8KICAgIGlmIChUaGlzLT5zSW5mby5kd0xlbmd0aCAhPSBzdGFydCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICAvKiBDb252ZXJ0IHBvc2l0aW9uIHRvIGZyYW1lL2Jsb2NrICovCiAgICBzdGFydCA9IFRoaXMtPmxMYXN0RnJhbWUgKyAxOwoKICAgIGlmICgoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSVNJTlRFUkxFQVZFRCkgPT0gMCkgewogICAgICBGSVhNRSgiOiBub3QgaW50ZXJsZWF2ZWQsIGNvdWxkIGNvbGxlY3QgYXVkaW8gZGF0YSFcbiIpOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiB2YXJpYWJsZSBzYW1wbGUgc2l6ZSAtLSB2aWRlbyBsaWtlICovCiAgICBpZiAoc2FtcGxlcyA+IDEpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogbXVzdCB3ZSBmaWxsIHVwIHdpdGggZW1wdHkgZnJhbWVzPyAqLwogICAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgIT0gLTEpIHsKICAgICAgRk9VUkNDIGNraWQyID0gTUFLRUFWSUNLSUQoY2t0eXBlRElCY29tcHJlc3NlZCwgVGhpcy0+blN0cmVhbSk7CgogICAgICB3aGlsZSAoc3RhcnQgPiBUaGlzLT5sTGFzdEZyYW1lICsgMSkgewoJaHIgPSBBVklGSUxFX1dyaXRlQmxvY2soVGhpcywgVGhpcy0+bExhc3RGcmFtZSArIDEsIGNraWQyLCAwLCBOVUxMLCAwKTsKCWlmIChGQUlMRUQoaHIpKQoJICByZXR1cm4gaHI7CiAgICAgIH0KICAgIH0KICB9CgogIC8qIHdyaXRlIHRoZSBibG9jayBub3cgKi8KICBociA9IEFWSUZJTEVfV3JpdGVCbG9jayhUaGlzLCBzdGFydCwgY2tpZCwgZmxhZ3MsIGJ1ZmZlciwgYnVmZmVyc2l6ZSk7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICAgKnNhbXB3cml0dGVuID0gc2FtcGxlczsKICAgIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICAgKmJ5dGVzd3JpdHRlbiA9IGJ1ZmZlcnNpemU7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSAgTE9ORyBzYW1wbGVzKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgRklYTUUoIiglcCwlbGQsJWxkKTogc3R1YlxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzdGFydCA8IDAgfHwgc2FtcGxlcyA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEZWxldGUgYmVmb3JlIHN0YXJ0IG9mIHN0cmVhbT8gKi8KICBpZiAoc3RhcnQgKyBzYW1wbGVzIDwgVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIERlbGV0ZSBhZnRlciBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmIChzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRm9yIHRoZSByZXN0IHdlIG5lZWQgd3JpdGUgcGVybWlzc2lvbnMgKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIDEuIG92ZXJ3cml0ZSB0aGUgZGF0YSB3aXRoIEpVTksKICAgKgogICAqIGlmIElTSU5URVJMRUFWRUQgewogICAqICAgMi4gY29uY2F0IGFsbCBuZWlnaGJvdXJlZCBKVU5LLWJsb2NrcyBpbiB0aGlzIHJlY29yZCB0byBvbmUKICAgKiAgIDMuIGlmIHRoaXMgcmVjb3JkIG9ubHkgY29udGFpbnMgSlVOSyBhbmQgaXMgYXQgZW5kIHNldCBkd05leHRGcmFtZVBvcwogICAqICAgICAgdG8gc3RhcnQgb2YgdGhpcyByZWNvcmQsIHJlcGVhdCB0aGlzLgogICAqIH0gZWxzZSB7CiAgICogICAyLiBjb25jYXQgYWxsIG5laWdoYm91cmVkIEpVTkstYmxvY2tzLgogICAqICAgMy4gaWYgdGhlIEpVTksgYmxvY2sgaXMgYXQgdGhlIGVuZCwgdGhlbiBzZXQgZHdOZXh0RnJhbWVQb3MgdG8KICAgKiAgICAgIHN0YXJ0IG9mIHRoaXMgYmxvY2suCiAgICogfQogICAqLwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgIExQVk9JRCBscCwgTFBMT05HIGxwcmVhZCkKewogIElDT01fVEhJUyhJQVZJU3RyZWFtSW1wbCxpZmFjZSk7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBmY2MsIGxwLCBscHJlYWQpOwoKICBpZiAoZmNjID09IGNraWRTVFJFQU1IQU5ETEVSREFUQSkgewogICAgaWYgKFRoaXMtPmxwSGFuZGxlckRhdGEgIT0gTlVMTCAmJiBUaGlzLT5jYkhhbmRsZXJEYXRhID4gMCkgewogICAgICBpZiAobHAgPT0gTlVMTCB8fCAqbHByZWFkIDw9IDApIHsKCSpscHJlYWQgPSBUaGlzLT5jYkhhbmRsZXJEYXRhOwoJcmV0dXJuIEFWSUVSUl9PSzsKICAgICAgfQoKICAgICAgbWVtY3B5KGxwLCBUaGlzLT5scEhhbmRsZXJEYXRhLCBtaW4oVGhpcy0+Y2JIYW5kbGVyRGF0YSwgKmxwcmVhZCkpOwogICAgICBpZiAoKmxwcmVhZCA8IFRoaXMtPmNiSGFuZGxlckRhdGEpCglyZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgfSBlbHNlCiAgICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwogIH0gZWxzZQogICAgcmV0dXJuIFJlYWRFeHRyYUNodW5rKCZUaGlzLT5leHRyYSwgZmNjLCBscCwgbHByZWFkKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgIExQVk9JRCBscCwgTE9ORyBzaXplKQp7CiAgSUNPTV9USElTKElBVklTdHJlYW1JbXBsLGlmYWNlKTsKCiAgVFJBQ0UoIiglcCwweCUwOGx4LCVwLCVsZClcbiIsIGlmYWNlLCBmY2MsIGxwLCBzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBuZWVkIHdyaXRlIHBlcm1pc3Npb24gKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIGFscmVhZHkgd3JpdHRlbiBzb21ldGhpbmcgdG8gdGhpcyBmaWxlPyAqLwogIGlmIChUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zICE9IDApIHsKICAgIC8qIHRoZSBkYXRhIHdpbGwgYmUgaW5zZXJ0ZWQgYmVmb3JlIHRoZSAnbW92aScgY2h1bmssIHNvIGNoZWNrIGZvcgogICAgICogZW5vdWdoIHNwYWNlICovCiAgICBEV09SRCBkd1BvcyA9IEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChUaGlzLT5wYWYpOwoKICAgIC8qIGNraWQsc2l6ZSA9PiAyICogc2l6ZW9mKERXT1JEKSAqLwogICAgZHdQb3MgKz0gMiAqIHNpemVvZihEV09SRCkgKyBzaXplOwogICAgaWYgKHNpemUgPj0gVGhpcy0+cGFmLT5kd01vdmlDaHVua1BvcyAtIDIgKiBzaXplb2YoRFdPUkQpKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOyAvKiBub3QgZW5vdWdoIHNwYWNlIGxlZnQgKi8KICB9CgogIFRoaXMtPnBhZi0+ZkRpcnR5ID0gVFJVRTsKCiAgaWYgKGZjYyA9PSBja2lkU1RSRUFNSEFORExFUkRBVEEpIHsKICAgIGlmIChUaGlzLT5scEhhbmRsZXJEYXRhICE9IE5VTEwpIHsKICAgICAgRklYTUUoIjogaGFuZGxlciBkYXRhIGFscmVhZHkgc2V0IC0tIG92ZXJ3aXJ0ZT9cbiIpOwogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwogICAgfQoKICAgIFRoaXMtPmxwSGFuZGxlckRhdGEgPSBHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBzaXplKTsKICAgIGlmIChUaGlzLT5scEhhbmRsZXJEYXRhID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+Y2JIYW5kbGVyRGF0YSA9IHNpemU7CiAgICBtZW1jcHkoVGhpcy0+bHBIYW5kbGVyRGF0YSwgbHAsIHNpemUpOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gV3JpdGVFeHRyYUNodW5rKCZUaGlzLT5leHRyYSwgZmNjLCBscCwgc2l6ZSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtICppZmFjZSwKCQkJCQkgICBMUEFWSVNUUkVBTUlORk9XIGluZm8sIExPTkcgaW5mb2xlbikKewogIEZJWE1FKCIoJXAsJXAsJWxkKTogc3R1YlxuIiwgaWZhY2UsIGluZm8sIGluZm9sZW4pOwoKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZEZyYW1lKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBja2lkLCBEV09SRCBzaXplLCBEV09SRCBvZmZzZXQsIERXT1JEIGZsYWdzKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKCiAgc3dpdGNoIChUV09DQ0Zyb21GT1VSQ0MoY2tpZCkpIHsKICBjYXNlIGNrdHlwZURJQmJpdHM6CiAgICBpZiAoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fVFJVU1RDS1RZUEUpCiAgICAgIGZsYWdzIHw9IEFWSUlGX0tFWUZSQU1FOwogICAgYnJlYWs7CiAgY2FzZSBja3R5cGVESUJjb21wcmVzc2VkOgogICAgaWYgKFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX1RSVVNUQ0tUWVBFKQogICAgICBmbGFncyAmPSB+QVZJSUZfS0VZRlJBTUU7CiAgICBicmVhazsKICBjYXNlIGNrdHlwZVBBTGNoYW5nZToKICAgIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlICE9IHN0cmVhbXR5cGVWSURFTykgewogICAgICBFUlIoIjogZm91bmQgcGFsZXR0ZSBjaGFuZ2UgaW4gbm9uLXZpZGVvIHN0cmVhbSFcbiIpOwogICAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKICAgIH0KICAgIFRoaXMtPnNJbmZvLmR3RmxhZ3MgfD0gQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTOwogICAgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCsrOwoKICAgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzID09IE5VTEwgfHwgVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCA8IFRoaXMtPm5JZHhGbXRDaGFuZ2VzKSB7CiAgICAgIFVJTlQgbiA9IFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7CgogICAgICBUaGlzLT5uSWR4Rm10Q2hhbmdlcyArPSAxNjsKICAgICAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXMgPT0gTlVMTCkKCVRoaXMtPmlkeEZtdENoYW5nZXMgPQoJICBHbG9iYWxBbGxvY1B0cihHSE5ELCBUaGlzLT5uSWR4Rm10Q2hhbmdlcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGVsc2UKCVRoaXMtPmlkeEZtdENoYW5nZXMgPQoJICBHbG9iYWxSZUFsbG9jUHRyKFRoaXMtPmlkeEZtdENoYW5nZXMsCgkJCSAgIFRoaXMtPm5JZHhGbXRDaGFuZ2VzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpLCBHSE5EKTsKICAgICAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXMgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgICAgVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkICAgICAgICAgID0gVGhpcy0+bExhc3RGcmFtZTsKICAgICAgVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5kd0ZsYWdzICAgICAgID0gMDsKICAgICAgVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5kd0NodW5rT2Zmc2V0ID0gb2Zmc2V0OwogICAgICBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmR3Q2h1bmtMZW5ndGggPSBzaXplOwoKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgY2t0eXBlV0FWRWJ5dGVzOgogICAgaWYgKFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX1RSVVNUQ0tUWVBFKQogICAgICBmbGFncyB8PSBBVklJRl9LRVlGUkFNRTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBXQVJOKCI6IHVua25vd24gVFdPQ0MgMHglMDRYIGZvdW5kXG4iLCBUV09DQ0Zyb21GT1VSQ0MoY2tpZCkpOwogICAgYnJlYWs7CiAgfTsKCiAgLyogZmlyc3QgZnJhbWUgaXMgYWx3YXN5IGEga2V5ZnJhbWUgKi8KICBpZiAoVGhpcy0+bExhc3RGcmFtZSA9PSAtMSkKICAgIGZsYWdzIHw9IEFWSUlGX0tFWUZSQU1FOwoKICBpZiAoVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgc2l6ZSkKICAgIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IHNpemU7CgogIC8qIGdldCBtZW1vcnkgZm9yIGluZGV4ICovCiAgaWYgKFRoaXMtPmlkeEZyYW1lcyA9PSBOVUxMIHx8IFRoaXMtPmxMYXN0RnJhbWUgKyAxID49IFRoaXMtPm5JZHhGcmFtZXMpIHsKICAgIFRoaXMtPm5JZHhGcmFtZXMgKz0gNTEyOwogICAgaWYgKFRoaXMtPmlkeEZyYW1lcyA9PSBOVUxMKQogICAgICBUaGlzLT5pZHhGcmFtZXMgPQoJR2xvYmFsQWxsb2NQdHIoR0hORCwgVGhpcy0+bklkeEZyYW1lcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGVsc2UKCVRoaXMtPmlkeEZyYW1lcyA9CgkgIEdsb2JhbFJlQWxsb2NQdHIoVGhpcy0+aWR4RnJhbWVzLAoJCQkgICBUaGlzLT5uSWR4RnJhbWVzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpLCBHSE5EKTsKICAgIGlmIChUaGlzLT5pZHhGcmFtZXMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgfQoKICBUaGlzLT5sTGFzdEZyYW1lKys7CiAgVGhpcy0+aWR4RnJhbWVzW1RoaXMtPmxMYXN0RnJhbWVdLmNraWQgICAgICAgICAgPSBja2lkOwogIFRoaXMtPmlkeEZyYW1lc1tUaGlzLT5sTGFzdEZyYW1lXS5kd0ZsYWdzICAgICAgID0gZmxhZ3M7CiAgVGhpcy0+aWR4RnJhbWVzW1RoaXMtPmxMYXN0RnJhbWVdLmR3Q2h1bmtPZmZzZXQgPSBvZmZzZXQ7CiAgVGhpcy0+aWR4RnJhbWVzW1RoaXMtPmxMYXN0RnJhbWVdLmR3Q2h1bmtMZW5ndGggPSBzaXplOwoKICAvKiB1cGRhdGUgQVZJU1RSRUFNSU5GTyBzdHJ1Y3R1cmUgaWYgbmVjZXNzYXJ5ICovCiAgaWYgKFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDw9IFRoaXMtPmxMYXN0RnJhbWUpCiAgICBUaGlzLT5zSW5mby5kd0xlbmd0aCA9IFRoaXMtPmxMYXN0RnJhbWUgKyAxOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZFJlY29yZChJQVZJRmlsZUltcGwgKlRoaXMpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwgJiYgVGhpcy0+cHBTdHJlYW1zWzBdICE9IE5VTEwpOwoKICBpZiAoVGhpcy0+aWR4UmVjb3JkcyA9PSBOVUxMIHx8IFRoaXMtPmNiSWR4UmVjb3JkcyA9PSAwKSB7CiAgICBUaGlzLT5jYklkeFJlY29yZHMgKz0gMTAyNCAqIHNpemVvZihBVklJTkRFWEVOVFJZKTsKICAgIFRoaXMtPmlkeFJlY29yZHMgPSBHbG9iYWxBbGxvY1B0cihHSE5ELCBUaGlzLT5jYklkeFJlY29yZHMpOwogICAgaWYgKFRoaXMtPmlkeFJlY29yZHMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgfQoKICBhc3NlcnQoVGhpcy0+bklkeFJlY29yZHMgPCBUaGlzLT5jYklkeFJlY29yZHMvc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKCiAgVGhpcy0+aWR4UmVjb3Jkc1tUaGlzLT5uSWR4UmVjb3Jkc10uY2tpZCAgICAgICAgICA9IGxpc3R0eXBlQVZJUkVDT1JEOwogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmR3RmxhZ3MgICAgICAgPSBBVklJRl9MSVNUOwogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmR3Q2h1bmtPZmZzZXQgPQogICAgVGhpcy0+Y2tMYXN0UmVjb3JkLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpOwogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmR3Q2h1bmtMZW5ndGggPQogICAgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZTsKICBUaGlzLT5uSWR4UmVjb3JkcysrOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgRFdPUkQgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgRFdPUkQgZHdQb3M7CiAgRFdPUkQgblN0cmVhbTsKCiAgLyogUklGRixoZHJsLG1vdmksYXZpaCA9PiAoMyAqIDMgKyAyKSAqIHNpemVvZihEV09SRCkgPSAxMSAqIHNpemVvZihEV09SRCkgKi8KICBkd1BvcyA9IDExICogc2l6ZW9mKERXT1JEKSArIHNpemVvZihNYWluQVZJSGVhZGVyKTsKCiAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICBJQVZJU3RyZWFtSW1wbCAqcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKCiAgICAvKiBzdHJsLHN0cmgsc3RyZiA9PiAoMyArIDIgKiAyKSAqIHNpemVvZihEV09SRCkgPSA3ICogc2l6ZW9mKERXT1JEKSAqLwogICAgZHdQb3MgKz0gNyAqIHNpemVvZihEV09SRCkgKyBzaXplb2YoQVZJU3RyZWFtSGVhZGVyKTsKICAgIGR3UG9zICs9ICgocFN0cmVhbS0+Y2JGb3JtYXQgKyAxKSAmIH4xVSk7CiAgICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgPiAwKQogICAgICBkd1BvcyArPSAyICogc2l6ZW9mKERXT1JEKSArICgocFN0cmVhbS0+Y2JIYW5kbGVyRGF0YSArIDEpICYgfjFVKTsKICAgIGlmIChsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpID4gMCkKICAgICAgZHdQb3MgKz0gMiAqIHNpemVvZihEV09SRCkgKyAoKGxzdHJsZW5XKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkgKyAxKSAmIH4xVSk7CiAgfQoKICBpZiAoVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPT0gMCkgewogICAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgPSBkd1BvczsKCiAgICAvKiBwYWQgdG8gbXVsdGlwbGUgb2YgQVZJX0hFQURFUlNJWkUgb25seSBpZiB3ZSBhcmUgbW9yZSB0aGFuIDggYnl0ZXMgYXdheSBmcm9tIGl0ICovCiAgICBpZiAoKChkd1BvcyArIEFWSV9IRUFERVJTSVpFKSAmIH4oQVZJX0hFQURFUlNJWkUgLSAxKSkgLSBkd1BvcyA+IDIgKiBzaXplb2YoRFdPUkQpKQogICAgICBUaGlzLT5kd05leHRGcmFtZVBvcyA9IChkd1BvcyArIEFWSV9IRUFERVJTSVpFKSAmIH4oQVZJX0hFQURFUlNJWkUgLSAxKTsKCiAgICBUaGlzLT5kd01vdmlDaHVua1BvcyA9IFRoaXMtPmR3TmV4dEZyYW1lUG9zIC0gc2l6ZW9mKERXT1JEKTsKICB9CgogIHJldHVybiBkd1BvczsKfQoKc3RhdGljIHZvaWQgICAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oSUFWSUZpbGVJbXBsICpwYWYsIERXT1JEIG5yLCBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIElBVklTdHJlYW1JbXBsICpwc3RyZWFtOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChwYWYgIT0gTlVMTCk7CiAgYXNzZXJ0KG5yIDwgTUFYX0FWSVNUUkVBTVMpOwogIGFzc2VydChwYWYtPnBwU3RyZWFtc1tucl0gIT0gTlVMTCk7CgogIHBzdHJlYW0gPSBwYWYtPnBwU3RyZWFtc1tucl07CgogIHBzdHJlYW0tPmxwVnRibCAgICAgICAgID0gJmlhdmlzdDsKICBwc3RyZWFtLT5yZWYgICAgICAgICAgICA9IDA7CiAgcHN0cmVhbS0+cGFmICAgICAgICAgICAgPSBwYWY7CiAgcHN0cmVhbS0+blN0cmVhbSAgICAgICAgPSBucjsKICBwc3RyZWFtLT5kd0N1cnJlbnRGcmFtZSA9IChEV09SRCktMTsKICBwc3RyZWFtLT5sTGFzdEZyYW1lICAgID0gLTE7CgogIGlmIChhc2kgIT0gTlVMTCkgewogICAgbWVtY3B5KCZwc3RyZWFtLT5zSW5mbywgYXNpLCBzaXplb2YocHN0cmVhbS0+c0luZm8pKTsKCiAgICBpZiAoYXNpLT5kd0xlbmd0aCA+IDApIHsKICAgICAgLyogcHJlLWFsbG9jYXRlIG1lbSBmb3IgZnJhbWUtaW5kZXggc3RydWN0dXJlICovCiAgICAgIHBzdHJlYW0tPmlkeEZyYW1lcyA9CgkoQVZJSU5ERVhFTlRSWSopR2xvYmFsQWxsb2NQdHIoR0hORCwgYXNpLT5kd0xlbmd0aCAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGlmIChwc3RyZWFtLT5pZHhGcmFtZXMgIT0gTlVMTCkKCXBzdHJlYW0tPm5JZHhGcmFtZXMgPSBhc2ktPmR3TGVuZ3RoOwogICAgfQogICAgaWYgKGFzaS0+ZHdGb3JtYXRDaGFuZ2VDb3VudCA+IDApIHsKICAgICAgLyogcHJlLWFsbG9jYXRlIG1lbSBmb3IgZm9ybWF0Y2hhbmdlLWluZGV4IHN0cnVjdHVyZSAqLwogICAgICBwc3RyZWFtLT5pZHhGbXRDaGFuZ2VzID0KCShBVklJTkRFWEVOVFJZKilHbG9iYWxBbGxvY1B0cihHSE5ELCBhc2ktPmR3Rm9ybWF0Q2hhbmdlQ291bnQgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBpZiAocHN0cmVhbS0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMKQoJcHN0cmVhbS0+bklkeEZtdENoYW5nZXMgPSBhc2ktPmR3Rm9ybWF0Q2hhbmdlQ291bnQ7CiAgICB9CgogICAgLyogVGhlc2UgdmFsdWVzIHdpbGwgYmUgY29tcHV0ZWQgKi8KICAgIHBzdHJlYW0tPnNJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IDA7CiAgICBwc3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSAwOwogICAgcHN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAgID0gMDsKICAgIHBzdHJlYW0tPnNJbmZvLmR3RWRpdENvdW50ICAgICAgICAgICA9IDE7CiAgICBpZiAocHN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplID4gMCkKICAgICAgU2V0UmVjdEVtcHR5KCZwc3RyZWFtLT5zSW5mby5yY0ZyYW1lKTsKICB9CgogIHBzdHJlYW0tPnNJbmZvLmR3Q2FwcyA9IEFWSUZJTEVDQVBTX0NBTlJFQUR8QVZJRklMRUNBUFNfQ0FOV1JJVEU7Cn0KCnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oSUFWSVN0cmVhbUltcGwgKlRoaXMpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwoKICBUaGlzLT5kd0N1cnJlbnRGcmFtZSA9IChEV09SRCktMTsKICBUaGlzLT5sTGFzdEZyYW1lICAgID0gLTE7CiAgVGhpcy0+cGFmID0gTlVMTDsKICBpZiAoVGhpcy0+aWR4RnJhbWVzICE9IE5VTEwpIHsKICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+aWR4RnJhbWVzKTsKICAgIFRoaXMtPmlkeEZyYW1lcyAgPSBOVUxMOwogICAgVGhpcy0+bklkeEZyYW1lcyA9IDA7CiAgfQogIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzICE9IE5VTEwpIHsKICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+aWR4Rm10Q2hhbmdlcyk7CiAgICBUaGlzLT5pZHhGbXRDaGFuZ2VzID0gTlVMTDsKICB9CiAgaWYgKFRoaXMtPmxwQnVmZmVyICE9IE5VTEwpIHsKICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+bHBCdWZmZXIpOwogICAgVGhpcy0+bHBCdWZmZXIgPSBOVUxMOwogICAgVGhpcy0+Y2JCdWZmZXIgPSAwOwogIH0KICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMKSB7CiAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmxwSGFuZGxlckRhdGEpOwogICAgVGhpcy0+bHBIYW5kbGVyRGF0YSA9IE5VTEw7CiAgICBUaGlzLT5jYkhhbmRsZXJEYXRhID0gMDsKICB9CiAgaWYgKFRoaXMtPmV4dHJhLmxwICE9IE5VTEwpIHsKICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+ZXh0cmEubHApOwogICAgVGhpcy0+ZXh0cmEubHAgPSBOVUxMOwogICAgVGhpcy0+ZXh0cmEuY2IgPSAwOwogIH0KICBpZiAoVGhpcy0+bHBGb3JtYXQgIT0gTlVMTCkgewogICAgR2xvYmFsRnJlZVB0cihUaGlzLT5scEZvcm1hdCk7CiAgICBUaGlzLT5scEZvcm1hdCA9IE5VTEw7CiAgICBUaGlzLT5jYkZvcm1hdCA9IDA7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIE1haW5BVklIZWFkZXIgICBNYWluQVZJSGRyOwogIE1NQ0tJTkZPICAgICAgICBja1JJRkY7CiAgTU1DS0lORk8gICAgICAgIGNrTElTVDE7CiAgTU1DS0lORk8gICAgICAgIGNrTElTVDI7CiAgTU1DS0lORk8gICAgICAgIGNrOwogIElBVklTdHJlYW1JbXBsICpwU3RyZWFtOwogIERXT1JEICAgICAgICAgICBuU3RyZWFtOwogIEhSRVNVTFQgICAgICAgICBocjsKCiAgaWYgKFRoaXMtPmhtbWlvID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVPUEVOOwoKICAvKiBpbml0aWFsaXplIHN0cmVhbSBwdHIncyAqLwogIG1lbXNldChUaGlzLT5wcFN0cmVhbXMsIDAsIHNpemVvZihUaGlzLT5wcFN0cmVhbXMpKTsKCiAgLyogdHJ5IHRvIGdldCAiUklGRiIgY2h1bmsgLS0gbXVzdCBub3QgYmUgYXQgYmVnaW5uaW5nIG9mIGZpbGUhICovCiAgY2tSSUZGLmZjY1R5cGUgPSBmb3JtdHlwZUFWSTsKICBpZiAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZja1JJRkYsIE5VTEwsIE1NSU9fRklORFJJRkYpICE9IFNfT0spIHsKICAgIEVSUigiOiBub3QgYW4gQVZJIVxuIik7CiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIH0KCiAgLyogZ2V0ICJMSVNUIiAiaGRybCIgKi8KICBja0xJU1QxLmZjY1R5cGUgPSBsaXN0dHlwZUFWSUhFQURFUjsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZja0xJU1QxLCAmY2tSSUZGLCBNTUlPX0ZJTkRMSVNUKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgLyogZ2V0ICJhdmloIiBjaHVuayAqLwogIGNrLmNraWQgPSBja2lkQVZJTUFJTkhEUjsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDEsIE1NSU9fRklORENIVU5LKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgaWYgKGNrLmNrc2l6ZSAhPSBzaXplb2YoTWFpbkFWSUhkcikpIHsKICAgIEVSUigiOiBpbnZhbGlkIHNpemUgb2YgJWxkIGZvciBNYWluQVZJSGVhZGVyIVxuIiwgY2suY2tzaXplKTsKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwogIH0KICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUikmTWFpbkFWSUhkciwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBjaGVjayBmb3IgTUFYX0FWSVNUUkVBTVMgbGltaXQgKi8KICBpZiAoTWFpbkFWSUhkci5kd1N0cmVhbXMgPiBNQVhfQVZJU1RSRUFNUykgewogICAgV0FSTigiZmlsZSBjb250YWlucyAlbHUgc3RyZWFtcywgYnV0IG9ubHkgc3VwcG9ydHMgJWQgLS0gY2hhbmdlIE1BWF9BVklTVFJFQU1TIVxuIiwgTWFpbkFWSUhkci5kd1N0cmVhbXMsIE1BWF9BVklTVFJFQU1TKTsKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfQoKICAvKiBhZGp1c3QgcGVybWlzc2lvbnMgaWYgY29weXJpZ2h0ZWQgbWF0ZXJpYWwgaW4gZmlsZSAqLwogIGlmIChNYWluQVZJSGRyLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19DT1BZUklHSFRFRCkgewogICAgVGhpcy0+dU1vZGUgJj0gfk1NSU9fUldNT0RFOwogICAgVGhpcy0+dU1vZGUgfD0gTU1JT19SRUFEOwogIH0KCiAgLyogY29udmVydCBNYWluQVZJSGVhZGVyIGludG8gQVZJRklMSU5GT1cgKi8KICBtZW1zZXQoJlRoaXMtPmZJbmZvLCAwLCBzaXplb2YoVGhpcy0+ZkluZm8pKTsKICBUaGlzLT5mSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3TWljcm9TZWNQZXJGcmFtZTsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgICAgICAgICAgICAgPSAxMDAwMDAwOwogIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgICAgICA9IE1haW5BVklIZHIuZHdNYXhCeXRlc1BlclNlYzsKICBUaGlzLT5mSW5mby5kd0ZsYWdzICAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3RmxhZ3M7CiAgVGhpcy0+ZkluZm8uZHdDYXBzICAgICAgICAgICAgICAgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3VG90YWxGcmFtZXM7CiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd1N0cmVhbXM7CiAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gTWFpbkFWSUhkci5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgVGhpcy0+ZkluZm8uZHdXaWR0aCAgICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd1dpZHRoOwogIFRoaXMtPmZJbmZvLmR3SGVpZ2h0ICAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdIZWlnaHQ7CiAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQVZJRklMRVRZUEUsIFRoaXMtPmZJbmZvLnN6RmlsZVR5cGUsCgkgICAgICBzaXplb2YoVGhpcy0+ZkluZm8uc3pGaWxlVHlwZSkpOwoKICAvKiBnbyBiYWNrIHRvIGludG8gaGVhZGVyIGxpc3QgKi8KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogZm9yZWFjaCBzdHJlYW0gZXhpc3RzIGEgIkxJU1QiLCJzdHJsIiBjaHVuayAqLwogIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgLyogZ2V0IG5leHQgbmVzdGVkIGNodW5rIGluIHRoaXMgIkxJU1QiLCJzdHJsIiAqLwogICAgaWYgKG1taW9EZXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMiwgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogICAgLyogbmVzdGVkIGNodW5rIG11c3QgYmUgb2YgdHlwZSAiTElTVCIsInN0cmwiIC0tIHdoZW4gbm90IG5vcm1hbGx5IEpVTksgKi8KICAgIGlmIChja0xJU1QyLmNraWQgPT0gRk9VUkNDX0xJU1QgJiYKCWNrTElTVDIuZmNjVHlwZSA9PSBsaXN0dHlwZVNUUkVBTUhFQURFUikgewogICAgICBwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dID0KCShJQVZJU3RyZWFtSW1wbCopTG9jYWxBbGxvYyhMUFRSLCBzaXplb2YoSUFWSVN0cmVhbUltcGwpKTsKICAgICAgaWYgKHBTdHJlYW0gPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBBVklGSUxFX0NvbnN0cnVjdEFWSVN0cmVhbShUaGlzLCBuU3RyZWFtLCBOVUxMKTsKCiAgICAgIGNrLmNraWQgPSAwOwogICAgICB3aGlsZSAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDIsIDApID09IFNfT0spIHsKCXN3aXRjaCAoY2suY2tpZCkgewoJY2FzZSBja2lkU1RSRUFNSEFORExFUkRBVEE6CgkgIGlmIChwU3RyZWFtLT5scEhhbmRsZXJEYXRhICE9IE5VTEwpCgkgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgkgIHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgPSBHbG9iYWxBbGxvY1B0cihHTUVNX0RERVNIQVJFfEdNRU1fTU9WRUFCTEUsCgkJCQkJCSAgY2suY2tzaXplKTsKCSAgaWYgKHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgPT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCSAgcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YSA9IGNrLmNrc2l6ZTsKCgkgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKXBTdHJlYW0tPmxwSGFuZGxlckRhdGEsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgkgIGJyZWFrOwoJY2FzZSBja2lkU1RSRUFNRk9STUFUOgoJICBpZiAocFN0cmVhbS0+bHBGb3JtYXQgIT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKICAgICAgICAgIGlmIChjay5ja3NpemUgPT0gMCkKICAgICAgICAgICAgYnJlYWs7CgoJICBwU3RyZWFtLT5scEZvcm1hdCA9IEdsb2JhbEFsbG9jUHRyKEdNRU1fRERFU0hBUkV8R01FTV9NT1ZFQUJMRSwKCQkJCQkgICAgIGNrLmNrc2l6ZSk7CgkgIGlmIChwU3RyZWFtLT5scEZvcm1hdCA9PSBOVUxMKQoJICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoJICBwU3RyZWFtLT5jYkZvcm1hdCA9IGNrLmNrc2l6ZTsKCgkgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKXBTdHJlYW0tPmxwRm9ybWF0LCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCSAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKCSAgaWYgKHBTdHJlYW0tPnNJbmZvLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKSB7CgkgICAgTFBCSVRNQVBJTkZPSEVBREVSIGxwYmkgPSAoTFBCSVRNQVBJTkZPSEVBREVSKXBTdHJlYW0tPmxwRm9ybWF0OwoKCSAgICAvKiBzb21lIGNvcnJlY3Rpb25zIHRvIHRoZSB2aWRlbyBmb3JtYXQgKi8KCSAgICBpZiAobHBiaS0+YmlDbHJVc2VkID09IDAgJiYgbHBiaS0+YmlCaXRDb3VudCA8PSA4KQoJICAgICAgbHBiaS0+YmlDbHJVc2VkID0gMXUgPDwgbHBiaS0+YmlCaXRDb3VudDsKCSAgICBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiA9PSBCSV9SR0IgJiYgbHBiaS0+YmlTaXplSW1hZ2UgPT0gMCkKCSAgICAgIGxwYmktPmJpU2l6ZUltYWdlID0gRElCV0lEVEhCWVRFUygqbHBiaSkgKiBscGJpLT5iaUhlaWdodDsKCSAgICBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiAhPSBCSV9SR0IgJiYgbHBiaS0+YmlCaXRDb3VudCA9PSA4KSB7CgkgICAgICBpZiAocFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciA9PSBtbWlvRk9VUkNDKCdSJywnTCcsJ0UnLCcwJykgfHwKCQkgIHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gbW1pb0ZPVVJDQygnUicsJ0wnLCdFJywnICcpKQoJCWxwYmktPmJpQ29tcHJlc3Npb24gPSBCSV9STEU4OwoJICAgIH0KCSAgICBpZiAobHBiaS0+YmlDb21wcmVzc2lvbiA9PSBCSV9SR0IgJiYKCQkocFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciA9PSAwIHx8CgkJIHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gbW1pb0ZPVVJDQygnTicsJ08nLCdOJywnRScpKSkKCSAgICAgIHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPSBjb21wdHlwZURJQjsKCgkgICAgLyogaW5pdCByY0ZyYW1lIGlmIGl0J3MgZW1wdHkgKi8KCSAgICBpZiAoSXNSZWN0RW1wdHkoJnBTdHJlYW0tPnNJbmZvLnJjRnJhbWUpKQoJICAgICAgU2V0UmVjdCgmcFN0cmVhbS0+c0luZm8ucmNGcmFtZSwgMCwgMCwgbHBiaS0+YmlXaWR0aCwgbHBiaS0+YmlIZWlnaHQpOwoJICB9CgkgIGJyZWFrOwoJY2FzZSBja2lkU1RSRUFNSEVBREVSOgoJICB7CgkgICAgc3RhdGljIGNvbnN0IFdDSEFSIHN0cmVhbVR5cGVGbXRbXSA9IHsnJScsJzQnLCcuJywnNCcsJ2gnLCdzJywwfTsKCgkgICAgQVZJU3RyZWFtSGVhZGVyIHN0cmVhbUhkcjsKCSAgICBXQ0hBUiAgICAgICAgICAgc3pUeXBlWzI1XTsKCSAgICBXQ0hBUiAgICAgICAgICAgc3RyZWFtTmFtZUZtdFsyNV07CgkgICAgVUlOVCAgICAgICAgICAgIGNvdW50OwoJICAgIExPTkcgICAgICAgICAgICBuID0gY2suY2tzaXplOwoKCSAgICBpZiAoY2suY2tzaXplID4gc2l6ZW9mKHN0cmVhbUhkcikpCgkgICAgICBuID0gc2l6ZW9mKHN0cmVhbUhkcik7CgoJICAgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKSZzdHJlYW1IZHIsIG4pICE9IG4pCgkgICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKCSAgICBwU3RyZWFtLT5zSW5mby5mY2NUeXBlICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZmNjVHlwZTsKCSAgICBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyICAgICAgICAgICAgPSBzdHJlYW1IZHIuZmNjSGFuZGxlcjsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0ZsYWdzICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdGbGFnczsKCSAgICBwU3RyZWFtLT5zSW5mby53UHJpb3JpdHkgICAgICAgICAgICAgPSBzdHJlYW1IZHIud1ByaW9yaXR5OwoJICAgIHBTdHJlYW0tPnNJbmZvLndMYW5ndWFnZSAgICAgICAgICAgICA9IHN0cmVhbUhkci53TGFuZ3VhZ2U7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdJbml0aWFsRnJhbWVzICAgICAgID0gc3RyZWFtSGRyLmR3SW5pdGlhbEZyYW1lczsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1NjYWxlICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdTY2FsZTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdSYXRlOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3U3RhcnQgICAgICAgICAgICAgICA9IHN0cmVhbUhkci5kd1N0YXJ0OwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IHN0cmVhbUhkci5kd0xlbmd0aDsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPQoJICAgICAgc3RyZWFtSGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1F1YWxpdHkgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdRdWFsaXR5OwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3U2FtcGxlU2l6ZSAgICAgICAgICA9IHN0cmVhbUhkci5kd1NhbXBsZVNpemU7CgkgICAgcFN0cmVhbS0+c0luZm8ucmNGcmFtZS5sZWZ0ICAgICAgICAgID0gc3RyZWFtSGRyLnJjRnJhbWUubGVmdDsKCSAgICBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnRvcCAgICAgICAgICAgPSBzdHJlYW1IZHIucmNGcmFtZS50b3A7CgkgICAgcFN0cmVhbS0+c0luZm8ucmNGcmFtZS5yaWdodCAgICAgICAgID0gc3RyZWFtSGRyLnJjRnJhbWUucmlnaHQ7CgkgICAgcFN0cmVhbS0+c0luZm8ucmNGcmFtZS5ib3R0b20gICAgICAgID0gc3RyZWFtSGRyLnJjRnJhbWUuYm90dG9tOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3RWRpdENvdW50ICAgICAgICAgICA9IDA7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAgID0gMDsKCgkgICAgLyogZ2VuZXJhdGUgZGVzY3JpcHRpb24gZm9yIHN0cmVhbSBsaWtlICJmaWxlbmFtZS5hdmkgVHlwZSAjbiIgKi8KCSAgICBpZiAoc3RyZWFtSGRyLmZjY1R5cGUgPT0gc3RyZWFtdHlwZVZJREVPKQoJICAgICAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfVklERU8sIHN6VHlwZSwgc2l6ZW9mKHN6VHlwZSkpOwoJICAgIGVsc2UgaWYgKHN0cmVhbUhkci5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKCSAgICAgIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX0FVRElPLCBzelR5cGUsIHNpemVvZihzelR5cGUpKTsKCSAgICBlbHNlCgkgICAgICB3c3ByaW50Zlcoc3pUeXBlLCBzdHJlYW1UeXBlRm10LCAoY2hhciopJnN0cmVhbUhkci5mY2NUeXBlKTsKCgkgICAgLyogZ2V0IGNvdW50IG9mIHRoaXMgc3RyZWFtdHlwZSB1cCB0byB0aGlzIHN0cmVhbSAqLwoJICAgIGNvdW50ID0gMDsKCSAgICBmb3IgKG4gPSBuU3RyZWFtOyAwIDw9IG47IG4tLSkgewoJICAgICAgaWYgKFRoaXMtPnBwU3RyZWFtc1tuXS0+c0luZm8uZmNjSGFuZGxlciA9PSBzdHJlYW1IZHIuZmNjVHlwZSkKCQljb3VudCsrOwoJICAgIH0KCgkgICAgbWVtc2V0KHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwgMCwgc2l6ZW9mKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkpOwoKCSAgICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19BVklTVFJFQU1GT1JNQVQsIHN0cmVhbU5hbWVGbXQsIHNpemVvZihzdHJlYW1OYW1lRm10KSk7CgoJICAgIC8qIEZJWE1FOiBhdm9pZCBvdmVyZmxvdyAtLSBiZXR0ZXIgdXNlIHdzbnByaW50ZlcsIHdoaWNoIGRvZXNuJ3QgZXhpc3RzICEgKi8KCSAgICB3c3ByaW50ZlcocFN0cmVhbS0+c0luZm8uc3pOYW1lLCBzdHJlYW1OYW1lRm10LAoJCSAgICAgIEFWSUZJTEVfQmFzZW5hbWVXKFRoaXMtPnN6RmlsZU5hbWUpLCBzelR5cGUsIGNvdW50KTsKCSAgfQoJICBicmVhazsKCWNhc2UgY2tpZFNUUkVBTU5BTUU6CgkgIHsgLyogc3RyZWFtbmFtZSB3aWxsIGJlIHNhdmVkIGFzIEFTQ0lJIHN0cmluZyAqLwoJICAgIExQU1RSIHN0ciA9IChMUFNUUilMb2NhbEFsbG9jKExNRU1fRklYRUQsIGNrLmNrc2l6ZSk7CgkgICAgaWYgKHN0ciA9PSBOVUxMKQoJICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgoJICAgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKXN0ciwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCgkgICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKCSAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3RyLCAtMSwgcFN0cmVhbS0+c0luZm8uc3pOYW1lLAoJCQkJc2l6ZW9mKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkvc2l6ZW9mKHBTdHJlYW0tPnNJbmZvLnN6TmFtZVswXSkpOwoKCSAgICBMb2NhbEZyZWUoKEhMT0NBTClzdHIpOwoJICB9CgkgIGJyZWFrOwoJY2FzZSBja2lkQVZJUEFERElORzoKCWNhc2UgbW1pb0ZPVVJDQygncCcsJ2EnLCdkJywnZCcpOgoJICBicmVhazsKCWRlZmF1bHQ6CgkgIFdBUk4oIjogZm91bmQgZXh0cmEgY2h1bmsgMHglMDhsWFxuIiwgY2suY2tpZCk7CgkgIGhyID0gUmVhZENodW5rSW50b0V4dHJhKCZwU3RyZWFtLT5leHRyYSwgVGhpcy0+aG1taW8sICZjayk7CgkgIGlmIChGQUlMRUQoaHIpKQoJICAgIHJldHVybiBocjsKCX07CgoJaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCSAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLyogbmVzdGVkIGNodW5rcyBpbiAiTElTVCIsImhkcmwiIHdoaWNoIGFyZSBub3Qgb2YgdHlwZSAiTElTVCIsInN0cmwiICovCiAgICAgIGhyID0gUmVhZENodW5rSW50b0V4dHJhKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2tMSVNUMik7CiAgICAgIGlmIChGQUlMRUQoaHIpKQoJcmV0dXJuIGhyOwogICAgfQogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QyLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIH0KCiAgLyogcmVhZCBhbnkgZXh0cmEgaGVhZGVycyBpbiAiTElTVCIsImhkcmwiICovCiAgRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrLCAmY2tMSVNUMSwgMCk7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogc2VhcmNoICJMSVNUIiwibW92aSIgY2h1bmsgaW4gIlJJRkYiLCJBVkkgIiAqLwogIGNrTElTVDEuZmNjVHlwZSA9IGxpc3R0eXBlQVZJTU9WSUU7CiAgaHIgPSBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgJmNrUklGRiwKCQkJICAgICAgTU1JT19GSU5ETElTVCk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIFRoaXMtPmR3TW92aUNodW5rUG9zID0gY2tMSVNUMS5kd0RhdGFPZmZzZXQ7CiAgVGhpcy0+ZHdJZHhDaHVua1BvcyAgPSBja0xJU1QxLmNrc2l6ZSArIGNrTElTVDEuZHdEYXRhT2Zmc2V0OwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIHRyeSB0byBmaW5kIGFuIGluZGV4ICovCiAgY2suY2tpZCA9IGNraWRBVklORVdJTkRFWDsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sCgkJCSAgICAgICZjaywgJmNrUklGRiwgTU1JT19GSU5EQ0hVTkspOwogIGlmIChTVUNDRUVERUQoaHIpICYmIGNrLmNrc2l6ZSA+IDApIHsKICAgIGlmIChGQUlMRUQoQVZJRklMRV9Mb2FkSW5kZXgoVGhpcywgY2suY2tzaXplLCBja0xJU1QxLmR3RGF0YU9mZnNldCkpKQogICAgICBUaGlzLT5mSW5mby5kd0ZsYWdzICY9IH5BVklGSUxFSU5GT19IQVNJTkRFWDsKICB9CgogIC8qIHdoZW4gd2UgaGF2ZW4ndCBmb3VuZCBhbiBpbmRleCBvciBpdCdzIGJhZCwgdGhlbiBidWlsZCBvbmUKICAgKiBieSBwYXJzaW5nICdtb3ZpJyBjaHVuayAqLwogIGlmICgoVGhpcy0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0hBU0lOREVYKSA9PSAwKSB7CiAgICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspCiAgICAgIFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+bExhc3RGcmFtZSA9IC0xOwoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgY2tMSVNUMS5kd0RhdGFPZmZzZXQgKyBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCkgPT0gLTEpIHsKICAgICAgRVJSKCI6IE9vcHMsIGNhbid0IHNlZWsgYmFjayB0byAnbW92aScgY2h1bmshXG4iKTsKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIH0KCiAgICAvKiBzZWVrIHRocm91Z2ggdGhlICdtb3ZpJyBsaXN0IHVudGlsIGVuZCAqLwogICAgd2hpbGUgKG1taW9EZXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssICZja0xJU1QxLCAwKSA9PSBTX09LKSB7CiAgICAgIGlmIChjay5ja2lkICE9IEZPVVJDQ19MSVNUKSB7CglpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSA9PSBTX09LKSB7CgkgIG5TdHJlYW0gPSBTdHJlYW1Gcm9tRk9VUkNDKGNrLmNraWQpOwoKCSAgaWYgKG5TdHJlYW0gPiBUaGlzLT5mSW5mby5kd1N0cmVhbXMpCgkgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgoJICBBVklGSUxFX0FkZEZyYW1lKFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSwgY2suY2tpZCwgY2suY2tzaXplLAoJCQkgICBjay5kd0RhdGFPZmZzZXQgLSAyICogc2l6ZW9mKERXT1JEKSwgMCk7Cgl9IGVsc2UgewoJICBuU3RyZWFtID0gU3RyZWFtRnJvbUZPVVJDQyhjay5ja2lkKTsKCSAgV0FSTigiOiBmaWxlIHNlZW1zIHRvIGJlIHRydW5jYXRlZCFcbiIpOwoJICBpZiAoblN0cmVhbSA8PSBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKCSAgICAgIFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+c0luZm8uZHdTYW1wbGVTaXplID4gMCkgewoJICAgIGNrLmNrc2l6ZSA9IG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX0VORCk7CgkgICAgaWYgKGNrLmNrc2l6ZSAhPSAtMSkgewoJICAgICAgY2suY2tzaXplIC09IGNrLmR3RGF0YU9mZnNldDsKCSAgICAgIGNrLmNrc2l6ZSAmPSB+KFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+c0luZm8uZHdTYW1wbGVTaXplIC0gMSk7CgoJICAgICAgQVZJRklMRV9BZGRGcmFtZShUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0sIGNrLmNraWQsIGNrLmNrc2l6ZSwKCQkJICAgICAgIGNrLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpLCAwKTsKCSAgICB9CgkgIH0KCX0KICAgICAgfQogICAgfQogIH0KCiAgLyogZmluZCBvdGhlciBjaHVua3MgKi8KICBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssICZja1JJRkYsIDApOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIHNpemUsIERXT1JEIG9mZnNldCkKewogIEFWSUlOREVYRU5UUlkgKmxwOwogIERXT1JEICAgICAgICAgIHBvcywgbjsKICBIUkVTVUxUICAgICAgICBociA9IEFWSUVSUl9PSzsKICBCT09MICAgICAgICAgICBiQWJzb2x1dGUgPSBUUlVFOwoKICBscCA9IChBVklJTkRFWEVOVFJZKilHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLAoJCQkJICAgICAgSURYX1BFUl9CTE9DSyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogYWRqdXN0IGxpbWl0cyBmb3IgaW5kZXggdGFibGVzLCBzbyB0aGF0IGluc2VydGluZyB3aWxsIGJlIGZhc3RlciAqLwogIGZvciAobiA9IDA7IG4gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG4rKykgewogICAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbbl07CgogICAgcFN0cmVhbS0+bExhc3RGcmFtZSA9IC0xOwoKICAgIGlmIChwU3RyZWFtLT5pZHhGcmFtZXMgIT0gTlVMTCkgewogICAgICBHbG9iYWxGcmVlUHRyKHBTdHJlYW0tPmlkeEZyYW1lcyk7CiAgICAgIHBTdHJlYW0tPmlkeEZyYW1lcyAgPSBOVUxMOwogICAgICBwU3RyZWFtLT5uSWR4RnJhbWVzID0gMDsKICAgIH0KCiAgICBpZiAocFN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgICAgaWYgKG4gPiAwICYmIFRoaXMtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEKSB7CglwU3RyZWFtLT5uSWR4RnJhbWVzID0gVGhpcy0+cHBTdHJlYW1zWzBdLT5uSWR4RnJhbWVzOwogICAgICB9IGVsc2UgaWYgKHBTdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSkgewoJcFN0cmVhbS0+bklkeEZyYW1lcyA9CgkgIHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoIC8gcFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwogICAgICB9CiAgICB9IGVsc2UKICAgICAgcFN0cmVhbS0+bklkeEZyYW1lcyA9IHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoOwoKICAgIHBTdHJlYW0tPmlkeEZyYW1lcyA9CiAgICAgIChBVklJTkRFWEVOVFJZKilHbG9iYWxBbGxvY1B0cihHSE5ELCBwU3RyZWFtLT5uSWR4RnJhbWVzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgIGlmIChwU3RyZWFtLT5pZHhGcmFtZXMgPT0gTlVMTCAmJiBwU3RyZWFtLT5uSWR4RnJhbWVzID4gMCkgewogICAgICBwU3RyZWFtLT5uSWR4RnJhbWVzID0gMDsKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICB9CiAgfQoKICBwb3MgPSAoRFdPUkQpLTE7CiAgd2hpbGUgKHNpemUgIT0gMCkgewogICAgTE9ORyByZWFkID0gbWluKElEWF9QRVJfQkxPQ0sgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSksIHNpemUpOwoKICAgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKWxwLCByZWFkKSAhPSByZWFkKSB7CiAgICAgIGhyID0gQVZJRVJSX0ZJTEVSRUFEOwogICAgICBicmVhazsKICAgIH0KICAgIHNpemUgLT0gcmVhZDsKCiAgICBpZiAocG9zID09IChEV09SRCktMSkKICAgICAgcG9zID0gb2Zmc2V0IC0gbHAtPmR3Q2h1bmtPZmZzZXQgKyBzaXplb2YoRFdPUkQpOwoKICAgIEFWSUZJTEVfUGFyc2VJbmRleChUaGlzLCBscCwgcmVhZCAvIHNpemVvZihBVklJTkRFWEVOVFJZKSwKCQkgICAgICAgcG9zLCAmYkFic29sdXRlKTsKICB9CgogIGlmIChscCAhPSBOVUxMKQogICAgR2xvYmFsRnJlZVB0cihscCk7CgogIC8qIGNoZWNraW5nIC4uLiAqLwogIGZvciAobiA9IDA7IG4gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG4rKykgewogICAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbbl07CgogICAgaWYgKHBTdHJlYW0tPnNJbmZvLmR3U2FtcGxlU2l6ZSA9PSAwICYmCglwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCAhPSBwU3RyZWFtLT5sTGFzdEZyYW1lKzEpCiAgICAgIEVSUigic3RyZWFtICVsdSBsZW5ndGggbWlzbWF0Y2g6IGR3TGVuZ3RoPSVsdSBmb3VuZD0lbGRcbiIsCgkgICBuLCBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCwgcFN0cmVhbS0+bExhc3RGcmFtZSk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUGFyc2VJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIEFWSUlOREVYRU5UUlkgKmxwLAoJCQkJICBMT05HIGNvdW50LCBEV09SRCBwb3MsIEJPT0wgKmJBYnNvbHV0ZSkKewogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgZm9yICg7IGNvdW50ID4gMDsgY291bnQtLSwgbHArKykgewogICAgV09SRCBuU3RyZWFtID0gU3RyZWFtRnJvbUZPVVJDQyhscC0+Y2tpZCk7CgogICAgaWYgKGxwLT5ja2lkID09IGxpc3R0eXBlQVZJUkVDT1JEIHx8IG5TdHJlYW0gPT0gMHg3RikKICAgICAgY29udGludWU7IC8qIHNraXAgdGhlc2UgKi8KCiAgICBpZiAoblN0cmVhbSA+IFRoaXMtPmZJbmZvLmR3U3RyZWFtcykKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogICAgaWYgKCpiQWJzb2x1dGUgPT0gVFJVRSAmJiBscC0+ZHdDaHVua09mZnNldCA8IFRoaXMtPmR3TW92aUNodW5rUG9zKQogICAgICAqYkFic29sdXRlID0gRkFMU0U7CgogICAgaWYgKCpiQWJzb2x1dGUpCiAgICAgIGxwLT5kd0NodW5rT2Zmc2V0ICs9IHNpemVvZihEV09SRCk7CiAgICBlbHNlCiAgICAgIGxwLT5kd0NodW5rT2Zmc2V0ICs9IHBvczsKCiAgICBpZiAoRkFJTEVEKEFWSUZJTEVfQWRkRnJhbWUoVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLCBscC0+Y2tpZCwgbHAtPmR3Q2h1bmtMZW5ndGgsIGxwLT5kd0NodW5rT2Zmc2V0LCBscC0+ZHdGbGFncykpKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUmVhZEJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBwb3MsCgkJCQkgTFBWT0lEIGJ1ZmZlciwgTE9ORyBzaXplKQp7CiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoVGhpcyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5wYWYtPmhtbWlvICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5zSW5mby5kd1N0YXJ0IDw9IHBvcyAmJiBwb3MgPCBUaGlzLT5zSW5mby5kd0xlbmd0aCk7CiAgYXNzZXJ0KHBvcyA8PSBUaGlzLT5sTGFzdEZyYW1lKTsKCiAgLyogc2hvdWxkIHdlIHJlYWQgYXMgbXVjaCBhcyBibG9jayBnaXZlcyB1cz8gKi8KICBpZiAoc2l6ZSA9PSAwIHx8IHNpemUgPiBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoKQogICAgc2l6ZSA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGg7CgogIC8qIHJlYWQgaW50byBvdXQgb3duIGJ1ZmZlciBvciBnaXZlbiBvbmU/ICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMKSB7CiAgICAvKiB3ZSBhbHNvIHJlYWQgdGhlIGNodW5rICovCiAgICBzaXplICs9IDIgKiBzaXplb2YoRFdPUkQpOwoKICAgIC8qIGNoZWNrIHRoYXQgYnVmZmVyIGlzIGJpZyBlbm91Z2ggLS0gZG9uJ3QgdHJ1c3QgZHdTdWdnZXN0ZWRCdWZmZXJTaXplICovCiAgICBpZiAoVGhpcy0+bHBCdWZmZXIgPT0gTlVMTCB8fCBzaXplIDwgVGhpcy0+Y2JCdWZmZXIpIHsKICAgICAgRFdPUkQgbWF4U2l6ZSA9IG1heChzaXplLCBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwoKICAgICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwpCglUaGlzLT5scEJ1ZmZlciA9IChMUERXT1JEKUdsb2JhbEFsbG9jUHRyKEdNRU1fTU9WRUFCTEUsIG1heFNpemUpOwogICAgICBlbHNlCglUaGlzLT5scEJ1ZmZlciA9CgkgIChMUERXT1JEKUdsb2JhbFJlQWxsb2NQdHIoVGhpcy0+bHBCdWZmZXIsIG1heFNpemUsIEdNRU1fTU9WRUFCTEUpOwogICAgICBpZiAoVGhpcy0+bHBCdWZmZXIgPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBUaGlzLT5jYkJ1ZmZlciA9IG1heChzaXplLCBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUpOwogICAgfQoKICAgIC8qIG5vdyByZWFkIHRoZSBjb21wbGV0ZSBjaHVuayBpbnRvIG91ciBidWZmZXIgKi8KICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rT2Zmc2V0LCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICBpZiAobW1pb1JlYWQoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKVRoaXMtPmxwQnVmZmVyLCBzaXplKSAhPSBzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAgIC8qIGNoZWNrIGlmIGl0IHdhcyB0aGUgY29ycmVjdCBibG9jayB3aGljaCB3ZSBoYXZlIHJlYWQgKi8KICAgIGlmIChUaGlzLT5scEJ1ZmZlclswXSAhPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5ja2lkIHx8CglUaGlzLT5scEJ1ZmZlclsxXSAhPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoKSB7CiAgICAgIEVSUigiOiBibG9jayAlbGQgbm90IGZvdW5kIGF0IDB4JTA4bFhcbiIsIHBvcywgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCk7CiAgICAgIEVSUigiOiBJbmRleCBzYXlzOiAnJTQuNHMnKDB4JTA4bFgpIHNpemUgMHglMDhsWFxuIiwKCSAgKGNoYXIqKSZUaGlzLT5pZHhGcmFtZXNbcG9zXS5ja2lkLCBUaGlzLT5pZHhGcmFtZXNbcG9zXS5ja2lkLAoJICBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoKTsKICAgICAgRVJSKCI6IERhdGEgIHNheXM6ICclNC40cycoMHglMDhsWCkgc2l6ZSAweCUwOGxYXG4iLAoJICAoY2hhciopJlRoaXMtPmxwQnVmZmVyWzBdLCBUaGlzLT5scEJ1ZmZlclswXSwgVGhpcy0+bHBCdWZmZXJbMV0pOwogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgfQogIH0gZWxzZSB7CiAgICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgICBpZiAobW1pb1JlYWQoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgc2l6ZSkgIT0gc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIExQTE9ORyBwb3MsCgkJCQkgICAgICBMUExPTkcgb2Zmc2V0KQp7CiAgRFdPUkQgYmxvY2s7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KHBvcyAhPSBOVUxMKTsKICBhc3NlcnQob2Zmc2V0ICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCk7CiAgYXNzZXJ0KCpwb3MgPj0gVGhpcy0+c0luZm8uZHdTdGFydCk7CgogIC8qIGNvbnZlcnQgc3RhcnQgc2FtcGxlIHRvIHN0YXJ0IGJ5dGVzICovCiAgKCpvZmZzZXQpICA9ICgqcG9zKSAtIFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgKCpvZmZzZXQpICo9IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKCiAgLyogY29udmVydCBieXRlcyB0byBibG9jayBudW1iZXIgKi8KICBmb3IgKGJsb2NrID0gMDsgYmxvY2sgPD0gVGhpcy0+bExhc3RGcmFtZTsgYmxvY2srKykgewogICAgaWYgKFRoaXMtPmlkeEZyYW1lc1tibG9ja10uZHdDaHVua0xlbmd0aCA8PSAqb2Zmc2V0KQogICAgICAoKm9mZnNldCkgLT0gVGhpcy0+aWR4RnJhbWVzW2Jsb2NrXS5kd0NodW5rTGVuZ3RoOwogICAgZWxzZQogICAgICBicmVhazsKICB9CgogICpwb3MgPSBibG9jazsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBNYWluQVZJSGVhZGVyICAgTWFpbkFWSUhkcjsKICBJQVZJU3RyZWFtSW1wbCogcFN0cmVhbTsKICBNTUNLSU5GTyAgICAgICAgY2tSSUZGOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QxOwogIE1NQ0tJTkZPICAgICAgICBja0xJU1QyOwogIE1NQ0tJTkZPICAgICAgICBjazsKICBEV09SRCAgICAgICAgICAgblN0cmVhbTsKICBEV09SRCAgICAgICAgICAgZHdQb3M7CiAgSFJFU1VMVCAgICAgICAgIGhyOwoKICAvKiBpbml0aWFsaXplIHNvbWUgdGhpbmdzICovCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcyk7CgogIC8qIHdyaXR0ZW4gb25lIHJlY29yZCB0byBtdWNoPyAqLwogIGlmIChUaGlzLT5ja0xhc3RSZWNvcmQuZHdGbGFncyAmIE1NSU9fRElSVFkpIHsKICAgIFRoaXMtPmR3TmV4dEZyYW1lUG9zIC09IDMgKiBzaXplb2YoRFdPUkQpOwogICAgaWYgKFRoaXMtPm5JZHhSZWNvcmRzID4gMCkKICAgICAgVGhpcy0+bklkeFJlY29yZHMtLTsKICB9CgogIEFWSUZJTEVfVXBkYXRlSW5mbyhUaGlzKTsKCiAgYXNzZXJ0KFRoaXMtPmZJbmZvLmR3U2NhbGUgIT0gMCk7CgogIG1lbXNldCgmTWFpbkFWSUhkciwgMCwgc2l6ZW9mKE1haW5BVklIZHIpKTsKICBNYWluQVZJSGRyLmR3TWljcm9TZWNQZXJGcmFtZSAgICA9IE11bERpdihUaGlzLT5mSW5mby5kd1JhdGUsIDEwMDAwMDAsCgkJCQkJICAgIFRoaXMtPmZJbmZvLmR3U2NhbGUpOwogIE1haW5BVklIZHIuZHdNYXhCeXRlc1BlclNlYyAgICAgID0gVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYzsKICBNYWluQVZJSGRyLmR3UGFkZGluZ0dyYW51bGFyaXR5ICA9IEFWSV9IRUFERVJTSVpFOwogIE1haW5BVklIZHIuZHdGbGFncyAgICAgICAgICAgICAgID0gVGhpcy0+ZkluZm8uZHdGbGFnczsKICBNYWluQVZJSGRyLmR3VG90YWxGcmFtZXMgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3TGVuZ3RoOwogIE1haW5BVklIZHIuZHdJbml0aWFsRnJhbWVzICAgICAgID0gMDsKICBNYWluQVZJSGRyLmR3U3RyZWFtcyAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsKICBNYWluQVZJSGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICBNYWluQVZJSGRyLmR3V2lkdGggICAgICAgICAgICAgICA9IFRoaXMtPmZJbmZvLmR3V2lkdGg7CiAgTWFpbkFWSUhkci5kd0hlaWdodCAgICAgICAgICAgICAgPSBUaGlzLT5mSW5mby5kd0hlaWdodDsKICBNYWluQVZJSGRyLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IFRoaXMtPmR3SW5pdGlhbEZyYW1lczsKCiAgLyogbm93IGJlZ2luIHdyaXRpbmcgLi4uICovCiAgbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfU0VUKTsKCiAgLyogUklGRiBjaHVuayAqLwogIGNrUklGRi5ja3NpemUgID0gMDsKICBja1JJRkYuZmNjVHlwZSA9IGZvcm10eXBlQVZJOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja1JJRkYsIE1NSU9fQ1JFQVRFUklGRikgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBBVkkgaGVhZGVybGlzdCAqLwogIGNrTElTVDEuY2tzaXplICA9IDA7CiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklIRUFERVI7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDEsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBNYWluQVZJSGVhZGVyICovCiAgY2suY2tpZCAgICA9IGNraWRBVklNQUlOSERSOwogIGNrLmNrc2l6ZSAgPSBzaXplb2YoTWFpbkFWSUhkcik7CiAgY2suZmNjVHlwZSA9IDA7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZNYWluQVZJSGRyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogd3JpdGUgdGhlIGhlYWRlcnMgb2YgZWFjaCBzdHJlYW0gaW50byBhIHNlcGFyYXRlIHN0cmVhbWhlYWRlciBsaXN0ICovCiAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICBBVklTdHJlYW1IZWFkZXIgc3RySGRyOwoKICAgIHBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV07CgogICAgLyogYmVnaW4gdGhlIG5ldyBzdHJlYW1oZWFkZXIgbGlzdCAqLwogICAgY2tMSVNUMi5ja3NpemUgID0gMDsKICAgIGNrTElTVDIuZmNjVHlwZSA9IGxpc3R0eXBlU1RSRUFNSEVBREVSOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDIsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogICAgLyogY3JlYXRlIGFuIEFWSVN0cmVhbUhlYWRlciBmcm9tIHRoZSBBVlNUUkVBTUlORk8gKi8KICAgIHN0ckhkci5mY2NUeXBlICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5mY2NUeXBlOwogICAgc3RySGRyLmZjY0hhbmRsZXIgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXI7CiAgICBzdHJIZHIuZHdGbGFncyAgICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdGbGFnczsKICAgIHN0ckhkci53UHJpb3JpdHkgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby53UHJpb3JpdHk7CiAgICBzdHJIZHIud0xhbmd1YWdlICAgICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8ud0xhbmd1YWdlOwogICAgc3RySGRyLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lczsKICAgIHN0ckhkci5kd1NjYWxlICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1NjYWxlOwogICAgc3RySGRyLmR3UmF0ZSAgICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3UmF0ZTsKICAgIHN0ckhkci5kd1N0YXJ0ICAgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1N0YXJ0OwogICAgc3RySGRyLmR3TGVuZ3RoICAgICAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoOwogICAgc3RySGRyLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA9IHBTdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKICAgIHN0ckhkci5kd1F1YWxpdHkgICAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5kd1F1YWxpdHk7CiAgICBzdHJIZHIuZHdTYW1wbGVTaXplICAgICAgICAgID0gcFN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgc3RySGRyLnJjRnJhbWUubGVmdCAgICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUubGVmdDsKICAgIHN0ckhkci5yY0ZyYW1lLnRvcCAgICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnRvcDsKICAgIHN0ckhkci5yY0ZyYW1lLnJpZ2h0ICAgICAgICAgPSBwU3RyZWFtLT5zSW5mby5yY0ZyYW1lLnJpZ2h0OwogICAgc3RySGRyLnJjRnJhbWUuYm90dG9tICAgICAgICA9IHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUuYm90dG9tOwoKICAgIC8qIG5vdyB3cml0ZSB0aGUgQVZJU3RyZWFtSGVhZGVyICovCiAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNSEVBREVSOwogICAgY2suY2tzaXplID0gc2l6ZW9mKHN0ckhkcik7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZzdHJIZHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgIC8qIC4uLiB0aGUgaG9wZWZ1bGx5IGV2ZXIgcHJlc2VudCBzdHJlYW1mb3JtYXQgLi4uICovCiAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNRk9STUFUOwogICAgY2suY2tzaXplID0gcFN0cmVhbS0+Y2JGb3JtYXQ7CiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKHBTdHJlYW0tPmxwRm9ybWF0ICE9IE5VTEwgJiYgY2suY2tzaXplID4gMCkgewogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+bHBGb3JtYXQsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICAvKiAuLi4gc29tZSBvcHRpb25hbCBleGlzdGluZyBoYW5kbGVyIGRhdGEgLi4uICovCiAgICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgPiAwKSB7CiAgICAgIGNrLmNraWQgICA9IGNraWRTVFJFQU1IQU5ETEVSREFUQTsKICAgICAgY2suY2tzaXplID0gcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YTsKICAgICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5scEhhbmRsZXJEYXRhLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CgogICAgLyogLi4uIHNvbWUgb3B0aW9uYWwgYWRkaXRpb25hbCBleHRyYSBjaHVuayBmb3IgdGhpcyBzdHJlYW0gLi4uICovCiAgICBpZiAocFN0cmVhbS0+ZXh0cmEubHAgIT0gTlVMTCAmJiBwU3RyZWFtLT5leHRyYS5jYiA+IDApIHsKICAgICAgLyogdGhlIGNodW5rIGhlYWRlcihzKSBhcmUgYWxyZWFkeSBpbiB0aGUgc3RydWN1dHVyZSAqLwogICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpcFN0cmVhbS0+ZXh0cmEubHAsIHBTdHJlYW0tPmV4dHJhLmNiKSAhPSBwU3RyZWFtLT5leHRyYS5jYikKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgfQoKICAgIC8qIC4uLiBhbiBvcHRpb25hbCBuYW1lIGZvciB0aGlzIHN0cmVhbSAuLi4gKi8KICAgIGlmIChsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpID4gMCkgewogICAgICBMUFNUUiBzdHI7CgogICAgICBjay5ja2lkICAgPSBja2lkU1RSRUFNTkFNRTsKICAgICAgY2suY2tzaXplID0gbHN0cmxlblcocFN0cmVhbS0+c0luZm8uc3pOYW1lKSArIDE7CiAgICAgIGlmIChjay5ja3NpemUgJiAxKSAvKiBhbGlnbiAqLwoJY2suY2tzaXplKys7CiAgICAgIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgICAgLyogdGhlIHN0cmVhbW5hbWUgbXVzdCBiZSBzYXZlZCBpbiBBU0NJSSBub3QgVW5pY29kZSAqLwogICAgICBzdHIgPSAoTFBTVFIpTG9jYWxBbGxvYyhMUFRSLCBjay5ja3NpemUpOwogICAgICBpZiAoc3RyID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwgLTEsIHN0ciwKCQkJICBjay5ja3NpemUsIE5VTEwsIE5VTEwpOwoKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKXN0ciwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpIHsKCUxvY2FsRnJlZSgoSExPQ0FMKXN0cik7CQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIH0KCiAgICAgIExvY2FsRnJlZSgoSExPQ0FMKXN0cik7CiAgICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIH0KCiAgICAvKiBjbG9zZSBzdHJlYW1oZWFkZXIgbGlzdCBmb3IgdGhpcyBzdHJlYW0gKi8KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMiwgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfSAvKiBmb3IgKDAgPD0gblN0cmVhbSA8IE1haW5BVklIZHIuZHdTdHJlYW1zKSAqLwoKICAvKiBjbG9zZSB0aGUgYXZpaGVhZGVyIGxpc3QgKi8KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogY2hlY2sgZm9yIHBhZGRpbmcgdG8gcHJlLWd1ZXNzZWQgJ21vdmknLWNodW5rIHBvc2l0aW9uICovCiAgZHdQb3MgPSBja0xJU1QxLmR3RGF0YU9mZnNldCArIGNrTElTVDEuY2tzaXplOwogIGlmIChUaGlzLT5kd01vdmlDaHVua1BvcyAtIDIgKiBzaXplb2YoRFdPUkQpID4gZHdQb3MpIHsKICAgIGNrLmNraWQgICA9IGNraWRBVklQQURESU5HOwogICAgY2suY2tzaXplID0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgLSBkd1BvcyAtIDQgKiBzaXplb2YoRFdPUkQpOwogICAgYXNzZXJ0KChMT05HKWNrLmNrc2l6ZSA+PSAwKTsKCiAgICBpZiAobW1pb0NyZWF0ZUNodW5rKFRoaXMtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBjay5ja3NpemUsIFNFRUtfQ1VSKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CgogIC8qIG5vdyB3cml0ZSB0aGUgJ21vdmknIGNodW5rICovCiAgbW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmR3TW92aUNodW5rUG9zIC0gMiAqIHNpemVvZihEV09SRCksIFNFRUtfU0VUKTsKICBja0xJU1QxLmNrc2l6ZSAgPSAwOwogIGNrTElTVDEuZmNjVHlwZSA9IGxpc3R0eXBlQVZJTU9WSUU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrTElTVDEsIE1NSU9fQ1JFQVRFTElTVCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgVGhpcy0+ZHdOZXh0RnJhbWVQb3MsIFNFRUtfU0VUKSA9PSAtMSkKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiB3cml0ZSAnaWR4MScgY2h1bmsgKi8KICBociA9IEFWSUZJTEVfU2F2ZUluZGV4KFRoaXMpOwogIGlmIChGQUlMRUQoaHIpKQogICAgcmV0dXJuIGhyOwoKICAvKiB3cml0ZSBvcHRpb25hbCBleHRyYSBmaWxlIGNodW5rcyAqLwogIGlmIChUaGlzLT5maWxlZXh0cmEubHAgIT0gTlVMTCAmJiBUaGlzLT5maWxlZXh0cmEuY2IgPiAwKSB7CiAgICAvKiBhcyBmb3IgdGhlIHN0cmVhbXMsIGFyZSB0aGUgY2h1bmsgaGVhZGVyKHMpIGluIHRoZSBzdHJ1Y3R1cmUgKi8KICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilUaGlzLT5maWxlZXh0cmEubHAsIFRoaXMtPmZpbGVleHRyYS5jYikgIT0gVGhpcy0+ZmlsZWV4dHJhLmNiKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICB9CgogIC8qIGNsb3NlIFJJRkYgY2h1bmsgKi8KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrUklGRiwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAvKiBhZGQgc29tZSBKVU5LIGF0IGVuZCBmb3IgYmFkIHBhcnNlcnMgKi8KICBtZW1zZXQoJmNrUklGRiwgMCwgc2l6ZW9mKGNrUklGRikpOwogIG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZja1JJRkYsIHNpemVvZihja1JJRkYpKTsKICBtbWlvRmx1c2goVGhpcy0+aG1taW8sIDApOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVJbmRleChJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBJQVZJU3RyZWFtSW1wbCAqcFN0cmVhbTsKICBBVklJTkRFWEVOVFJZICAgaWR4OwogIE1NQ0tJTkZPICAgICAgICBjazsKICBEV09SRCAgICAgICAgICAgblN0cmVhbTsKICBMT05HICAgICAgICAgICAgbjsKCiAgY2suY2tpZCAgID0gY2tpZEFWSU5FV0lOREVYOwogIGNrLmNrc2l6ZSA9IDA7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIGlmIChUaGlzLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSVNJTlRFUkxFQVZFRCkgewogICAgLyogaXMgaW50ZXJsZWF2ZWQgLS0gd3JpdGUgYmxvY2sgb2YgY29yZXNwb25kaW5nIGZyYW1lcyAqLwogICAgTE9ORyBsSW5pdGlhbEZyYW1lcyA9IDA7CiAgICBMT05HIHN0ZXBzaXplOwogICAgTE9ORyBpOwoKICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbMF0tPnNJbmZvLmR3U2FtcGxlU2l6ZSA9PSAwKQogICAgICBzdGVwc2l6ZSA9IDE7CiAgICBlbHNlCiAgICAgIHN0ZXBzaXplID0gQVZJU3RyZWFtVGltZVRvU2FtcGxlKChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1swXSwgMTAwMDAwMCk7CgogICAgYXNzZXJ0KHN0ZXBzaXplID4gMCk7CgogICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICAgIGlmIChsSW5pdGlhbEZyYW1lcyA8IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+c0luZm8uZHdJbml0aWFsRnJhbWVzKQoJbEluaXRpYWxGcmFtZXMgPSBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lczsKICAgIH0KCiAgICBmb3IgKGkgPSAtbEluaXRpYWxGcmFtZXM7IGkgPCAoTE9ORylUaGlzLT5mSW5mby5kd0xlbmd0aCAtIGxJbml0aWFsRnJhbWVzOwoJIGkgKz0gc3RlcHNpemUpIHsKICAgICAgRFdPUkQgbkZyYW1lID0gbEluaXRpYWxGcmFtZXMgKyBpOwoKICAgICAgYXNzZXJ0KG5GcmFtZSA8IFRoaXMtPm5JZHhSZWNvcmRzKTsKCiAgICAgIGlkeC5ja2lkICAgICAgICAgID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgICAgIGlkeC5kd0ZsYWdzICAgICAgID0gQVZJSUZfTElTVDsKICAgICAgaWR4LmR3Q2h1bmtMZW5ndGggPSBUaGlzLT5pZHhSZWNvcmRzW25GcmFtZV0uZHdDaHVua0xlbmd0aDsKICAgICAgaWR4LmR3Q2h1bmtPZmZzZXQgPSBUaGlzLT5pZHhSZWNvcmRzW25GcmFtZV0uZHdDaHVua09mZnNldAoJLSBUaGlzLT5kd01vdmlDaHVua1BvczsKICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgICAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CglwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwoKCS8qIGhlYXZlIHdlIHJlYWNoZWQgc3RhcnQgb2YgdGhpcyBzdHJlYW0/ICovCglpZiAoLShMT05HKXBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyA+IGkpCgkgIGNvbnRpbnVlOwoKCWlmIChwU3RyZWFtLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgPCBsSW5pdGlhbEZyYW1lcykKCSAgbkZyYW1lIC09IChsSW5pdGlhbEZyYW1lcyAtIHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyk7CgoJLyogcmVhY2hlZCBlbmQgb2YgdGhpcyBzdHJlYW0/ICovCglpZiAocFN0cmVhbS0+bExhc3RGcmFtZSA8PSBuRnJhbWUpCgkgIGNvbnRpbnVlOwoKCWlmICgocFN0cmVhbS0+c0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUykgJiYKCSAgICBwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50ICE9IDAgJiYKCSAgICBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzICE9IE5VTEwpIHsKCSAgRFdPUkQgcG9zOwoKCSAgZm9yIChwb3MgPSAwOyBwb3MgPCBwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBwb3MrKykgewoJICAgIGlmIChwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uY2tpZCA9PSBuRnJhbWUpIHsKCSAgICAgIGlkeC5kd0ZsYWdzID0gQVZJSUZfTk9USU1FOwoJICAgICAgaWR4LmNraWQgICAgPSBNQUtFQVZJQ0tJRChja3R5cGVQQUxjaGFuZ2UsIHBTdHJlYW0tPm5TdHJlYW0pOwoJICAgICAgaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua0xlbmd0aDsKCSAgICAgIGlkeC5kd0NodW5rT2Zmc2V0ID0gcFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmR3Q2h1bmtPZmZzZXQKCQktIFRoaXMtPmR3TW92aUNodW5rUG9zOwoKCSAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCgkJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgkgICAgICBicmVhazsKCSAgICB9CgkgIH0KCX0gLyogaWYgaGF2ZSBmb3JtYXRjaGFuZ2VzICovCgoJaWR4LmNraWQgICAgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5ja2lkOwoJaWR4LmR3RmxhZ3MgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5kd0ZsYWdzOwoJaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5kd0NodW5rTGVuZ3RoOwoJaWR4LmR3Q2h1bmtPZmZzZXQgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbkZyYW1lXS5kd0NodW5rT2Zmc2V0CgkgIC0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CglpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgICAgfQogICAgfQogIH0gZWxzZSB7CiAgICAvKiBub3QgaW50ZXJsZWF2ZWQgLS0gd3JpdGUgaW5kZXggZm9yIGVhY2ggc3RyZWFtIGF0IG9uY2UgKi8KICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgICBwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwoKICAgICAgZm9yIChuID0gMDsgbiA8PSBwU3RyZWFtLT5sTGFzdEZyYW1lOyBuKyspIHsKCWlmICgocFN0cmVhbS0+c0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUykgJiYKCSAgICAocFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAhPSAwKSkgewoJICBEV09SRCBwb3M7CgoJICBmb3IgKHBvcyA9IDA7IHBvcyA8IHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7IHBvcysrKSB7CgkgICAgaWYgKHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5ja2lkID09IG4pIHsKCSAgICAgIGlkeC5kd0ZsYWdzID0gQVZJSUZfTk9USU1FOwoJICAgICAgaWR4LmNraWQgICAgPSBNQUtFQVZJQ0tJRChja3R5cGVQQUxjaGFuZ2UsIHBTdHJlYW0tPm5TdHJlYW0pOwoJICAgICAgaWR4LmR3Q2h1bmtMZW5ndGggPSBwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua0xlbmd0aDsKCSAgICAgIGlkeC5kd0NodW5rT2Zmc2V0ID0KCQlwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uZHdDaHVua09mZnNldCAtIFRoaXMtPmR3TW92aUNodW5rUG9zOwoJICAgICAgaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCQlyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCSAgICAgIGJyZWFrOwoJICAgIH0KCSAgfQoJfSAvKiBpZiBoYXZlIGZvcm1hdGNoYW5nZXMgKi8KCglpZHguY2tpZCAgICAgICAgICA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5ja2lkOwoJaWR4LmR3RmxhZ3MgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbl0uZHdGbGFnczsKCWlkeC5kd0NodW5rTGVuZ3RoID0gcFN0cmVhbS0+aWR4RnJhbWVzW25dLmR3Q2h1bmtMZW5ndGg7CglpZHguZHdDaHVua09mZnNldCA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5kd0NodW5rT2Zmc2V0CgkgIC0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CgoJaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCSAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIH0KICAgIH0KICB9IC8qIGlmIG5vdCBpbnRlcmxlYXZlZCAqLwoKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBVTE9ORyAgQVZJRklMRV9TZWFyY2hTdHJlYW0oSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBmY2MsIExPTkcgbFNraXApCnsKICBVSU5UIGk7CiAgVUlOVCBuU3RyZWFtOwoKICAvKiBwcmUtY29uZGl0aW9uICovCiAgYXNzZXJ0KGxTa2lwID49IDApOwoKICBpZiAoZmNjICE9IDApIHsKICAgIC8qIHNlYXJjaCB0aGUgbnVtYmVyIG9mIHRoZSBzcGVjaWZpZWQgc3RyZWFtICovCiAgICBuU3RyZWFtID0gKFVMT05HKS0xOwogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICAgIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbaV0gIT0gTlVMTCk7CgogICAgICBpZiAoVGhpcy0+cHBTdHJlYW1zW2ldLT5zSW5mby5mY2NUeXBlID09IGZjYykgewoJaWYgKGxTa2lwID09IDApIHsKCSAgblN0cmVhbSA9IGk7CgkgIGJyZWFrOwoJfSBlbHNlCgkgIGxTa2lwLS07CiAgICAgIH0KICAgIH0KICB9IGVsc2UKICAgIG5TdHJlYW0gPSBsU2tpcDsKCiAgcmV0dXJuIG5TdHJlYW07Cn0KCnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfVXBkYXRlSW5mbyhJQVZJRmlsZUltcGwgKlRoaXMpCnsKICBVSU5UIGk7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CgogIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdDYXBzICAgICAgICAgICAgICAgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSAwOwogIFRoaXMtPmZJbmZvLmR3V2lkdGggICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdIZWlnaHQgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3UmF0ZSAgICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdMZW5ndGggICAgICAgICAgICAgID0gMDsKICBUaGlzLT5kd0luaXRpYWxGcmFtZXMgICAgICAgICAgICAgPSAwOwoKICBmb3IgKGkgPSAwOyBpIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBpKyspIHsKICAgIEFWSVNUUkVBTUlORk9XICpwc2k7CiAgICBEV09SRCAgICAgICAgICAgbjsKCiAgICAvKiBwcmUtY29uZGl0aW9ucyAqLwogICAgYXNzZXJ0KFRoaXMtPnBwU3RyZWFtc1tpXSAhPSBOVUxMKTsKCiAgICBwc2kgPSAmVGhpcy0+cHBTdHJlYW1zW2ldLT5zSW5mbzsKICAgIGFzc2VydChwc2ktPmR3U2NhbGUgIT0gMCk7CiAgICBhc3NlcnQocHNpLT5kd1JhdGUgIT0gMCk7CgogICAgaWYgKGkgPT0gMCkgewogICAgICAvKiB1c2UgZmlyc3Qgc3RyZWFtIHRpbWluZ3MgYXMgYmFzZSAqLwogICAgICBUaGlzLT5mSW5mby5kd1NjYWxlICA9IHBzaS0+ZHdTY2FsZTsKICAgICAgVGhpcy0+ZkluZm8uZHdSYXRlICAgPSBwc2ktPmR3UmF0ZTsKICAgICAgVGhpcy0+ZkluZm8uZHdMZW5ndGggPSBwc2ktPmR3TGVuZ3RoOwogICAgfSBlbHNlIHsKICAgICAgbiA9IEFWSVN0cmVhbVNhbXBsZVRvU2FtcGxlKChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1swXSwKCQkJCSAgKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zW2ldLHBzaS0+ZHdMZW5ndGgpOwogICAgICBpZiAoVGhpcy0+ZkluZm8uZHdMZW5ndGggPCBuKQoJVGhpcy0+ZkluZm8uZHdMZW5ndGggPSBuOwogICAgfQoKICAgIGlmIChUaGlzLT5kd0luaXRpYWxGcmFtZXMgPCBwc2ktPmR3SW5pdGlhbEZyYW1lcykKICAgICAgVGhpcy0+ZHdJbml0aWFsRnJhbWVzID0gcHNpLT5kd0luaXRpYWxGcmFtZXM7CgogICAgaWYgKFRoaXMtPmZJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA8IHBzaS0+ZHdTdWdnZXN0ZWRCdWZmZXJTaXplKQogICAgICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBwc2ktPmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZTsKCiAgICBpZiAocHNpLT5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgICAvKiBmaXhlZCBzYW1wbGUgc2l6ZSAtLSBleGFjdCBjb21wdXRhdGlvbiAqLwogICAgICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICs9IE11bERpdihwc2ktPmR3U2FtcGxlU2l6ZSwgcHNpLT5kd1JhdGUsCgkJCQkJICAgICBwc2ktPmR3U2NhbGUpOwogICAgfSBlbHNlIHsKICAgICAgLyogdmFyaWFibGUgc2FtcGxlIHNpemUgLS0gb25seSB1cHBlciBsaW1pdCAqLwogICAgICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICs9IE11bERpdihwc2ktPmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSwKCQkJCQkgICAgIHBzaS0+ZHdSYXRlLCBwc2ktPmR3U2NhbGUpOwoKICAgICAgLyogdXBkYXRlIGRpbWVuc2lvbnMgKi8KICAgICAgbiA9IHBzaS0+cmNGcmFtZS5yaWdodCAtIHBzaS0+cmNGcmFtZS5sZWZ0OwogICAgICBpZiAoVGhpcy0+ZkluZm8uZHdXaWR0aCA8IG4pCglUaGlzLT5mSW5mby5kd1dpZHRoID0gbjsKICAgICAgbiA9IHBzaS0+cmNGcmFtZS5ib3R0b20gLSBwc2ktPnJjRnJhbWUudG9wOwogICAgICBpZiAoVGhpcy0+ZkluZm8uZHdIZWlnaHQgPCBuKQoJVGhpcy0+ZkluZm8uZHdIZWlnaHQgPSBuOwogICAgfQogIH0KfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Xcml0ZUJsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBibG9jaywKCQkJCSAgRk9VUkNDIGNraWQsIERXT1JEIGZsYWdzLCBMUFZPSUQgYnVmZmVyLAoJCQkJICBMT05HIHNpemUpCnsKICBNTUNLSU5GTyBjazsKCiAgY2suY2tpZCAgICA9IGNraWQ7CiAgY2suY2tzaXplICA9IHNpemU7CiAgY2suZmNjVHlwZSA9IDA7CgogIC8qIGlmIG5vIGZyYW1lL2Jsb2NrIGlzIGFscmVhZHkgd3JpdHRlbiwgd2UgbXVzdCBjb21wdXRlIHN0YXJ0IG9mIG1vdmkgY2h1bmsgKi8KICBpZiAoVGhpcy0+cGFmLT5kd01vdmlDaHVua1BvcyA9PSAwKQogICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KFRoaXMtPnBhZik7CgogIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAoYnVmZmVyICE9IE5VTEwgJiYgc2l6ZSA+IDApIHsKICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+cGFmLT5obW1pbywgKEhQU1RSKWJ1ZmZlciwgc2l6ZSkgIT0gc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQogIGlmIChtbWlvQXNjZW5kKFRoaXMtPnBhZi0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICBUaGlzLT5wYWYtPmZEaXJ0eSAgICAgICAgID0gVFJVRTsKICBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zID0gbW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgMCwgU0VFS19DVVIpOwoKICByZXR1cm4gQVZJRklMRV9BZGRGcmFtZShUaGlzLCBja2lkLCBzaXplLAoJCQkgIGNrLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpLCBmbGFncyk7Cn0K