LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgovKiBUT0RPOgogKiAgLSBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSBpcyBtaXNzaW5nIGZvciB0aGUgSUFWSVN0cmVhbUltcGwKICogIC0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGU6IEZJTkRfSU5ERVggaXNuJ3Qgc3VwcG9ydGVkLgogKiAgLSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdDogZm9ybWF0Y2hhbmdlcyBhcmVuJ3QgcmVhZCBpbi4KICogIC0gSUFWSVN0cmVhbV9mbkRlbGV0ZTogYSBzdHViLgogKiAgLSBJQVZJU3RyZWFtX2ZuU2V0SW5mbzogYSBzdHViLgogKiAgLSBtYWtlIHRocmVhZCBzYWZlCiAqCiAqIEtOT1dOIEJ1Z3M6CiAqICAtIG5hdGl2ZSB2ZXJzaW9uIGNhbiBoYW5ndXAgd2hlbiByZWFkaW5nIGEgZmlsZSBnZW5lcmF0ZWQgd2l0aCB0aGlzIERMTC4KICogICAgV2hlbiBpbmRleCBpcyBtaXNzaW5nIGl0IHdvcmtzLCBidXQgaW5kZXggc2VlbXMgdG8gYmUgb2theS4KICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIndpbmRvd3N4LmgiCiNpbmNsdWRlICJtbXN5c3RlbS5oIgojaW5jbHVkZSAidmZ3LmgiCgojaW5jbHVkZSAiYXZpZmlsZV9wcml2YXRlLmgiCiNpbmNsdWRlICJleHRyYWNodW5rLmgiCgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChhdmlmaWxlKTsKCiNpZm5kZWYgSURYX1BFUl9CTE9DSwojZGVmaW5lIElEWF9QRVJfQkxPQ0sgMjczMAojZW5kaWYKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElBVklGaWxlKiBpZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuQWRkUmVmKElBVklGaWxlKiBpZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJRmlsZV9mblJlbGVhc2UoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuSW5mbyhJQVZJRmlsZSppZmFjZSxBVklGSUxFSU5GT1cqYWZpLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsRFdPUkQgZmNjVHlwZSxMT05HIGxQYXJhbSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxQQVZJU1RSRUFNKmF2aXMsQVZJU1RSRUFNSU5GT1cqYXNpKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuV3JpdGVEYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HIHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5SZWFkRGF0YShJQVZJRmlsZSppZmFjZSxEV09SRCBja2lkLExQVk9JRCBscERhdGEsTE9ORyAqc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkVuZFJlY29yZChJQVZJRmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSppZmFjZSxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUFWSUZpbGVWdGJsIGlhdmlmdCA9IHsKICBJQVZJRmlsZV9mblF1ZXJ5SW50ZXJmYWNlLAogIElBVklGaWxlX2ZuQWRkUmVmLAogIElBVklGaWxlX2ZuUmVsZWFzZSwKICBJQVZJRmlsZV9mbkluZm8sCiAgSUFWSUZpbGVfZm5HZXRTdHJlYW0sCiAgSUFWSUZpbGVfZm5DcmVhdGVTdHJlYW0sCiAgSUFWSUZpbGVfZm5Xcml0ZURhdGEsCiAgSUFWSUZpbGVfZm5SZWFkRGF0YSwKICBJQVZJRmlsZV9mbkVuZFJlY29yZCwKICBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbQp9OwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlKElQZXJzaXN0RmlsZSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuQWRkUmVmKElQZXJzaXN0RmlsZSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSppZmFjZSxDTFNJRCpwQ2xhc3NJRCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5KElQZXJzaXN0RmlsZSppZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUsRFdPUkQgZHdNb2RlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmUoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSxCT09MIGZSZW1lbWJlcik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkKElQZXJzaXN0RmlsZSppZmFjZSxMUENPTEVTVFIgcHN6RmlsZU5hbWUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuR2V0Q3VyRmlsZShJUGVyc2lzdEZpbGUqaWZhY2UsTFBPTEVTVFIqcHBzekZpbGVOYW1lKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSVBlcnNpc3RGaWxlVnRibCBpcGVyc2lzdGZ0ID0gewogIElQZXJzaXN0RmlsZV9mblF1ZXJ5SW50ZXJmYWNlLAogIElQZXJzaXN0RmlsZV9mbkFkZFJlZiwKICBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlLAogIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQsCiAgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eSwKICBJUGVyc2lzdEZpbGVfZm5Mb2FkLAogIElQZXJzaXN0RmlsZV9mblNhdmUsCiAgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZCwKICBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0qaWZhY2UsUkVGSUlEIHJlZmlpZCxMUFZPSUQgKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0qaWZhY2UpOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtKmlmYWNlLExQQVJBTSBsUGFyYW0xLExQQVJBTSBsUGFyYW0yKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cgKnBzaSxMT05HIHNpemUpOwpzdGF0aWMgTE9ORyAgICBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMT05HIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRm9ybWF0KElBVklTdHJlYW0qaWZhY2UsTE9ORyBwb3MsTFBWT0lEIGZvcm1hdCxMT05HICpmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgZm9ybWF0c2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZChJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLExPTkcgKmJ5dGVzcmVhZCxMT05HICpzYW1wbGVzcmVhZCk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSppZmFjZSxMT05HIHN0YXJ0LExPTkcgc2FtcGxlcyxMUFZPSUQgYnVmZmVyLExPTkcgYnVmZmVyc2l6ZSxEV09SRCBmbGFncyxMT05HICpzYW1wd3JpdHRlbixMT05HICpieXRlc3dyaXR0ZW4pOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyAqbHByZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSppZmFjZSxEV09SRCBmY2MsTFBWT0lEIGxwLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0SW5mbyhJQVZJU3RyZWFtKmlmYWNlLEFWSVNUUkVBTUlORk9XKmluZm8sTE9ORyBpbmZvbGVuKTsKCnN0YXRpYyBjb25zdCBzdHJ1Y3QgSUFWSVN0cmVhbVZ0YmwgaWF2aXN0ID0gewogIElBVklTdHJlYW1fZm5RdWVyeUludGVyZmFjZSwKICBJQVZJU3RyZWFtX2ZuQWRkUmVmLAogIElBVklTdHJlYW1fZm5SZWxlYXNlLAogIElBVklTdHJlYW1fZm5DcmVhdGUsCiAgSUFWSVN0cmVhbV9mbkluZm8sCiAgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUsCiAgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQsCiAgSUFWSVN0cmVhbV9mblNldEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuUmVhZCwKICBJQVZJU3RyZWFtX2ZuV3JpdGUsCiAgSUFWSVN0cmVhbV9mbkRlbGV0ZSwKICBJQVZJU3RyZWFtX2ZuUmVhZERhdGEsCiAgSUFWSVN0cmVhbV9mbldyaXRlRGF0YSwKICBJQVZJU3RyZWFtX2ZuU2V0SW5mbwp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklGaWxlSW1wbCBJQVZJRmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSVBlcnNpc3RGaWxlSW1wbCB7CiAgLyogSVVua25vd24gc3R1ZmYgKi8KICBjb25zdCBJUGVyc2lzdEZpbGVWdGJsICpscFZ0Ymw7CgogIC8qIElQZXJzaXN0RmlsZSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKfSBJUGVyc2lzdEZpbGVJbXBsOwoKdHlwZWRlZiBzdHJ1Y3QgX0lBVklTdHJlYW1JbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElBVklTdHJlYW1WdGJsICpscFZ0Ymw7CiAgTE9ORwkJICAgIHJlZjsKCiAgLyogSUFWSVN0cmVhbSBzdHVmZiAqLwogIElBVklGaWxlSW1wbCAgICAgKnBhZjsKICBEV09SRCAgICAgICAgICAgICBuU3RyZWFtOyAgICAgICAvKiB0aGUgbi10aCBzdHJlYW0gaW4gZmlsZSAqLwogIEFWSVNUUkVBTUlORk9XICAgIHNJbmZvOwoKICBMUFZPSUQgICAgICAgICAgICBscEZvcm1hdDsKICBEV09SRCAgICAgICAgICAgICBjYkZvcm1hdDsKCiAgTFBWT0lEICAgICAgICAgICAgbHBIYW5kbGVyRGF0YTsKICBEV09SRCAgICAgICAgICAgICBjYkhhbmRsZXJEYXRhOwoKICBFWFRSQUNIVU5LUyAgICAgICBleHRyYTsKCiAgTFBEV09SRCAgICAgICAgICAgbHBCdWZmZXI7CiAgRFdPUkQgICAgICAgICAgICAgY2JCdWZmZXI7ICAgICAgIC8qIHNpemUgb2YgbHBCdWZmZXIgKi8KICBEV09SRCAgICAgICAgICAgICBkd0N1cnJlbnRGcmFtZTsgLyogZnJhbWUvYmxvY2sgY3VycmVudGx5IGluIGxwQnVmZmVyICovCgogIExPTkcgICAgICAgICAgICAgIGxMYXN0RnJhbWU7ICAgIC8qIGxhc3QgY29ycmVjdCBpbmRleCBpbiBpZHhGcmFtZXMgKi8KICBBVklJTkRFWEVOVFJZICAgICppZHhGcmFtZXM7CiAgRFdPUkQgICAgICAgICAgICAgbklkeEZyYW1lczsgICAgIC8qIHVwcGVyIGluZGV4IGxpbWl0IG9mIGlkeEZyYW1lcyAqLwogIEFWSUlOREVYRU5UUlkgICAgKmlkeEZtdENoYW5nZXM7CiAgRFdPUkQgICAgICAgICAgICAgbklkeEZtdENoYW5nZXM7IC8qIHVwcGVyIGluZGV4IGxpbWl0IG9mIGlkeEZtdENoYW5nZXMgKi8KfSBJQVZJU3RyZWFtSW1wbDsKCnN0cnVjdCBfSUFWSUZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElBVklGaWxlVnRibCAgICAgKmxwVnRibDsKICBMT05HCQkgICAgcmVmOwoKICAvKiBJQVZJRmlsZSBzdHVmZi4uLiAqLwogIElQZXJzaXN0RmlsZUltcGwgIGlQZXJzaXN0RmlsZTsKCiAgQVZJRklMRUlORk9XICAgICAgZkluZm87CiAgSUFWSVN0cmVhbUltcGwgICAqcHBTdHJlYW1zW01BWF9BVklTVFJFQU1TXTsKCiAgRVhUUkFDSFVOS1MgICAgICAgZmlsZWV4dHJhOwoKICBEV09SRCAgICAgICAgICAgICBkd01vdmlDaHVua1BvczsgIC8qIHNvbWUgc3R1ZmYgZm9yIHNhdmluZyAuLi4gKi8KICBEV09SRCAgICAgICAgICAgICBkd0lkeENodW5rUG9zOwogIERXT1JEICAgICAgICAgICAgIGR3TmV4dEZyYW1lUG9zOwogIERXT1JEICAgICAgICAgICAgIGR3SW5pdGlhbEZyYW1lczsKCiAgTU1DS0lORk8gICAgICAgICAgY2tMYXN0UmVjb3JkOwogIEFWSUlOREVYRU5UUlkgICAgKmlkeFJlY29yZHM7ICAgICAgLyogd29uJ3QgYmUgdXBkYXRlZCB3aGlsZSBsb2FkaW5nICovCiAgRFdPUkQgICAgICAgICAgICAgbklkeFJlY29yZHM7ICAgICAvKiBjdXJyZW50IGZpbGwgbGV2ZWwgKi8KICBEV09SRCAgICAgICAgICAgICBjYklkeFJlY29yZHM7ICAgIC8qIHNpemUgb2YgaWR4UmVjb3JkcyAqLwoKICAvKiBJUGVyc2lzdEZpbGUgc3R1ZmYgLi4uICovCiAgSE1NSU8gICAgICAgICAgICAgaG1taW87CiAgTFBXU1RSICAgICAgICAgICAgc3pGaWxlTmFtZTsKICBVSU5UICAgICAgICAgICAgICB1TW9kZTsKICBCT09MICAgICAgICAgICAgICBmRGlydHk7Cn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0FkZEZyYW1lKElBVklTdHJlYW1JbXBsICpUaGlzLCBEV09SRCBja2lkLCBEV09SRCBzaXplLAoJCQkJRFdPUkQgb2Zmc2V0LCBEV09SRCBmbGFncyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQWRkUmVjb3JkKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBEV09SRCAgIEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgdm9pZCAgICBBVklGSUxFX0NvbnN0cnVjdEFWSVN0cmVhbShJQVZJRmlsZUltcGwgKnBhZiwgRFdPUkQgbnIsCgkJCQkJICBMUEFWSVNUUkVBTUlORk9XIGFzaSk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oSUFWSVN0cmVhbUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEluZGV4KElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgc2l6ZSwgRFdPUkQgb2Zmc2V0KTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9QYXJzZUluZGV4KElBVklGaWxlSW1wbCAqVGhpcywgQVZJSU5ERVhFTlRSWSAqbHAsCgkJCQkgIExPTkcgY291bnQsIERXT1JEIHBvcywgQk9PTCAqYkFic29sdXRlKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9SZWFkQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIHN0YXJ0LAoJCQkJIExQVk9JRCBidWZmZXIsIExPTkcgc2l6ZSk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIExQTE9ORyBwb3MsCgkJCQkgICAgICBMUExPTkcgb2Zmc2V0KTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlRmlsZShJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVJbmRleChJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgVUxPTkcgICBBVklGSUxFX1NlYXJjaFN0cmVhbShJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIGZjY1R5cGUsCgkJCQkgICAgTE9ORyBsU2tpcCk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfVXBkYXRlSW5mbyhJQVZJRmlsZUltcGwgKlRoaXMpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1dyaXRlQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGJsb2NrLAoJCQkJICBGT1VSQ0MgY2tpZCwgRFdPUkQgZmxhZ3MsIExQVk9JRCBidWZmZXIsCgkJCQkgIExPTkcgc2l6ZSk7CgpIUkVTVUxUIEFWSUZJTEVfQ3JlYXRlQVZJRmlsZShSRUZJSUQgcmlpZCwgTFBWT0lEICpwcHYpCnsKICBJQVZJRmlsZUltcGwgKnBmaWxlOwogIEhSRVNVTFQgICAgICAgaHI7CgogIGFzc2VydChyaWlkICE9IE5VTEwgJiYgcHB2ICE9IE5VTEwpOwoKICAqcHB2ID0gTlVMTDsKCiAgcGZpbGUgPSAoSUFWSUZpbGVJbXBsKilMb2NhbEFsbG9jKExQVFIsIHNpemVvZihJQVZJRmlsZUltcGwpKTsKICBpZiAocGZpbGUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICBwZmlsZS0+bHBWdGJsID0gJmlhdmlmdDsKICBwZmlsZS0+cmVmID0gMDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLmxwVnRibCA9ICZpcGVyc2lzdGZ0OwogIHBmaWxlLT5pUGVyc2lzdEZpbGUucGFmID0gcGZpbGU7CgogIGhyID0gSUFWSUZpbGVfUXVlcnlJbnRlcmZhY2UoKElBVklGaWxlKilwZmlsZSwgcmlpZCwgcHB2KTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIExvY2FsRnJlZSgoSExPQ0FMKXBmaWxlKTsKCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5RdWVyeUludGVyZmFjZShJQVZJRmlsZSAqaWZhY2UsIFJFRklJRCByZWZpaWQsCgkJCQkJCUxQVk9JRCAqb2JqKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyZWZpaWQpLCBvYmopOwoKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93biwgcmVmaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lBVklGaWxlLCByZWZpaWQpKSB7CiAgICAqb2JqID0gaWZhY2U7CiAgICBJQVZJRmlsZV9BZGRSZWYoaWZhY2UpOwoKICAgIHJldHVybiBTX09LOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQoJklJRF9JUGVyc2lzdEZpbGUsIHJlZmlpZCkpIHsKICAgICpvYmogPSAmVGhpcy0+aVBlcnNpc3RGaWxlOwogICAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJRmlsZV9mbkFkZFJlZihJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIHJlZik7CgogIHJldHVybiByZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5SZWxlYXNlKElBVklGaWxlICppZmFjZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKICBVSU5UIGk7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWREZWNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIHJlZik7CgogIGlmICghcmVmKSB7CiAgICBpZiAoVGhpcy0+ZkRpcnR5KSB7CiAgICAgIC8qIG5lZWQgdG8gd3JpdGUgaGVhZGVycyB0byBmaWxlICovCiAgICAgIEFWSUZJTEVfU2F2ZUZpbGUoVGhpcyk7CiAgICB9CgogICAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbaV0gIT0gTlVMTCkgewoJaWYgKFRoaXMtPnBwU3RyZWFtc1tpXS0+cmVmICE9IDApIHsKCSAgRVJSKCI6IHNvbWVvbmUgaGFzIHN0aWxsICVsdSByZWZlcmVuY2UgdG8gc3RyZWFtICV1ICglcCkhXG4iLAoJICAgICAgIFRoaXMtPnBwU3RyZWFtc1tpXS0+cmVmLCBpLCBUaGlzLT5wcFN0cmVhbXNbaV0pOwoJfQoJQVZJRklMRV9EZXN0cnVjdEFWSVN0cmVhbShUaGlzLT5wcFN0cmVhbXNbaV0pOwoJTG9jYWxGcmVlKChITE9DQUwpVGhpcy0+cHBTdHJlYW1zW2ldKTsKCVRoaXMtPnBwU3RyZWFtc1tpXSA9IE5VTEw7CiAgICAgIH0KICAgIH0KCiAgICBpZiAoVGhpcy0+aWR4UmVjb3JkcyAhPSBOVUxMKSB7CiAgICAgIEdsb2JhbEZyZWVQdHIoVGhpcy0+aWR4UmVjb3Jkcyk7CiAgICAgIFRoaXMtPmlkeFJlY29yZHMgID0gTlVMTDsKICAgICAgVGhpcy0+bklkeFJlY29yZHMgPSAwOwogICAgfQoKICAgIGlmIChUaGlzLT5maWxlZXh0cmEubHAgIT0gTlVMTCkgewogICAgICBHbG9iYWxGcmVlUHRyKFRoaXMtPmZpbGVleHRyYS5scCk7CiAgICAgIFRoaXMtPmZpbGVleHRyYS5scCA9IE5VTEw7CiAgICAgIFRoaXMtPmZpbGVleHRyYS5jYiA9IDA7CiAgICB9CgogICAgaWYgKFRoaXMtPnN6RmlsZU5hbWUgIT0gTlVMTCkgewogICAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzLT5zekZpbGVOYW1lKTsKICAgICAgVGhpcy0+c3pGaWxlTmFtZSA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+aG1taW8gIT0gTlVMTCkgewogICAgICBtbWlvQ2xvc2UoVGhpcy0+aG1taW8sIDApOwogICAgICBUaGlzLT5obW1pbyA9IE5VTEw7CiAgICB9CgogICAgTG9jYWxGcmVlKChITE9DQUwpVGhpcyk7CiAgfQogIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUgKmlmYWNlLCBMUEFWSUZJTEVJTkZPVyBhZmksCgkJCQkgICAgICBMT05HIHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxhZmksc2l6ZSk7CgogIGlmIChhZmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBBVklGSUxFX1VwZGF0ZUluZm8oVGhpcyk7CgogIG1lbWNweShhZmksICZUaGlzLT5mSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+ZkluZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5mSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFVMT05HIG5TdHJlYW07CgogIFRSQUNFKCIoJXAsJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBsUGFyYW0gPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgICphdmlzID0gKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwogICAgSUFWSVN0cmVhbV9BZGRSZWYoKmF2aXMpOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBTb3JyeSwgYnV0IHRoZSBzcGVjaWZpZWQgc3RyZWFtIGRvZXNuJ3QgZXhpc3QgKi8KICByZXR1cm4gQVZJRVJSX05PREFUQTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlICppZmFjZSxQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgaWZhY2UsIGF2aXMsIGFzaSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXZpcyA9PSBOVUxMIHx8IGFzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKmF2aXMgPSBOVUxMOwoKICAvKiBEb2VzIHRoZSB1c2VyIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBDYW4gd2UgYWRkIGFub3RoZXIgc3RyZWFtPyAqLwogIG4gPSBUaGlzLT5mSW5mby5kd1N0cmVhbXM7CiAgaWYgKG4gPj0gTUFYX0FWSVNUUkVBTVMgfHwgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkgewogICAgLyogYWxyZWFkeSByZWFjaGVkIG1heCBuciBvZiBzdHJlYW1zCiAgICAgKiBvciBoYXZlIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gZGlzayAqLwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIGNoZWNrIEFWSVNUUkVBTUlORk8gZm9yIHNvbWUgcmVhbGx5IG5lZWRlZCB0aGluZ3MgKi8KICBpZiAoYXNpLT5mY2NUeXBlID09IDAgfHwgYXNpLT5kd1NjYWxlID09IDAgfHwgYXNpLT5kd1JhdGUgPT0gMCkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBub3cgaXQgc2VlbXMgdG8gYmUgc2F2ZSB0byBhZGQgdGhlIHN0cmVhbSAqLwogIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCk7CiAgVGhpcy0+cHBTdHJlYW1zW25dID0gKElBVklTdHJlYW1JbXBsKilMb2NhbEFsbG9jKExQVFIsCgkJCQkJCSAgIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKiBpbml0aWFsaXplIHRoZSBuZXcgYWxsb2NhdGVkIHN0cmVhbSAqLwogIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKFRoaXMsIG4sIGFzaSk7CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcysrOwogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIHVwZGF0ZSBvdXIgQVZJRklMRUlORk8gc3RydWN0dXJlICovCiAgQVZJRklMRV9VcGRhdGVJbmZvKFRoaXMpOwoKICAvKiByZXR1cm4gaXQgKi8KICAqYXZpcyA9IChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1tuXTsKICBJQVZJU3RyZWFtX0FkZFJlZigqYXZpcyk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGNraWQsCgkJCQkJICAgTFBWT0lEIGxwRGF0YSwgTE9ORyBzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJWxkKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHBEYXRhID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmZpbGVleHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgTFBWT0lEIGxwRGF0YSwgTE9ORyAqc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZmlsZWV4dHJhLCBja2lkLCBscERhdGEsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIG5vIGZyYW1lcyB3cml0dGVuIHRvIGFueSBzdHJlYW0/IC0tIGNvbXB1dGUgc3RhcnQgb2YgJ21vdmknLWNodW5rICovCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcyk7CgogIFRoaXMtPmZJbmZvLmR3RmxhZ3MgIHw9IEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQ7CgogIC8qIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gYW55IHN0cmVhbSwgLi4uICovCiAgaWYgKFRoaXMtPmNrTGFzdFJlY29yZC5kd0ZsYWdzICYgTU1JT19ESVJUWSkgewogICAgLyogY2xvc2UgbGFzdCByZWNvcmQgKi8KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tMYXN0UmVjb3JkLCAwKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICBBVklGSUxFX0FkZFJlY29yZChUaGlzKTsKCiAgICBpZiAoVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSArIDMgKiBzaXplb2YoRFdPUkQpKQogICAgICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplICsgMyAqIHNpemVvZihEV09SRCk7CiAgfQoKICAvKiB3cml0ZSBvdXQgYSBuZXcgcmVjb3JkIGludG8gZmlsZSwgYnV0IGRvbid0IGNsb3NlIGl0ICovCiAgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSAgPSAwOwogIFRoaXMtPmNrTGFzdFJlY29yZC5mY2NUeXBlID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJlRoaXMtPmNrTGFzdFJlY29yZCwgTU1JT19DUkVBVEVMSVNUKSAhPSAwKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgKz0gMyAqIHNpemVvZihEV09SRCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGZjY1R5cGUsCgkJCQkJICAgICAgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFVMT05HIG5TdHJlYW07CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHVzZXIgd3JpdGUgcGVybWlzc2lvbnM/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgIC8qIC4uLiBzbyBkZWxldGUgaXQgbm93ICovCiAgICBMb2NhbEZyZWUoKEhMT0NBTClUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0pOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgLSBuU3RyZWFtID4gMCkKICAgICAgbWVtY3B5KFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0sIFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0gKyAxLAoJICAgICAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zIC0gblN0cmVhbSkgKiBzaXplb2YoSUFWSVN0cmVhbUltcGwqKSk7CgogICAgVGhpcy0+cHBTdHJlYW1zW1RoaXMtPmZJbmZvLmR3U3RyZWFtc10gPSBOVUxMOwogICAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zLS07CiAgICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAgIC8qIFRoaXMtPmZJbmZvIHdpbGwgYmUgdXBkYXRlZCBmdXJ0aGVyIHdoZW4gYXNrZWQgZm9yICovCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChQQVZJRklMRSlUaGlzLT5wYWYsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQQ0xTSUQgcENsYXNzSUQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBDbGFzc0lEKTsKCiAgaWYgKHBDbGFzc0lEID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBtZW1jcHkocENsYXNzSUQsICZDTFNJRF9BVklGaWxlLCBzaXplb2YoQ0xTSURfQVZJRmlsZSkpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLCBpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiAoVGhpcy0+cGFmLT5mRGlydHkgPyBTX09LIDogU19GQUxTRSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsIERXT1JEIGR3TW9kZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBpbnQgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4bFgpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGR3TW9kZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKICBpZiAoVGhpcy0+cGFmLT5obW1pbyAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogTm8gcmV1c2Ugb2YgdGhpcyBvYmplY3QgZm9yIGFub3RoZXIgZmlsZSEgKi8KCiAgLyogcmVtZWJlciBtb2RlIGFuZCBuYW1lICovCiAgVGhpcy0+cGFmLT51TW9kZSA9IGR3TW9kZTsKCiAgbGVuID0gbHN0cmxlblcocHN6RmlsZU5hbWUpICsgMTsKICBUaGlzLT5wYWYtPnN6RmlsZU5hbWUgPSAoTFBXU1RSKUxvY2FsQWxsb2MoTFBUUiwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgbHN0cmNweVcoVGhpcy0+cGFmLT5zekZpbGVOYW1lLCBwc3pGaWxlTmFtZSk7CgogIC8qIHRyeSB0byBvcGVuIHRoZSBmaWxlICovCiAgVGhpcy0+cGFmLT5obW1pbyA9IG1taW9PcGVuVyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIE5VTEwsCgkJCSAgICAgICBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICBpZiAoVGhpcy0+cGFmLT5obW1pbyA9PSBOVUxMKSB7CiAgICAvKiBtbWlvT3Blblcgbm90IGluIG5hdGl2ZSBETExzIG9mIFdpbjl4IC0tIHRyeSBtbWlvT3BlbkEgKi8KICAgIExQU1RSIHN6RmlsZU5hbWU7CgogICAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAwLCBOVUxMLCBOVUxMKTsKICAgIHN6RmlsZU5hbWUgPSBMb2NhbEFsbG9jKExQVFIsIGxlbiAqIHNpemVvZihDSEFSKSk7CiAgICBpZiAoc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgVGhpcy0+cGFmLT5zekZpbGVOYW1lLCAtMSwgc3pGaWxlTmFtZSwKCQkJbGVuLCBOVUxMLCBOVUxMKTsKCiAgICBUaGlzLT5wYWYtPmhtbWlvID0gbW1pb09wZW5BKHN6RmlsZU5hbWUsIE5VTEwsIE1NSU9fQUxMT0NCVUYgfCBkd01vZGUpOwogICAgTG9jYWxGcmVlKChITE9DQUwpc3pGaWxlTmFtZSk7CiAgICBpZiAoVGhpcy0+cGFmLT5obW1pbyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVPUEVOOwogIH0KCiAgLyogc2hvdWxkIHdlIGNyZWF0ZSBhIG5ldyBmaWxlPyAqLwogIGlmIChkd01vZGUgJiBPRl9DUkVBVEUpIHsKICAgIG1lbXNldCgmIFRoaXMtPnBhZi0+ZkluZm8sIDAsIHNpemVvZihUaGlzLT5wYWYtPmZJbmZvKSk7CiAgICBUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgPSBBVklGSUxFSU5GT19IQVNJTkRFWCB8IEFWSUZJTEVJTkZPX1RSVVNUQ0tUWVBFOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlCiAgICByZXR1cm4gQVZJRklMRV9Mb2FkRmlsZShUaGlzLT5wYWYpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCSAgTFBDT0xFU1RSIHBzekZpbGVOYW1lLEJPT0wgZlJlbWVtYmVyKQp7CiAgVFJBQ0UoIiglcCwlcywlZClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSwgZlJlbWVtYmVyKTsKCiAgLyogV2Ugd3JpdGUgZGlyZWN0bHkgdG8gZGlzaywgc28gbm90aGluZyB0byBkby4gKi8KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJICAgTFBDT0xFU1RSIHBzekZpbGVOYW1lKQp7CiAgVFJBQ0UoIiglcCwlcylcbiIsIGlmYWNlLCBkZWJ1Z3N0cl93KHBzekZpbGVOYW1lKSk7CgogIC8qIFdlIHdyaXRlIGRpcmVjdGx5IHRvIGRpc2ssIHNvIG5vdGhpbmcgdG8gZG8uICovCgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQT0xFU1RSICpwcHN6RmlsZU5hbWUpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGlmYWNlLCBwcHN6RmlsZU5hbWUpOwoKICBpZiAocHBzekZpbGVOYW1lID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAqcHBzekZpbGVOYW1lID0gTlVMTDsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgaWYgKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSAhPSBOVUxMKSB7CiAgICBpbnQgbGVuID0gbHN0cmxlblcoVGhpcy0+cGFmLT5zekZpbGVOYW1lKSArIDE7CgogICAgKnBwc3pGaWxlTmFtZSA9IChMUE9MRVNUUilHbG9iYWxBbGxvY1B0cihHSE5ELCBsZW4gKiBzaXplb2YoV0NIQVIpKTsKICAgIGlmICgqcHBzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIHN0cmNweVcoKnBwc3pGaWxlTmFtZSwgVGhpcy0+cGFmLT5zekZpbGVOYW1lKTsKICB9CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSAqaWZhY2UsCgkJCQkJCSAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVzLCVwKVxuIiwgaWZhY2UsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJU3RyZWFtLCByZWZpaWQpKSB7CiAgICAqb2JqID0gVGhpczsKICAgIElBVklTdHJlYW1fQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9CiAgLyogRklYTUU6IElBVklTdHJlYW1pbmcgaW50ZXJmYWNlICovCgogIHJldHVybiBPTEVfRV9FTlVNX05PTU9SRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQWRkUmVmKElBVklTdHJlYW0gKmlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgcmVmKTsKCiAgLyogYWxzbyBhZGQgcmVmIHRvIHBhcmVudCwgc28gdGhhdCBpdCBkb2Vzbid0IGtpbGwgdXMgKi8KICBpZiAoVGhpcy0+cGFmICE9IE5VTEwpCiAgICBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7CgogIHJldHVybiByZWY7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mblJlbGVhc2UoSUFWSVN0cmVhbSogaWZhY2UpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAoVGhpcy0+cGFmICE9IE5VTEwpCiAgICBJQVZJRmlsZV9SZWxlYXNlKChQQVZJRklMRSlUaGlzLT5wYWYpOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkNyZWF0ZShJQVZJU3RyZWFtICppZmFjZSwgTFBBUkFNIGxQYXJhbTEsCgkJCQkJICBMUEFSQU0gbFBhcmFtMikKewogIFRSQUNFKCIoJXAsMHglMDhsWCwweCUwOGxYKVxuIiwgaWZhY2UsIGxQYXJhbTEsIGxQYXJhbTIpOwoKICAvKiBUaGlzIElBVklTdHJlYW0gaW50ZXJmYWNlIG5lZWRzIGFuIEFWSUZpbGUgKi8KICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSAqaWZhY2UsTFBBVklTVFJFQU1JTkZPVyBwc2ksCgkJCQkJTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcCwlbGQpXG4iLCBpZmFjZSwgcHNpLCBzaXplKTsKCiAgaWYgKHBzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFNJWkU7CgogIG1lbWNweShwc2ksICZUaGlzLT5zSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+c0luZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5zSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBMT05HIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgTE9ORyBmbGFncykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIExPTkcgb2Zmc2V0ID0gMDsKCiAgVFJBQ0UoIiglcCwlbGQsMHglMDhsWClcbiIsaWZhY2UscG9zLGZsYWdzKTsKCiAgaWYgKGZsYWdzICYgRklORF9GUk9NX1NUQVJUKSB7CiAgICBwb3MgPSBUaGlzLT5zSW5mby5kd1N0YXJ0OwogICAgZmxhZ3MgJj0gfihGSU5EX0ZST01fU1RBUlR8RklORF9QUkVWKTsKICAgIGZsYWdzIHw9IEZJTkRfTkVYVDsKICB9CgogIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgLyogY29udmVydCBzYW1wbGVzIGludG8gYmxvY2sgbnVtYmVyIHdpdGggb2Zmc2V0ICovCiAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKFRoaXMsICZwb3MsICZvZmZzZXQpOwogIH0KCiAgaWYgKGZsYWdzICYgRklORF9UWVBFKSB7CiAgICBpZiAoZmxhZ3MgJiBGSU5EX0tFWSkgewogICAgICB3aGlsZSAoMCA8PSBwb3MgJiYgcG9zIDw9IFRoaXMtPmxMYXN0RnJhbWUpIHsKCWlmIChUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0ZsYWdzICYgQVZJSUZfS0VZRlJBTUUpCgkgIGdvdG8gUkVUVVJOX0ZPVU5EOwoKCWlmIChmbGFncyAmIEZJTkRfTkVYVCkKCSAgcG9zKys7CgllbHNlCgkgIHBvcy0tOwogICAgICB9OwogICAgfSBlbHNlIGlmIChmbGFncyAmIEZJTkRfQU5ZKSB7CiAgICAgIHdoaWxlICgwIDw9IHBvcyAmJiBwb3MgPD0gVGhpcy0+bExhc3RGcmFtZSkgewoJaWYgKFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGggPiAwKQoJICBnb3RvIFJFVFVSTl9GT1VORDsKCglpZiAoZmxhZ3MgJiBGSU5EX05FWFQpCgkgIHBvcysrOwoJZWxzZQoJICBwb3MtLTsKCiAgICAgIH07CiAgICB9IGVsc2UgaWYgKChmbGFncyAmIEZJTkRfRk9STUFUKSAmJiBUaGlzLT5pZHhGbXRDaGFuZ2VzICE9IE5VTEwgJiYKCSAgICAgICBUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgICBpZiAoZmxhZ3MgJiBGSU5EX05FWFQpIHsKCVVMT05HIG47CgoJZm9yIChuID0gMDsgbiA8IFRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7IG4rKykKCSAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZCA+PSBwb3MpIHsKICAgICAgICAgICAgcG9zID0gVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkOwoJICAgIGdvdG8gUkVUVVJOX0ZPVU5EOwogICAgICAgICAgfQogICAgICB9IGVsc2UgewoJTE9ORyBuOwoKCWZvciAobiA9IChMT05HKVRoaXMtPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQ7IG4gPj0gMDsgbi0tKSB7CgkgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQgPD0gcG9zKSB7CiAgICAgICAgICAgIHBvcyA9IFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZDsKCSAgICBnb3RvIFJFVFVSTl9GT1VORDsKICAgICAgICAgIH0KCX0KCglpZiAocG9zID4gKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCkKCSAgcmV0dXJuIDA7IC8qIGZvcm1hdCBjaGFuZ2VzIGFsd2F5cyBmb3IgZmlyc3QgZnJhbWUgKi8KICAgICAgfQogICAgfQoKICAgIHJldHVybiAtMTsKICB9CgogUkVUVVJOX0ZPVU5EOgogIGlmIChwb3MgPCAoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0KQogICAgcmV0dXJuIC0xOwoKICBzd2l0Y2ggKGZsYWdzICYgRklORF9SRVQpIHsKICBjYXNlIEZJTkRfTEVOR1RIOgogICAgLyogcGh5c2ljYWwgc2l6ZSAqLwogICAgcG9zID0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aDsKICAgIGJyZWFrOwogIGNhc2UgRklORF9PRkZTRVQ6CiAgICAvKiBwaHlzaWNhbCBwb3NpdGlvbiAqLwogICAgcG9zID0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCArIDIgKiBzaXplb2YoRFdPUkQpCiAgICAgICsgb2Zmc2V0ICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgYnJlYWs7CiAgY2FzZSBGSU5EX1NJWkU6CiAgICAvKiBsb2dpY2FsIHNpemUgKi8KICAgIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUpCiAgICAgIHBvcyA9IFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGVsc2UKICAgICAgcG9zID0gMTsKICAgIGJyZWFrOwogIGNhc2UgRklORF9JTkRFWDoKICAgIEZJWE1FKCI6IEZJTkRfSU5ERVggZmxhZyBpcyBub3Qgc3VwcG9ydGVkIVxuIik7CiAgICAvKiBUaGlzIGlzIGFuIGluZGV4IGluIHRoZSBpbmRleC10YWJsZSBvbiBkaXNjLiAqLwogICAgYnJlYWs7CiAgfTsgLyogZWxzZSBsb2dpY2FsIHBvc2l0aW9uICovCgogIHJldHVybiBwb3M7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICAgTFBWT0lEIGZvcm1hdCwgTE9ORyAqZm9ybWF0c2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHBvcywgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgaWYgKGZvcm1hdHNpemUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIG9ubHkgaW50ZXJlc3RlZCBpbiBuZWVkZWQgYnVmZmVyc2l6ZT8gKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgKmZvcm1hdHNpemUgPD0gMCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KCiAgLyogY29weSBpbml0aWFsIGZvcm1hdCAob25seSBhcyBtdWNoIGFzIHdpbGwgZml0KSAqLwogIG1lbWNweShmb3JtYXQsIFRoaXMtPmxwRm9ybWF0LCBtaW4oKihEV09SRCopZm9ybWF0c2l6ZSwgVGhpcy0+Y2JGb3JtYXQpKTsKICBpZiAoKihEV09SRCopZm9ybWF0c2l6ZSA8IFRoaXMtPmNiRm9ybWF0KSB7CiAgICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiRm9ybWF0OwogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICB9CgogIC8qIENvdWxkIGZvcm1hdCBjaGFuZ2U/IFdoZW4geWVzIHdpbGwgaXQgY2hhbmdlPyAqLwogIGlmICgoVGhpcy0+c0luZm8uZHdGbGFncyAmIEFWSVNUUkVBTUlORk9fRk9STUFUQ0hBTkdFUykgJiYKICAgICAgcG9zID4gVGhpcy0+c0luZm8uZHdTdGFydCkgewogICAgTE9ORyBsTGFzdEZtdDsKCiAgICBsTGFzdEZtdCA9IElBVklTdHJlYW1fZm5GaW5kU2FtcGxlKGlmYWNlLCBwb3MsIEZJTkRfRk9STUFUfEZJTkRfUFJFVik7CiAgICBpZiAobExhc3RGbXQgPiAwKSB7CiAgICAgIEZJWE1FKCI6IG5lZWQgdG8gcmVhZCBmb3JtYXRjaGFuZ2UgZm9yICVsZCAtLSB1bmltcGxlbWVudGVkIVxuIixsTGFzdEZtdCk7CiAgICB9CiAgfQoKICAqZm9ybWF0c2l6ZSA9IFRoaXMtPmNiRm9ybWF0OwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0KElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHBvcywKCQkJCQkgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgZm9ybWF0c2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIExQQklUTUFQSU5GT0hFQURFUiBscGJpTmV3ID0gKExQQklUTUFQSU5GT0hFQURFUilmb3JtYXQ7CgogIFRSQUNFKCIoJXAsJWxkLCVwLCVsZClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoZm9ybWF0ID09IE5VTEwgfHwgZm9ybWF0c2l6ZSA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgLyogY2FuIG9ubHkgc2V0IGZvcm1hdCBiZWZvcmUgZnJhbWUgaXMgd3JpdHRlbiEgKi8KICBpZiAoVGhpcy0+bExhc3RGcmFtZSA+IHBvcykKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogIC8qIGluaXRpYWwgZm9ybWF0IG9yIGEgZm9ybWF0Y2hhbmdlPyAqLwogIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKSB7CiAgICAvKiBpbml0aWFsIGZvcm1hdCAqLwogICAgaWYgKFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkKICAgICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogdXNlciBoYXMgdXNlZCBBUEkgaW4gd3Jvbmcgc2VxdW5lY2UhICovCgogICAgVGhpcy0+bHBGb3JtYXQgPSBHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBmb3JtYXRzaXplKTsKICAgIGlmIChUaGlzLT5scEZvcm1hdCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIFRoaXMtPmNiRm9ybWF0ID0gZm9ybWF0c2l6ZTsKCiAgICBtZW1jcHkoVGhpcy0+bHBGb3JtYXQsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogICAgLyogdXBkYXRlIHNvbWUgaW5mb3MgYWJvdXQgc3RyZWFtICovCiAgICBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgTE9ORyBsRGltOwoKICAgICAgbERpbSA9IFRoaXMtPnNJbmZvLnJjRnJhbWUucmlnaHQgLSBUaGlzLT5zSW5mby5yY0ZyYW1lLmxlZnQ7CiAgICAgIGlmIChsRGltIDwgbHBiaU5ldy0+YmlXaWR0aCkKCVRoaXMtPnNJbmZvLnJjRnJhbWUucmlnaHQgPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmxlZnQgKyBscGJpTmV3LT5iaVdpZHRoOwogICAgICBsRGltID0gVGhpcy0+c0luZm8ucmNGcmFtZS5ib3R0b20gLSBUaGlzLT5zSW5mby5yY0ZyYW1lLnRvcDsKICAgICAgaWYgKGxEaW0gPCBscGJpTmV3LT5iaUhlaWdodCkKCVRoaXMtPnNJbmZvLnJjRnJhbWUuYm90dG9tID0gVGhpcy0+c0luZm8ucmNGcmFtZS50b3AgKyBscGJpTmV3LT5iaUhlaWdodDsKICAgIH0gZWxzZSBpZiAoVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCiAgICAgIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSA9ICgoTFBXQVZFRk9STUFURVgpVGhpcy0+bHBGb3JtYXQpLT5uQmxvY2tBbGlnbjsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZSB7CiAgICBNTUNLSU5GTyAgICAgICAgICAgY2s7CiAgICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU9sZCA9IChMUEJJVE1BUElORk9IRUFERVIpVGhpcy0+bHBGb3JtYXQ7CiAgICBSR0JRVUFEICAgICAgICAgICAqcmdiTmV3ICA9IChSR0JRVUFEKikoKExQQllURSlscGJpTmV3ICsgbHBiaU5ldy0+YmlTaXplKTsKICAgIEFWSVBBTENIQU5HRSAgICAgICpscHBjID0gTlVMTDsKICAgIFVJTlQgICAgICAgICAgICAgICBuOwoKICAgIC8qIHBlcmhhcHMgZm9ybWF0IGNoYW5nZSwgY2hlY2sgaXQgLi4uICovCiAgICBpZiAoVGhpcy0+Y2JGb3JtYXQgIT0gZm9ybWF0c2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICAvKiBubyBmb3JtYXQgY2hhbmdlLCBvbmx5IHRoZSBpbml0aWFsIG9uZSAqLwogICAgaWYgKG1lbWNtcChUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKSA9PSAwKQogICAgICByZXR1cm4gQVZJRVJSX09LOwoKICAgIC8qIGNoZWNrIHRoYXQncyBvbmx5IHRoZSBwYWxldHRlLCB3aGljaCBjaGFuZ2VzICovCiAgICBpZiAobHBiaU9sZC0+YmlTaXplICAgICAgICAhPSBscGJpTmV3LT5iaVNpemUgfHwKCWxwYmlPbGQtPmJpV2lkdGggICAgICAgIT0gbHBiaU5ldy0+YmlXaWR0aCB8fAoJbHBiaU9sZC0+YmlIZWlnaHQgICAgICAhPSBscGJpTmV3LT5iaUhlaWdodCB8fAoJbHBiaU9sZC0+YmlQbGFuZXMgICAgICAhPSBscGJpTmV3LT5iaVBsYW5lcyB8fAoJbHBiaU9sZC0+YmlCaXRDb3VudCAgICAhPSBscGJpTmV3LT5iaUJpdENvdW50IHx8CglscGJpT2xkLT5iaUNvbXByZXNzaW9uICE9IGxwYmlOZXctPmJpQ29tcHJlc3Npb24gfHwKCWxwYmlPbGQtPmJpQ2xyVXNlZCAgICAgIT0gbHBiaU5ldy0+YmlDbHJVc2VkKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIFRoaXMtPnNJbmZvLmR3RmxhZ3MgfD0gQVZJU1RSRUFNSU5GT19GT1JNQVRDSEFOR0VTOwoKICAgIC8qIHNpbXBseSBzYXkgYWxsIGNvbG9ycyBoYXZlIGNoYW5nZWQgKi8KICAgIGNrLmNraWQgICA9IE1BS0VBVklDS0lEKGNrdHlwZVBBTGNoYW5nZSwgVGhpcy0+blN0cmVhbSk7CiAgICBjay5ja3NpemUgPSAyICogc2l6ZW9mKFdPUkQpICsgbHBiaU9sZC0+YmlDbHJVc2VkICogc2l6ZW9mKFBBTEVUVEVFTlRSWSk7CiAgICBscHBjID0gKEFWSVBBTENIQU5HRSopR2xvYmFsQWxsb2NQdHIoR01FTV9NT1ZFQUJMRSwgY2suY2tzaXplKTsKICAgIGlmIChscHBjID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIGxwcGMtPmJGaXJzdEVudHJ5ID0gMDsKICAgIGxwcGMtPmJOdW1FbnRyaWVzID0gKGxwYmlPbGQtPmJpQ2xyVXNlZCA8IDI1NiA/IGxwYmlPbGQtPmJpQ2xyVXNlZCA6IDApOwogICAgbHBwYy0+d0ZsYWdzICAgICAgPSAwOwogICAgZm9yIChuID0gMDsgbiA8IGxwYmlPbGQtPmJpQ2xyVXNlZDsgbisrKSB7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlUmVkICAgPSByZ2JOZXdbbl0ucmdiUmVkOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUdyZWVuID0gcmdiTmV3W25dLnJnYkdyZWVuOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUJsdWUgID0gcmdiTmV3W25dLnJnYkJsdWU7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlRmxhZ3MgPSAwOwogICAgfQoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpbHBwYywgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MgKz0gY2suY2tzaXplICsgMiAqIHNpemVvZihEV09SRCk7CgogICAgR2xvYmFsRnJlZVB0cihscHBjKTsKCiAgICByZXR1cm4gQVZJRklMRV9BZGRGcmFtZShUaGlzLCBja3R5cGVQQUxjaGFuZ2UsIG4sIGNrLmR3RGF0YU9mZnNldCwgMCk7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCUxPTkcgYnVmZmVyc2l6ZSwgTFBMT05HIGJ5dGVzcmVhZCwKCQkJCQlMUExPTkcgc2FtcGxlc3JlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBEV09SRCAgICBzaXplOwogIEhSRVNVTFQgIGhyOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJXAsJWxkLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLCBidWZmZXIsCiAJYnVmZmVyc2l6ZSwgYnl0ZXNyZWFkLCBzYW1wbGVzcmVhZCk7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKGJ5dGVzcmVhZCAhPSBOVUxMKQogICAgKmJ5dGVzcmVhZCA9IDA7CiAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAqc2FtcGxlc3JlYWQgPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQgPiBzdGFydCkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOyAvKiBjb3VsZG4ndCByZWFkIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0gKi8KICBpZiAoVGhpcy0+c0luZm8uZHdTdGFydCArIFRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgKERXT1JEKXN0YXJ0KQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7IC8qIHN0YXJ0IGlzIHBhc3QgZW5kIG9mIHN0cmVhbSAqLwoKICAvKiBzaG91bGQgd2UgcmVhZCBhcyBtdWNoIGFzIHBvc3NpYmxlPyAqLwogIGlmIChzYW1wbGVzID09IC0xKSB7CiAgICAvKiBVc2VyIHNob3VsZCBrbm93IGhvdyBtdWNoIHdlIGhhdmUgcmVhZCAqLwogICAgaWYgKGJ5dGVzcmVhZCA9PSBOVUxMICYmIHNhbXBsZXNyZWFkID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgaWYgKFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZSAhPSAwKQogICAgICBzYW1wbGVzID0gYnVmZmVyc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGVsc2UKICAgICAgc2FtcGxlcyA9IDE7CiAgfQoKICAvKiBsaW1pdCB0byBlbmQgb2Ygc3RyZWFtICovCiAgaWYgKChMT05HKVRoaXMtPnNJbmZvLmR3TGVuZ3RoIDwgc2FtcGxlcykKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICBpZiAoKHN0YXJ0IC0gVGhpcy0+c0luZm8uZHdTdGFydCkgPiAoVGhpcy0+c0luZm8uZHdMZW5ndGggLSBzYW1wbGVzKSkKICAgIHNhbXBsZXMgPSBUaGlzLT5zSW5mby5kd0xlbmd0aCAtIChzdGFydCAtIFRoaXMtPnNJbmZvLmR3U3RhcnQpOwoKICAvKiBub3RoaW5nIHRvIHJlYWQ/IFRoZW4gbGVhdmUgLi4uICovCiAgaWYgKHNhbXBsZXMgPT0gMCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgLyogZml4ZWQgc2FtcGxlc2l6ZSAtLSB3ZSBjYW4gcmVhZCBvdmVyIGZyYW1lL2Jsb2NrIGJvdW5kYXJpZXMgKi8KICAgIExPTkcgYmxvY2sgPSBzdGFydDsKICAgIExPTkcgb2Zmc2V0ID0gMDsKCiAgICAvKiBjb252ZXJ0IHN0YXJ0IHNhbXBsZSB0byBibG9jayxvZmZzZXQgcGFpciAqLwogICAgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhUaGlzLCAmYmxvY2ssICZvZmZzZXQpOwoKICAgIC8qIGNvbnZlcnQgc2FtcGxlcyB0byBieXRlcyAqLwogICAgc2FtcGxlcyAqPSBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CgogICAgd2hpbGUgKHNhbXBsZXMgPiAwICYmIGJ1ZmZlcnNpemUgPiAwKSB7CiAgICAgIGlmIChibG9jayAhPSBUaGlzLT5kd0N1cnJlbnRGcmFtZSkgewoJaHIgPSBBVklGSUxFX1JlYWRCbG9jayhUaGlzLCBibG9jaywgTlVMTCwgMCk7CglpZiAoRkFJTEVEKGhyKSkKCSAgcmV0dXJuIGhyOwogICAgICB9CgogICAgICBzaXplID0gbWluKChEV09SRClzYW1wbGVzLCAoRFdPUkQpYnVmZmVyc2l6ZSk7CiAgICAgIHNpemUgPSBtaW4oc2l6ZSwgVGhpcy0+Y2JCdWZmZXIgLSBvZmZzZXQpOwogICAgICBtZW1jcHkoYnVmZmVyLCAoKEJZVEUqKSZUaGlzLT5scEJ1ZmZlclsyXSkgKyBvZmZzZXQsIHNpemUpOwoKICAgICAgYmxvY2srKzsKICAgICAgb2Zmc2V0ID0gMDsKICAgICAgYnVmZmVyID0gKChMUEJZVEUpYnVmZmVyKStzaXplOwogICAgICBzYW1wbGVzICAgIC09IHNpemU7CiAgICAgIGJ1ZmZlcnNpemUgLT0gc2l6ZTsKCiAgICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKCSpieXRlc3JlYWQgICArPSBzaXplOwogICAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKCSpzYW1wbGVzcmVhZCArPSBzaXplIC8gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwogICAgfQoKICAgIGlmIChzYW1wbGVzID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICBlbHNlCiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfSBlbHNlIHsKICAgIC8qIHZhcmlhYmxlIHNhbXBsZXNpemUgLS0gd2UgY2FuIG9ubHkgcmVhZCBvbmUgZnVsbCBmcmFtZS9ibG9jayAqLwogICAgaWYgKHNhbXBsZXMgPiAxKQogICAgICBzYW1wbGVzID0gMTsKCiAgICBhc3NlcnQoc3RhcnQgPD0gVGhpcy0+bExhc3RGcmFtZSk7CiAgICBzaXplID0gVGhpcy0+aWR4RnJhbWVzW3N0YXJ0XS5kd0NodW5rTGVuZ3RoOwogICAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIGJ1ZmZlcnNpemUgPj0gc2l6ZSkgewogICAgICBociA9IEFWSUZJTEVfUmVhZEJsb2NrKFRoaXMsIHN0YXJ0LCBidWZmZXIsIHNpemUpOwogICAgICBpZiAoRkFJTEVEKGhyKSkKCXJldHVybiBocjsKICAgIH0gZWxzZSBpZiAoYnVmZmVyICE9IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CgogICAgLyogZmlsbCBvdXQgcmV0dXJuIHBhcmFtZXRlcnMgaWYgZ2l2ZW4gKi8KICAgIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICAgKmJ5dGVzcmVhZCA9IHNpemU7CiAgICBpZiAoc2FtcGxlc3JlYWQgIT0gTlVMTCkKICAgICAgKnNhbXBsZXNyZWFkID0gc2FtcGxlczsKCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgTE9ORyBzYW1wbGVzLCBMUFZPSUQgYnVmZmVyLAoJCQkJCSBMT05HIGJ1ZmZlcnNpemUsIERXT1JEIGZsYWdzLAoJCQkJCSBMUExPTkcgc2FtcHdyaXR0ZW4sCgkJCQkJIExQTE9ORyBieXRlc3dyaXR0ZW4pCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBGT1VSQ0MgIGNraWQ7CiAgSFJFU1VMVCBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzLAoJYnVmZmVyLCBidWZmZXJzaXplLCBmbGFncywgc2FtcHdyaXR0ZW4sIGJ5dGVzd3JpdHRlbik7CgogIC8qIGNsZWFyIHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAqc2FtcHdyaXR0ZW4gPSAwOwogIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICpieXRlc3dyaXR0ZW4gPSAwOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGJ1ZmZlciA9PSBOVUxMICYmIChidWZmZXJzaXplID4gMCB8fCBzYW1wbGVzID4gMCkpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHdlIHdyaXRlIHBlcm1pc3Npb24/ICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICBzd2l0Y2ggKFRoaXMtPnNJbmZvLmZjY1R5cGUpIHsKICBjYXNlIHN0cmVhbXR5cGVBVURJTzoKICAgIGNraWQgPSBNQUtFQVZJQ0tJRChja3R5cGVXQVZFYnl0ZXMsIFRoaXMtPm5TdHJlYW0pOwogICAgYnJlYWs7CiAgZGVmYXVsdDoKICAgIGlmICgoZmxhZ3MgJiBBVklJRl9LRVlGUkFNRSkgJiYgYnVmZmVyc2l6ZSAhPSAwKQogICAgICBja2lkID0gTUFLRUFWSUNLSUQoY2t0eXBlRElCYml0cywgVGhpcy0+blN0cmVhbSk7CiAgICBlbHNlCiAgICAgIGNraWQgPSBNQUtFQVZJQ0tJRChja3R5cGVESUJjb21wcmVzc2VkLCBUaGlzLT5uU3RyZWFtKTsKICAgIGJyZWFrOwogIH07CgogIC8qIGFwcGVuZCB0byBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmIChzdGFydCA9PSAtMSkgewogICAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPT0gLTEpCiAgICAgIHN0YXJ0ID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGVsc2UKICAgICAgc3RhcnQgPSBUaGlzLT5zSW5mby5kd0xlbmd0aDsKICB9IGVsc2UgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPT0gLTEpCiAgICBUaGlzLT5zSW5mby5kd1N0YXJ0ID0gc3RhcnQ7CgogIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgLyogZml4ZWQgc2FtcGxlIHNpemUgLS0gYXVkaW8gbGlrZSAqLwogICAgaWYgKHNhbXBsZXMgKiBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gYnVmZmVyc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgICAvKiBDb3VsZG4ndCBza2lwIGF1ZGlvLWxpa2UgZGF0YSAtLSBVc2VyIG11c3Qgc3VwcGx5IGFwcHJvcHJpYXRlIHNpbGVuY2UgKi8KICAgIGlmIChUaGlzLT5zSW5mby5kd0xlbmd0aCAhPSBzdGFydCkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKCiAgICAvKiBDb252ZXJ0IHBvc2l0aW9uIHRvIGZyYW1lL2Jsb2NrICovCiAgICBzdGFydCA9IFRoaXMtPmxMYXN0RnJhbWUgKyAxOwoKICAgIGlmICgoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSVNJTlRFUkxFQVZFRCkgPT0gMCkgewogICAgICBGSVhNRSgiOiBub3QgaW50ZXJsZWF2ZWQsIGNvdWxkIGNvbGxlY3QgYXVkaW8gZGF0YSFcbiIpOwogICAgfQogIH0gZWxzZSB7CiAgICAvKiB2YXJpYWJsZSBzYW1wbGUgc2l6ZSAtLSB2aWRlbyBsaWtlICovCiAgICBpZiAoc2FtcGxlcyA+IDEpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogbXVzdCB3ZSBmaWxsIHVwIHdpdGggZW1wdHkgZnJhbWVzPyAqLwogICAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgIT0gLTEpIHsKICAgICAgRk9VUkNDIGNraWQyID0gTUFLRUFWSUNLSUQoY2t0eXBlRElCY29tcHJlc3NlZCwgVGhpcy0+blN0cmVhbSk7CgogICAgICB3aGlsZSAoc3RhcnQgPiBUaGlzLT5sTGFzdEZyYW1lICsgMSkgewoJaHIgPSBBVklGSUxFX1dyaXRlQmxvY2soVGhpcywgVGhpcy0+bExhc3RGcmFtZSArIDEsIGNraWQyLCAwLCBOVUxMLCAwKTsKCWlmIChGQUlMRUQoaHIpKQoJICByZXR1cm4gaHI7CiAgICAgIH0KICAgIH0KICB9CgogIC8qIHdyaXRlIHRoZSBibG9jayBub3cgKi8KICBociA9IEFWSUZJTEVfV3JpdGVCbG9jayhUaGlzLCBzdGFydCwgY2tpZCwgZmxhZ3MsIGJ1ZmZlciwgYnVmZmVyc2l6ZSk7CiAgaWYgKFNVQ0NFRURFRChocikpIHsKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoc2FtcHdyaXR0ZW4gIT0gTlVMTCkKICAgICAgKnNhbXB3cml0dGVuID0gc2FtcGxlczsKICAgIGlmIChieXRlc3dyaXR0ZW4gIT0gTlVMTCkKICAgICAgKmJ5dGVzd3JpdHRlbiA9IGJ1ZmZlcnNpemU7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCSAgTE9ORyBzYW1wbGVzKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgRklYTUUoIiglcCwlbGQsJWxkKTogc3R1YlxuIiwgaWZhY2UsIHN0YXJ0LCBzYW1wbGVzKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChzdGFydCA8IDAgfHwgc2FtcGxlcyA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBEZWxldGUgYmVmb3JlIHN0YXJ0IG9mIHN0cmVhbT8gKi8KICBpZiAoc3RhcnQgKyBzYW1wbGVzIDwgVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIERlbGV0ZSBhZnRlciBlbmQgb2Ygc3RyZWFtPyAqLwogIGlmIChzdGFydCA+IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKQogICAgcmV0dXJuIEFWSUVSUl9PSzsKCiAgLyogRm9yIHRoZSByZXN0IHdlIG5lZWQgd3JpdGUgcGVybWlzc2lvbnMgKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIDEuIG92ZXJ3cml0ZSB0aGUgZGF0YSB3aXRoIEpVTksKICAgKgogICAqIGlmIElTSU5URVJMRUFWRUQgewogICAqICAgMi4gY29uY2F0IGFsbCBuZWlnaGJvdXJlZCBKVU5LLWJsb2NrcyBpbiB0aGlzIHJlY29yZCB0byBvbmUKICAgKiAgIDMuIGlmIHRoaXMgcmVjb3JkIG9ubHkgY29udGFpbnMgSlVOSyBhbmQgaXMgYXQgZW5kIHNldCBkd05leHRGcmFtZVBvcwogICAqICAgICAgdG8gc3RhcnQgb2YgdGhpcyByZWNvcmQsIHJlcGVhdCB0aGlzLgogICAqIH0gZWxzZSB7CiAgICogICAyLiBjb25jYXQgYWxsIG5laWdoYm91cmVkIEpVTkstYmxvY2tzLgogICAqICAgMy4gaWYgdGhlIEpVTksgYmxvY2sgaXMgYXQgdGhlIGVuZCwgdGhlbiBzZXQgZHdOZXh0RnJhbWVQb3MgdG8KICAgKiAgICAgIHN0YXJ0IG9mIHRoaXMgYmxvY2suCiAgICogfQogICAqLwoKICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgIExQVk9JRCBscCwgTFBMT05HIGxwcmVhZCkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBmY2MsIGxwLCBscHJlYWQpOwoKICBpZiAoZmNjID09IGNraWRTVFJFQU1IQU5ETEVSREFUQSkgewogICAgaWYgKFRoaXMtPmxwSGFuZGxlckRhdGEgIT0gTlVMTCAmJiBUaGlzLT5jYkhhbmRsZXJEYXRhID4gMCkgewogICAgICBpZiAobHAgPT0gTlVMTCB8fCAqbHByZWFkIDw9IDApIHsKCSpscHJlYWQgPSBUaGlzLT5jYkhhbmRsZXJEYXRhOwoJcmV0dXJuIEFWSUVSUl9PSzsKICAgICAgfQoKICAgICAgbWVtY3B5KGxwLCBUaGlzLT5scEhhbmRsZXJEYXRhLCBtaW4oVGhpcy0+Y2JIYW5kbGVyRGF0YSwgKmxwcmVhZCkpOwogICAgICBpZiAoKmxwcmVhZCA8IFRoaXMtPmNiSGFuZGxlckRhdGEpCglyZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgfSBlbHNlCiAgICAgIHJldHVybiBBVklFUlJfTk9EQVRBOwogIH0gZWxzZQogICAgcmV0dXJuIFJlYWRFeHRyYUNodW5rKCZUaGlzLT5leHRyYSwgZmNjLCBscCwgbHByZWFkKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZURhdGEoSUFWSVN0cmVhbSAqaWZhY2UsIERXT1JEIGZjYywKCQkJCQkgICAgIExQVk9JRCBscCwgTE9ORyBzaXplKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGx4LCVwLCVsZClcbiIsIGlmYWNlLCBmY2MsIGxwLCBzaXplKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKICBpZiAoc2l6ZSA8PSAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICAvKiBuZWVkIHdyaXRlIHBlcm1pc3Npb24gKi8KICBpZiAoKFRoaXMtPnBhZi0+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+c0luZm8uc3pOYW1lLCBzdHJlYW1OYW1lRm10LAoJCSAgICAgIEFWSUZJTEVfQmFzZW5hbWVXKFRoaXMtPnN6RmlsZU5hbWUpLCBzelR5cGUsIGNvdW50KTsKCSAgfQoJICBicmVhazsKCWNhc2UgY2tpZFNUUkVBTU5BTUU6CgkgIHsgLyogc3RyZWFtbmFtZSB3aWxsIGJlIHNhdmVkIGFzIEFTQ0lJIHN0cmluZyAqLwoJICAgIExQU1RSIHN0ciA9IChMUFNUUilMb2NhbEFsbG9jKExNRU1fRklYRUQsIGNrLmNrc2l6ZSk7CgkgICAgaWYgKHN0ciA9PSBOVUxMKQoJICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgoJICAgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKXN0ciwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCgkgICAgewoJICAgICAgTG9jYWxGcmVlKChITE9DQUwpc3RyKTsKCSAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgkgICAgfQoKCSAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgc3RyLCAtMSwgcFN0cmVhbS0+c0luZm8uc3pOYW1lLAoJCQkJc2l6ZW9mKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkvc2l6ZW9mKHBTdHJlYW0tPnNJbmZvLnN6TmFtZVswXSkpOwoKCSAgICBMb2NhbEZyZWUoKEhMT0NBTClzdHIpOwoJICB9CgkgIGJyZWFrOwoJY2FzZSBja2lkQVZJUEFERElORzoKCWNhc2UgbW1pb0ZPVVJDQygncCcsJ2EnLCdkJywnZCcpOgoJICBicmVhazsKCWRlZmF1bHQ6CgkgIFdBUk4oIjogZm91bmQgZXh0cmEgY2h1bmsgMHglMDhsWFxuIiwgY2suY2tpZCk7CgkgIGhyID0gUmVhZENodW5rSW50b0V4dHJhKCZwU3RyZWFtLT5leHRyYSwgVGhpcy0+aG1taW8sICZjayk7CgkgIGlmIChGQUlMRUQoaHIpKQoJICAgIHJldHVybiBocjsKCX07CgoJaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKCSAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLyogbmVzdGVkIGNodW5rcyBpbiAiTElTVCIsImhkcmwiIHdoaWNoIGFyZSBub3Qgb2YgdHlwZSAiTElTVCIsInN0cmwiICovCiAgICAgIGhyID0gUmVhZENodW5rSW50b0V4dHJhKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2tMSVNUMik7CiAgICAgIGlmIChGQUlMRUQoaHIpKQoJcmV0dXJuIGhyOwogICAgfQogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QyLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIH0KCiAgLyogcmVhZCBhbnkgZXh0cmEgaGVhZGVycyBpbiAiTElTVCIsImhkcmwiICovCiAgRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywgJmNrLCAmY2tMSVNUMSwgMCk7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogc2VhcmNoICJMSVNUIiwibW92aSIgY2h1bmsgaW4gIlJJRkYiLCJBVkkgIiAqLwogIGNrTElTVDEuZmNjVHlwZSA9IGxpc3R0eXBlQVZJTU9WSUU7CiAgaHIgPSBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgJmNrUklGRiwKCQkJICAgICAgTU1JT19GSU5ETElTVCk7CiAgaWYgKEZBSUxFRChocikpCiAgICByZXR1cm4gaHI7CgogIFRoaXMtPmR3TW92aUNodW5rUG9zID0gY2tMSVNUMS5kd0RhdGFPZmZzZXQ7CiAgVGhpcy0+ZHdJZHhDaHVua1BvcyAgPSBja0xJU1QxLmNrc2l6ZSArIGNrTElTVDEuZHdEYXRhT2Zmc2V0OwogIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMSwgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogIC8qIHRyeSB0byBmaW5kIGFuIGluZGV4ICovCiAgY2suY2tpZCA9IGNraWRBVklORVdJTkRFWDsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sCgkJCSAgICAgICZjaywgJmNrUklGRiwgTU1JT19GSU5EQ0hVTkspOwogIGlmIChTVUNDRUVERUQoaHIpICYmIGNrLmNrc2l6ZSA+IDApIHsKICAgIGlmIChGQUlMRUQoQVZJRklMRV9Mb2FkSW5kZXgoVGhpcywgY2suY2tzaXplLCBja0xJU1QxLmR3RGF0YU9mZnNldCkpKQogICAgICBUaGlzLT5mSW5mby5kd0ZsYWdzICY9IH5BVklGSUxFSU5GT19IQVNJTkRFWDsKICB9CgogIC8qIHdoZW4gd2UgaGF2ZW4ndCBmb3VuZCBhbiBpbmRleCBvciBpdCdzIGJhZCwgdGhlbiBidWlsZCBvbmUKICAgKiBieSBwYXJzaW5nICdtb3ZpJyBjaHVuayAqLwogIGlmICgoVGhpcy0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0hBU0lOREVYKSA9PSAwKSB7CiAgICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspCiAgICAgIFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+bExhc3RGcmFtZSA9IC0xOwoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgY2tMSVNUMS5kd0RhdGFPZmZzZXQgKyBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCkgPT0gLTEpIHsKICAgICAgRVJSKCI6IE9vcHMsIGNhbid0IHNlZWsgYmFjayB0byAnbW92aScgY2h1bmshXG4iKTsKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIH0KCiAgICAvKiBzZWVrIHRocm91Z2ggdGhlICdtb3ZpJyBsaXN0IHVudGlsIGVuZCAqLwogICAgd2hpbGUgKG1taW9EZXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssICZja0xJU1QxLCAwKSA9PSBTX09LKSB7CiAgICAgIGlmIChjay5ja2lkICE9IEZPVVJDQ19MSVNUKSB7CglpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSA9PSBTX09LKSB7CgkgIG5TdHJlYW0gPSBTdHJlYW1Gcm9tRk9VUkNDKGNrLmNraWQpOwoKCSAgaWYgKG5TdHJlYW0gPiBUaGlzLT5mSW5mby5kd1N0cmVhbXMpCgkgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgoJICBBVklGSUxFX0FkZEZyYW1lKFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSwgY2suY2tpZCwgY2suY2tzaXplLAoJCQkgICBjay5kd0RhdGFPZmZzZXQgLSAyICogc2l6ZW9mKERXT1JEKSwgMCk7Cgl9IGVsc2UgewoJICBuU3RyZWFtID0gU3RyZWFtRnJvbUZPVVJDQyhjay5ja2lkKTsKCSAgV0FSTigiOiBmaWxlIHNlZW1zIHRvIGJlIHRydW5jYXRlZCFcbiIpOwoJICBpZiAoblN0cmVhbSA8PSBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKCSAgICAgIFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+c0luZm8uZHdTYW1wbGVTaXplID4gMCkgewoJICAgIGNrLmNrc2l6ZSA9IG1taW9TZWVrKFRoaXMtPmhtbWlvLCAwLCBTRUVLX0VORCk7CgkgICAgaWYgKGNrLmNrc2l6ZSAhPSAtMSkgewoJICAgICAgY2suY2tzaXplIC09IGNrLmR3RGF0YU9mZnNldDsKCSAgICAgIGNrLmNrc2l6ZSAmPSB+KFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXS0+c0luZm8uZHdTYW1wbGVTaXplIC0gMSk7CgoJICAgICAgQVZJRklMRV9BZGRGcmFtZShUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0sIGNrLmNraWQsIGNrLmNrc2l6ZSwKCQkJICAgICAgIGNrLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpLCAwKTsKCSAgICB9CgkgIH0KCX0KICAgICAgfQogICAgfQogIH0KCiAgLyogZmluZCBvdGhlciBjaHVua3MgKi8KICBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssICZja1JJRkYsIDApOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIERXT1JEIHNpemUsIERXT1JEIG9mZnNldCkKewogIEFWSUlOREVYRU5UUlkgKmxwOwogIERXT1JEICAgICAgICAgIHBvcywgbjsKICBIUkVTVUxUICAgICAgICBociA9IEFWSUVSUl9PSzsKICBCT09MICAgICAgICAgICBiQWJzb2x1dGUgPSBUUlVFOwoKICBscCA9IChBVklJTkRFWEVOVFJZKilHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLAoJCQkJICAgICAgSURYX1BFUl9CTE9DSyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgaWYgKGxwID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgLyogYWRqdXN0IGxpbWl0cyBmb3IgaW5kZXggdGFibGVzLCBzbyB0aGF0IGluc2VydGluZyB3aWxsIGJlIGZhc3RlciAqLwogIGZvciAobiA9IDA7IG4gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG4rKykgewogICAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbbl07CgogICAgcFN0cmVhbS0+bExhc3RGcmFtZSA9IC0xOwoKICAgIGlmIChwU3RyZWFtLT5pZHhGcmFtZXMgIT0gTlVMTCkgewogICAgICBHbG9iYWxGcmVlUHRyKHBTdHJlYW0tPmlkeEZyYW1lcyk7CiAgICAgIHBTdHJlYW0tPmlkeEZyYW1lcyAgPSBOVUxMOwogICAgICBwU3RyZWFtLT5uSWR4RnJhbWVzID0gMDsKICAgIH0KCiAgICBpZiAocFN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgICAgaWYgKG4gPiAwICYmIFRoaXMtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19JU0lOVEVSTEVBVkVEKSB7CglwU3RyZWFtLT5uSWR4RnJhbWVzID0gVGhpcy0+cHBTdHJlYW1zWzBdLT5uSWR4RnJhbWVzOwogICAgICB9IGVsc2UgaWYgKHBTdHJlYW0tPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSkgewoJcFN0cmVhbS0+bklkeEZyYW1lcyA9CgkgIHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoIC8gcFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplOwogICAgICB9CiAgICB9IGVsc2UKICAgICAgcFN0cmVhbS0+bklkeEZyYW1lcyA9IHBTdHJlYW0tPnNJbmZvLmR3TGVuZ3RoOwoKICAgIHBTdHJlYW0tPmlkeEZyYW1lcyA9CiAgICAgIChBVklJTkRFWEVOVFJZKilHbG9iYWxBbGxvY1B0cihHSE5ELCBwU3RyZWFtLT5uSWR4RnJhbWVzICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKICAgIGlmIChwU3RyZWFtLT5pZHhGcmFtZXMgPT0gTlVMTCAmJiBwU3RyZWFtLT5uSWR4RnJhbWVzID4gMCkgewogICAgICBwU3RyZWFtLT5uSWR4RnJhbWVzID0gMDsKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICB9CiAgfQoKICBwb3MgPSAoRFdPUkQpLTE7CiAgd2hpbGUgKHNpemUgIT0gMCkgewogICAgTE9ORyByZWFkID0gbWluKElEWF9QRVJfQkxPQ0sgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSksIHNpemUpOwoKICAgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKWxwLCByZWFkKSAhPSByZWFkKSB7CiAgICAgIGhyID0gQVZJRVJSX0ZJTEVSRUFEOwogICAgICBicmVhazsKICAgIH0KICAgIHNpemUgLT0gcmVhZDsKCiAgICBpZiAocG9zID09IChEV09SRCktMSkKICAgICAgcG9zID0gb2Zmc2V0IC0gbHAtPmR3Q2h1bmtPZmZzZXQgKyBzaXplb2YoRFdPUkQpOwoKICAgIEFWSUZJTEVfUGFyc2VJbmRleChUaGlzLCBscCwgcmVhZCAvIHNpemVvZihBVklJTkRFWEVOVFJZKSwKCQkgICAgICAgcG9zLCAmYkFic29sdXRlKTsKICB9CgogIGlmIChscCAhPSBOVUxMKQogICAgR2xvYmFsRnJlZVB0cihscCk7CgogIC8qIGNoZWNraW5nIC4uLiAqLwogIGZvciAobiA9IDA7IG4gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG4rKykgewogICAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW0gPSBUaGlzLT5wcFN0cmVhbXNbbl07CgogICAgaWYgKHBTdHJlYW0tPnNJbmZvLmR3U2FtcGxlU2l6ZSA9PSAwICYmCglwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCAhPSBwU3RyZWFtLT5sTGFzdEZyYW1lKzEpCiAgICAgIEVSUigic3RyZWFtICVsdSBsZW5ndGggbWlzbWF0Y2g6IGR3TGVuZ3RoPSVsdSBmb3VuZD0lbGRcbiIsCgkgICBuLCBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCwgcFN0cmVhbS0+bExhc3RGcmFtZSk7CiAgfQoKICByZXR1cm4gaHI7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfUGFyc2VJbmRleChJQVZJRmlsZUltcGwgKlRoaXMsIEFWSUlOREVYRU5UUlkgKmxwLAoJCQkJICBMT05HIGNvdW50LCBEV09SRCBwb3MsIEJPT0wgKmJBYnNvbHV0ZSkKewogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgZm9yICg7IGNvdW50ID4gMDsgY291bnQtLSwgbHArKykgewogICAgV09SRCBuU3RyZWFtID0gU3RyZWFtRnJvbUZPVVJDQyhscC0+Y2tpZCk7CgogICAgaWYgKGxwLT5ja2lkID09IGxpc3R0eXBlQVZJUkVDT1JEIHx8IG5TdHJlYW0gPT0gMHg3RikKICAgICAgY29udGludWU7IC8qIHNraXAgdGhlc2UgKi8KCiAgICBpZiAoblN0cmVhbSA+IFRoaXMtPmZJbmZvLmR3U3RyZWFtcykKICAgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgogICAgaWYgKCpiQWJzb2x1dGUgJiYgbHAtPmR3Q2h1bmtPZmZzZXQgPCBUaGlzLT5kd01vdmlDaHVua1BvcykKICAgICAgKmJBYnNvbHV0ZSA9IEZBTFNFOwoKICAgIGlmICgqYkFic29sdXRlKQogICAgICBscC0+ZHdDaHVua09mZnNldCArPSBzaXplb2YoRFdPUkQpOwogICAgZWxzZQogICAgICBscC0+ZHdDaHVua09mZnNldCArPSBwb3M7CgogICAgaWYgKEZBSUxFRChBVklGSUxFX0FkZEZyYW1lKFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSwgbHAtPmNraWQsIGxwLT5kd0NodW5rTGVuZ3RoLCBscC0+ZHdDaHVua09mZnNldCwgbHAtPmR3RmxhZ3MpKSkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1JlYWRCbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgcG9zLAoJCQkJIExQVk9JRCBidWZmZXIsIExPTkcgc2l6ZSkKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+cGFmLT5obW1pbyAhPSBOVUxMKTsKICBhc3NlcnQoVGhpcy0+c0luZm8uZHdTdGFydCA8PSBwb3MgJiYgcG9zIDwgVGhpcy0+c0luZm8uZHdMZW5ndGgpOwogIGFzc2VydChwb3MgPD0gVGhpcy0+bExhc3RGcmFtZSk7CgogIC8qIHNob3VsZCB3ZSByZWFkIGFzIG11Y2ggYXMgYmxvY2sgZ2l2ZXMgdXM/ICovCiAgaWYgKHNpemUgPT0gMCB8fCBzaXplID4gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCkKICAgIHNpemUgPSBUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoOwoKICAvKiByZWFkIGludG8gb3V0IG93biBidWZmZXIgb3IgZ2l2ZW4gb25lPyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCkgewogICAgLyogd2UgYWxzbyByZWFkIHRoZSBjaHVuayAqLwogICAgc2l6ZSArPSAyICogc2l6ZW9mKERXT1JEKTsKCiAgICAvKiBjaGVjayB0aGF0IGJ1ZmZlciBpcyBiaWcgZW5vdWdoIC0tIGRvbid0IHRydXN0IGR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSAqLwogICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwgfHwgc2l6ZSA8IFRoaXMtPmNiQnVmZmVyKSB7CiAgICAgIERXT1JEIG1heFNpemUgPSBtYXgoc2l6ZSwgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKCiAgICAgIGlmIChUaGlzLT5scEJ1ZmZlciA9PSBOVUxMKQoJVGhpcy0+bHBCdWZmZXIgPSAoTFBEV09SRClHbG9iYWxBbGxvY1B0cihHTUVNX01PVkVBQkxFLCBtYXhTaXplKTsKICAgICAgZWxzZQoJVGhpcy0+bHBCdWZmZXIgPQoJICAoTFBEV09SRClHbG9iYWxSZUFsbG9jUHRyKFRoaXMtPmxwQnVmZmVyLCBtYXhTaXplLCBHTUVNX01PVkVBQkxFKTsKICAgICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgVGhpcy0+Y2JCdWZmZXIgPSBtYXgoc2l6ZSwgVGhpcy0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKTsKICAgIH0KCiAgICAvKiBub3cgcmVhZCB0aGUgY29tcGxldGUgY2h1bmsgaW50byBvdXIgYnVmZmVyICovCiAgICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua09mZnNldCwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgaWYgKG1taW9SZWFkKFRoaXMtPnBhZi0+aG1taW8sIChIUFNUUilUaGlzLT5scEJ1ZmZlciwgc2l6ZSkgIT0gc2l6ZSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgICAvKiBjaGVjayBpZiBpdCB3YXMgdGhlIGNvcnJlY3QgYmxvY2sgd2hpY2ggd2UgaGF2ZSByZWFkICovCiAgICBpZiAoVGhpcy0+bHBCdWZmZXJbMF0gIT0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uY2tpZCB8fAoJVGhpcy0+bHBCdWZmZXJbMV0gIT0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCkgewogICAgICBFUlIoIjogYmxvY2sgJWxkIG5vdCBmb3VuZCBhdCAweCUwOGxYXG4iLCBwb3MsIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQpOwogICAgICBFUlIoIjogSW5kZXggc2F5czogJyU0LjRzJygweCUwOGxYKSBzaXplIDB4JTA4bFhcbiIsCgkgIChjaGFyKikmVGhpcy0+aWR4RnJhbWVzW3Bvc10uY2tpZCwgVGhpcy0+aWR4RnJhbWVzW3Bvc10uY2tpZCwKCSAgVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aCk7CiAgICAgIEVSUigiOiBEYXRhICBzYXlzOiAnJTQuNHMnKDB4JTA4bFgpIHNpemUgMHglMDhsWFxuIiwKCSAgKGNoYXIqKSZUaGlzLT5scEJ1ZmZlclswXSwgVGhpcy0+bHBCdWZmZXJbMF0sIFRoaXMtPmxwQnVmZmVyWzFdKTsKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIH0KICB9IGVsc2UgewogICAgaWYgKG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKSwgU0VFS19TRVQpID09IC0xKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgaWYgKG1taW9SZWFkKFRoaXMtPnBhZi0+aG1taW8sIChIUFNUUilidWZmZXIsIHNpemUpICE9IHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1NhbXBsZXNUb0Jsb2NrKElBVklTdHJlYW1JbXBsICpUaGlzLCBMUExPTkcgcG9zLAoJCQkJICAgICAgTFBMT05HIG9mZnNldCkKewogIExPTkcgYmxvY2s7CgogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCk7CiAgYXNzZXJ0KHBvcyAhPSBOVUxMKTsKICBhc3NlcnQob2Zmc2V0ICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCk7CiAgYXNzZXJ0KCpwb3MgPj0gVGhpcy0+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