LyoKICogQ29weXJpZ2h0IDE5OTkgTWFyY3VzIE1laXNzbmVyCiAqIENvcHlyaWdodCAyMDAyLTIwMDMgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgovKiBUT0RPOgogKiAgLSBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSBpcyBtaXNzaW5nIGZvciB0aGUgSUFWSVN0cmVhbUltcGwKICogIC0gSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGU6IEZJTkRfSU5ERVggaXNuJ3Qgc3VwcG9ydGVkLgogKiAgLSBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdDogZm9ybWF0Y2hhbmdlcyBhcmVuJ3QgcmVhZCBpbi4KICogIC0gSUFWSVN0cmVhbV9mbkRlbGV0ZTogYSBzdHViLgogKiAgLSBJQVZJU3RyZWFtX2ZuU2V0SW5mbzogYSBzdHViLgogKiAgLSBtYWtlIHRocmVhZCBzYWZlCiAqCiAqIEtOT1dOIEJ1Z3M6CiAqICAtIG5hdGl2ZSB2ZXJzaW9uIGNhbiBoYW5ndXAgd2hlbiByZWFkaW5nIGEgZmlsZSBnZW5lcmF0ZWQgd2l0aCB0aGlzIERMTC4KICogICAgV2hlbiBpbmRleCBpcyBtaXNzaW5nIGl0IHdvcmtzLCBidXQgaW5kZXggc2VlbXMgdG8gYmUgb2theS4KICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CgojaW5jbHVkZSAid2luZGVmLmgiCiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgIm1tc3lzdGVtLmgiCiNpbmNsdWRlICJ2ZncuaCIKCiNpbmNsdWRlICJhdmlmaWxlX3ByaXZhdGUuaCIKI2luY2x1ZGUgImV4dHJhY2h1bmsuaCIKCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKI2lmbmRlZiBJRFhfUEVSX0JMT0NLCiNkZWZpbmUgSURYX1BFUl9CTE9DSyAyNzMwCiNlbmRpZgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUqIGlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEICpvYmopOwpzdGF0aWMgVUxPTkcgICBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUqIGlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSogaWZhY2UpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5JbmZvKElBVklGaWxlKmlmYWNlLEFWSUZJTEVJTkZPVyphZmksTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuR2V0U3RyZWFtKElBVklGaWxlKmlmYWNlLFBBVklTVFJFQU0qYXZpcyxEV09SRCBmY2NUeXBlLExPTkcgbFBhcmFtKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlKmlmYWNlLFBBVklTVFJFQU0qYXZpcyxBVklTVFJFQU1JTkZPVyphc2kpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5Xcml0ZURhdGEoSUFWSUZpbGUqaWZhY2UsRFdPUkQgY2tpZCxMUFZPSUQgbHBEYXRhLExPTkcgc2l6ZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mblJlYWREYXRhKElBVklGaWxlKmlmYWNlLERXT1JEIGNraWQsTFBWT0lEIGxwRGF0YSxMT05HICpzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRW5kUmVjb3JkKElBVklGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtKElBVklGaWxlKmlmYWNlLERXT1JEIGZjY1R5cGUsTE9ORyBsUGFyYW0pOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJQVZJRmlsZVZ0YmwgaWF2aWZ0ID0gewogIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSUFWSUZpbGVfZm5BZGRSZWYsCiAgSUFWSUZpbGVfZm5SZWxlYXNlLAogIElBVklGaWxlX2ZuSW5mbywKICBJQVZJRmlsZV9mbkdldFN0cmVhbSwKICBJQVZJRmlsZV9mbkNyZWF0ZVN0cmVhbSwKICBJQVZJRmlsZV9mbldyaXRlRGF0YSwKICBJQVZJRmlsZV9mblJlYWREYXRhLAogIElBVklGaWxlX2ZuRW5kUmVjb3JkLAogIElBVklGaWxlX2ZuRGVsZXRlU3RyZWFtCn07CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSVBlcnNpc3RGaWxlKmlmYWNlLFJFRklJRCByZWZpaWQsTFBWT0lEKm9iaik7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5BZGRSZWYoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mblJlbGVhc2UoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldENsYXNzSUQoSVBlcnNpc3RGaWxlKmlmYWNlLENMU0lEKnBDbGFzc0lEKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbklzRGlydHkoSVBlcnNpc3RGaWxlKmlmYWNlKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkxvYWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSxEV09SRCBkd01vZGUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZShJUGVyc2lzdEZpbGUqaWZhY2UsTFBDT0xFU1RSIHBzekZpbGVOYW1lLEJPT0wgZlJlbWVtYmVyKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mblNhdmVDb21wbGV0ZWQoSVBlcnNpc3RGaWxlKmlmYWNlLExQQ09MRVNUUiBwc3pGaWxlTmFtZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDdXJGaWxlKElQZXJzaXN0RmlsZSppZmFjZSxMUE9MRVNUUipwcHN6RmlsZU5hbWUpOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJUGVyc2lzdEZpbGVWdGJsIGlwZXJzaXN0ZnQgPSB7CiAgSVBlcnNpc3RGaWxlX2ZuUXVlcnlJbnRlcmZhY2UsCiAgSVBlcnNpc3RGaWxlX2ZuQWRkUmVmLAogIElQZXJzaXN0RmlsZV9mblJlbGVhc2UsCiAgSVBlcnNpc3RGaWxlX2ZuR2V0Q2xhc3NJRCwKICBJUGVyc2lzdEZpbGVfZm5Jc0RpcnR5LAogIElQZXJzaXN0RmlsZV9mbkxvYWQsCiAgSVBlcnNpc3RGaWxlX2ZuU2F2ZSwKICBJUGVyc2lzdEZpbGVfZm5TYXZlQ29tcGxldGVkLAogIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUKfTsKCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSVN0cmVhbSppZmFjZSxSRUZJSUQgcmVmaWlkLExQVk9JRCAqb2JqKTsKc3RhdGljIFVMT05HICAgV0lOQVBJIElBVklTdHJlYW1fZm5BZGRSZWYoSUFWSVN0cmVhbSppZmFjZSk7CnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuUmVsZWFzZShJQVZJU3RyZWFtKiBpZmFjZSk7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuQ3JlYXRlKElBVklTdHJlYW0qaWZhY2UsTFBBUkFNIGxQYXJhbTEsTFBBUkFNIGxQYXJhbTIpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkluZm8oSUFWSVN0cmVhbSppZmFjZSxBVklTVFJFQU1JTkZPVyAqcHNpLExPTkcgc2l6ZSk7CnN0YXRpYyBMT05HICAgIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExPTkcgZmxhZ3MpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSppZmFjZSxMT05HIHBvcyxMUFZPSUQgZm9ybWF0LExPTkcgKmZvcm1hdHNpemUpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtKmlmYWNlLExPTkcgcG9zLExQVk9JRCBmb3JtYXQsTE9ORyBmb3JtYXRzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMsTFBWT0lEIGJ1ZmZlcixMT05HIGJ1ZmZlcnNpemUsTE9ORyAqYnl0ZXNyZWFkLExPTkcgKnNhbXBsZXNyZWFkKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5Xcml0ZShJQVZJU3RyZWFtKmlmYWNlLExPTkcgc3RhcnQsTE9ORyBzYW1wbGVzLExQVk9JRCBidWZmZXIsTE9ORyBidWZmZXJzaXplLERXT1JEIGZsYWdzLExPTkcgKnNhbXB3cml0dGVuLExPTkcgKmJ5dGVzd3JpdHRlbik7CnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuRGVsZXRlKElBVklTdHJlYW0qaWZhY2UsTE9ORyBzdGFydCxMT05HIHNhbXBsZXMpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWREYXRhKElBVklTdHJlYW0qaWZhY2UsRFdPUkQgZmNjLExQVk9JRCBscCxMT05HICpscHJlYWQpOwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbldyaXRlRGF0YShJQVZJU3RyZWFtKmlmYWNlLERXT1JEIGZjYyxMUFZPSUQgbHAsTE9ORyBzaXplKTsKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0qaWZhY2UsQVZJU1RSRUFNSU5GT1cqaW5mbyxMT05HIGluZm9sZW4pOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBJQVZJU3RyZWFtVnRibCBpYXZpc3QgPSB7CiAgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlLAogIElBVklTdHJlYW1fZm5BZGRSZWYsCiAgSUFWSVN0cmVhbV9mblJlbGVhc2UsCiAgSUFWSVN0cmVhbV9mbkNyZWF0ZSwKICBJQVZJU3RyZWFtX2ZuSW5mbywKICBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZSwKICBJQVZJU3RyZWFtX2ZuUmVhZEZvcm1hdCwKICBJQVZJU3RyZWFtX2ZuU2V0Rm9ybWF0LAogIElBVklTdHJlYW1fZm5SZWFkLAogIElBVklTdHJlYW1fZm5Xcml0ZSwKICBJQVZJU3RyZWFtX2ZuRGVsZXRlLAogIElBVklTdHJlYW1fZm5SZWFkRGF0YSwKICBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhLAogIElBVklTdHJlYW1fZm5TZXRJbmZvCn07Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSUZpbGVJbXBsIElBVklGaWxlSW1wbDsKCnR5cGVkZWYgc3RydWN0IF9JUGVyc2lzdEZpbGVJbXBsIHsKICAvKiBJVW5rbm93biBzdHVmZiAqLwogIGNvbnN0IElQZXJzaXN0RmlsZVZ0YmwgKmxwVnRibDsKCiAgLyogSVBlcnNpc3RGaWxlIHN0dWZmICovCiAgSUFWSUZpbGVJbXBsICAgICAqcGFmOwp9IElQZXJzaXN0RmlsZUltcGw7Cgp0eXBlZGVmIHN0cnVjdCBfSUFWSVN0cmVhbUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSVN0cmVhbVZ0YmwgKmxwVnRibDsKICBMT05HCQkgICAgcmVmOwoKICAvKiBJQVZJU3RyZWFtIHN0dWZmICovCiAgSUFWSUZpbGVJbXBsICAgICAqcGFmOwogIERXT1JEICAgICAgICAgICAgIG5TdHJlYW07ICAgICAgIC8qIHRoZSBuLXRoIHN0cmVhbSBpbiBmaWxlICovCiAgQVZJU1RSRUFNSU5GT1cgICAgc0luZm87CgogIExQVk9JRCAgICAgICAgICAgIGxwRm9ybWF0OwogIERXT1JEICAgICAgICAgICAgIGNiRm9ybWF0OwoKICBMUFZPSUQgICAgICAgICAgICBscEhhbmRsZXJEYXRhOwogIERXT1JEICAgICAgICAgICAgIGNiSGFuZGxlckRhdGE7CgogIEVYVFJBQ0hVTktTICAgICAgIGV4dHJhOwoKICBMUERXT1JEICAgICAgICAgICBscEJ1ZmZlcjsKICBEV09SRCAgICAgICAgICAgICBjYkJ1ZmZlcjsgICAgICAgLyogc2l6ZSBvZiBscEJ1ZmZlciAqLwogIERXT1JEICAgICAgICAgICAgIGR3Q3VycmVudEZyYW1lOyAvKiBmcmFtZS9ibG9jayBjdXJyZW50bHkgaW4gbHBCdWZmZXIgKi8KCiAgTE9ORyAgICAgICAgICAgICAgbExhc3RGcmFtZTsgICAgLyogbGFzdCBjb3JyZWN0IGluZGV4IGluIGlkeEZyYW1lcyAqLwogIEFWSUlOREVYRU5UUlkgICAgKmlkeEZyYW1lczsKICBEV09SRCAgICAgICAgICAgICBuSWR4RnJhbWVzOyAgICAgLyogdXBwZXIgaW5kZXggbGltaXQgb2YgaWR4RnJhbWVzICovCiAgQVZJSU5ERVhFTlRSWSAgICAqaWR4Rm10Q2hhbmdlczsKICBEV09SRCAgICAgICAgICAgICBuSWR4Rm10Q2hhbmdlczsgLyogdXBwZXIgaW5kZXggbGltaXQgb2YgaWR4Rm10Q2hhbmdlcyAqLwp9IElBVklTdHJlYW1JbXBsOwoKc3RydWN0IF9JQVZJRmlsZUltcGwgewogIC8qIElVbmtub3duIHN0dWZmICovCiAgY29uc3QgSUFWSUZpbGVWdGJsICAgICAqbHBWdGJsOwogIExPTkcJCSAgICByZWY7CgogIC8qIElBVklGaWxlIHN0dWZmLi4uICovCiAgSVBlcnNpc3RGaWxlSW1wbCAgaVBlcnNpc3RGaWxlOwoKICBBVklGSUxFSU5GT1cgICAgICBmSW5mbzsKICBJQVZJU3RyZWFtSW1wbCAgICpwcFN0cmVhbXNbTUFYX0FWSVNUUkVBTVNdOwoKICBFWFRSQUNIVU5LUyAgICAgICBmaWxlZXh0cmE7CgogIERXT1JEICAgICAgICAgICAgIGR3TW92aUNodW5rUG9zOyAgLyogc29tZSBzdHVmZiBmb3Igc2F2aW5nIC4uLiAqLwogIERXT1JEICAgICAgICAgICAgIGR3SWR4Q2h1bmtQb3M7CiAgRFdPUkQgICAgICAgICAgICAgZHdOZXh0RnJhbWVQb3M7CiAgRFdPUkQgICAgICAgICAgICAgZHdJbml0aWFsRnJhbWVzOwoKICBNTUNLSU5GTyAgICAgICAgICBja0xhc3RSZWNvcmQ7CiAgQVZJSU5ERVhFTlRSWSAgICAqaWR4UmVjb3JkczsgICAgICAvKiB3b24ndCBiZSB1cGRhdGVkIHdoaWxlIGxvYWRpbmcgKi8KICBEV09SRCAgICAgICAgICAgICBuSWR4UmVjb3JkczsgICAgIC8qIGN1cnJlbnQgZmlsbCBsZXZlbCAqLwogIERXT1JEICAgICAgICAgICAgIGNiSWR4UmVjb3JkczsgICAgLyogc2l6ZSBvZiBpZHhSZWNvcmRzICovCgogIC8qIElQZXJzaXN0RmlsZSBzdHVmZiAuLi4gKi8KICBITU1JTyAgICAgICAgICAgICBobW1pbzsKICBMUFdTVFIgICAgICAgICAgICBzekZpbGVOYW1lOwogIFVJTlQgICAgICAgICAgICAgIHVNb2RlOwogIEJPT0wgICAgICAgICAgICAgIGZEaXJ0eTsKfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQWRkRnJhbWUoSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGNraWQsIERXT1JEIHNpemUsCgkJCQlEV09SRCBvZmZzZXQsIERXT1JEIGZsYWdzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9BZGRSZWNvcmQoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIERXT1JEICAgQVZJRklMRV9Db21wdXRlTW92aVN0YXJ0KElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKElBVklGaWxlSW1wbCAqcGFmLCBEV09SRCBuciwKCQkJCQkgIExQQVZJU1RSRUFNSU5GT1cgYXNpKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9EZXN0cnVjdEFWSVN0cmVhbShJQVZJU3RyZWFtSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEZpbGUoSUFWSUZpbGVJbXBsICpUaGlzKTsKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9Mb2FkSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzLCBEV09SRCBzaXplLCBEV09SRCBvZmZzZXQpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1BhcnNlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzLCBBVklJTkRFWEVOVFJZICpscCwKCQkJCSAgTE9ORyBjb3VudCwgRFdPUkQgcG9zLCBCT09MICpiQWJzb2x1dGUpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1JlYWRCbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgc3RhcnQsCgkJCQkgTFBWT0lEIGJ1ZmZlciwgTE9ORyBzaXplKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgTFBMT05HIHBvcywKCQkJCSAgICAgIExQTE9ORyBvZmZzZXQpOwpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1NhdmVGaWxlKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfU2F2ZUluZGV4KElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBVTE9ORyAgIEFWSUZJTEVfU2VhcmNoU3RyZWFtKElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgZmNjVHlwZSwKCQkJCSAgICBMT05HIGxTa2lwKTsKc3RhdGljIHZvaWQgICAgQVZJRklMRV9VcGRhdGVJbmZvKElBVklGaWxlSW1wbCAqVGhpcyk7CnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfV3JpdGVCbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgYmxvY2ssCgkJCQkgIEZPVVJDQyBja2lkLCBEV09SRCBmbGFncywgTFBWT0lEIGJ1ZmZlciwKCQkJCSAgTE9ORyBzaXplKTsKCkhSRVNVTFQgQVZJRklMRV9DcmVhdGVBVklGaWxlKFJFRklJRCByaWlkLCBMUFZPSUQgKnBwdikKewogIElBVklGaWxlSW1wbCAqcGZpbGU7CiAgSFJFU1VMVCAgICAgICBocjsKCiAgYXNzZXJ0KHJpaWQgIT0gTlVMTCAmJiBwcHYgIT0gTlVMTCk7CgogICpwcHYgPSBOVUxMOwoKICBwZmlsZSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSUFWSUZpbGVJbXBsKSk7CiAgaWYgKHBmaWxlID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgcGZpbGUtPmxwVnRibCA9ICZpYXZpZnQ7CiAgcGZpbGUtPnJlZiA9IDA7CiAgcGZpbGUtPmlQZXJzaXN0RmlsZS5scFZ0YmwgPSAmaXBlcnNpc3RmdDsKICBwZmlsZS0+aVBlcnNpc3RGaWxlLnBhZiA9IHBmaWxlOwoKICBociA9IElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChJQVZJRmlsZSopcGZpbGUsIHJpaWQsIHBwdik7CiAgaWYgKEZBSUxFRChocikpCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBwZmlsZSk7CgogIHJldHVybiBocjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUXVlcnlJbnRlcmZhY2UoSUFWSUZpbGUgKmlmYWNlLCBSRUZJSUQgcmVmaWlkLAoJCQkJCQlMUFZPSUQgKm9iaikKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIFRoaXMsIGRlYnVnc3RyX2d1aWQocmVmaWlkKSwgb2JqKTsKCiAgaWYgKElzRXF1YWxHVUlEKCZJSURfSVVua25vd24sIHJlZmlpZCkgfHwKICAgICAgSXNFcXVhbEdVSUQoJklJRF9JQVZJRmlsZSwgcmVmaWlkKSkgewogICAgKm9iaiA9IGlmYWNlOwogICAgSUFWSUZpbGVfQWRkUmVmKGlmYWNlKTsKCiAgICByZXR1cm4gU19PSzsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEKCZJSURfSVBlcnNpc3RGaWxlLCByZWZpaWQpKSB7CiAgICAqb2JqID0gJlRoaXMtPmlQZXJzaXN0RmlsZTsKICAgIElBVklGaWxlX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSUZpbGVfZm5BZGRSZWYoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkSW5jcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklGaWxlX2ZuUmVsZWFzZShJQVZJRmlsZSAqaWZhY2UpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CiAgVUlOVCBpOwogIFVMT05HIHJlZiA9IEludGVybG9ja2VkRGVjcmVtZW50KCZUaGlzLT5yZWYpOwoKICBUUkFDRSgiKCVwKSAtPiAlbGRcbiIsIGlmYWNlLCByZWYpOwoKICBpZiAoIXJlZikgewogICAgaWYgKFRoaXMtPmZEaXJ0eSkgewogICAgICAvKiBuZWVkIHRvIHdyaXRlIGhlYWRlcnMgdG8gZmlsZSAqLwogICAgICBBVklGSUxFX1NhdmVGaWxlKFRoaXMpOwogICAgfQoKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IGkrKykgewogICAgICBpZiAoVGhpcy0+cHBTdHJlYW1zW2ldICE9IE5VTEwpIHsKCWlmIChUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiAhPSAwKSB7CgkgIEVSUigiOiBzb21lb25lIGhhcyBzdGlsbCAlbHUgcmVmZXJlbmNlIHRvIHN0cmVhbSAldSAoJXApIVxuIiwKCSAgICAgICBUaGlzLT5wcFN0cmVhbXNbaV0tPnJlZiwgaSwgVGhpcy0+cHBTdHJlYW1zW2ldKTsKCX0KCUFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oVGhpcy0+cHBTdHJlYW1zW2ldKTsKCUhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnBwU3RyZWFtc1tpXSk7CglUaGlzLT5wcFN0cmVhbXNbaV0gPSBOVUxMOwogICAgICB9CiAgICB9CgogICAgaWYgKFRoaXMtPmlkeFJlY29yZHMgIT0gTlVMTCkgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5pZHhSZWNvcmRzKTsKICAgICAgVGhpcy0+aWR4UmVjb3JkcyAgPSBOVUxMOwogICAgICBUaGlzLT5uSWR4UmVjb3JkcyA9IDA7CiAgICB9CgogICAgaWYgKFRoaXMtPmZpbGVleHRyYS5scCAhPSBOVUxMKSB7CiAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmZpbGVleHRyYS5scCk7CiAgICAgIFRoaXMtPmZpbGVleHRyYS5scCA9IE5VTEw7CiAgICAgIFRoaXMtPmZpbGVleHRyYS5jYiA9IDA7CiAgICB9CgogICAgaWYgKFRoaXMtPnN6RmlsZU5hbWUgIT0gTlVMTCkgewogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5zekZpbGVOYW1lKTsKICAgICAgVGhpcy0+c3pGaWxlTmFtZSA9IE5VTEw7CiAgICB9CiAgICBpZiAoVGhpcy0+aG1taW8gIT0gTlVMTCkgewogICAgICBtbWlvQ2xvc2UoVGhpcy0+aG1taW8sIDApOwogICAgICBUaGlzLT5obW1pbyA9IE5VTEw7CiAgICB9CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcyk7CiAgfQogIHJldHVybiByZWY7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkluZm8oSUFWSUZpbGUgKmlmYWNlLCBMUEFWSUZJTEVJTkZPVyBhZmksCgkJCQkgICAgICBMT05HIHNpemUpCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIixpZmFjZSxhZmksc2l6ZSk7CgogIGlmIChhZmkgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBBVklGSUxFX1VwZGF0ZUluZm8oVGhpcyk7CgogIG1lbWNweShhZmksICZUaGlzLT5mSW5mbywgbWluKChEV09SRClzaXplLCBzaXplb2YoVGhpcy0+ZkluZm8pKSk7CgogIGlmICgoRFdPUkQpc2l6ZSA8IHNpemVvZihUaGlzLT5mSW5mbykpCiAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkdldFN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIFBBVklTVFJFQU0gKmF2aXMsCgkJCQkJICAgRFdPUkQgZmNjVHlwZSwgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFVMT05HIG5TdHJlYW07CgogIFRSQUNFKCIoJXAsJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgYXZpcywgZmNjVHlwZSwgbFBhcmFtKTsKCiAgaWYgKGF2aXMgPT0gTlVMTCB8fCBsUGFyYW0gPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgICphdmlzID0gKFBBVklTVFJFQU0pVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dOwogICAgSUFWSVN0cmVhbV9BZGRSZWYoKmF2aXMpOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfQoKICAvKiBTb3JyeSwgYnV0IHRoZSBzcGVjaWZpZWQgc3RyZWFtIGRvZXNuJ3QgZXhpc3QgKi8KICByZXR1cm4gQVZJRVJSX05PREFUQTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuQ3JlYXRlU3RyZWFtKElBVklGaWxlICppZmFjZSxQQVZJU1RSRUFNICphdmlzLAoJCQkJCSAgICAgIExQQVZJU1RSRUFNSU5GT1cgYXNpKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBEV09SRCBuOwoKICBUUkFDRSgiKCVwLCVwLCVwKVxuIiwgaWZhY2UsIGF2aXMsIGFzaSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoYXZpcyA9PSBOVUxMIHx8IGFzaSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgKmF2aXMgPSBOVUxMOwoKICAvKiBEb2VzIHRoZSB1c2VyIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBDYW4gd2UgYWRkIGFub3RoZXIgc3RyZWFtPyAqLwogIG4gPSBUaGlzLT5mSW5mby5kd1N0cmVhbXM7CiAgaWYgKG4gPj0gTUFYX0FWSVNUUkVBTVMgfHwgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgIT0gMCkgewogICAgLyogYWxyZWFkeSByZWFjaGVkIG1heCBuciBvZiBzdHJlYW1zCiAgICAgKiBvciBoYXZlIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gZGlzayAqLwogICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICB9CgogIC8qIGNoZWNrIEFWSVNUUkVBTUlORk8gZm9yIHNvbWUgcmVhbGx5IG5lZWRlZCB0aGluZ3MgKi8KICBpZiAoYXNpLT5mY2NUeXBlID09IDAgfHwgYXNpLT5kd1NjYWxlID09IDAgfHwgYXNpLT5kd1JhdGUgPT0gMCkKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAvKiBub3cgaXQgc2VlbXMgdG8gYmUgc2F2ZSB0byBhZGQgdGhlIHN0cmVhbSAqLwogIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCk7CiAgVGhpcy0+cHBTdHJlYW1zW25dID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksCgkJCQkJCSAgIHNpemVvZihJQVZJU3RyZWFtSW1wbCkpOwogIGlmIChUaGlzLT5wcFN0cmVhbXNbbl0gPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAvKiBpbml0aWFsaXplIHRoZSBuZXcgYWxsb2NhdGVkIHN0cmVhbSAqLwogIEFWSUZJTEVfQ29uc3RydWN0QVZJU3RyZWFtKFRoaXMsIG4sIGFzaSk7CgogIFRoaXMtPmZJbmZvLmR3U3RyZWFtcysrOwogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIHVwZGF0ZSBvdXIgQVZJRklMRUlORk8gc3RydWN0dXJlICovCiAgQVZJRklMRV9VcGRhdGVJbmZvKFRoaXMpOwoKICAvKiByZXR1cm4gaXQgKi8KICAqYXZpcyA9IChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1tuXTsKICBJQVZJU3RyZWFtX0FkZFJlZigqYXZpcyk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbldyaXRlRGF0YShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGNraWQsCgkJCQkJICAgTFBWT0lEIGxwRGF0YSwgTE9ORyBzaXplKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJWxkKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHBEYXRhID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwogIGlmIChzaXplIDwgMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogRG8gd2UgaGF2ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmZpbGVleHRyYSwgY2tpZCwgbHBEYXRhLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklGaWxlX2ZuUmVhZERhdGEoSUFWSUZpbGUgKmlmYWNlLCBEV09SRCBja2lkLAoJCQkJCSAgTFBWT0lEIGxwRGF0YSwgTE9ORyAqc2l6ZSkKewogIElBVklGaWxlSW1wbCAqVGhpcyA9IChJQVZJRmlsZUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwweCUwOGxYLCVwLCVwKVxuIiwgaWZhY2UsIGNraWQsIGxwRGF0YSwgc2l6ZSk7CgogIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZmlsZWV4dHJhLCBja2lkLCBscERhdGEsIHNpemUpOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSUZpbGVfZm5FbmRSZWNvcmQoSUFWSUZpbGUgKmlmYWNlKQp7CiAgSUFWSUZpbGVJbXBsICpUaGlzID0gKElBVklGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwKVxuIixpZmFjZSk7CgogIGlmICgoVGhpcy0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIFRoaXMtPmZEaXJ0eSA9IFRSVUU7CgogIC8qIG5vIGZyYW1lcyB3cml0dGVuIHRvIGFueSBzdHJlYW0/IC0tIGNvbXB1dGUgc3RhcnQgb2YgJ21vdmknLWNodW5rICovCiAgaWYgKFRoaXMtPmR3TW92aUNodW5rUG9zID09IDApCiAgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcyk7CgogIFRoaXMtPmZJbmZvLmR3RmxhZ3MgIHw9IEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQ7CgogIC8qIGFscmVhZHkgd3JpdHRlbiBmcmFtZXMgdG8gYW55IHN0cmVhbSwgLi4uICovCiAgaWYgKFRoaXMtPmNrTGFzdFJlY29yZC5kd0ZsYWdzICYgTU1JT19ESVJUWSkgewogICAgLyogY2xvc2UgbGFzdCByZWNvcmQgKi8KICAgIGlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmVGhpcy0+Y2tMYXN0UmVjb3JkLCAwKSAhPSAwKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICBBVklGSUxFX0FkZFJlY29yZChUaGlzKTsKCiAgICBpZiAoVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplIDwgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSArIDMgKiBzaXplb2YoRFdPUkQpKQogICAgICBUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBUaGlzLT5ja0xhc3RSZWNvcmQuY2tzaXplICsgMyAqIHNpemVvZihEV09SRCk7CiAgfQoKICAvKiB3cml0ZSBvdXQgYSBuZXcgcmVjb3JkIGludG8gZmlsZSwgYnV0IGRvbid0IGNsb3NlIGl0ICovCiAgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZSAgPSAwOwogIFRoaXMtPmNrTGFzdFJlY29yZC5mY2NUeXBlID0gbGlzdHR5cGVBVklSRUNPUkQ7CiAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJlRoaXMtPmNrTGFzdFJlY29yZCwgTU1JT19DUkVBVEVMSVNUKSAhPSAwKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgKz0gMyAqIHNpemVvZihEV09SRCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJRmlsZV9mbkRlbGV0ZVN0cmVhbShJQVZJRmlsZSAqaWZhY2UsIERXT1JEIGZjY1R5cGUsCgkJCQkJICAgICAgTE9ORyBsUGFyYW0pCnsKICBJQVZJRmlsZUltcGwgKlRoaXMgPSAoSUFWSUZpbGVJbXBsICopaWZhY2U7CgogIFVMT05HIG5TdHJlYW07CgogIFRSQUNFKCIoJXAsMHglMDhsWCwlbGQpXG4iLCBpZmFjZSwgZmNjVHlwZSwgbFBhcmFtKTsKCiAgLyogY2hlY2sgcGFyYW1ldGVyICovCiAgaWYgKGxQYXJhbSA8IDApCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBIYXZlIHVzZXIgd3JpdGUgcGVybWlzc2lvbnM/ICovCiAgaWYgKChUaGlzLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgblN0cmVhbSA9IEFWSUZJTEVfU2VhcmNoU3RyZWFtKFRoaXMsIGZjY1R5cGUsIGxQYXJhbSk7CgogIC8qIERvZXMgdGhlIHJlcXVlc3RlZCBzdHJlYW0gZXhpc3Q/ICovCiAgaWYgKG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXMgJiYKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dICE9IE5VTEwpIHsKICAgIC8qIC4uLiBzbyBkZWxldGUgaXQgbm93ICovCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0pOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N0cmVhbXMgLSBuU3RyZWFtID4gMCkKICAgICAgbWVtY3B5KFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0sIFRoaXMtPnBwU3RyZWFtcyArIG5TdHJlYW0gKyAxLAoJICAgICAoVGhpcy0+ZkluZm8uZHdTdHJlYW1zIC0gblN0cmVhbSkgKiBzaXplb2YoSUFWSVN0cmVhbUltcGwqKSk7CgogICAgVGhpcy0+cHBTdHJlYW1zW1RoaXMtPmZJbmZvLmR3U3RyZWFtc10gPSBOVUxMOwogICAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zLS07CiAgICBUaGlzLT5mRGlydHkgPSBUUlVFOwoKICAgIC8qIFRoaXMtPmZJbmZvIHdpbGwgYmUgdXBkYXRlZCBmdXJ0aGVyIHdoZW4gYXNrZWQgZm9yICovCiAgICByZXR1cm4gQVZJRVJSX09LOwogIH0gZWxzZQogICAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5RdWVyeUludGVyZmFjZShJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICAgUkVGSUlEIHJlZmlpZCwgTFBWT0lEICpvYmopCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1F1ZXJ5SW50ZXJmYWNlKChQQVZJRklMRSlUaGlzLT5wYWYsIHJlZmlpZCwgb2JqKTsKfQoKc3RhdGljIFVMT05HICAgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkFkZFJlZihJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiBJQVZJRmlsZV9BZGRSZWYoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBVTE9ORyAgIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5SZWxlYXNlKElQZXJzaXN0RmlsZSAqaWZhY2UpCnsKICBJUGVyc2lzdEZpbGVJbXBsICpUaGlzID0gKElQZXJzaXN0RmlsZUltcGwgKilpZmFjZTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKCiAgcmV0dXJuIElBVklGaWxlX1JlbGVhc2UoKFBBVklGSUxFKVRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5HZXRDbGFzc0lEKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJCUxQQ0xTSUQgcENsYXNzSUQpCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBDbGFzc0lEKTsKCiAgaWYgKHBDbGFzc0lEID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICBtZW1jcHkocENsYXNzSUQsICZDTFNJRF9BVklGaWxlLCBzaXplb2YoQ0xTSURfQVZJRmlsZSkpOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuSXNEaXJ0eShJUGVyc2lzdEZpbGUgKmlmYWNlKQp7CiAgSVBlcnNpc3RGaWxlSW1wbCAqVGhpcyA9IChJUGVyc2lzdEZpbGVJbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXApXG4iLCBpZmFjZSk7CgogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CgogIHJldHVybiAoVGhpcy0+cGFmLT5mRGlydHkgPyBTX09LIDogU19GQUxTRSk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5Mb2FkKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsIERXT1JEIGR3TW9kZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBpbnQgbGVuOwoKICBUUkFDRSgiKCVwLCVzLDB4JTA4bFgpXG4iLCBpZmFjZSwgZGVidWdzdHJfdyhwc3pGaWxlTmFtZSksIGR3TW9kZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlciAqLwogIGlmIChwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgYXNzZXJ0KFRoaXMtPnBhZiAhPSBOVUxMKTsKICBpZiAoVGhpcy0+cGFmLT5obW1pbyAhPSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9FUlJPUjsgLyogTm8gcmV1c2Ugb2YgdGhpcyBvYmplY3QgZm9yIGFub3RoZXIgZmlsZSEgKi8KCiAgLyogcmVtZWJlciBtb2RlIGFuZCBuYW1lICovCiAgVGhpcy0+cGFmLT51TW9kZSA9IGR3TW9kZTsKCiAgbGVuID0gbHN0cmxlblcocHN6RmlsZU5hbWUpICsgMTsKICBUaGlzLT5wYWYtPnN6RmlsZU5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgaWYgKFRoaXMtPnBhZi0+c3pGaWxlTmFtZSA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgbHN0cmNweVcoVGhpcy0+cGFmLT5zekZpbGVOYW1lLCBwc3pGaWxlTmFtZSk7CgogIC8qIHRyeSB0byBvcGVuIHRoZSBmaWxlICovCiAgVGhpcy0+cGFmLT5obW1pbyA9IG1taW9PcGVuVyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIE5VTEwsCgkJCSAgICAgICBNTUlPX0FMTE9DQlVGIHwgZHdNb2RlKTsKICBpZiAoVGhpcy0+cGFmLT5obW1pbyA9PSBOVUxMKSB7CiAgICAvKiBtbWlvT3Blblcgbm90IGluIG5hdGl2ZSBETExzIG9mIFdpbjl4IC0tIHRyeSBtbWlvT3BlbkEgKi8KICAgIExQU1RSIHN6RmlsZU5hbWU7CgogICAgbGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSwgLTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAwLCBOVUxMLCBOVUxMKTsKICAgIHN6RmlsZU5hbWUgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGVuICogc2l6ZW9mKENIQVIpKTsKICAgIGlmIChzekZpbGVOYW1lID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBUaGlzLT5wYWYtPnN6RmlsZU5hbWUsIC0xLCBzekZpbGVOYW1lLAoJCQlsZW4sIE5VTEwsIE5VTEwpOwoKICAgIFRoaXMtPnBhZi0+aG1taW8gPSBtbWlvT3BlbkEoc3pGaWxlTmFtZSwgTlVMTCwgTU1JT19BTExPQ0JVRiB8IGR3TW9kZSk7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzekZpbGVOYW1lKTsKICAgIGlmIChUaGlzLT5wYWYtPmhtbWlvID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfRklMRU9QRU47CiAgfQoKICAvKiBzaG91bGQgd2UgY3JlYXRlIGEgbmV3IGZpbGU/ICovCiAgaWYgKGR3TW9kZSAmIE9GX0NSRUFURSkgewogICAgbWVtc2V0KCYgVGhpcy0+cGFmLT5mSW5mbywgMCwgc2l6ZW9mKFRoaXMtPnBhZi0+ZkluZm8pKTsKICAgIFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyA9IEFWSUZJTEVJTkZPX0hBU0lOREVYIHwgQVZJRklMRUlORk9fVFJVU1RDS1RZUEU7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBBVklGSUxFX0xvYWRGaWxlKFRoaXMtPnBhZik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJUGVyc2lzdEZpbGVfZm5TYXZlKElQZXJzaXN0RmlsZSAqaWZhY2UsCgkJCQkJICBMUENPTEVTVFIgcHN6RmlsZU5hbWUsQk9PTCBmUmVtZW1iZXIpCnsKICBUUkFDRSgiKCVwLCVzLCVkKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpLCBmUmVtZW1iZXIpOwoKICAvKiBXZSB3cml0ZSBkaXJlY3RseSB0byBkaXNrLCBzbyBub3RoaW5nIHRvIGRvLiAqLwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSVBlcnNpc3RGaWxlX2ZuU2F2ZUNvbXBsZXRlZChJUGVyc2lzdEZpbGUgKmlmYWNlLAoJCQkJCQkgICBMUENPTEVTVFIgcHN6RmlsZU5hbWUpCnsKICBUUkFDRSgiKCVwLCVzKVxuIiwgaWZhY2UsIGRlYnVnc3RyX3cocHN6RmlsZU5hbWUpKTsKCiAgLyogV2Ugd3JpdGUgZGlyZWN0bHkgdG8gZGlzaywgc28gbm90aGluZyB0byBkby4gKi8KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElQZXJzaXN0RmlsZV9mbkdldEN1ckZpbGUoSVBlcnNpc3RGaWxlICppZmFjZSwKCQkJCQkJTFBPTEVTVFIgKnBwc3pGaWxlTmFtZSkKewogIElQZXJzaXN0RmlsZUltcGwgKlRoaXMgPSAoSVBlcnNpc3RGaWxlSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgaWZhY2UsIHBwc3pGaWxlTmFtZSk7CgogIGlmIChwcHN6RmlsZU5hbWUgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICpwcHN6RmlsZU5hbWUgPSBOVUxMOwoKICBhc3NlcnQoVGhpcy0+cGFmICE9IE5VTEwpOwoKICBpZiAoVGhpcy0+cGFmLT5zekZpbGVOYW1lICE9IE5VTEwpIHsKICAgIGludCBsZW4gPSBsc3RybGVuVyhUaGlzLT5wYWYtPnN6RmlsZU5hbWUpICsgMTsKCiAgICAqcHBzekZpbGVOYW1lID0gQ29UYXNrTWVtQWxsb2MobGVuICogc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoKnBwc3pGaWxlTmFtZSA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICBzdHJjcHlXKCpwcHN6RmlsZU5hbWUsIFRoaXMtPnBhZi0+c3pGaWxlTmFtZSk7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblF1ZXJ5SW50ZXJmYWNlKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCQkgIFJFRklJRCByZWZpaWQsIExQVk9JRCAqb2JqKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgVFJBQ0UoIiglcCwlcywlcClcbiIsIGlmYWNlLCBkZWJ1Z3N0cl9ndWlkKHJlZmlpZCksIG9iaik7CgogIGlmIChJc0VxdWFsR1VJRCgmSUlEX0lVbmtub3duLCByZWZpaWQpIHx8CiAgICAgIElzRXF1YWxHVUlEKCZJSURfSUFWSVN0cmVhbSwgcmVmaWlkKSkgewogICAgKm9iaiA9IFRoaXM7CiAgICBJQVZJU3RyZWFtX0FkZFJlZihpZmFjZSk7CgogICAgcmV0dXJuIFNfT0s7CiAgfQogIC8qIEZJWE1FOiBJQVZJU3RyZWFtaW5nIGludGVyZmFjZSAqLwoKICByZXR1cm4gT0xFX0VfRU5VTV9OT01PUkU7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkFkZFJlZihJQVZJU3RyZWFtICppZmFjZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CiAgVUxPTkcgcmVmID0gSW50ZXJsb2NrZWRJbmNyZW1lbnQoJlRoaXMtPnJlZik7CgogIFRSQUNFKCIoJXApIC0+ICVsZFxuIiwgaWZhY2UsIHJlZik7CgogIC8qIGFsc28gYWRkIHJlZiB0byBwYXJlbnQsIHNvIHRoYXQgaXQgZG9lc24ndCBraWxsIHVzICovCiAgaWYgKFRoaXMtPnBhZiAhPSBOVUxMKQogICAgSUFWSUZpbGVfQWRkUmVmKChQQVZJRklMRSlUaGlzLT5wYWYpOwoKICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJIElBVklTdHJlYW1fZm5SZWxlYXNlKElBVklTdHJlYW0qIGlmYWNlKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgVFJBQ0UoIiglcCkgLT4gJWxkXG4iLCBpZmFjZSwgcmVmKTsKCiAgaWYgKFRoaXMtPnBhZiAhPSBOVUxMKQogICAgSUFWSUZpbGVfUmVsZWFzZSgoUEFWSUZJTEUpVGhpcy0+cGFmKTsKCiAgcmV0dXJuIHJlZjsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5DcmVhdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExQQVJBTSBsUGFyYW0xLAoJCQkJCSAgTFBBUkFNIGxQYXJhbTIpCnsKICBUUkFDRSgiKCVwLDB4JTA4bFgsMHglMDhsWClcbiIsIGlmYWNlLCBsUGFyYW0xLCBsUGFyYW0yKTsKCiAgLyogVGhpcyBJQVZJU3RyZWFtIGludGVyZmFjZSBuZWVkcyBhbiBBVklGaWxlICovCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5JbmZvKElBVklTdHJlYW0gKmlmYWNlLExQQVZJU1RSRUFNSU5GT1cgcHNpLAoJCQkJCUxPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsJXAsJWxkKVxuIiwgaWZhY2UsIHBzaSwgc2l6ZSk7CgogIGlmIChwc2kgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURTSVpFOwoKICBtZW1jcHkocHNpLCAmVGhpcy0+c0luZm8sIG1pbigoRFdPUkQpc2l6ZSwgc2l6ZW9mKFRoaXMtPnNJbmZvKSkpOwoKICBpZiAoKERXT1JEKXNpemUgPCBzaXplb2YoVGhpcy0+c0luZm8pKQogICAgcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgTE9ORyBXSU5BUEkgSUFWSVN0cmVhbV9mbkZpbmRTYW1wbGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgIExPTkcgZmxhZ3MpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBMT05HIG9mZnNldCA9IDA7CgogIFRSQUNFKCIoJXAsJWxkLDB4JTA4bFgpXG4iLGlmYWNlLHBvcyxmbGFncyk7CgogIGlmIChmbGFncyAmIEZJTkRfRlJPTV9TVEFSVCkgewogICAgcG9zID0gVGhpcy0+c0luZm8uZHdTdGFydDsKICAgIGZsYWdzICY9IH4oRklORF9GUk9NX1NUQVJUfEZJTkRfUFJFVik7CiAgICBmbGFncyB8PSBGSU5EX05FWFQ7CiAgfQoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGNvbnZlcnQgc2FtcGxlcyBpbnRvIGJsb2NrIG51bWJlciB3aXRoIG9mZnNldCAqLwogICAgQVZJRklMRV9TYW1wbGVzVG9CbG9jayhUaGlzLCAmcG9zLCAmb2Zmc2V0KTsKICB9CgogIGlmIChmbGFncyAmIEZJTkRfVFlQRSkgewogICAgaWYgKGZsYWdzICYgRklORF9LRVkpIHsKICAgICAgd2hpbGUgKDAgPD0gcG9zICYmIHBvcyA8PSBUaGlzLT5sTGFzdEZyYW1lKSB7CglpZiAoVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdGbGFncyAmIEFWSUlGX0tFWUZSQU1FKQoJICBnb3RvIFJFVFVSTl9GT1VORDsKCglpZiAoZmxhZ3MgJiBGSU5EX05FWFQpCgkgIHBvcysrOwoJZWxzZQoJICBwb3MtLTsKICAgICAgfTsKICAgIH0gZWxzZSBpZiAoZmxhZ3MgJiBGSU5EX0FOWSkgewogICAgICB3aGlsZSAoMCA8PSBwb3MgJiYgcG9zIDw9IFRoaXMtPmxMYXN0RnJhbWUpIHsKCWlmIChUaGlzLT5pZHhGcmFtZXNbcG9zXS5kd0NodW5rTGVuZ3RoID4gMCkKCSAgZ290byBSRVRVUk5fRk9VTkQ7CgoJaWYgKGZsYWdzICYgRklORF9ORVhUKQoJICBwb3MrKzsKCWVsc2UKCSAgcG9zLS07CgogICAgICB9OwogICAgfSBlbHNlIGlmICgoZmxhZ3MgJiBGSU5EX0ZPUk1BVCkgJiYgVGhpcy0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMICYmCgkgICAgICAgVGhpcy0+c0luZm8uZmNjVHlwZSA9PSBzdHJlYW10eXBlVklERU8pIHsKICAgICAgaWYgKGZsYWdzICYgRklORF9ORVhUKSB7CglVTE9ORyBuOwoKCWZvciAobiA9IDA7IG4gPCBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBuKyspCgkgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQgPj0gcG9zKSB7CiAgICAgICAgICAgIHBvcyA9IFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZDsKCSAgICBnb3RvIFJFVFVSTl9GT1VORDsKICAgICAgICAgIH0KICAgICAgfSBlbHNlIHsKCUxPTkcgbjsKCglmb3IgKG4gPSAoTE9ORylUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBuID49IDA7IG4tLSkgewoJICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5ja2lkIDw9IHBvcykgewogICAgICAgICAgICBwb3MgPSBUaGlzLT5pZHhGbXRDaGFuZ2VzW25dLmNraWQ7CgkgICAgZ290byBSRVRVUk5fRk9VTkQ7CiAgICAgICAgICB9Cgl9CgoJaWYgKHBvcyA+IChMT05HKVRoaXMtPnNJbmZvLmR3U3RhcnQpCgkgIHJldHVybiAwOyAvKiBmb3JtYXQgY2hhbmdlcyBhbHdheXMgZm9yIGZpcnN0IGZyYW1lICovCiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gLTE7CiAgfQoKIFJFVFVSTl9GT1VORDoKICBpZiAocG9zIDwgKExPTkcpVGhpcy0+c0luZm8uZHdTdGFydCkKICAgIHJldHVybiAtMTsKCiAgc3dpdGNoIChmbGFncyAmIEZJTkRfUkVUKSB7CiAgY2FzZSBGSU5EX0xFTkdUSDoKICAgIC8qIHBoeXNpY2FsIHNpemUgKi8KICAgIHBvcyA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGg7CiAgICBicmVhazsKICBjYXNlIEZJTkRfT0ZGU0VUOgogICAgLyogcGh5c2ljYWwgcG9zaXRpb24gKi8KICAgIHBvcyA9IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtPZmZzZXQgKyAyICogc2l6ZW9mKERXT1JEKQogICAgICArIG9mZnNldCAqIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIGJyZWFrOwogIGNhc2UgRklORF9TSVpFOgogICAgLyogbG9naWNhbCBzaXplICovCiAgICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplKQogICAgICBwb3MgPSBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBlbHNlCiAgICAgIHBvcyA9IDE7CiAgICBicmVhazsKICBjYXNlIEZJTkRfSU5ERVg6CiAgICBGSVhNRSgiOiBGSU5EX0lOREVYIGZsYWcgaXMgbm90IHN1cHBvcnRlZCFcbiIpOwogICAgLyogVGhpcyBpcyBhbiBpbmRleCBpbiB0aGUgaW5kZXgtdGFibGUgb24gZGlzYy4gKi8KICAgIGJyZWFrOwogIH07IC8qIGVsc2UgbG9naWNhbCBwb3NpdGlvbiAqLwoKICByZXR1cm4gcG9zOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblJlYWRGb3JtYXQoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgcG9zLAoJCQkJCSAgICAgIExQVk9JRCBmb3JtYXQsIExPTkcgKmZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlcClcbiIsIGlmYWNlLCBwb3MsIGZvcm1hdCwgZm9ybWF0c2l6ZSk7CgogIGlmIChmb3JtYXRzaXplID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAvKiBvbmx5IGludGVyZXN0ZWQgaW4gbmVlZGVkIGJ1ZmZlcnNpemU/ICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8ICpmb3JtYXRzaXplIDw9IDApIHsKICAgICpmb3JtYXRzaXplID0gVGhpcy0+Y2JGb3JtYXQ7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9CgogIC8qIGNvcHkgaW5pdGlhbCBmb3JtYXQgKG9ubHkgYXMgbXVjaCBhcyB3aWxsIGZpdCkgKi8KICBtZW1jcHkoZm9ybWF0LCBUaGlzLT5scEZvcm1hdCwgbWluKCooRFdPUkQqKWZvcm1hdHNpemUsIFRoaXMtPmNiRm9ybWF0KSk7CiAgaWYgKCooRFdPUkQqKWZvcm1hdHNpemUgPCBUaGlzLT5jYkZvcm1hdCkgewogICAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKICAgIHJldHVybiBBVklFUlJfQlVGRkVSVE9PU01BTEw7CiAgfQoKICAvKiBDb3VsZCBmb3JtYXQgY2hhbmdlPyBXaGVuIHllcyB3aWxsIGl0IGNoYW5nZT8gKi8KICBpZiAoKFRoaXMtPnNJbmZvLmR3RmxhZ3MgJiBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVMpICYmCiAgICAgIHBvcyA+IFRoaXMtPnNJbmZvLmR3U3RhcnQpIHsKICAgIExPTkcgbExhc3RGbXQ7CgogICAgbExhc3RGbXQgPSBJQVZJU3RyZWFtX2ZuRmluZFNhbXBsZShpZmFjZSwgcG9zLCBGSU5EX0ZPUk1BVHxGSU5EX1BSRVYpOwogICAgaWYgKGxMYXN0Rm10ID4gMCkgewogICAgICBGSVhNRSgiOiBuZWVkIHRvIHJlYWQgZm9ybWF0Y2hhbmdlIGZvciAlbGQgLS0gdW5pbXBsZW1lbnRlZCFcbiIsbExhc3RGbXQpOwogICAgfQogIH0KCiAgKmZvcm1hdHNpemUgPSBUaGlzLT5jYkZvcm1hdDsKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mblNldEZvcm1hdChJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBwb3MsCgkJCQkJICAgICBMUFZPSUQgZm9ybWF0LCBMT05HIGZvcm1hdHNpemUpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBMUEJJVE1BUElORk9IRUFERVIgbHBiaU5ldyA9IChMUEJJVE1BUElORk9IRUFERVIpZm9ybWF0OwoKICBUUkFDRSgiKCVwLCVsZCwlcCwlbGQpXG4iLCBpZmFjZSwgcG9zLCBmb3JtYXQsIGZvcm1hdHNpemUpOwoKICAvKiBjaGVjayBwYXJhbWV0ZXJzICovCiAgaWYgKGZvcm1hdCA9PSBOVUxMIHx8IGZvcm1hdHNpemUgPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIC8qIERvIHdlIGhhdmUgd3JpdGUgcGVybWlzc2lvbj8gKi8KICBpZiAoKFRoaXMtPnBhZi0+dU1vZGUgJiBNTUlPX1JXTU9ERSkgPT0gMCkKICAgIHJldHVybiBBVklFUlJfUkVBRE9OTFk7CgogIC8qIGNhbiBvbmx5IHNldCBmb3JtYXQgYmVmb3JlIGZyYW1lIGlzIHdyaXR0ZW4hICovCiAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPiBwb3MpCiAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAvKiBpbml0aWFsIGZvcm1hdCBvciBhIGZvcm1hdGNoYW5nZT8gKi8KICBpZiAoVGhpcy0+bHBGb3JtYXQgPT0gTlVMTCkgewogICAgLyogaW5pdGlhbCBmb3JtYXQgKi8KICAgIGlmIChUaGlzLT5wYWYtPmR3TW92aUNodW5rUG9zICE9IDApCiAgICAgIHJldHVybiBBVklFUlJfRVJST1I7IC8qIHVzZXIgaGFzIHVzZWQgQVBJIGluIHdyb25nIHNlcXVuZWNlISAqLwoKICAgIFRoaXMtPmxwRm9ybWF0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGZvcm1hdHNpemUpOwogICAgaWYgKFRoaXMtPmxwRm9ybWF0ID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogICAgVGhpcy0+Y2JGb3JtYXQgPSBmb3JtYXRzaXplOwoKICAgIG1lbWNweShUaGlzLT5scEZvcm1hdCwgZm9ybWF0LCBmb3JtYXRzaXplKTsKCiAgICAvKiB1cGRhdGUgc29tZSBpbmZvcyBhYm91dCBzdHJlYW0gKi8KICAgIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewogICAgICBMT05HIGxEaW07CgogICAgICBsRGltID0gVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCAtIFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdDsKICAgICAgaWYgKGxEaW0gPCBscGJpTmV3LT5iaVdpZHRoKQoJVGhpcy0+c0luZm8ucmNGcmFtZS5yaWdodCA9IFRoaXMtPnNJbmZvLnJjRnJhbWUubGVmdCArIGxwYmlOZXctPmJpV2lkdGg7CiAgICAgIGxEaW0gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLmJvdHRvbSAtIFRoaXMtPnNJbmZvLnJjRnJhbWUudG9wOwogICAgICBpZiAobERpbSA8IGxwYmlOZXctPmJpSGVpZ2h0KQoJVGhpcy0+c0luZm8ucmNGcmFtZS5ib3R0b20gPSBUaGlzLT5zSW5mby5yY0ZyYW1lLnRvcCArIGxwYmlOZXctPmJpSGVpZ2h0OwogICAgfSBlbHNlIGlmIChUaGlzLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVBVURJTykKICAgICAgVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplID0gKChMUFdBVkVGT1JNQVRFWClUaGlzLT5scEZvcm1hdCktPm5CbG9ja0FsaWduOwoKICAgIHJldHVybiBBVklFUlJfT0s7CiAgfSBlbHNlIHsKICAgIE1NQ0tJTkZPICAgICAgICAgICBjazsKICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpT2xkID0gKExQQklUTUFQSU5GT0hFQURFUilUaGlzLT5scEZvcm1hdDsKICAgIFJHQlFVQUQgICAgICAgICAgICpyZ2JOZXcgID0gKFJHQlFVQUQqKSgoTFBCWVRFKWxwYmlOZXcgKyBscGJpTmV3LT5iaVNpemUpOwogICAgQVZJUEFMQ0hBTkdFICAgICAgKmxwcGMgPSBOVUxMOwogICAgVUlOVCAgICAgICAgICAgICAgIG47CgogICAgLyogcGVyaGFwcyBmb3JtYXQgY2hhbmdlLCBjaGVjayBpdCAuLi4gKi8KICAgIGlmIChUaGlzLT5jYkZvcm1hdCAhPSBmb3JtYXRzaXplKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIG5vIGZvcm1hdCBjaGFuZ2UsIG9ubHkgdGhlIGluaXRpYWwgb25lICovCiAgICBpZiAobWVtY21wKFRoaXMtPmxwRm9ybWF0LCBmb3JtYXQsIGZvcm1hdHNpemUpID09IDApCiAgICAgIHJldHVybiBBVklFUlJfT0s7CgogICAgLyogY2hlY2sgdGhhdCdzIG9ubHkgdGhlIHBhbGV0dGUsIHdoaWNoIGNoYW5nZXMgKi8KICAgIGlmIChscGJpT2xkLT5iaVNpemUgICAgICAgICE9IGxwYmlOZXctPmJpU2l6ZSB8fAoJbHBiaU9sZC0+YmlXaWR0aCAgICAgICAhPSBscGJpTmV3LT5iaVdpZHRoIHx8CglscGJpT2xkLT5iaUhlaWdodCAgICAgICE9IGxwYmlOZXctPmJpSGVpZ2h0IHx8CglscGJpT2xkLT5iaVBsYW5lcyAgICAgICE9IGxwYmlOZXctPmJpUGxhbmVzIHx8CglscGJpT2xkLT5iaUJpdENvdW50ICAgICE9IGxwYmlOZXctPmJpQml0Q291bnQgfHwKCWxwYmlPbGQtPmJpQ29tcHJlc3Npb24gIT0gbHBiaU5ldy0+YmlDb21wcmVzc2lvbiB8fAoJbHBiaU9sZC0+YmlDbHJVc2VkICAgICAhPSBscGJpTmV3LT5iaUNsclVzZWQpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgVGhpcy0+c0luZm8uZHdGbGFncyB8PSBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVM7CgogICAgLyogc2ltcGx5IHNheSBhbGwgY29sb3JzIGhhdmUgY2hhbmdlZCAqLwogICAgY2suY2tpZCAgID0gTUFLRUFWSUNLSUQoY2t0eXBlUEFMY2hhbmdlLCBUaGlzLT5uU3RyZWFtKTsKICAgIGNrLmNrc2l6ZSA9IDIgKiBzaXplb2YoV09SRCkgKyBscGJpT2xkLT5iaUNsclVzZWQgKiBzaXplb2YoUEFMRVRURUVOVFJZKTsKICAgIGxwcGMgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKICAgIGlmIChscHBjID09IE5VTEwpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwoKICAgIGxwcGMtPmJGaXJzdEVudHJ5ID0gMDsKICAgIGxwcGMtPmJOdW1FbnRyaWVzID0gKGxwYmlPbGQtPmJpQ2xyVXNlZCA8IDI1NiA/IGxwYmlPbGQtPmJpQ2xyVXNlZCA6IDApOwogICAgbHBwYy0+d0ZsYWdzICAgICAgPSAwOwogICAgZm9yIChuID0gMDsgbiA8IGxwYmlPbGQtPmJpQ2xyVXNlZDsgbisrKSB7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlUmVkICAgPSByZ2JOZXdbbl0ucmdiUmVkOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUdyZWVuID0gcmdiTmV3W25dLnJnYkdyZWVuOwogICAgICBscHBjLT5wZU5ld1tuXS5wZUJsdWUgID0gcmdiTmV3W25dLnJnYkJsdWU7CiAgICAgIGxwcGMtPnBlTmV3W25dLnBlRmxhZ3MgPSAwOwogICAgfQoKICAgIGlmIChtbWlvU2VlayhUaGlzLT5wYWYtPmhtbWlvLCBUaGlzLT5wYWYtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Xcml0ZShUaGlzLT5wYWYtPmhtbWlvLCAoSFBTVFIpbHBwYywgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIFRoaXMtPnBhZi0+ZHdOZXh0RnJhbWVQb3MgKz0gY2suY2tzaXplICsgMiAqIHNpemVvZihEV09SRCk7CgogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHBwYyk7CgogICAgcmV0dXJuIEFWSUZJTEVfQWRkRnJhbWUoVGhpcywgY2t0eXBlUEFMY2hhbmdlLCBuLCBjay5kd0RhdGFPZmZzZXQsIDApOwogIH0KfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkKElBVklTdHJlYW0gKmlmYWNlLCBMT05HIHN0YXJ0LAoJCQkJCUxPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQlMT05HIGJ1ZmZlcnNpemUsIExQTE9ORyBieXRlc3JlYWQsCgkJCQkJTFBMT05HIHNhbXBsZXNyZWFkKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgRFdPUkQgICAgc2l6ZTsKICBIUkVTVUxUICBocjsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCVwLCVsZCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywgYnVmZmVyLAogCWJ1ZmZlcnNpemUsIGJ5dGVzcmVhZCwgc2FtcGxlc3JlYWQpOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChieXRlc3JlYWQgIT0gTlVMTCkKICAgICpieXRlc3JlYWQgPSAwOwogIGlmIChzYW1wbGVzcmVhZCAhPSBOVUxMKQogICAgKnNhbXBsZXNyZWFkID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmICgoTE9ORylUaGlzLT5zSW5mby5kd1N0YXJ0ID4gc3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX05PREFUQTsgLyogY291bGRuJ3QgcmVhZCBiZWZvcmUgc3RhcnQgb2Ygc3RyZWFtICovCiAgaWYgKFRoaXMtPnNJbmZvLmR3U3RhcnQgKyBUaGlzLT5zSW5mby5kd0xlbmd0aCA8IChEV09SRClzdGFydCkKICAgIHJldHVybiBBVklFUlJfTk9EQVRBOyAvKiBzdGFydCBpcyBwYXN0IGVuZCBvZiBzdHJlYW0gKi8KCiAgLyogc2hvdWxkIHdlIHJlYWQgYXMgbXVjaCBhcyBwb3NzaWJsZT8gKi8KICBpZiAoc2FtcGxlcyA9PSAtMSkgewogICAgLyogVXNlciBzaG91bGQga25vdyBob3cgbXVjaCB3ZSBoYXZlIHJlYWQgKi8KICAgIGlmIChieXRlc3JlYWQgPT0gTlVMTCAmJiBzYW1wbGVzcmVhZCA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JBRFBBUkFNOwoKICAgIGlmIChUaGlzLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkKICAgICAgc2FtcGxlcyA9IGJ1ZmZlcnNpemUgLyBUaGlzLT5zSW5mby5kd1NhbXBsZVNpemU7CiAgICBlbHNlCiAgICAgIHNhbXBsZXMgPSAxOwogIH0KCiAgLyogbGltaXQgdG8gZW5kIG9mIHN0cmVhbSAqLwogIGlmICgoTE9ORylUaGlzLT5zSW5mby5kd0xlbmd0aCA8IHNhbXBsZXMpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgaWYgKChzdGFydCAtIFRoaXMtPnNJbmZvLmR3U3RhcnQpID4gKFRoaXMtPnNJbmZvLmR3TGVuZ3RoIC0gc2FtcGxlcykpCiAgICBzYW1wbGVzID0gVGhpcy0+c0luZm8uZHdMZW5ndGggLSAoc3RhcnQgLSBUaGlzLT5zSW5mby5kd1N0YXJ0KTsKCiAgLyogbm90aGluZyB0byByZWFkPyBUaGVuIGxlYXZlIC4uLiAqLwogIGlmIChzYW1wbGVzID09IDApCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGZpeGVkIHNhbXBsZXNpemUgLS0gd2UgY2FuIHJlYWQgb3ZlciBmcmFtZS9ibG9jayBib3VuZGFyaWVzICovCiAgICBMT05HIGJsb2NrID0gc3RhcnQ7CiAgICBMT05HIG9mZnNldCA9IDA7CgogICAgLyogY29udmVydCBzdGFydCBzYW1wbGUgdG8gYmxvY2ssb2Zmc2V0IHBhaXIgKi8KICAgIEFWSUZJTEVfU2FtcGxlc1RvQmxvY2soVGhpcywgJmJsb2NrLCAmb2Zmc2V0KTsKCiAgICAvKiBjb252ZXJ0IHNhbXBsZXMgdG8gYnl0ZXMgKi8KICAgIHNhbXBsZXMgKj0gVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplOwoKICAgIHdoaWxlIChzYW1wbGVzID4gMCAmJiBidWZmZXJzaXplID4gMCkgewogICAgICBpZiAoYmxvY2sgIT0gVGhpcy0+ZHdDdXJyZW50RnJhbWUpIHsKCWhyID0gQVZJRklMRV9SZWFkQmxvY2soVGhpcywgYmxvY2ssIE5VTEwsIDApOwoJaWYgKEZBSUxFRChocikpCgkgIHJldHVybiBocjsKICAgICAgfQoKICAgICAgc2l6ZSA9IG1pbigoRFdPUkQpc2FtcGxlcywgKERXT1JEKWJ1ZmZlcnNpemUpOwogICAgICBzaXplID0gbWluKHNpemUsIFRoaXMtPmNiQnVmZmVyIC0gb2Zmc2V0KTsKICAgICAgbWVtY3B5KGJ1ZmZlciwgKChCWVRFKikmVGhpcy0+bHBCdWZmZXJbMl0pICsgb2Zmc2V0LCBzaXplKTsKCiAgICAgIGJsb2NrKys7CiAgICAgIG9mZnNldCA9IDA7CiAgICAgIGJ1ZmZlciA9ICgoTFBCWVRFKWJ1ZmZlcikrc2l6ZTsKICAgICAgc2FtcGxlcyAgICAtPSBzaXplOwogICAgICBidWZmZXJzaXplIC09IHNpemU7CgogICAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCgkqYnl0ZXNyZWFkICAgKz0gc2l6ZTsKICAgICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCgkqc2FtcGxlc3JlYWQgKz0gc2l6ZSAvIFRoaXMtPnNJbmZvLmR3U2FtcGxlU2l6ZTsKICAgIH0KCiAgICBpZiAoc2FtcGxlcyA9PSAwKQogICAgICByZXR1cm4gQVZJRVJSX09LOwogICAgZWxzZQogICAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwogIH0gZWxzZSB7CiAgICAvKiB2YXJpYWJsZSBzYW1wbGVzaXplIC0tIHdlIGNhbiBvbmx5IHJlYWQgb25lIGZ1bGwgZnJhbWUvYmxvY2sgKi8KICAgIGlmIChzYW1wbGVzID4gMSkKICAgICAgc2FtcGxlcyA9IDE7CgogICAgYXNzZXJ0KHN0YXJ0IDw9IFRoaXMtPmxMYXN0RnJhbWUpOwogICAgc2l6ZSA9IFRoaXMtPmlkeEZyYW1lc1tzdGFydF0uZHdDaHVua0xlbmd0aDsKICAgIGlmIChidWZmZXIgIT0gTlVMTCAmJiBidWZmZXJzaXplID49IHNpemUpIHsKICAgICAgaHIgPSBBVklGSUxFX1JlYWRCbG9jayhUaGlzLCBzdGFydCwgYnVmZmVyLCBzaXplKTsKICAgICAgaWYgKEZBSUxFRChocikpCglyZXR1cm4gaHI7CiAgICB9IGVsc2UgaWYgKGJ1ZmZlciAhPSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX0JVRkZFUlRPT1NNQUxMOwoKICAgIC8qIGZpbGwgb3V0IHJldHVybiBwYXJhbWV0ZXJzIGlmIGdpdmVuICovCiAgICBpZiAoYnl0ZXNyZWFkICE9IE5VTEwpCiAgICAgICpieXRlc3JlYWQgPSBzaXplOwogICAgaWYgKHNhbXBsZXNyZWFkICE9IE5VTEwpCiAgICAgICpzYW1wbGVzcmVhZCA9IHNhbXBsZXM7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGUoSUFWSVN0cmVhbSAqaWZhY2UsIExPTkcgc3RhcnQsCgkJCQkJIExPTkcgc2FtcGxlcywgTFBWT0lEIGJ1ZmZlciwKCQkJCQkgTE9ORyBidWZmZXJzaXplLCBEV09SRCBmbGFncywKCQkJCQkgTFBMT05HIHNhbXB3cml0dGVuLAoJCQkJCSBMUExPTkcgYnl0ZXN3cml0dGVuKQp7CiAgSUFWSVN0cmVhbUltcGwgKlRoaXMgPSAoSUFWSVN0cmVhbUltcGwgKilpZmFjZTsKCiAgRk9VUkNDICBja2lkOwogIEhSRVNVTFQgaHI7CgogIFRSQUNFKCIoJXAsJWxkLCVsZCwlcCwlbGQsMHglMDhsWCwlcCwlcClcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcywKCWJ1ZmZlciwgYnVmZmVyc2l6ZSwgZmxhZ3MsIHNhbXB3cml0dGVuLCBieXRlc3dyaXR0ZW4pOwoKICAvKiBjbGVhciByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogIGlmIChzYW1wd3JpdHRlbiAhPSBOVUxMKQogICAgKnNhbXB3cml0dGVuID0gMDsKICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAqYnl0ZXN3cml0dGVuID0gMDsKCiAgLyogY2hlY2sgcGFyYW1ldGVycyAqLwogIGlmIChidWZmZXIgPT0gTlVMTCAmJiAoYnVmZmVyc2l6ZSA+IDAgfHwgc2FtcGxlcyA+IDApKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogSGF2ZSB3ZSB3cml0ZSBwZXJtaXNzaW9uPyAqLwogIGlmICgoVGhpcy0+cGFmLT51TW9kZSAmIE1NSU9fUldNT0RFKSA9PSAwKQogICAgcmV0dXJuIEFWSUVSUl9SRUFET05MWTsKCiAgc3dpdGNoIChUaGlzLT5zSW5mby5mY2NUeXBlKSB7CiAgY2FzZSBzdHJlYW10eXBlQVVESU86CiAgICBja2lkID0gTUFLRUFWSUNLSUQoY2t0eXBlV0FWRWJ5dGVzLCBUaGlzLT5uU3RyZWFtKTsKICAgIGJyZWFrOwogIGRlZmF1bHQ6CiAgICBpZiAoKGZsYWdzICYgQVZJSUZfS0VZRlJBTUUpICYmIGJ1ZmZlcnNpemUgIT0gMCkKICAgICAgY2tpZCA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmJpdHMsIFRoaXMtPm5TdHJlYW0pOwogICAgZWxzZQogICAgICBja2lkID0gTUFLRUFWSUNLSUQoY2t0eXBlRElCY29tcHJlc3NlZCwgVGhpcy0+blN0cmVhbSk7CiAgICBicmVhazsKICB9OwoKICAvKiBhcHBlbmQgdG8gZW5kIG9mIHN0cmVhbT8gKi8KICBpZiAoc3RhcnQgPT0gLTEpIHsKICAgIGlmIChUaGlzLT5sTGFzdEZyYW1lID09IC0xKQogICAgICBzdGFydCA9IFRoaXMtPnNJbmZvLmR3U3RhcnQ7CiAgICBlbHNlCiAgICAgIHN0YXJ0ID0gVGhpcy0+c0luZm8uZHdMZW5ndGg7CiAgfSBlbHNlIGlmIChUaGlzLT5sTGFzdEZyYW1lID09IC0xKQogICAgVGhpcy0+c0luZm8uZHdTdGFydCA9IHN0YXJ0OwoKICBpZiAoVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IDApIHsKICAgIC8qIGZpeGVkIHNhbXBsZSBzaXplIC0tIGF1ZGlvIGxpa2UgKi8KICAgIGlmIChzYW1wbGVzICogVGhpcy0+c0luZm8uZHdTYW1wbGVTaXplICE9IGJ1ZmZlcnNpemUpCiAgICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogICAgLyogQ291bGRuJ3Qgc2tpcCBhdWRpby1saWtlIGRhdGEgLS0gVXNlciBtdXN0IHN1cHBseSBhcHByb3ByaWF0ZSBzaWxlbmNlICovCiAgICBpZiAoVGhpcy0+c0luZm8uZHdMZW5ndGggIT0gc3RhcnQpCiAgICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CgogICAgLyogQ29udmVydCBwb3NpdGlvbiB0byBmcmFtZS9ibG9jayAqLwogICAgc3RhcnQgPSBUaGlzLT5sTGFzdEZyYW1lICsgMTsKCiAgICBpZiAoKFRoaXMtPnBhZi0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQpID09IDApIHsKICAgICAgRklYTUUoIjogbm90IGludGVybGVhdmVkLCBjb3VsZCBjb2xsZWN0IGF1ZGlvIGRhdGEhXG4iKTsKICAgIH0KICB9IGVsc2UgewogICAgLyogdmFyaWFibGUgc2FtcGxlIHNpemUgLS0gdmlkZW8gbGlrZSAqLwogICAgaWYgKHNhbXBsZXMgPiAxKQogICAgICByZXR1cm4gQVZJRVJSX1VOU1VQUE9SVEVEOwoKICAgIC8qIG11c3Qgd2UgZmlsbCB1cCB3aXRoIGVtcHR5IGZyYW1lcz8gKi8KICAgIGlmIChUaGlzLT5sTGFzdEZyYW1lICE9IC0xKSB7CiAgICAgIEZPVVJDQyBja2lkMiA9IE1BS0VBVklDS0lEKGNrdHlwZURJQmNvbXByZXNzZWQsIFRoaXMtPm5TdHJlYW0pOwoKICAgICAgd2hpbGUgKHN0YXJ0ID4gVGhpcy0+bExhc3RGcmFtZSArIDEpIHsKCWhyID0gQVZJRklMRV9Xcml0ZUJsb2NrKFRoaXMsIFRoaXMtPmxMYXN0RnJhbWUgKyAxLCBja2lkMiwgMCwgTlVMTCwgMCk7CglpZiAoRkFJTEVEKGhyKSkKCSAgcmV0dXJuIGhyOwogICAgICB9CiAgICB9CiAgfQoKICAvKiB3cml0ZSB0aGUgYmxvY2sgbm93ICovCiAgaHIgPSBBVklGSUxFX1dyaXRlQmxvY2soVGhpcywgc3RhcnQsIGNraWQsIGZsYWdzLCBidWZmZXIsIGJ1ZmZlcnNpemUpOwogIGlmIChTVUNDRUVERUQoaHIpKSB7CiAgICAvKiBmaWxsIG91dCByZXR1cm4gcGFyYW1ldGVycyBpZiBnaXZlbiAqLwogICAgaWYgKHNhbXB3cml0dGVuICE9IE5VTEwpCiAgICAgICpzYW1wd3JpdHRlbiA9IHNhbXBsZXM7CiAgICBpZiAoYnl0ZXN3cml0dGVuICE9IE5VTEwpCiAgICAgICpieXRlc3dyaXR0ZW4gPSBidWZmZXJzaXplOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgSUFWSVN0cmVhbV9mbkRlbGV0ZShJQVZJU3RyZWFtICppZmFjZSwgTE9ORyBzdGFydCwKCQkJCQkgIExPTkcgc2FtcGxlcykKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIEZJWE1FKCIoJXAsJWxkLCVsZCk6IHN0dWJcbiIsIGlmYWNlLCBzdGFydCwgc2FtcGxlcyk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAoc3RhcnQgPCAwIHx8IHNhbXBsZXMgPCAwKQogICAgcmV0dXJuIEFWSUVSUl9CQURQQVJBTTsKCiAgLyogRGVsZXRlIGJlZm9yZSBzdGFydCBvZiBzdHJlYW0/ICovCiAgaWYgKHN0YXJ0ICsgc2FtcGxlcyA8IFRoaXMtPnNJbmZvLmR3U3RhcnQpCiAgICByZXR1cm4gQVZJRVJSX09LOwoKICAvKiBEZWxldGUgYWZ0ZXIgZW5kIG9mIHN0cmVhbT8gKi8KICBpZiAoc3RhcnQgPiBUaGlzLT5zSW5mby5kd0xlbmd0aCkKICAgIHJldHVybiBBVklFUlJfT0s7CgogIC8qIEZvciB0aGUgcmVzdCB3ZSBuZWVkIHdyaXRlIHBlcm1pc3Npb25zICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiAxLiBvdmVyd3JpdGUgdGhlIGRhdGEgd2l0aCBKVU5LCiAgICoKICAgKiBpZiBJU0lOVEVSTEVBVkVEIHsKICAgKiAgIDIuIGNvbmNhdCBhbGwgbmVpZ2hib3VyZWQgSlVOSy1ibG9ja3MgaW4gdGhpcyByZWNvcmQgdG8gb25lCiAgICogICAzLiBpZiB0aGlzIHJlY29yZCBvbmx5IGNvbnRhaW5zIEpVTksgYW5kIGlzIGF0IGVuZCBzZXQgZHdOZXh0RnJhbWVQb3MKICAgKiAgICAgIHRvIHN0YXJ0IG9mIHRoaXMgcmVjb3JkLCByZXBlYXQgdGhpcy4KICAgKiB9IGVsc2UgewogICAqICAgMi4gY29uY2F0IGFsbCBuZWlnaGJvdXJlZCBKVU5LLWJsb2Nrcy4KICAgKiAgIDMuIGlmIHRoZSBKVU5LIGJsb2NrIGlzIGF0IHRoZSBlbmQsIHRoZW4gc2V0IGR3TmV4dEZyYW1lUG9zIHRvCiAgICogICAgICBzdGFydCBvZiB0aGlzIGJsb2NrLgogICAqIH0KICAgKi8KCiAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5SZWFkRGF0YShJQVZJU3RyZWFtICppZmFjZSwgRFdPUkQgZmNjLAoJCQkJCSAgICBMUFZPSUQgbHAsIExQTE9ORyBscHJlYWQpCnsKICBJQVZJU3RyZWFtSW1wbCAqVGhpcyA9IChJQVZJU3RyZWFtSW1wbCAqKWlmYWNlOwoKICBUUkFDRSgiKCVwLDB4JTA4bFgsJXAsJXApXG4iLCBpZmFjZSwgZmNjLCBscCwgbHByZWFkKTsKCiAgaWYgKGZjYyA9PSBja2lkU1RSRUFNSEFORExFUkRBVEEpIHsKICAgIGlmIChUaGlzLT5scEhhbmRsZXJEYXRhICE9IE5VTEwgJiYgVGhpcy0+Y2JIYW5kbGVyRGF0YSA+IDApIHsKICAgICAgaWYgKGxwID09IE5VTEwgfHwgKmxwcmVhZCA8PSAwKSB7CgkqbHByZWFkID0gVGhpcy0+Y2JIYW5kbGVyRGF0YTsKCXJldHVybiBBVklFUlJfT0s7CiAgICAgIH0KCiAgICAgIG1lbWNweShscCwgVGhpcy0+bHBIYW5kbGVyRGF0YSwgbWluKFRoaXMtPmNiSGFuZGxlckRhdGEsICpscHJlYWQpKTsKICAgICAgaWYgKCpscHJlYWQgPCBUaGlzLT5jYkhhbmRsZXJEYXRhKQoJcmV0dXJuIEFWSUVSUl9CVUZGRVJUT09TTUFMTDsKICAgICAgcmV0dXJuIEFWSUVSUl9PSzsKICAgIH0gZWxzZQogICAgICByZXR1cm4gQVZJRVJSX05PREFUQTsKICB9IGVsc2UKICAgIHJldHVybiBSZWFkRXh0cmFDaHVuaygmVGhpcy0+ZXh0cmEsIGZjYywgbHAsIGxwcmVhZCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBJQVZJU3RyZWFtX2ZuV3JpdGVEYXRhKElBVklTdHJlYW0gKmlmYWNlLCBEV09SRCBmY2MsCgkJCQkJICAgICBMUFZPSUQgbHAsIExPTkcgc2l6ZSkKewogIElBVklTdHJlYW1JbXBsICpUaGlzID0gKElBVklTdHJlYW1JbXBsICopaWZhY2U7CgogIFRSQUNFKCIoJXAsMHglMDhseCwlcCwlbGQpXG4iLCBpZmFjZSwgZmNjLCBscCwgc2l6ZSk7CgogIC8qIGNoZWNrIHBhcmFtZXRlcnMgKi8KICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CiAgaWYgKHNpemUgPD0gMCkKICAgIHJldHVybiBBVklFUlJfQkFEU0laRTsKCiAgLyogbmVlZCB3cml0ZSBwZXJtaXNzaW9uICovCiAgaWYgKChUaGlzLT5wYWYtPnVNb2RlICYgTU1JT19SV01PREUpID09IDApCiAgICByZXR1cm4gQVZJRVJSX1JFQURPTkxZOwoKICAvKiBhbHJlYWR5IHdyaXR0ZW4gc29tZXRoaW5nIHRvIHRoaXMgZmlsZT8gKi8KICBpZiAoVGhpcy0+cGFmLT5kd01vdmlDaHVua1BvcyAhPSAwKSB7CiAgICAvKiB0aGUgZGF0YSB3aWxsIGJlIGluc2VydGVkIGJlZm9yZSB0aGUgJ21vdmknIGNodW5rLCBzbyBjaGVjayBmb3IKICAgICAqIGVub3VnaCBzcGFjZSAqLwogICAgRFdPUkQgZHdQb3MgPSBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoVGhpcy0+cGFmKTsKCiAgICAvKiBja2lkLHNpemUgPT4gMiAqIHNpemVvZihEV09SRCkgKi8KICAgIGR3UG9zICs9IDIgKiBzaXplb2YoRFdPUkQpICsgc2l6ZTsKICAgIGlmIChzaXplID49IFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgLSAyICogc2l6ZW9mKERXT1JEKSkKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsgLyogbm90IGVub3VnaCBzcGFjZSBsZWZ0ICovCiAgfQoKICBUaGlzLT5wYWYtPmZEaXJ0eSA9IFRSVUU7CgogIGlmIChmY2MgPT0gY2tpZFNUUkVBTUhBTkRMRVJEQVRBKSB7CiAgICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMKSB7CiAgICAgIEZJWE1FKCI6IGhhbmRsZXIgZGF0YSBhbHJlYWR5IHNldCAtLSBvdmVyd2lydGU/XG4iKTsKICAgICAgcmV0dXJuIEFWSUVSUl9VTlNVUFBPUlRFRDsKICAgIH0KCiAgICBUaGlzLT5scEhhbmRsZXJEYXRhID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIHNpemUpOwogICAgaWYgKFRoaXMtPmxwSGFuZGxlckRhdGEgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICBUaGlzLT5jYkhhbmRsZXJEYXRhID0gc2l6ZTsKICAgIG1lbWNweShUaGlzLT5scEhhbmRsZXJEYXRhLCBscCwgc2l6ZSk7CgogICAgcmV0dXJuIEFWSUVSUl9PSzsKICB9IGVsc2UKICAgIHJldHVybiBXcml0ZUV4dHJhQ2h1bmsoJlRoaXMtPmV4dHJhLCBmY2MsIGxwLCBzaXplKTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIElBVklTdHJlYW1fZm5TZXRJbmZvKElBVklTdHJlYW0gKmlmYWNlLAoJCQkJCSAgIExQQVZJU1RSRUFNSU5GT1cgaW5mbywgTE9ORyBpbmZvbGVuKQp7CiAgRklYTUUoIiglcCwlcCwlbGQpOiBzdHViXG4iLCBpZmFjZSwgaW5mbywgaW5mb2xlbik7CgogIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQWRkRnJhbWUoSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIGNraWQsIERXT1JEIHNpemUsIERXT1JEIG9mZnNldCwgRFdPUkQgZmxhZ3MpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwoKICBzd2l0Y2ggKFRXT0NDRnJvbUZPVVJDQyhja2lkKSkgewogIGNhc2UgY2t0eXBlRElCYml0czoKICAgIGlmIChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19UUlVTVENLVFlQRSkKICAgICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CiAgICBicmVhazsKICBjYXNlIGNrdHlwZURJQmNvbXByZXNzZWQ6CiAgICBpZiAoVGhpcy0+cGFmLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fVFJVU1RDS1RZUEUpCiAgICAgIGZsYWdzICY9IH5BVklJRl9LRVlGUkFNRTsKICAgIGJyZWFrOwogIGNhc2UgY2t0eXBlUEFMY2hhbmdlOgogICAgaWYgKFRoaXMtPnNJbmZvLmZjY1R5cGUgIT0gc3RyZWFtdHlwZVZJREVPKSB7CiAgICAgIEVSUigiOiBmb3VuZCBwYWxldHRlIGNoYW5nZSBpbiBub24tdmlkZW8gc3RyZWFtIVxuIik7CiAgICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwogICAgfQogICAgVGhpcy0+c0luZm8uZHdGbGFncyB8PSBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVM7CiAgICBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50Kys7CgogICAgaWYgKFRoaXMtPmlkeEZtdENoYW5nZXMgPT0gTlVMTCB8fCBUaGlzLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50IDwgVGhpcy0+bklkeEZtdENoYW5nZXMpIHsKICAgICAgVUlOVCBuID0gVGhpcy0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsKCiAgICAgIFRoaXMtPm5JZHhGbXRDaGFuZ2VzICs9IDE2OwogICAgICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlcyA9PSBOVUxMKQoJVGhpcy0+aWR4Rm10Q2hhbmdlcyA9CgkgIEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5uSWR4Rm10Q2hhbmdlcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGVsc2UKCVRoaXMtPmlkeEZtdENoYW5nZXMgPQoJICBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5pZHhGbXRDaGFuZ2VzLAoJCQkgICBUaGlzLT5uSWR4Rm10Q2hhbmdlcyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGlmIChUaGlzLT5pZHhGbXRDaGFuZ2VzID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKCiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uY2tpZCAgICAgICAgICA9IFRoaXMtPmxMYXN0RnJhbWU7CiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uZHdGbGFncyAgICAgICA9IDA7CiAgICAgIFRoaXMtPmlkeEZtdENoYW5nZXNbbl0uZHdDaHVua09mZnNldCA9IG9mZnNldDsKICAgICAgVGhpcy0+aWR4Rm10Q2hhbmdlc1tuXS5kd0NodW5rTGVuZ3RoID0gc2l6ZTsKCiAgICAgIHJldHVybiBBVklFUlJfT0s7CiAgICB9CiAgICBicmVhazsKICBjYXNlIGNrdHlwZVdBVkVieXRlczoKICAgIGlmIChUaGlzLT5wYWYtPmZJbmZvLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19UUlVTVENLVFlQRSkKICAgICAgZmxhZ3MgfD0gQVZJSUZfS0VZRlJBTUU7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgV0FSTigiOiB1bmtub3duIFRXT0NDIDB4JTA0WCBmb3VuZFxuIiwgVFdPQ0NGcm9tRk9VUkNDKGNraWQpKTsKICAgIGJyZWFrOwogIH07CgogIC8qIGZpcnN0IGZyYW1lIGlzIGFsd2FzeSBhIGtleWZyYW1lICovCiAgaWYgKFRoaXMtPmxMYXN0RnJhbWUgPT0gLTEpCiAgICBmbGFncyB8PSBBVklJRl9LRVlGUkFNRTsKCiAgaWYgKFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSA8IHNpemUpCiAgICBUaGlzLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSBzaXplOwoKICAvKiBnZXQgbWVtb3J5IGZvciBpbmRleCAqLwogIGlmIChUaGlzLT5pZHhGcmFtZXMgPT0gTlVMTCB8fCBUaGlzLT5sTGFzdEZyYW1lICsgMSA+PSBUaGlzLT5uSWR4RnJhbWVzKSB7CiAgICBUaGlzLT5uSWR4RnJhbWVzICs9IDUxMjsKICAgIGlmIChUaGlzLT5pZHhGcmFtZXMgPT0gTlVMTCkKICAgICAgVGhpcy0+aWR4RnJhbWVzID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIFRoaXMtPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBlbHNlCglUaGlzLT5pZHhGcmFtZXMgPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5pZHhGcmFtZXMsCgkJCSAgIFRoaXMtPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgaWYgKFRoaXMtPmlkeEZyYW1lcyA9PSBOVUxMKQogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICB9CgogIFRoaXMtPmxMYXN0RnJhbWUrKzsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uY2tpZCAgICAgICAgICA9IGNraWQ7CiAgVGhpcy0+aWR4RnJhbWVzW1RoaXMtPmxMYXN0RnJhbWVdLmR3RmxhZ3MgICAgICAgPSBmbGFnczsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uZHdDaHVua09mZnNldCA9IG9mZnNldDsKICBUaGlzLT5pZHhGcmFtZXNbVGhpcy0+bExhc3RGcmFtZV0uZHdDaHVua0xlbmd0aCA9IHNpemU7CgogIC8qIHVwZGF0ZSBBVklTVFJFQU1JTkZPIHN0cnVjdHVyZSBpZiBuZWNlc3NhcnkgKi8KICBpZiAoVGhpcy0+c0luZm8uZHdMZW5ndGggPD0gVGhpcy0+bExhc3RGcmFtZSkKICAgIFRoaXMtPnNJbmZvLmR3TGVuZ3RoID0gVGhpcy0+bExhc3RGcmFtZSArIDE7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfQWRkUmVjb3JkKElBVklGaWxlSW1wbCAqVGhpcykKewogIC8qIHByZS1jb25kaXRpb25zICovCiAgYXNzZXJ0KFRoaXMgIT0gTlVMTCAmJiBUaGlzLT5wcFN0cmVhbXNbMF0gIT0gTlVMTCk7CgogIGlmIChUaGlzLT5pZHhSZWNvcmRzID09IE5VTEwgfHwgVGhpcy0+Y2JJZHhSZWNvcmRzID09IDApIHsKICAgIFRoaXMtPmNiSWR4UmVjb3JkcyArPSAxMDI0ICogc2l6ZW9mKEFWSUlOREVYRU5UUlkpOwogICAgVGhpcy0+aWR4UmVjb3JkcyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBUaGlzLT5jYklkeFJlY29yZHMpOwogICAgaWYgKFRoaXMtPmlkeFJlY29yZHMgPT0gTlVMTCkKICAgICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgfQoKICBhc3NlcnQoVGhpcy0+bklkeFJlY29yZHMgPCBUaGlzLT5jYklkeFJlY29yZHMvc2l6ZW9mKEFWSUlOREVYRU5UUlkpKTsKCiAgVGhpcy0+aWR4UmVjb3Jkc1tUaGlzLT5uSWR4UmVjb3Jkc10uY2tpZCAgICAgICAgICA9IGxpc3R0eXBlQVZJUkVDT1JEOwogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmR3RmxhZ3MgICAgICAgPSBBVklJRl9MSVNUOwogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmR3Q2h1bmtPZmZzZXQgPQogICAgVGhpcy0+Y2tMYXN0UmVjb3JkLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpOwogIFRoaXMtPmlkeFJlY29yZHNbVGhpcy0+bklkeFJlY29yZHNdLmR3Q2h1bmtMZW5ndGggPQogICAgVGhpcy0+Y2tMYXN0UmVjb3JkLmNrc2l6ZTsKICBUaGlzLT5uSWR4UmVjb3JkcysrOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgRFdPUkQgICBBVklGSUxFX0NvbXB1dGVNb3ZpU3RhcnQoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgRFdPUkQgZHdQb3M7CiAgRFdPUkQgblN0cmVhbTsKCiAgLyogUklGRixoZHJsLG1vdmksYXZpaCA9PiAoMyAqIDMgKyAyKSAqIHNpemVvZihEV09SRCkgPSAxMSAqIHNpemVvZihEV09SRCkgKi8KICBkd1BvcyA9IDExICogc2l6ZW9mKERXT1JEKSArIHNpemVvZihNYWluQVZJSGVhZGVyKTsKCiAgZm9yIChuU3RyZWFtID0gMDsgblN0cmVhbSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgblN0cmVhbSsrKSB7CiAgICBJQVZJU3RyZWFtSW1wbCAqcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKCiAgICAvKiBzdHJsLHN0cmgsc3RyZiA9PiAoMyArIDIgKiAyKSAqIHNpemVvZihEV09SRCkgPSA3ICogc2l6ZW9mKERXT1JEKSAqLwogICAgZHdQb3MgKz0gNyAqIHNpemVvZihEV09SRCkgKyBzaXplb2YoQVZJU3RyZWFtSGVhZGVyKTsKICAgIGR3UG9zICs9ICgocFN0cmVhbS0+Y2JGb3JtYXQgKyAxKSAmIH4xVSk7CiAgICBpZiAocFN0cmVhbS0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMICYmIHBTdHJlYW0tPmNiSGFuZGxlckRhdGEgPiAwKQogICAgICBkd1BvcyArPSAyICogc2l6ZW9mKERXT1JEKSArICgocFN0cmVhbS0+Y2JIYW5kbGVyRGF0YSArIDEpICYgfjFVKTsKICAgIGlmIChsc3RybGVuVyhwU3RyZWFtLT5zSW5mby5zek5hbWUpID4gMCkKICAgICAgZHdQb3MgKz0gMiAqIHNpemVvZihEV09SRCkgKyAoKGxzdHJsZW5XKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSkgKyAxKSAmIH4xVSk7CiAgfQoKICBpZiAoVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPT0gMCkgewogICAgVGhpcy0+ZHdOZXh0RnJhbWVQb3MgPSBkd1BvczsKCiAgICAvKiBwYWQgdG8gbXVsdGlwbGUgb2YgQVZJX0hFQURFUlNJWkUgb25seSBpZiB3ZSBhcmUgbW9yZSB0aGFuIDggYnl0ZXMgYXdheSBmcm9tIGl0ICovCiAgICBpZiAoKChkd1BvcyArIEFWSV9IRUFERVJTSVpFKSAmIH4oQVZJX0hFQURFUlNJWkUgLSAxKSkgLSBkd1BvcyA+IDIgKiBzaXplb2YoRFdPUkQpKQogICAgICBUaGlzLT5kd05leHRGcmFtZVBvcyA9IChkd1BvcyArIEFWSV9IRUFERVJTSVpFKSAmIH4oQVZJX0hFQURFUlNJWkUgLSAxKTsKCiAgICBUaGlzLT5kd01vdmlDaHVua1BvcyA9IFRoaXMtPmR3TmV4dEZyYW1lUG9zIC0gc2l6ZW9mKERXT1JEKTsKICB9CgogIHJldHVybiBkd1BvczsKfQoKc3RhdGljIHZvaWQgICAgQVZJRklMRV9Db25zdHJ1Y3RBVklTdHJlYW0oSUFWSUZpbGVJbXBsICpwYWYsIERXT1JEIG5yLCBMUEFWSVNUUkVBTUlORk9XIGFzaSkKewogIElBVklTdHJlYW1JbXBsICpwc3RyZWFtOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChwYWYgIT0gTlVMTCk7CiAgYXNzZXJ0KG5yIDwgTUFYX0FWSVNUUkVBTVMpOwogIGFzc2VydChwYWYtPnBwU3RyZWFtc1tucl0gIT0gTlVMTCk7CgogIHBzdHJlYW0gPSBwYWYtPnBwU3RyZWFtc1tucl07CgogIHBzdHJlYW0tPmxwVnRibCAgICAgICAgID0gJmlhdmlzdDsKICBwc3RyZWFtLT5yZWYgICAgICAgICAgICA9IDA7CiAgcHN0cmVhbS0+cGFmICAgICAgICAgICAgPSBwYWY7CiAgcHN0cmVhbS0+blN0cmVhbSAgICAgICAgPSBucjsKICBwc3RyZWFtLT5kd0N1cnJlbnRGcmFtZSA9IChEV09SRCktMTsKICBwc3RyZWFtLT5sTGFzdEZyYW1lICAgID0gLTE7CgogIGlmIChhc2kgIT0gTlVMTCkgewogICAgbWVtY3B5KCZwc3RyZWFtLT5zSW5mbywgYXNpLCBzaXplb2YocHN0cmVhbS0+c0luZm8pKTsKCiAgICBpZiAoYXNpLT5kd0xlbmd0aCA+IDApIHsKICAgICAgLyogcHJlLWFsbG9jYXRlIG1lbSBmb3IgZnJhbWUtaW5kZXggc3RydWN0dXJlICovCiAgICAgIHBzdHJlYW0tPmlkeEZyYW1lcyA9CglIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwgYXNpLT5kd0xlbmd0aCAqIHNpemVvZihBVklJTkRFWEVOVFJZKSk7CiAgICAgIGlmIChwc3RyZWFtLT5pZHhGcmFtZXMgIT0gTlVMTCkKCXBzdHJlYW0tPm5JZHhGcmFtZXMgPSBhc2ktPmR3TGVuZ3RoOwogICAgfQogICAgaWYgKGFzaS0+ZHdGb3JtYXRDaGFuZ2VDb3VudCA+IDApIHsKICAgICAgLyogcHJlLWFsbG9jYXRlIG1lbSBmb3IgZm9ybWF0Y2hhbmdlLWluZGV4IHN0cnVjdHVyZSAqLwogICAgICBwc3RyZWFtLT5pZHhGbXRDaGFuZ2VzID0KCUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBhc2ktPmR3Rm9ybWF0Q2hhbmdlQ291bnQgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgICBpZiAocHN0cmVhbS0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMKQoJcHN0cmVhbS0+bklkeEZtdENoYW5nZXMgPSBhc2ktPmR3Rm9ybWF0Q2hhbmdlQ291bnQ7CiAgICB9CgogICAgLyogVGhlc2UgdmFsdWVzIHdpbGwgYmUgY29tcHV0ZWQgKi8KICAgIHBzdHJlYW0tPnNJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IDA7CiAgICBwc3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPSAwOwogICAgcHN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAgID0gMDsKICAgIHBzdHJlYW0tPnNJbmZvLmR3RWRpdENvdW50ICAgICAgICAgICA9IDE7CiAgICBpZiAocHN0cmVhbS0+c0luZm8uZHdTYW1wbGVTaXplID4gMCkKICAgICAgU2V0UmVjdEVtcHR5KCZwc3RyZWFtLT5zSW5mby5yY0ZyYW1lKTsKICB9CgogIHBzdHJlYW0tPnNJbmZvLmR3Q2FwcyA9IEFWSUZJTEVDQVBTX0NBTlJFQUR8QVZJRklMRUNBUFNfQ0FOV1JJVEU7Cn0KCnN0YXRpYyB2b2lkICAgIEFWSUZJTEVfRGVzdHJ1Y3RBVklTdHJlYW0oSUFWSVN0cmVhbUltcGwgKlRoaXMpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwoKICBUaGlzLT5kd0N1cnJlbnRGcmFtZSA9IChEV09SRCktMTsKICBUaGlzLT5sTGFzdEZyYW1lICAgID0gLTE7CiAgVGhpcy0+cGFmID0gTlVMTDsKICBpZiAoVGhpcy0+aWR4RnJhbWVzICE9IE5VTEwpIHsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmlkeEZyYW1lcyk7CiAgICBUaGlzLT5pZHhGcmFtZXMgID0gTlVMTDsKICAgIFRoaXMtPm5JZHhGcmFtZXMgPSAwOwogIH0KICBpZiAoVGhpcy0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5pZHhGbXRDaGFuZ2VzKTsKICAgIFRoaXMtPmlkeEZtdENoYW5nZXMgPSBOVUxMOwogIH0KICBpZiAoVGhpcy0+bHBCdWZmZXIgIT0gTlVMTCkgewogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgVGhpcy0+bHBCdWZmZXIpOwogICAgVGhpcy0+bHBCdWZmZXIgPSBOVUxMOwogICAgVGhpcy0+Y2JCdWZmZXIgPSAwOwogIH0KICBpZiAoVGhpcy0+bHBIYW5kbGVyRGF0YSAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scEhhbmRsZXJEYXRhKTsKICAgIFRoaXMtPmxwSGFuZGxlckRhdGEgPSBOVUxMOwogICAgVGhpcy0+Y2JIYW5kbGVyRGF0YSA9IDA7CiAgfQogIGlmIChUaGlzLT5leHRyYS5scCAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5leHRyYS5scCk7CiAgICBUaGlzLT5leHRyYS5scCA9IE5VTEw7CiAgICBUaGlzLT5leHRyYS5jYiA9IDA7CiAgfQogIGlmIChUaGlzLT5scEZvcm1hdCAhPSBOVUxMKSB7CiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzLT5scEZvcm1hdCk7CiAgICBUaGlzLT5scEZvcm1hdCA9IE5VTEw7CiAgICBUaGlzLT5jYkZvcm1hdCA9IDA7CiAgfQp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX0xvYWRGaWxlKElBVklGaWxlSW1wbCAqVGhpcykKewogIE1haW5BVklIZWFkZXIgICBNYWluQVZJSGRyOwogIE1NQ0tJTkZPICAgICAgICBja1JJRkY7CiAgTU1DS0lORk8gICAgICAgIGNrTElTVDE7CiAgTU1DS0lORk8gICAgICAgIGNrTElTVDI7CiAgTU1DS0lORk8gICAgICAgIGNrOwogIElBVklTdHJlYW1JbXBsICpwU3RyZWFtOwogIERXT1JEICAgICAgICAgICBuU3RyZWFtOwogIEhSRVNVTFQgICAgICAgICBocjsKCiAgaWYgKFRoaXMtPmhtbWlvID09IE5VTEwpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVPUEVOOwoKICAvKiBpbml0aWFsaXplIHN0cmVhbSBwdHIncyAqLwogIG1lbXNldChUaGlzLT5wcFN0cmVhbXMsIDAsIHNpemVvZihUaGlzLT5wcFN0cmVhbXMpKTsKCiAgLyogdHJ5IHRvIGdldCAiUklGRiIgY2h1bmsgLS0gbXVzdCBub3QgYmUgYXQgYmVnaW5uaW5nIG9mIGZpbGUhICovCiAgY2tSSUZGLmZjY1R5cGUgPSBmb3JtdHlwZUFWSTsKICBpZiAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZja1JJRkYsIE5VTEwsIE1NSU9fRklORFJJRkYpICE9IFNfT0spIHsKICAgIEVSUigiOiBub3QgYW4gQVZJIVxuIik7CiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogIH0KCiAgLyogZ2V0ICJMSVNUIiAiaGRybCIgKi8KICBja0xJU1QxLmZjY1R5cGUgPSBsaXN0dHlwZUFWSUhFQURFUjsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZja0xJU1QxLCAmY2tSSUZGLCBNTUlPX0ZJTkRMSVNUKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgLyogZ2V0ICJhdmloIiBjaHVuayAqLwogIGNrLmNraWQgPSBja2lkQVZJTUFJTkhEUjsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDEsIE1NSU9fRklORENIVU5LKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgaWYgKGNrLmNrc2l6ZSAhPSBzaXplb2YoTWFpbkFWSUhkcikpIHsKICAgIEVSUigiOiBpbnZhbGlkIHNpemUgb2YgJWxkIGZvciBNYWluQVZJSGVhZGVyIVxuIiwgY2suY2tzaXplKTsKICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwogIH0KICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUikmTWFpbkFWSUhkciwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBjaGVjayBmb3IgTUFYX0FWSVNUUkVBTVMgbGltaXQgKi8KICBpZiAoTWFpbkFWSUhkci5kd1N0cmVhbXMgPiBNQVhfQVZJU1RSRUFNUykgewogICAgV0FSTigiZmlsZSBjb250YWlucyAlbHUgc3RyZWFtcywgYnV0IG9ubHkgc3VwcG9ydHMgJWQgLS0gY2hhbmdlIE1BWF9BVklTVFJFQU1TIVxuIiwgTWFpbkFWSUhkci5kd1N0cmVhbXMsIE1BWF9BVklTVFJFQU1TKTsKICAgIHJldHVybiBBVklFUlJfVU5TVVBQT1JURUQ7CiAgfQoKICAvKiBhZGp1c3QgcGVybWlzc2lvbnMgaWYgY29weXJpZ2h0ZWQgbWF0ZXJpYWwgaW4gZmlsZSAqLwogIGlmIChNYWluQVZJSGRyLmR3RmxhZ3MgJiBBVklGSUxFSU5GT19DT1BZUklHSFRFRCkgewogICAgVGhpcy0+dU1vZGUgJj0gfk1NSU9fUldNT0RFOwogICAgVGhpcy0+dU1vZGUgfD0gTU1JT19SRUFEOwogIH0KCiAgLyogY29udmVydCBNYWluQVZJSGVhZGVyIGludG8gQVZJRklMSU5GT1cgKi8KICBtZW1zZXQoJlRoaXMtPmZJbmZvLCAwLCBzaXplb2YoVGhpcy0+ZkluZm8pKTsKICBUaGlzLT5mSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3TWljcm9TZWNQZXJGcmFtZTsKICBUaGlzLT5mSW5mby5kd1NjYWxlICAgICAgICAgICAgICAgPSAxMDAwMDAwOwogIFRoaXMtPmZJbmZvLmR3TWF4Qnl0ZXNQZXJTZWMgICAgICA9IE1haW5BVklIZHIuZHdNYXhCeXRlc1BlclNlYzsKICBUaGlzLT5mSW5mby5kd0ZsYWdzICAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3RmxhZ3M7CiAgVGhpcy0+ZkluZm8uZHdDYXBzICAgICAgICAgICAgICAgID0gQVZJRklMRUNBUFNfQ0FOUkVBRHxBVklGSUxFQ0FQU19DQU5XUklURTsKICBUaGlzLT5mSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSBNYWluQVZJSGRyLmR3VG90YWxGcmFtZXM7CiAgVGhpcy0+ZkluZm8uZHdTdHJlYW1zICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd1N0cmVhbXM7CiAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gTWFpbkFWSUhkci5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgVGhpcy0+ZkluZm8uZHdXaWR0aCAgICAgICAgICAgICAgID0gTWFpbkFWSUhkci5kd1dpZHRoOwogIFRoaXMtPmZJbmZvLmR3SGVpZ2h0ICAgICAgICAgICAgICA9IE1haW5BVklIZHIuZHdIZWlnaHQ7CiAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQVZJRklMRVRZUEUsIFRoaXMtPmZJbmZvLnN6RmlsZVR5cGUsCgkgICAgICBzaXplb2YoVGhpcy0+ZkluZm8uc3pGaWxlVHlwZSkpOwoKICAvKiBnbyBiYWNrIHRvIGludG8gaGVhZGVyIGxpc3QgKi8KICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogZm9yZWFjaCBzdHJlYW0gZXhpc3RzIGEgIkxJU1QiLCJzdHJsIiBjaHVuayAqLwogIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgLyogZ2V0IG5leHQgbmVzdGVkIGNodW5rIGluIHRoaXMgIkxJU1QiLCJzdHJsIiAqLwogICAgaWYgKG1taW9EZXNjZW5kKFRoaXMtPmhtbWlvLCAmY2tMSVNUMiwgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgogICAgLyogbmVzdGVkIGNodW5rIG11c3QgYmUgb2YgdHlwZSAiTElTVCIsInN0cmwiIC0tIHdoZW4gbm90IG5vcm1hbGx5IEpVTksgKi8KICAgIGlmIChja0xJU1QyLmNraWQgPT0gRk9VUkNDX0xJU1QgJiYKCWNrTElTVDIuZmNjVHlwZSA9PSBsaXN0dHlwZVNUUkVBTUhFQURFUikgewogICAgICBwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dID0KCUhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplb2YoSUFWSVN0cmVhbUltcGwpKTsKICAgICAgaWYgKHBTdHJlYW0gPT0gTlVMTCkKCXJldHVybiBBVklFUlJfTUVNT1JZOwogICAgICBBVklGSUxFX0NvbnN0cnVjdEFWSVN0cmVhbShUaGlzLCBuU3RyZWFtLCBOVUxMKTsKCiAgICAgIGNrLmNraWQgPSAwOwogICAgICB3aGlsZSAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDIsIDApID09IFNfT0spIHsKCXN3aXRjaCAoY2suY2tpZCkgewoJY2FzZSBja2lkU1RSRUFNSEFORExFUkRBVEE6CgkgIGlmIChwU3RyZWFtLT5scEhhbmRsZXJEYXRhICE9IE5VTEwpCgkgICAgcmV0dXJuIEFWSUVSUl9CQURGT1JNQVQ7CgkgIHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKCSAgaWYgKHBTdHJlYW0tPmxwSGFuZGxlckRhdGEgPT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCSAgcFN0cmVhbS0+Y2JIYW5kbGVyRGF0YSA9IGNrLmNrc2l6ZTsKCgkgIGlmIChtbWlvUmVhZChUaGlzLT5obW1pbywgKEhQU1RSKXBTdHJlYW0tPmxwSGFuZGxlckRhdGEsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKQoJICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CgkgIGJyZWFrOwoJY2FzZSBja2lkU1RSRUFNRk9STUFUOgoJICBpZiAocFN0cmVhbS0+bHBGb3JtYXQgIT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKICAgICAgICAgIGlmIChjay5ja3NpemUgPT0gMCkKICAgICAgICAgICAgYnJlYWs7CgoJICBwU3RyZWFtLT5scEZvcm1hdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBjay5ja3NpemUpOwoJICBpZiAocFN0cmVhbS0+bHBGb3JtYXQgPT0gTlVMTCkKCSAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCSAgcFN0cmVhbS0+Y2JGb3JtYXQgPSBjay5ja3NpemU7CgoJICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUilwU3RyZWFtLT5scEZvcm1hdCwgY2suY2tzaXplKSAhPSBjay5ja3NpemUpCgkgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCgkgIGlmIChwU3RyZWFtLT5zSW5mby5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykgewoJICAgIExQQklUTUFQSU5GT0hFQURFUiBscGJpID0gKExQQklUTUFQSU5GT0hFQURFUilwU3RyZWFtLT5scEZvcm1hdDsKCgkgICAgLyogc29tZSBjb3JyZWN0aW9ucyB0byB0aGUgdmlkZW8gZm9ybWF0ICovCgkgICAgaWYgKGxwYmktPmJpQ2xyVXNlZCA9PSAwICYmIGxwYmktPmJpQml0Q291bnQgPD0gOCkKCSAgICAgIGxwYmktPmJpQ2xyVXNlZCA9IDF1IDw8IGxwYmktPmJpQml0Q291bnQ7CgkgICAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCICYmIGxwYmktPmJpU2l6ZUltYWdlID09IDApCgkgICAgICBscGJpLT5iaVNpemVJbWFnZSA9IERJQldJRFRIQllURVMoKmxwYmkpICogbHBiaS0+YmlIZWlnaHQ7CgkgICAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gIT0gQklfUkdCICYmIGxwYmktPmJpQml0Q291bnQgPT0gOCkgewoJICAgICAgaWYgKHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gbW1pb0ZPVVJDQygnUicsJ0wnLCdFJywnMCcpIHx8CgkJICBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID09IG1taW9GT1VSQ0MoJ1InLCdMJywnRScsJyAnKSkKCQlscGJpLT5iaUNvbXByZXNzaW9uID0gQklfUkxFODsKCSAgICB9CgkgICAgaWYgKGxwYmktPmJpQ29tcHJlc3Npb24gPT0gQklfUkdCICYmCgkJKHBTdHJlYW0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gMCB8fAoJCSBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID09IG1taW9GT1VSQ0MoJ04nLCdPJywnTicsJ0UnKSkpCgkgICAgICBwU3RyZWFtLT5zSW5mby5mY2NIYW5kbGVyID0gY29tcHR5cGVESUI7CgoJICAgIC8qIGluaXQgcmNGcmFtZSBpZiBpdCdzIGVtcHR5ICovCgkgICAgaWYgKElzUmVjdEVtcHR5KCZwU3RyZWFtLT5zSW5mby5yY0ZyYW1lKSkKCSAgICAgIFNldFJlY3QoJnBTdHJlYW0tPnNJbmZvLnJjRnJhbWUsIDAsIDAsIGxwYmktPmJpV2lkdGgsIGxwYmktPmJpSGVpZ2h0KTsKCSAgfQoJICBicmVhazsKCWNhc2UgY2tpZFNUUkVBTUhFQURFUjoKCSAgewoJICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBzdHJlYW1UeXBlRm10W10gPSB7JyUnLCc0JywnLicsJzQnLCdoJywncycsMH07CgoJICAgIEFWSVN0cmVhbUhlYWRlciBzdHJlYW1IZHI7CgkgICAgV0NIQVIgICAgICAgICAgIHN6VHlwZVsyNV07CgkgICAgV0NIQVIgICAgICAgICAgIHN0cmVhbU5hbWVGbXRbMjVdOwoJICAgIFVJTlQgICAgICAgICAgICBjb3VudDsKCSAgICBMT05HICAgICAgICAgICAgbiA9IGNrLmNrc2l6ZTsKCgkgICAgaWYgKGNrLmNrc2l6ZSA+IHNpemVvZihzdHJlYW1IZHIpKQoJICAgICAgbiA9IHNpemVvZihzdHJlYW1IZHIpOwoKCSAgICBpZiAobW1pb1JlYWQoVGhpcy0+aG1taW8sIChIUFNUUikmc3RyZWFtSGRyLCBuKSAhPSBuKQoJICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCgkgICAgcFN0cmVhbS0+c0luZm8uZmNjVHlwZSAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmZjY1R5cGU7CgkgICAgcFN0cmVhbS0+c0luZm8uZmNjSGFuZGxlciAgICAgICAgICAgID0gc3RyZWFtSGRyLmZjY0hhbmRsZXI7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdGbGFncyAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3RmxhZ3M7CgkgICAgcFN0cmVhbS0+c0luZm8ud1ByaW9yaXR5ICAgICAgICAgICAgID0gc3RyZWFtSGRyLndQcmlvcml0eTsKCSAgICBwU3RyZWFtLT5zSW5mby53TGFuZ3VhZ2UgICAgICAgICAgICAgPSBzdHJlYW1IZHIud0xhbmd1YWdlOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcyAgICAgICA9IHN0cmVhbUhkci5kd0luaXRpYWxGcmFtZXM7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3U2NhbGU7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdSYXRlICAgICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3UmF0ZTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1N0YXJ0ICAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdTdGFydDsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0xlbmd0aCAgICAgICAgICAgICAgPSBzdHJlYW1IZHIuZHdMZW5ndGg7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0KCSAgICAgIHN0cmVhbUhkci5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CgkgICAgcFN0cmVhbS0+c0luZm8uZHdRdWFsaXR5ICAgICAgICAgICAgID0gc3RyZWFtSGRyLmR3UXVhbGl0eTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgICAgICAgICAgPSBzdHJlYW1IZHIuZHdTYW1wbGVTaXplOwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUubGVmdCAgICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLmxlZnQ7CgkgICAgcFN0cmVhbS0+c0luZm8ucmNGcmFtZS50b3AgICAgICAgICAgID0gc3RyZWFtSGRyLnJjRnJhbWUudG9wOwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUucmlnaHQgICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLnJpZ2h0OwoJICAgIHBTdHJlYW0tPnNJbmZvLnJjRnJhbWUuYm90dG9tICAgICAgICA9IHN0cmVhbUhkci5yY0ZyYW1lLmJvdHRvbTsKCSAgICBwU3RyZWFtLT5zSW5mby5kd0VkaXRDb3VudCAgICAgICAgICAgPSAwOwoJICAgIHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgICA9IDA7CgoJICAgIC8qIGdlbmVyYXRlIGRlc2NyaXB0aW9uIGZvciBzdHJlYW0gbGlrZSAiZmlsZW5hbWUuYXZpIFR5cGUgI24iICovCgkgICAgaWYgKHN0cmVhbUhkci5mY2NUeXBlID09IHN0cmVhbXR5cGVWSURFTykKCSAgICAgIExvYWRTdHJpbmdXKEFWSUZJTEVfaE1vZHVsZSwgSURTX1ZJREVPLCBzelR5cGUsIHNpemVvZihzelR5cGUpKTsKCSAgICBlbHNlIGlmIChzdHJlYW1IZHIuZmNjVHlwZSA9PSBzdHJlYW10eXBlQVVESU8pCgkgICAgICBMb2FkU3RyaW5nVyhBVklGSUxFX2hNb2R1bGUsIElEU19BVURJTywgc3pUeXBlLCBzaXplb2Yoc3pUeXBlKSk7CgkgICAgZWxzZQoJICAgICAgd3NwcmludGZXKHN6VHlwZSwgc3RyZWFtVHlwZUZtdCwgKGNoYXIqKSZzdHJlYW1IZHIuZmNjVHlwZSk7CgoJICAgIC8qIGdldCBjb3VudCBvZiB0aGlzIHN0cmVhbXR5cGUgdXAgdG8gdGhpcyBzdHJlYW0gKi8KCSAgICBjb3VudCA9IDA7CgkgICAgZm9yIChuID0gblN0cmVhbTsgMCA8PSBuOyBuLS0pIHsKCSAgICAgIGlmIChUaGlzLT5wcFN0cmVhbXNbbl0tPnNJbmZvLmZjY0hhbmRsZXIgPT0gc3RyZWFtSGRyLmZjY1R5cGUpCgkJY291bnQrKzsKCSAgICB9CgoJICAgIG1lbXNldChwU3RyZWFtLT5zSW5mby5zek5hbWUsIDAsIHNpemVvZihwU3RyZWFtLT5zSW5mby5zek5hbWUpKTsKCgkgICAgTG9hZFN0cmluZ1coQVZJRklMRV9oTW9kdWxlLCBJRFNfQVZJU1RSRUFNRk9STUFULCBzdHJlYW1OYW1lRm10LCBzaXplb2Yoc3RyZWFtTmFtZUZtdCkpOwoKCSAgICAvKiBGSVhNRTogYXZvaWQgb3ZlcmZsb3cgLS0gYmV0dGVyIHVzZSB3c25wcmludGZXLCB3aGljaCBkb2Vzbid0IGV4aXN0cyAhICovCgkgICAgd3NwcmludGZXKHBTdHJlYW0tPnNJbmZvLnN6TmFtZSwgc3RyZWFtTmFtZUZtdCwKCQkgICAgICBBVklGSUxFX0Jhc2VuYW1lVyhUaGlzLT5zekZpbGVOYW1lKSwgc3pUeXBlLCBjb3VudCk7CgkgIH0KCSAgYnJlYWs7CgljYXNlIGNraWRTVFJFQU1OQU1FOgoJICB7IC8qIHN0cmVhbW5hbWUgd2lsbCBiZSBzYXZlZCBhcyBBU0NJSSBzdHJpbmcgKi8KCSAgICBMUFNUUiBzdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKCSAgICBpZiAoc3RyID09IE5VTEwpCgkgICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKCgkgICAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpc3RyLCBjay5ja3NpemUpICE9IGNrLmNrc2l6ZSkKCSAgICB7CgkgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIpOwoJICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCSAgICB9CgoJICAgIE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzdHIsIC0xLCBwU3RyZWFtLT5zSW5mby5zek5hbWUsCgkJCQlzaXplb2YocFN0cmVhbS0+c0luZm8uc3pOYW1lKS9zaXplb2YocFN0cmVhbS0+c0luZm8uc3pOYW1lWzBdKSk7CgoJICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIHN0cik7CgkgIH0KCSAgYnJlYWs7CgljYXNlIGNraWRBVklQQURESU5HOgoJY2FzZSBtbWlvRk9VUkNDKCdwJywnYScsJ2QnLCdkJyk6CgkgIGJyZWFrOwoJZGVmYXVsdDoKCSAgV0FSTigiOiBmb3VuZCBleHRyYSBjaHVuayAweCUwOGxYXG4iLCBjay5ja2lkKTsKCSAgaHIgPSBSZWFkQ2h1bmtJbnRvRXh0cmEoJnBTdHJlYW0tPmV4dHJhLCBUaGlzLT5obW1pbywgJmNrKTsKCSAgaWYgKEZBSUxFRChocikpCgkgICAgcmV0dXJuIGhyOwoJfTsKCglpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICAvKiBuZXN0ZWQgY2h1bmtzIGluICJMSVNUIiwiaGRybCIgd2hpY2ggYXJlIG5vdCBvZiB0eXBlICJMSVNUIiwic3RybCIgKi8KICAgICAgaHIgPSBSZWFkQ2h1bmtJbnRvRXh0cmEoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZja0xJU1QyKTsKICAgICAgaWYgKEZBSUxFRChocikpCglyZXR1cm4gaHI7CiAgICB9CiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDIsIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICAvKiByZWFkIGFueSBleHRyYSBoZWFkZXJzIGluICJMSVNUIiwiaGRybCIgKi8KICBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKCZUaGlzLT5maWxlZXh0cmEsIFRoaXMtPmhtbWlvLCAmY2ssICZja0xJU1QxLCAwKTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwoKICAvKiBzZWFyY2ggIkxJU1QiLCJtb3ZpIiBjaHVuayBpbiAiUklGRiIsIkFWSSAiICovCiAgY2tMSVNUMS5mY2NUeXBlID0gbGlzdHR5cGVBVklNT1ZJRTsKICBociA9IEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZja0xJU1QxLCAmY2tSSUZGLAoJCQkgICAgICBNTUlPX0ZJTkRMSVNUKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgPSBja0xJU1QxLmR3RGF0YU9mZnNldDsKICBUaGlzLT5kd0lkeENodW5rUG9zICA9IGNrTElTVDEuY2tzaXplICsgY2tMSVNUMS5kd0RhdGFPZmZzZXQ7CiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKCiAgLyogdHJ5IHRvIGZpbmQgYW4gaW5kZXggKi8KICBjay5ja2lkID0gY2tpZEFWSU5FV0lOREVYOwogIGhyID0gRmluZENodW5rQW5kS2VlcEV4dHJhcygmVGhpcy0+ZmlsZWV4dHJhLCBUaGlzLT5obW1pbywKCQkJICAgICAgJmNrLCAmY2tSSUZGLCBNTUlPX0ZJTkRDSFVOSyk7CiAgaWYgKFNVQ0NFRURFRChocikgJiYgY2suY2tzaXplID4gMCkgewogICAgaWYgKEZBSUxFRChBVklGSUxFX0xvYWRJbmRleChUaGlzLCBjay5ja3NpemUsIGNrTElTVDEuZHdEYXRhT2Zmc2V0KSkpCiAgICAgIFRoaXMtPmZJbmZvLmR3RmxhZ3MgJj0gfkFWSUZJTEVJTkZPX0hBU0lOREVYOwogIH0KCiAgLyogd2hlbiB3ZSBoYXZlbid0IGZvdW5kIGFuIGluZGV4IG9yIGl0J3MgYmFkLCB0aGVuIGJ1aWxkIG9uZQogICAqIGJ5IHBhcnNpbmcgJ21vdmknIGNodW5rICovCiAgaWYgKChUaGlzLT5mSW5mby5kd0ZsYWdzICYgQVZJRklMRUlORk9fSEFTSU5ERVgpID09IDApIHsKICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykKICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5sTGFzdEZyYW1lID0gLTE7CgogICAgaWYgKG1taW9TZWVrKFRoaXMtPmhtbWlvLCBja0xJU1QxLmR3RGF0YU9mZnNldCArIHNpemVvZihEV09SRCksIFNFRUtfU0VUKSA9PSAtMSkgewogICAgICBFUlIoIjogT29wcywgY2FuJ3Qgc2VlayBiYWNrIHRvICdtb3ZpJyBjaHVuayFcbiIpOwogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVSRUFEOwogICAgfQoKICAgIC8qIHNlZWsgdGhyb3VnaCB0aGUgJ21vdmknIGxpc3QgdW50aWwgZW5kICovCiAgICB3aGlsZSAobW1pb0Rlc2NlbmQoVGhpcy0+aG1taW8sICZjaywgJmNrTElTVDEsIDApID09IFNfT0spIHsKICAgICAgaWYgKGNrLmNraWQgIT0gRk9VUkNDX0xJU1QpIHsKCWlmIChtbWlvQXNjZW5kKFRoaXMtPmhtbWlvLCAmY2ssIDApID09IFNfT0spIHsKCSAgblN0cmVhbSA9IFN0cmVhbUZyb21GT1VSQ0MoY2suY2tpZCk7CgoJICBpZiAoblN0cmVhbSA+IFRoaXMtPmZJbmZvLmR3U3RyZWFtcykKCSAgICByZXR1cm4gQVZJRVJSX0JBREZPUk1BVDsKCgkgIEFWSUZJTEVfQWRkRnJhbWUoVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLCBjay5ja2lkLCBjay5ja3NpemUsCgkJCSAgIGNrLmR3RGF0YU9mZnNldCAtIDIgKiBzaXplb2YoRFdPUkQpLCAwKTsKCX0gZWxzZSB7CgkgIG5TdHJlYW0gPSBTdHJlYW1Gcm9tRk9VUkNDKGNrLmNraWQpOwoJICBXQVJOKCI6IGZpbGUgc2VlbXMgdG8gYmUgdHJ1bmNhdGVkIVxuIik7CgkgIGlmIChuU3RyZWFtIDw9IFRoaXMtPmZJbmZvLmR3U3RyZWFtcyAmJgoJICAgICAgVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd1NhbXBsZVNpemUgPiAwKSB7CgkgICAgY2suY2tzaXplID0gbW1pb1NlZWsoVGhpcy0+aG1taW8sIDAsIFNFRUtfRU5EKTsKCSAgICBpZiAoY2suY2tzaXplICE9IC0xKSB7CgkgICAgICBjay5ja3NpemUgLT0gY2suZHdEYXRhT2Zmc2V0OwoJICAgICAgY2suY2tzaXplICY9IH4oVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd1NhbXBsZVNpemUgLSAxKTsKCgkgICAgICBBVklGSUxFX0FkZEZyYW1lKFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXSwgY2suY2tpZCwgY2suY2tzaXplLAoJCQkgICAgICAgY2suZHdEYXRhT2Zmc2V0IC0gMiAqIHNpemVvZihEV09SRCksIDApOwoJICAgIH0KCSAgfQoJfQogICAgICB9CiAgICB9CiAgfQoKICAvKiBmaW5kIG90aGVyIGNodW5rcyAqLwogIEZpbmRDaHVua0FuZEtlZXBFeHRyYXMoJlRoaXMtPmZpbGVleHRyYSwgVGhpcy0+aG1taW8sICZjaywgJmNrUklGRiwgMCk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfTG9hZEluZGV4KElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgc2l6ZSwgRFdPUkQgb2Zmc2V0KQp7CiAgQVZJSU5ERVhFTlRSWSAqbHA7CiAgRFdPUkQgICAgICAgICAgcG9zLCBuOwogIEhSRVNVTFQgICAgICAgIGhyID0gQVZJRVJSX09LOwogIEJPT0wgICAgICAgICAgIGJBYnNvbHV0ZSA9IFRSVUU7CgogIGxwID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIElEWF9QRVJfQkxPQ0sgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIC8qIGFkanVzdCBsaW1pdHMgZm9yIGluZGV4IHRhYmxlcywgc28gdGhhdCBpbnNlcnRpbmcgd2lsbCBiZSBmYXN0ZXIgKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuKyspIHsKICAgIElBVklTdHJlYW1JbXBsICpwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25dOwoKICAgIHBTdHJlYW0tPmxMYXN0RnJhbWUgPSAtMTsKCiAgICBpZiAocFN0cmVhbS0+aWR4RnJhbWVzICE9IE5VTEwpIHsKICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgcFN0cmVhbS0+aWR4RnJhbWVzKTsKICAgICAgcFN0cmVhbS0+aWR4RnJhbWVzICA9IE5VTEw7CiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSAwOwogICAgfQoKICAgIGlmIChwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgIT0gMCkgewogICAgICBpZiAobiA+IDAgJiYgVGhpcy0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQpIHsKCXBTdHJlYW0tPm5JZHhGcmFtZXMgPSBUaGlzLT5wcFN0cmVhbXNbMF0tPm5JZHhGcmFtZXM7CiAgICAgIH0gZWxzZSBpZiAocFN0cmVhbS0+c0luZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplKSB7CglwU3RyZWFtLT5uSWR4RnJhbWVzID0KCSAgcFN0cmVhbS0+c0luZm8uZHdMZW5ndGggLyBwU3RyZWFtLT5zSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CiAgICAgIH0KICAgIH0gZWxzZQogICAgICBwU3RyZWFtLT5uSWR4RnJhbWVzID0gcFN0cmVhbS0+c0luZm8uZHdMZW5ndGg7CgogICAgcFN0cmVhbS0+aWR4RnJhbWVzID0KICAgICAgSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHBTdHJlYW0tPm5JZHhGcmFtZXMgKiBzaXplb2YoQVZJSU5ERVhFTlRSWSkpOwogICAgaWYgKHBTdHJlYW0tPmlkeEZyYW1lcyA9PSBOVUxMICYmIHBTdHJlYW0tPm5JZHhGcmFtZXMgPiAwKSB7CiAgICAgIHBTdHJlYW0tPm5JZHhGcmFtZXMgPSAwOwogICAgICByZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgIH0KICB9CgogIHBvcyA9IChEV09SRCktMTsKICB3aGlsZSAoc2l6ZSAhPSAwKSB7CiAgICBMT05HIHJlYWQgPSBtaW4oSURYX1BFUl9CTE9DSyAqIHNpemVvZihBVklJTkRFWEVOVFJZKSwgc2l6ZSk7CgogICAgaWYgKG1taW9SZWFkKFRoaXMtPmhtbWlvLCAoSFBTVFIpbHAsIHJlYWQpICE9IHJlYWQpIHsKICAgICAgaHIgPSBBVklFUlJfRklMRVJFQUQ7CiAgICAgIGJyZWFrOwogICAgfQogICAgc2l6ZSAtPSByZWFkOwoKICAgIGlmIChwb3MgPT0gKERXT1JEKS0xKQogICAgICBwb3MgPSBvZmZzZXQgLSBscC0+ZHdDaHVua09mZnNldCArIHNpemVvZihEV09SRCk7CgogICAgQVZJRklMRV9QYXJzZUluZGV4KFRoaXMsIGxwLCByZWFkIC8gc2l6ZW9mKEFWSUlOREVYRU5UUlkpLAoJCSAgICAgICBwb3MsICZiQWJzb2x1dGUpOwogIH0KCiAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbHApOwoKICAvKiBjaGVja2luZyAuLi4gKi8KICBmb3IgKG4gPSAwOyBuIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuKyspIHsKICAgIElBVklTdHJlYW1JbXBsICpwU3RyZWFtID0gVGhpcy0+cHBTdHJlYW1zW25dOwoKICAgIGlmIChwU3RyZWFtLT5zSW5mby5kd1NhbXBsZVNpemUgPT0gMCAmJgoJcFN0cmVhbS0+c0luZm8uZHdMZW5ndGggIT0gcFN0cmVhbS0+bExhc3RGcmFtZSsxKQogICAgICBFUlIoInN0cmVhbSAlbHUgbGVuZ3RoIG1pc21hdGNoOiBkd0xlbmd0aD0lbHUgZm91bmQ9JWxkXG4iLAoJICAgbiwgcFN0cmVhbS0+c0luZm8uZHdMZW5ndGgsIHBTdHJlYW0tPmxMYXN0RnJhbWUpOwogIH0KCiAgcmV0dXJuIGhyOwp9CgpzdGF0aWMgSFJFU1VMVCBBVklGSUxFX1BhcnNlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzLCBBVklJTkRFWEVOVFJZICpscCwKCQkJCSAgTE9ORyBjb3VudCwgRFdPUkQgcG9zLCBCT09MICpiQWJzb2x1dGUpCnsKICBpZiAobHAgPT0gTlVMTCkKICAgIHJldHVybiBBVklFUlJfQkFEUEFSQU07CgogIGZvciAoOyBjb3VudCA+IDA7IGNvdW50LS0sIGxwKyspIHsKICAgIFdPUkQgblN0cmVhbSA9IFN0cmVhbUZyb21GT1VSQ0MobHAtPmNraWQpOwoKICAgIGlmIChscC0+Y2tpZCA9PSBsaXN0dHlwZUFWSVJFQ09SRCB8fCBuU3RyZWFtID09IDB4N0YpCiAgICAgIGNvbnRpbnVlOyAvKiBza2lwIHRoZXNlICovCgogICAgaWYgKG5TdHJlYW0gPiBUaGlzLT5mSW5mby5kd1N0cmVhbXMpCiAgICAgIHJldHVybiBBVklFUlJfQkFERk9STUFUOwoKICAgIGlmICgqYkFic29sdXRlICYmIGxwLT5kd0NodW5rT2Zmc2V0IDwgVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MpCiAgICAgICpiQWJzb2x1dGUgPSBGQUxTRTsKCiAgICBpZiAoKmJBYnNvbHV0ZSkKICAgICAgbHAtPmR3Q2h1bmtPZmZzZXQgKz0gc2l6ZW9mKERXT1JEKTsKICAgIGVsc2UKICAgICAgbHAtPmR3Q2h1bmtPZmZzZXQgKz0gcG9zOwoKICAgIGlmIChGQUlMRUQoQVZJRklMRV9BZGRGcmFtZShUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0sIGxwLT5ja2lkLCBscC0+ZHdDaHVua0xlbmd0aCwgbHAtPmR3Q2h1bmtPZmZzZXQsIGxwLT5kd0ZsYWdzKSkpCiAgICAgIHJldHVybiBBVklFUlJfTUVNT1JZOwogIH0KCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9SZWFkQmxvY2soSUFWSVN0cmVhbUltcGwgKlRoaXMsIERXT1JEIHBvcywKCQkJCSBMUFZPSUQgYnVmZmVyLCBMT05HIHNpemUpCnsKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwogIGFzc2VydChUaGlzLT5wYWYgIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnBhZi0+aG1taW8gIT0gTlVMTCk7CiAgYXNzZXJ0KFRoaXMtPnNJbmZvLmR3U3RhcnQgPD0gcG9zICYmIHBvcyA8IFRoaXMtPnNJbmZvLmR3TGVuZ3RoKTsKICBhc3NlcnQocG9zIDw9IFRoaXMtPmxMYXN0RnJhbWUpOwoKICAvKiBzaG91bGQgd2UgcmVhZCBhcyBtdWNoIGFzIGJsb2NrIGdpdmVzIHVzPyAqLwogIGlmIChzaXplID09IDAgfHwgc2l6ZSA+IFRoaXMtPmlkeEZyYW1lc1twb3NdLmR3Q2h1bmtMZW5ndGgpCiAgICBzaXplID0gVGhpcy0+aWR4RnJhbWVzW3Bvc10uZHdDaHVua0xlbmd0aDsKCiAgLyogcmVhZCBpbnRvIG91dCBvd24gYnVmZmVyIG9yIGdpdmVuIG9uZT8gKi8KICBpZiAoYnVmZmVyID09IE5VTEwpIHsKICAgIC8qIHdlIGFsc28gcmVhZCB0aGUgY2h1bmsgKi8KICAgIHNpemUgKz0gMiAqIHNpemVvZihEV09SRCk7CgogICAgLyogY2hlY2sgdGhhdCBidWZmZXIgaXMgYmlnIGVub3VnaCAtLSBkb24ndCB0cnVzdCBkd1N1Z2dlc3RlZEJ1ZmZlclNpemUgKi8KICAgIGlmIChUaGlzLT5scEJ1ZmZlciA9PSBOVUxMIHx8IHNpemUgPCBUaGlzLT5jYkJ1ZmZlcikgewogICAgICBEV09SRCBtYXhTaXplID0gbWF4KHNpemUsIFRoaXMtPnNJbmZvLmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSk7CgogICAgICBpZiAoVGhpcy0+bHBCdWZmZXIgPT0gTlVMTCkKCVRoaXMtPmxwQnVmZmVyID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIG1heFNpemUpOwogICAgICBlbHNlCglUaGlzLT5scEJ1ZmZlciA9IEhlYXBSZUFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPmxwQnVmZmVyLCBtYXhTaXplKTsKICAgICAgaWYgKFRoaXMtPmxwQnVmZmVyID09IE5VTEwpCglyZXR1cm4gQVZJRVJSX01FTU9SWTsKICAgICAgVGhpcy0+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+aG1taW8sICZjaywgMCkgIT0gU19PSykKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICAgICAgLyogdGhlIHN0cmVhbW5hbWUgbXVzdCBiZSBzYXZlZCBpbiBBU0NJSSBub3QgVW5pY29kZSAqLwogICAgICBzdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgY2suY2tzaXplKTsKICAgICAgaWYgKHN0ciA9PSBOVUxMKQoJcmV0dXJuIEFWSUVSUl9NRU1PUlk7CiAgICAgIFdpZGVDaGFyVG9NdWx0aUJ5dGUoQ1BfQUNQLCAwLCBwU3RyZWFtLT5zSW5mby5zek5hbWUsIC0xLCBzdHIsCgkJCSAgY2suY2tzaXplLCBOVUxMLCBOVUxMKTsKCiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUilzdHIsIGNrLmNrc2l6ZSkgIT0gY2suY2tzaXplKSB7CglIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIpOwkKCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICB9CgogICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBzdHIpOwogICAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQoJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICB9CgogICAgLyogY2xvc2Ugc3RyZWFtaGVhZGVyIGxpc3QgZm9yIHRoaXMgc3RyZWFtICovCiAgICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDIsIDApICE9IFNfT0spCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0gLyogZm9yICgwIDw9IG5TdHJlYW0gPCBNYWluQVZJSGRyLmR3U3RyZWFtcykgKi8KCiAgLyogY2xvc2UgdGhlIGF2aWhlYWRlciBsaXN0ICovCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja0xJU1QxLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIC8qIGNoZWNrIGZvciBwYWRkaW5nIHRvIHByZS1ndWVzc2VkICdtb3ZpJy1jaHVuayBwb3NpdGlvbiAqLwogIGR3UG9zID0gY2tMSVNUMS5kd0RhdGFPZmZzZXQgKyBja0xJU1QxLmNrc2l6ZTsKICBpZiAoVGhpcy0+ZHdNb3ZpQ2h1bmtQb3MgLSAyICogc2l6ZW9mKERXT1JEKSA+IGR3UG9zKSB7CiAgICBjay5ja2lkICAgPSBja2lkQVZJUEFERElORzsKICAgIGNrLmNrc2l6ZSA9IFRoaXMtPmR3TW92aUNodW5rUG9zIC0gZHdQb3MgLSA0ICogc2l6ZW9mKERXT1JEKTsKICAgIGFzc2VydCgoTE9ORyljay5ja3NpemUgPj0gMCk7CgogICAgaWYgKG1taW9DcmVhdGVDaHVuayhUaGlzLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICAgIGlmIChtbWlvU2VlayhUaGlzLT5obW1pbywgY2suY2tzaXplLCBTRUVLX0NVUikgPT0gLTEpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQoKICAvKiBub3cgd3JpdGUgdGhlICdtb3ZpJyBjaHVuayAqLwogIG1taW9TZWVrKFRoaXMtPmhtbWlvLCBUaGlzLT5kd01vdmlDaHVua1BvcyAtIDIgKiBzaXplb2YoRFdPUkQpLCBTRUVLX1NFVCk7CiAgY2tMSVNUMS5ja3NpemUgID0gMDsKICBja0xJU1QxLmZjY1R5cGUgPSBsaXN0dHlwZUFWSU1PVklFOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZja0xJU1QxLCBNTUlPX0NSRUFURUxJU1QpICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb1NlZWsoVGhpcy0+aG1taW8sIFRoaXMtPmR3TmV4dEZyYW1lUG9zLCBTRUVLX1NFVCkgPT0gLTEpCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKICBpZiAobW1pb0FzY2VuZChUaGlzLT5obW1pbywgJmNrTElTVDEsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogd3JpdGUgJ2lkeDEnIGNodW5rICovCiAgaHIgPSBBVklGSUxFX1NhdmVJbmRleChUaGlzKTsKICBpZiAoRkFJTEVEKGhyKSkKICAgIHJldHVybiBocjsKCiAgLyogd3JpdGUgb3B0aW9uYWwgZXh0cmEgZmlsZSBjaHVua3MgKi8KICBpZiAoVGhpcy0+ZmlsZWV4dHJhLmxwICE9IE5VTEwgJiYgVGhpcy0+ZmlsZWV4dHJhLmNiID4gMCkgewogICAgLyogYXMgZm9yIHRoZSBzdHJlYW1zLCBhcmUgdGhlIGNodW5rIGhlYWRlcihzKSBpbiB0aGUgc3RydWN0dXJlICovCiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpVGhpcy0+ZmlsZWV4dHJhLmxwLCBUaGlzLT5maWxlZXh0cmEuY2IpICE9IFRoaXMtPmZpbGVleHRyYS5jYikKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgfQoKICAvKiBjbG9zZSBSSUZGIGNodW5rICovCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZja1JJRkYsIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgLyogYWRkIHNvbWUgSlVOSyBhdCBlbmQgZm9yIGJhZCBwYXJzZXJzICovCiAgbWVtc2V0KCZja1JJRkYsIDAsIHNpemVvZihja1JJRkYpKTsKICBtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmY2tSSUZGLCBzaXplb2YoY2tSSUZGKSk7CiAgbW1pb0ZsdXNoKFRoaXMtPmhtbWlvLCAwKTsKCiAgcmV0dXJuIEFWSUVSUl9PSzsKfQoKc3RhdGljIEhSRVNVTFQgQVZJRklMRV9TYXZlSW5kZXgoSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgSUFWSVN0cmVhbUltcGwgKnBTdHJlYW07CiAgQVZJSU5ERVhFTlRSWSAgIGlkeDsKICBNTUNLSU5GTyAgICAgICAgY2s7CiAgRFdPUkQgICAgICAgICAgIG5TdHJlYW07CiAgTE9ORyAgICAgICAgICAgIG47CgogIGNrLmNraWQgICA9IGNraWRBVklORVdJTkRFWDsKICBjay5ja3NpemUgPSAwOwogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICBpZiAoVGhpcy0+ZkluZm8uZHdGbGFncyAmIEFWSUZJTEVJTkZPX0lTSU5URVJMRUFWRUQpIHsKICAgIC8qIGlzIGludGVybGVhdmVkIC0tIHdyaXRlIGJsb2NrIG9mIGNvcmVzcG9uZGluZyBmcmFtZXMgKi8KICAgIExPTkcgbEluaXRpYWxGcmFtZXMgPSAwOwogICAgTE9ORyBzdGVwc2l6ZTsKICAgIExPTkcgaTsKCiAgICBpZiAoVGhpcy0+cHBTdHJlYW1zWzBdLT5zSW5mby5kd1NhbXBsZVNpemUgPT0gMCkKICAgICAgc3RlcHNpemUgPSAxOwogICAgZWxzZQogICAgICBzdGVwc2l6ZSA9IEFWSVN0cmVhbVRpbWVUb1NhbXBsZSgoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbMF0sIDEwMDAwMDApOwoKICAgIGFzc2VydChzdGVwc2l6ZSA+IDApOwoKICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewogICAgICBpZiAobEluaXRpYWxGcmFtZXMgPCBUaGlzLT5wcFN0cmVhbXNbblN0cmVhbV0tPnNJbmZvLmR3SW5pdGlhbEZyYW1lcykKCWxJbml0aWFsRnJhbWVzID0gVGhpcy0+cHBTdHJlYW1zW25TdHJlYW1dLT5zSW5mby5kd0luaXRpYWxGcmFtZXM7CiAgICB9CgogICAgZm9yIChpID0gLWxJbml0aWFsRnJhbWVzOyBpIDwgKExPTkcpVGhpcy0+ZkluZm8uZHdMZW5ndGggLSBsSW5pdGlhbEZyYW1lczsKCSBpICs9IHN0ZXBzaXplKSB7CiAgICAgIERXT1JEIG5GcmFtZSA9IGxJbml0aWFsRnJhbWVzICsgaTsKCiAgICAgIGFzc2VydChuRnJhbWUgPCBUaGlzLT5uSWR4UmVjb3Jkcyk7CgogICAgICBpZHguY2tpZCAgICAgICAgICA9IGxpc3R0eXBlQVZJUkVDT1JEOwogICAgICBpZHguZHdGbGFncyAgICAgICA9IEFWSUlGX0xJU1Q7CiAgICAgIGlkeC5kd0NodW5rTGVuZ3RoID0gVGhpcy0+aWR4UmVjb3Jkc1tuRnJhbWVdLmR3Q2h1bmtMZW5ndGg7CiAgICAgIGlkeC5kd0NodW5rT2Zmc2V0ID0gVGhpcy0+aWR4UmVjb3Jkc1tuRnJhbWVdLmR3Q2h1bmtPZmZzZXQKCS0gVGhpcy0+ZHdNb3ZpQ2h1bmtQb3M7CiAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCglyZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgICAgIGZvciAoblN0cmVhbSA9IDA7IG5TdHJlYW0gPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IG5TdHJlYW0rKykgewoJcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKCgkvKiBoZWF2ZSB3ZSByZWFjaGVkIHN0YXJ0IG9mIHRoaXMgc3RyZWFtPyAqLwoJaWYgKC0oTE9ORylwU3RyZWFtLT5zSW5mby5kd0luaXRpYWxGcmFtZXMgPiBpKQoJICBjb250aW51ZTsKCglpZiAocFN0cmVhbS0+c0luZm8uZHdJbml0aWFsRnJhbWVzIDwgbEluaXRpYWxGcmFtZXMpCgkgIG5GcmFtZSAtPSAobEluaXRpYWxGcmFtZXMgLSBwU3RyZWFtLT5zSW5mby5kd0luaXRpYWxGcmFtZXMpOwoKCS8qIHJlYWNoZWQgZW5kIG9mIHRoaXMgc3RyZWFtPyAqLwoJaWYgKHBTdHJlYW0tPmxMYXN0RnJhbWUgPD0gbkZyYW1lKQoJICBjb250aW51ZTsKCglpZiAoKHBTdHJlYW0tPnNJbmZvLmR3RmxhZ3MgJiBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVMpICYmCgkgICAgcFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudCAhPSAwICYmCgkgICAgcFN0cmVhbS0+aWR4Rm10Q2hhbmdlcyAhPSBOVUxMKSB7CgkgIERXT1JEIHBvczsKCgkgIGZvciAocG9zID0gMDsgcG9zIDwgcFN0cmVhbS0+c0luZm8uZHdGb3JtYXRDaGFuZ2VDb3VudDsgcG9zKyspIHsKCSAgICBpZiAocFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmNraWQgPT0gbkZyYW1lKSB7CgkgICAgICBpZHguZHdGbGFncyA9IEFWSUlGX05PVElNRTsKCSAgICAgIGlkeC5ja2lkICAgID0gTUFLRUFWSUNLSUQoY2t0eXBlUEFMY2hhbmdlLCBwU3RyZWFtLT5uU3RyZWFtKTsKCSAgICAgIGlkeC5kd0NodW5rTGVuZ3RoID0gcFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmR3Q2h1bmtMZW5ndGg7CgkgICAgICBpZHguZHdDaHVua09mZnNldCA9IHBTdHJlYW0tPmlkeEZtdENoYW5nZXNbcG9zXS5kd0NodW5rT2Zmc2V0CgkJLSBUaGlzLT5kd01vdmlDaHVua1BvczsKCgkgICAgICBpZiAobW1pb1dyaXRlKFRoaXMtPmhtbWlvLCAoSFBTVFIpJmlkeCwgc2l6ZW9mKGlkeCkpICE9IHNpemVvZihpZHgpKQoJCXJldHVybiBBVklFUlJfRklMRVdSSVRFOwoJICAgICAgYnJlYWs7CgkgICAgfQoJICB9Cgl9IC8qIGlmIGhhdmUgZm9ybWF0Y2hhbmdlcyAqLwoKCWlkeC5ja2lkICAgICAgICAgID0gcFN0cmVhbS0+aWR4RnJhbWVzW25GcmFtZV0uY2tpZDsKCWlkeC5kd0ZsYWdzICAgICAgID0gcFN0cmVhbS0+aWR4RnJhbWVzW25GcmFtZV0uZHdGbGFnczsKCWlkeC5kd0NodW5rTGVuZ3RoID0gcFN0cmVhbS0+aWR4RnJhbWVzW25GcmFtZV0uZHdDaHVua0xlbmd0aDsKCWlkeC5kd0NodW5rT2Zmc2V0ID0gcFN0cmVhbS0+aWR4RnJhbWVzW25GcmFtZV0uZHdDaHVua09mZnNldAoJICAtIFRoaXMtPmR3TW92aUNodW5rUG9zOwoJaWYgKG1taW9Xcml0ZShUaGlzLT5obW1pbywgKEhQU1RSKSZpZHgsIHNpemVvZihpZHgpKSAhPSBzaXplb2YoaWR4KSkKCSAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgICAgIH0KICAgIH0KICB9IGVsc2UgewogICAgLyogbm90IGludGVybGVhdmVkIC0tIHdyaXRlIGluZGV4IGZvciBlYWNoIHN0cmVhbSBhdCBvbmNlICovCiAgICBmb3IgKG5TdHJlYW0gPSAwOyBuU3RyZWFtIDwgVGhpcy0+ZkluZm8uZHdTdHJlYW1zOyBuU3RyZWFtKyspIHsKICAgICAgcFN0cmVhbSA9IFRoaXMtPnBwU3RyZWFtc1tuU3RyZWFtXTsKCiAgICAgIGZvciAobiA9IDA7IG4gPD0gcFN0cmVhbS0+bExhc3RGcmFtZTsgbisrKSB7CglpZiAoKHBTdHJlYW0tPnNJbmZvLmR3RmxhZ3MgJiBBVklTVFJFQU1JTkZPX0ZPUk1BVENIQU5HRVMpICYmCgkgICAgKHBTdHJlYW0tPnNJbmZvLmR3Rm9ybWF0Q2hhbmdlQ291bnQgIT0gMCkpIHsKCSAgRFdPUkQgcG9zOwoKCSAgZm9yIChwb3MgPSAwOyBwb3MgPCBwU3RyZWFtLT5zSW5mby5kd0Zvcm1hdENoYW5nZUNvdW50OyBwb3MrKykgewoJICAgIGlmIChwU3RyZWFtLT5pZHhGbXRDaGFuZ2VzW3Bvc10uY2tpZCA9PSBuKSB7CgkgICAgICBpZHguZHdGbGFncyA9IEFWSUlGX05PVElNRTsKCSAgICAgIGlkeC5ja2lkICAgID0gTUFLRUFWSUNLSUQoY2t0eXBlUEFMY2hhbmdlLCBwU3RyZWFtLT5uU3RyZWFtKTsKCSAgICAgIGlkeC5kd0NodW5rTGVuZ3RoID0gcFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmR3Q2h1bmtMZW5ndGg7CgkgICAgICBpZHguZHdDaHVua09mZnNldCA9CgkJcFN0cmVhbS0+aWR4Rm10Q2hhbmdlc1twb3NdLmR3Q2h1bmtPZmZzZXQgLSBUaGlzLT5kd01vdmlDaHVua1BvczsKCSAgICAgIGlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCgkJcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgkgICAgICBicmVhazsKCSAgICB9CgkgIH0KCX0gLyogaWYgaGF2ZSBmb3JtYXRjaGFuZ2VzICovCgoJaWR4LmNraWQgICAgICAgICAgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbl0uY2tpZDsKCWlkeC5kd0ZsYWdzICAgICAgID0gcFN0cmVhbS0+aWR4RnJhbWVzW25dLmR3RmxhZ3M7CglpZHguZHdDaHVua0xlbmd0aCA9IHBTdHJlYW0tPmlkeEZyYW1lc1tuXS5kd0NodW5rTGVuZ3RoOwoJaWR4LmR3Q2h1bmtPZmZzZXQgPSBwU3RyZWFtLT5pZHhGcmFtZXNbbl0uZHdDaHVua09mZnNldAoJICAtIFRoaXMtPmR3TW92aUNodW5rUG9zOwoKCWlmIChtbWlvV3JpdGUoVGhpcy0+aG1taW8sIChIUFNUUikmaWR4LCBzaXplb2YoaWR4KSkgIT0gc2l6ZW9mKGlkeCkpCgkgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogICAgICB9CiAgICB9CiAgfSAvKiBpZiBub3QgaW50ZXJsZWF2ZWQgKi8KCiAgaWYgKG1taW9Bc2NlbmQoVGhpcy0+aG1taW8sICZjaywgMCkgIT0gU19PSykKICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwoKICByZXR1cm4gQVZJRVJSX09LOwp9CgpzdGF0aWMgVUxPTkcgIEFWSUZJTEVfU2VhcmNoU3RyZWFtKElBVklGaWxlSW1wbCAqVGhpcywgRFdPUkQgZmNjLCBMT05HIGxTa2lwKQp7CiAgVUlOVCBpOwogIFVJTlQgblN0cmVhbTsKCiAgLyogcHJlLWNvbmRpdGlvbiAqLwogIGFzc2VydChsU2tpcCA+PSAwKTsKCiAgaWYgKGZjYyAhPSAwKSB7CiAgICAvKiBzZWFyY2ggdGhlIG51bWJlciBvZiB0aGUgc3BlY2lmaWVkIHN0cmVhbSAqLwogICAgblN0cmVhbSA9IChVTE9ORyktMTsKICAgIGZvciAoaSA9IDA7IGkgPCBUaGlzLT5mSW5mby5kd1N0cmVhbXM7IGkrKykgewogICAgICBhc3NlcnQoVGhpcy0+cHBTdHJlYW1zW2ldICE9IE5VTEwpOwoKICAgICAgaWYgKFRoaXMtPnBwU3RyZWFtc1tpXS0+c0luZm8uZmNjVHlwZSA9PSBmY2MpIHsKCWlmIChsU2tpcCA9PSAwKSB7CgkgIG5TdHJlYW0gPSBpOwoJICBicmVhazsKCX0gZWxzZQoJICBsU2tpcC0tOwogICAgICB9CiAgICB9CiAgfSBlbHNlCiAgICBuU3RyZWFtID0gbFNraXA7CgogIHJldHVybiBuU3RyZWFtOwp9CgpzdGF0aWMgdm9pZCAgICBBVklGSUxFX1VwZGF0ZUluZm8oSUFWSUZpbGVJbXBsICpUaGlzKQp7CiAgVUlOVCBpOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChUaGlzICE9IE5VTEwpOwoKICBUaGlzLT5mSW5mby5kd01heEJ5dGVzUGVyU2VjICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3Q2FwcyAgICAgICAgICAgICAgICA9IEFWSUZJTEVDQVBTX0NBTlJFQUR8QVZJRklMRUNBUFNfQ0FOV1JJVEU7CiAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gMDsKICBUaGlzLT5mSW5mby5kd1dpZHRoICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3SGVpZ2h0ICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgICAgICAgICAgICAgID0gMDsKICBUaGlzLT5mSW5mby5kd1JhdGUgICAgICAgICAgICAgICAgPSAwOwogIFRoaXMtPmZJbmZvLmR3TGVuZ3RoICAgICAgICAgICAgICA9IDA7CiAgVGhpcy0+ZHdJbml0aWFsRnJhbWVzICAgICAgICAgICAgID0gMDsKCiAgZm9yIChpID0gMDsgaSA8IFRoaXMtPmZJbmZvLmR3U3RyZWFtczsgaSsrKSB7CiAgICBBVklTVFJFQU1JTkZPVyAqcHNpOwogICAgRFdPUkQgICAgICAgICAgIG47CgogICAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICAgIGFzc2VydChUaGlzLT5wcFN0cmVhbXNbaV0gIT0gTlVMTCk7CgogICAgcHNpID0gJlRoaXMtPnBwU3RyZWFtc1tpXS0+c0luZm87CiAgICBhc3NlcnQocHNpLT5kd1NjYWxlICE9IDApOwogICAgYXNzZXJ0KHBzaS0+ZHdSYXRlICE9IDApOwoKICAgIGlmIChpID09IDApIHsKICAgICAgLyogdXNlIGZpcnN0IHN0cmVhbSB0aW1pbmdzIGFzIGJhc2UgKi8KICAgICAgVGhpcy0+ZkluZm8uZHdTY2FsZSAgPSBwc2ktPmR3U2NhbGU7CiAgICAgIFRoaXMtPmZJbmZvLmR3UmF0ZSAgID0gcHNpLT5kd1JhdGU7CiAgICAgIFRoaXMtPmZJbmZvLmR3TGVuZ3RoID0gcHNpLT5kd0xlbmd0aDsKICAgIH0gZWxzZSB7CiAgICAgIG4gPSBBVklTdHJlYW1TYW1wbGVUb1NhbXBsZSgoUEFWSVNUUkVBTSlUaGlzLT5wcFN0cmVhbXNbMF0sCgkJCQkgIChQQVZJU1RSRUFNKVRoaXMtPnBwU3RyZWFtc1tpXSxwc2ktPmR3TGVuZ3RoKTsKICAgICAgaWYgKFRoaXMtPmZJbmZvLmR3TGVuZ3RoIDwgbikKCVRoaXMtPmZJbmZvLmR3TGVuZ3RoID0gbjsKICAgIH0KCiAgICBpZiAoVGhpcy0+ZHdJbml0aWFsRnJhbWVzIDwgcHNpLT5kd0luaXRpYWxGcmFtZXMpCiAgICAgIFRoaXMtPmR3SW5pdGlhbEZyYW1lcyA9IHBzaS0+ZHdJbml0aWFsRnJhbWVzOwoKICAgIGlmIChUaGlzLT5mSW5mby5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUgPCBwc2ktPmR3U3VnZ2VzdGVkQnVmZmVyU2l6ZSkKICAgICAgVGhpcy0+ZkluZm8uZHdTdWdnZXN0ZWRCdWZmZXJTaXplID0gcHNpLT5kd1N1Z2dlc3RlZEJ1ZmZlclNpemU7CgogICAgaWYgKHBzaS0+ZHdTYW1wbGVTaXplICE9IDApIHsKICAgICAgLyogZml4ZWQgc2FtcGxlIHNpemUgLS0gZXhhY3QgY29tcHV0YXRpb24gKi8KICAgICAgVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYyArPSBNdWxEaXYocHNpLT5kd1NhbXBsZVNpemUsIHBzaS0+ZHdSYXRlLAoJCQkJCSAgICAgcHNpLT5kd1NjYWxlKTsKICAgIH0gZWxzZSB7CiAgICAgIC8qIHZhcmlhYmxlIHNhbXBsZSBzaXplIC0tIG9ubHkgdXBwZXIgbGltaXQgKi8KICAgICAgVGhpcy0+ZkluZm8uZHdNYXhCeXRlc1BlclNlYyArPSBNdWxEaXYocHNpLT5kd1N1Z2dlc3RlZEJ1ZmZlclNpemUsCgkJCQkJICAgICBwc2ktPmR3UmF0ZSwgcHNpLT5kd1NjYWxlKTsKCiAgICAgIC8qIHVwZGF0ZSBkaW1lbnNpb25zICovCiAgICAgIG4gPSBwc2ktPnJjRnJhbWUucmlnaHQgLSBwc2ktPnJjRnJhbWUubGVmdDsKICAgICAgaWYgKFRoaXMtPmZJbmZvLmR3V2lkdGggPCBuKQoJVGhpcy0+ZkluZm8uZHdXaWR0aCA9IG47CiAgICAgIG4gPSBwc2ktPnJjRnJhbWUuYm90dG9tIC0gcHNpLT5yY0ZyYW1lLnRvcDsKICAgICAgaWYgKFRoaXMtPmZJbmZvLmR3SGVpZ2h0IDwgbikKCVRoaXMtPmZJbmZvLmR3SGVpZ2h0ID0gbjsKICAgIH0KICB9Cn0KCnN0YXRpYyBIUkVTVUxUIEFWSUZJTEVfV3JpdGVCbG9jayhJQVZJU3RyZWFtSW1wbCAqVGhpcywgRFdPUkQgYmxvY2ssCgkJCQkgIEZPVVJDQyBja2lkLCBEV09SRCBmbGFncywgTFBWT0lEIGJ1ZmZlciwKCQkJCSAgTE9ORyBzaXplKQp7CiAgTU1DS0lORk8gY2s7CgogIGNrLmNraWQgICAgPSBja2lkOwogIGNrLmNrc2l6ZSAgPSBzaXplOwogIGNrLmZjY1R5cGUgPSAwOwoKICAvKiBpZiBubyBmcmFtZS9ibG9jayBpcyBhbHJlYWR5IHdyaXR0ZW4sIHdlIG11c3QgY29tcHV0ZSBzdGFydCBvZiBtb3ZpIGNodW5rICovCiAgaWYgKFRoaXMtPnBhZi0+ZHdNb3ZpQ2h1bmtQb3MgPT0gMCkKICAgIEFWSUZJTEVfQ29tcHV0ZU1vdmlTdGFydChUaGlzLT5wYWYpOwoKICBpZiAobW1pb1NlZWsoVGhpcy0+cGFmLT5obW1pbywgVGhpcy0+cGFmLT5kd05leHRGcmFtZVBvcywgU0VFS19TRVQpID09IC0xKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CgogIGlmIChtbWlvQ3JlYXRlQ2h1bmsoVGhpcy0+cGFmLT5obW1pbywgJmNrLCAwKSAhPSBTX09LKQogICAgcmV0dXJuIEFWSUVSUl9GSUxFV1JJVEU7CiAgaWYgKGJ1ZmZlciAhPSBOVUxMICYmIHNpemUgPiAwKSB7CiAgICBpZiAobW1pb1dyaXRlKFRoaXMtPnBhZi0+aG1taW8sIChIUFNUUilidWZmZXIsIHNpemUpICE9IHNpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVdSSVRFOwogIH0KICBpZiAobW1pb0FzY2VuZChUaGlzLT5wYWYtPmhtbWlvLCAmY2ssIDApICE9IFNfT0spCiAgICByZXR1cm4gQVZJRVJSX0ZJTEVXUklURTsKCiAgVGhpcy0+cGFmLT5mRGlydHkgICAgICAgICA9IFRSVUU7CiAgVGhpcy0+cGFmLT5kd05leHRGcmFtZVBvcyA9IG1taW9TZWVrKFRoaXMtPnBhZi0+aG1taW8sIDAsIFNFRUtfQ1VSKTsKCiAgcmV0dXJuIEFWSUZJTEVfQWRkRnJhbWUoVGhpcywgY2tpZCwgc2l6ZSwKCQkJICBjay5kd0RhdGFPZmZzZXQgLSAyICogc2l6ZW9mKERXT1JEKSwgZmxhZ3MpOwp9Cg==