LyoJCURpcmVjdERyYXcgLSBJRGlyZWN0UGFsZXR0ZSBiYXNlIGludGVyZmFjZQogKgogKiBDb3B5cmlnaHQgMTk5Ny0yMDAwIE1hcmN1cyBNZWlzc25lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDA2IFN0ZWZhbiBE9nNpbmdlciBmb3IgQ29kZVdlYXZlcnMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lcnJvci5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgPGFzc2VydC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CgojaW5jbHVkZSAid2luZWQzZF9wcml2YXRlLmgiCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChkM2QpOwoKI2RlZmluZSBTSVpFX0JJVFMgKFdJTkVERFBDQVBTXzFCSVQgfCBXSU5FRERQQ0FQU18yQklUIHwgV0lORUREUENBUFNfNEJJVCB8IFdJTkVERFBDQVBTXzhCSVQpCgpzdGF0aWMgSFJFU1VMVCAgV0lOQVBJIElXaW5lRDNEUGFsZXR0ZUltcGxfUXVlcnlJbnRlcmZhY2UoSVdpbmVEM0RQYWxldHRlICppZmFjZSwgUkVGSUlEIHJlZmlpZCwgdm9pZCAqKm9iaikgewogICAgSVdpbmVEM0RQYWxldHRlSW1wbCAqVGhpcyA9IChJV2luZUQzRFBhbGV0dGVJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIixUaGlzLGRlYnVnc3RyX2d1aWQocmVmaWlkKSxvYmopOwoKICAgIGlmIChJc0VxdWFsR1VJRChyZWZpaWQsICZJSURfSVVua25vd24pCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmVmaWlkLCAmSUlEX0lXaW5lRDNEUGFsZXR0ZSkpIHsKICAgICAgICAqb2JqID0gaWZhY2U7CiAgICAgICAgSVdpbmVEM0RQYWxldHRlX0FkZFJlZihpZmFjZSk7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICB9CiAgICBlbHNlIHsKICAgICAgICAqb2JqID0gTlVMTDsKICAgICAgICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKICAgIH0KfQoKc3RhdGljIFVMT05HICBXSU5BUEkgSVdpbmVEM0RQYWxldHRlSW1wbF9BZGRSZWYoSVdpbmVEM0RQYWxldHRlICppZmFjZSkgewogICAgSVdpbmVEM0RQYWxldHRlSW1wbCAqVGhpcyA9IChJV2luZUQzRFBhbGV0dGVJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKS0+KCkgaW5jcmVtZW50aW5nIGZyb20gJXUuXG4iLCBUaGlzLCByZWYgLSAxKTsKCiAgICByZXR1cm4gcmVmOwp9CgpzdGF0aWMgVUxPTkcgIFdJTkFQSSBJV2luZUQzRFBhbGV0dGVJbXBsX1JlbGVhc2UoSVdpbmVEM0RQYWxldHRlICppZmFjZSkgewogICAgSVdpbmVEM0RQYWxldHRlSW1wbCAqVGhpcyA9IChJV2luZUQzRFBhbGV0dGVJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZERlY3JlbWVudCgmVGhpcy0+cmVmKTsKCiAgICBUUkFDRSgiKCVwKS0+KCkgZGVjcmVtZW50aW5nIGZyb20gJXUuXG4iLCBUaGlzLCByZWYgKyAxKTsKCiAgICBpZiAoIXJlZikgewogICAgICAgIERlbGV0ZU9iamVjdChUaGlzLT5ocGFsKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBUaGlzKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICByZXR1cm4gcmVmOwp9CgovKiBOb3QgY2FsbGVkIGZyb20gdGhlIHZ0YWJsZSAqLwpEV09SRCBJV2luZUQzRFBhbGV0dGVJbXBsX1NpemUoRFdPUkQgZHdGbGFncykgewogICAgc3dpdGNoIChkd0ZsYWdzICYgU0laRV9CSVRTKSB7CiAgICAgICAgY2FzZSBXSU5FRERQQ0FQU18xQklUOiByZXR1cm4gMjsKICAgICAgICBjYXNlIFdJTkVERFBDQVBTXzJCSVQ6IHJldHVybiA0OwogICAgICAgIGNhc2UgV0lORUREUENBUFNfNEJJVDogcmV0dXJuIDE2OwogICAgICAgIGNhc2UgV0lORUREUENBUFNfOEJJVDogcmV0dXJuIDI1NjsKICAgICAgICBkZWZhdWx0OiBhc3NlcnQoMCk7IHJldHVybiAyNTY7CiAgICB9Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgSVdpbmVEM0RQYWxldHRlSW1wbF9HZXRFbnRyaWVzKElXaW5lRDNEUGFsZXR0ZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBEV09SRCBTdGFydCwgRFdPUkQgQ291bnQsIFBBTEVUVEVFTlRSWSAqUGFsRW50KSB7CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsICpUaGlzID0gKElXaW5lRDNEUGFsZXR0ZUltcGwgKilpZmFjZTsKCiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJWQsJWQsJXApXG4iLFRoaXMsRmxhZ3MsU3RhcnQsQ291bnQsUGFsRW50KTsKCiAgICBpZiAoRmxhZ3MgIT0gMCkgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7IC8qIHVuY2hlY2tlZCAqLwogICAgaWYgKFN0YXJ0ICsgQ291bnQgPiBJV2luZUQzRFBhbGV0dGVJbXBsX1NpemUoVGhpcy0+RmxhZ3MpKQogICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwoKICAgIGlmIChUaGlzLT5GbGFncyAmIFdJTkVERFBDQVBTXzhCSVRFTlRSSUVTKQogICAgewogICAgICAgIHVuc2lnbmVkIGludCBpOwogICAgICAgIExQQllURSBlbnRyeSA9IChMUEJZVEUpUGFsRW50OwoKICAgICAgICBmb3IgKGk9U3RhcnQ7IGkgPCBDb3VudCtTdGFydDsgaSsrKQogICAgICAgICAgICAqZW50cnkrKyA9IFRoaXMtPnBhbGVudHNbaV0ucGVSZWQ7CiAgICB9CiAgICBlbHNlCiAgICAgICAgbWVtY3B5KFBhbEVudCwgVGhpcy0+cGFsZW50cytTdGFydCwgQ291bnQgKiBzaXplb2YoUEFMRVRURUVOVFJZKSk7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgSVdpbmVEM0RQYWxldHRlSW1wbF9TZXRFbnRyaWVzKElXaW5lRDNEUGFsZXR0ZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBEV09SRCBTdGFydCwgRFdPUkQgQ291bnQsIFBBTEVUVEVFTlRSWSAqUGFsRW50KQp7CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsICpUaGlzID0gKElXaW5lRDNEUGFsZXR0ZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEUmVzb3VyY2VJbXBsICpyZXM7CgogICAgVFJBQ0UoIiglcCktPiglMDh4LCVkLCVkLCVwKVxuIixUaGlzLEZsYWdzLFN0YXJ0LENvdW50LFBhbEVudCk7CiAgICBUUkFDRSgiUGFsZXR0ZSBmbGFnczogJSN4XG4iLCBUaGlzLT5GbGFncyk7CgogICAgaWYgKFRoaXMtPkZsYWdzICYgV0lORUREUENBUFNfOEJJVEVOVFJJRVMpIHsKICAgICAgICB1bnNpZ25lZCBpbnQgaTsKICAgICAgICBjb25zdCBCWVRFKiBlbnRyeSA9IChjb25zdCBCWVRFKilQYWxFbnQ7CgogICAgICAgIGZvciAoaT1TdGFydDsgaSA8IENvdW50K1N0YXJ0OyBpKyspCiAgICAgICAgICAgIFRoaXMtPnBhbGVudHNbaV0ucGVSZWQgPSAqZW50cnkrKzsKICAgIH0KICAgIGVsc2UgewogICAgICAgIG1lbWNweShUaGlzLT5wYWxlbnRzK1N0YXJ0LCBQYWxFbnQsIENvdW50ICogc2l6ZW9mKFBBTEVUVEVFTlRSWSkpOwoKICAgICAgICAvKiBXaGVuIFdJTkVERENBUFNfQUxMT1cyNTYgaXNuJ3Qgc2V0IHdlIG5lZWQgdG8gb3ZlcnJpZGUgZW50cnkgMCB3aXRoIGJsYWNrIGFuZCAyNTUgd2l0aCB3aGl0ZSAqLwogICAgICAgIGlmKCEoVGhpcy0+RmxhZ3MgJiBXSU5FRERQQ0FQU19BTExPVzI1NikpCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiV0lORUREUENBUFNfQUxMT1cyNTYgc2V0LCBvdmVycmlkaW5nIHBhbGV0dGUgZW50cnkgMCB3aXRoIGJsYWNrIGFuZCAyNTUgd2l0aCB3aGl0ZVxuIik7CiAgICAgICAgICAgIFRoaXMtPnBhbGVudHNbMF0ucGVSZWQgPSAwOwogICAgICAgICAgICBUaGlzLT5wYWxlbnRzWzBdLnBlR3JlZW4gPSAwOwogICAgICAgICAgICBUaGlzLT5wYWxlbnRzWzBdLnBlQmx1ZSA9IDA7CgogICAgICAgICAgICBUaGlzLT5wYWxlbnRzWzI1NV0ucGVSZWQgPSAyNTU7CiAgICAgICAgICAgIFRoaXMtPnBhbGVudHNbMjU1XS5wZUdyZWVuID0gMjU1OwogICAgICAgICAgICBUaGlzLT5wYWxlbnRzWzI1NV0ucGVCbHVlID0gMjU1OwogICAgICAgIH0KCiAgICAgICAgaWYgKFRoaXMtPmhwYWwpCiAgICAgICAgICAgIFNldFBhbGV0dGVFbnRyaWVzKFRoaXMtPmhwYWwsIFN0YXJ0LCBDb3VudCwgVGhpcy0+cGFsZW50cytTdGFydCk7CiAgICB9CgojaWYgMAogICAgLyogTm93LCBpZiB3ZSBhcmUgaW4gJ2RlcHRoIGNvbnZlcnNpb24gbW9kZScsIHVwZGF0ZSB0aGUgc2NyZWVuIHBhbGV0dGUgKi8KICAgIC8qIEZJWE1FOiB3ZSBuZWVkIHRvIHVwZGF0ZSB0aGUgaW1hZ2Ugb3Igd2Ugd29uJ3QgZ2V0IHBhbGV0dGUgZmFkaW5nLiAqLwogICAgaWYgKFRoaXMtPmRkcmF3LT5kLT5wYWxldHRlX2NvbnZlcnQgIT0gTlVMTCkKICAgICAgICBUaGlzLT5kZHJhdy0+ZC0+cGFsZXR0ZV9jb252ZXJ0KHBhbGVudCxUaGlzLT5zY3JlZW5fcGFsZW50cyxzdGFydCxjb3VudCk7CiNlbmRpZgoKICAgIC8qIElmIHRoZSBwYWxldHRlIGlzIGF0dGFjaGVkIHRvIHRoZSByZW5kZXIgdGFyZ2V0LCB1cGRhdGUgYWxsIHJlbmRlciB0YXJnZXRzICovCgogICAgTElTVF9GT1JfRUFDSF9FTlRSWShyZXMsICZUaGlzLT53aW5lRDNERGV2aWNlLT5yZXNvdXJjZXMsIElXaW5lRDNEUmVzb3VyY2VJbXBsLCByZXNvdXJjZS5yZXNvdXJjZV9saXN0X2VudHJ5KSB7CiAgICAgICAgaWYoSVdpbmVEM0RSZXNvdXJjZV9HZXRUeXBlKChJV2luZUQzRFJlc291cmNlICopIHJlcykgPT0gV0lORUQzRFJUWVBFX1NVUkZBQ0UpIHsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqaW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIHJlczsKICAgICAgICAgICAgaWYoaW1wbC0+cGFsZXR0ZSA9PSBUaGlzKQogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlYWxpemVQYWxldHRlKChJV2luZUQzRFN1cmZhY2UgKikgcmVzKTsKICAgICAgICB9CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgSVdpbmVEM0RQYWxldHRlSW1wbF9HZXRDYXBzKElXaW5lRDNEUGFsZXR0ZSAqaWZhY2UsIERXT1JEICpDYXBzKSB7CiAgICBJV2luZUQzRFBhbGV0dGVJbXBsICpUaGlzID0gKElXaW5lRDNEUGFsZXR0ZUltcGwgKilpZmFjZTsKICAgIFRSQUNFKCIoJXApLT4oJXApXG4iLCBUaGlzLCBDYXBzKTsKCiAgICAqQ2FwcyA9IFRoaXMtPkZsYWdzOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnN0YXRpYyBIUkVTVUxUICBXSU5BUEkgSVdpbmVEM0RQYWxldHRlSW1wbF9HZXRQYXJlbnQoSVdpbmVEM0RQYWxldHRlICppZmFjZSwgSVVua25vd24gKipQYXJlbnQpIHsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RQYWxldHRlSW1wbCAqKWlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIFBhcmVudCk7CgogICAgKlBhcmVudCA9IFRoaXMtPnBhcmVudDsKICAgIElVbmtub3duX0FkZFJlZihUaGlzLT5wYXJlbnQpOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCmNvbnN0IElXaW5lRDNEUGFsZXR0ZVZ0YmwgSVdpbmVEM0RQYWxldHRlX1Z0YmwgPQp7CiAgICAvKioqIElVbmtub3duICoqKi8KICAgIElXaW5lRDNEUGFsZXR0ZUltcGxfUXVlcnlJbnRlcmZhY2UsCiAgICBJV2luZUQzRFBhbGV0dGVJbXBsX0FkZFJlZiwKICAgIElXaW5lRDNEUGFsZXR0ZUltcGxfUmVsZWFzZSwKICAgIC8qKiogSVdpbmVEM0RQYWxldHRlICoqKi8KICAgIElXaW5lRDNEUGFsZXR0ZUltcGxfR2V0UGFyZW50LAogICAgSVdpbmVEM0RQYWxldHRlSW1wbF9HZXRFbnRyaWVzLAogICAgSVdpbmVEM0RQYWxldHRlSW1wbF9HZXRDYXBzLAogICAgSVdpbmVEM0RQYWxldHRlSW1wbF9TZXRFbnRyaWVzCn07Cg==