LyoKICogQ29weXJpZ2h0IChDKSAyMDA3IEhhYWtvbiBTcG9yc2hlaW0gPGhha29uLnNwb3JzaGVpbUB0YW5kYmVyZy5jb20+CiAqICAgICAgICAgICAgICAgMjAwOCBPbGUgQW5kcukgVmFkbGEgUmF2buVzIDxvbGUuYW5kcmUucmF2bmFzQHRhbmRiZXJnLmNvbT4KICogICAgICAgICAgICAgICAyMDA5IEtudXQgSW5nZSBIdmlkc3RlbiA8a251dC5pbmdlLmh2aWRzdGVuQHRhbmRiZXJnLmNvbT4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGlicmFyeSBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGlicmFyeSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMaWJyYXJ5IEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlCiAqIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3QsIEZpZnRoIEZsb29yLAogKiBCb3N0b24sIE1BIDAyMTEwLTEzMDEsIFVTQS4KICovCgojaW5jbHVkZSAia3N2aWRlb2hlbHBlcnMuaCIKCiNpbmNsdWRlIDxtYXRoLmg+CiNpbmNsdWRlIDx1dWlkcy5oPgojaW5jbHVkZSAia3NoZWxwZXJzLmgiCgpHU1RfREVCVUdfQ0FURUdPUllfRVhURVJOIChnc3Rfa3NfZGVidWcpOwojZGVmaW5lIEdTVF9DQVRfREVGQVVMVCBnc3Rfa3NfZGVidWcKCnN0YXRpYyBjb25zdCBHVUlEIE1FRElBU1VCVFlQRV9GT1VSQ0MgPQogICAgeyAweDAgLyogRm91ckNDIGhlcmUgKi8gLCAweDAwMDAsIDB4MDAxMCwgezB4ODAsIDB4MDAsIDB4MDAsIDB4QUEsIDB4MDAsCiAgICAweDM4LCAweDlCLCAweDcxfQp9OwoKdHlwZWRlZiBzdHJ1Y3QgX0tzVmlkZW9EZXZpY2VFbnRyeSBLc1ZpZGVvRGV2aWNlRW50cnk7CgpzdHJ1Y3QgX0tzVmlkZW9EZXZpY2VFbnRyeQp7CiAgS3NEZXZpY2VFbnRyeSAqZGV2aWNlOwogIGdpbnQgcHJpb3JpdHk7Cn07CgpzdGF0aWMgdm9pZAprc192aWRlb19kZXZpY2VfZW50cnlfZGVjaWRlX3ByaW9yaXR5IChLc1ZpZGVvRGV2aWNlRW50cnkgKiB2aWRlb2RldmljZSkKewogIEhBTkRMRSBmaWx0ZXJfaGFuZGxlOwoKICB2aWRlb2RldmljZS0+cHJpb3JpdHkgPSAwOwoKICBmaWx0ZXJfaGFuZGxlID0gQ3JlYXRlRmlsZSAodmlkZW9kZXZpY2UtPmRldmljZS0+cGF0aCwKICAgICAgR0VORVJJQ19SRUFEIHwgR0VORVJJQ19XUklURSwgMCwgTlVMTCwgT1BFTl9FWElTVElORywKICAgICAgRklMRV9BVFRSSUJVVEVfTk9STUFMIHwgRklMRV9GTEFHX09WRVJMQVBQRUQsIE5VTEwpOwogIGlmIChrc19pc192YWxpZF9oYW5kbGUgKGZpbHRlcl9oYW5kbGUpKSB7CiAgICBHVUlEICpwcm9wc2V0cyA9IE5VTEw7CiAgICBndWxvbmcgcHJvcHNldHNfbGVuOwoKICAgIGlmIChrc19vYmplY3RfZ2V0X3N1cHBvcnRlZF9wcm9wZXJ0eV9zZXRzIChmaWx0ZXJfaGFuZGxlLCAmcHJvcHNldHMsCiAgICAgICAgICAgICZwcm9wc2V0c19sZW4pKSB7CiAgICAgIGd1bG9uZyBpOwoKICAgICAgZm9yIChpID0gMDsgaSA8IHByb3BzZXRzX2xlbjsgaSsrKSB7CiAgICAgICAgaWYgKG1lbWNtcCAoJnByb3BzZXRzW2ldLCAmUFJPUFNFVElEX1ZJRENBUF9DQU1FUkFDT05UUk9MLAogICAgICAgICAgICAgICAgc2l6ZW9mIChHVUlEKSkgPT0gMCkgewogICAgICAgICAgdmlkZW9kZXZpY2UtPnByaW9yaXR5Kys7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgIH0KCiAgICAgIGdfZnJlZSAocHJvcHNldHMpOwogICAgfQogIH0KCiAgQ2xvc2VIYW5kbGUgKGZpbHRlcl9oYW5kbGUpOwp9CgpzdGF0aWMgZ2ludAprc192aWRlb19kZXZpY2VfZW50cnlfY29tcGFyZSAoZ2NvbnN0cG9pbnRlciBhLCBnY29uc3Rwb2ludGVyIGIpCnsKICBjb25zdCBLc1ZpZGVvRGV2aWNlRW50cnkgKnZpZGVvZGV2aWNlX2EgPSBhOwogIGNvbnN0IEtzVmlkZW9EZXZpY2VFbnRyeSAqdmlkZW9kZXZpY2VfYiA9IGI7CgogIGlmICh2aWRlb2RldmljZV9hLT5wcmlvcml0eSA+IHZpZGVvZGV2aWNlX2ItPnByaW9yaXR5KQogICAgcmV0dXJuIC0xOwogIGVsc2UgaWYgKHZpZGVvZGV2aWNlX2EtPnByaW9yaXR5ID09IHZpZGVvZGV2aWNlX2ItPnByaW9yaXR5KQogICAgcmV0dXJuIDA7CiAgZWxzZQogICAgcmV0dXJuIDE7Cn0KCkdMaXN0ICoKa3NfdmlkZW9fZGV2aWNlX2xpc3Rfc29ydF9jYW1lcmFzX2ZpcnN0IChHTGlzdCAqIGRldmljZXMpCnsKICBHTGlzdCAqdmlkZW9kZXZpY2VzID0gTlVMTCwgKndhbGs7CiAgZ3VpbnQgaTsKCiAgZm9yICh3YWxrID0gZGV2aWNlczsgd2FsayAhPSBOVUxMOyB3YWxrID0gd2Fsay0+bmV4dCkgewogICAgS3NEZXZpY2VFbnRyeSAqZGV2aWNlID0gd2Fsay0+ZGF0YTsKICAgIEtzVmlkZW9EZXZpY2VFbnRyeSAqdmlkZW9kZXZpY2U7CgogICAgdmlkZW9kZXZpY2UgPSBnX25ldyAoS3NWaWRlb0RldmljZUVudHJ5LCAxKTsKICAgIHZpZGVvZGV2aWNlLT5kZXZpY2UgPSBkZXZpY2U7CiAgICBrc192aWRlb19kZXZpY2VfZW50cnlfZGVjaWRlX3ByaW9yaXR5ICh2aWRlb2RldmljZSk7CgogICAgdmlkZW9kZXZpY2VzID0gZ19saXN0X2FwcGVuZCAodmlkZW9kZXZpY2VzLCB2aWRlb2RldmljZSk7CiAgfQoKICB2aWRlb2RldmljZXMgPSBnX2xpc3Rfc29ydCAodmlkZW9kZXZpY2VzLCBrc192aWRlb19kZXZpY2VfZW50cnlfY29tcGFyZSk7CgogIGdfbGlzdF9mcmVlIChkZXZpY2VzKTsKICBkZXZpY2VzID0gTlVMTDsKCiAgZm9yICh3YWxrID0gdmlkZW9kZXZpY2VzLCBpID0gMDsgd2FsayAhPSBOVUxMOyB3YWxrID0gd2Fsay0+bmV4dCwgaSsrKSB7CiAgICBLc1ZpZGVvRGV2aWNlRW50cnkgKnZpZGVvZGV2aWNlID0gd2Fsay0+ZGF0YTsKCiAgICB2aWRlb2RldmljZS0+ZGV2aWNlLT5pbmRleCA9IGk7CiAgICBkZXZpY2VzID0gZ19saXN0X2FwcGVuZCAoZGV2aWNlcywgdmlkZW9kZXZpY2UtPmRldmljZSk7CgogICAgZ19mcmVlICh2aWRlb2RldmljZSk7CiAgfQoKICBnX2xpc3RfZnJlZSAodmlkZW9kZXZpY2VzKTsKCiAgcmV0dXJuIGRldmljZXM7Cn0KCnN0YXRpYyBHc3RTdHJ1Y3R1cmUgKgprc192aWRlb19mb3JtYXRfdG9fc3RydWN0dXJlIChHVUlEIHN1YnR5cGVfZ3VpZCwgR1VJRCBmb3JtYXRfZ3VpZCkKewogIEdzdFN0cnVjdHVyZSAqc3RydWN0dXJlID0gTlVMTDsKICBjb25zdCBnY2hhciAqbWVkaWFfdHlwZSA9IE5VTEwsICpmb3JtYXQgPSBOVUxMOwoKICBpZiAoSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfTUpQRykgfHwgSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfVFZNSikgfHwgICAgIC8qIEZJWE1FOiBOT1QgdGVzdGVkICovCiAgICAgIElzRXF1YWxHVUlEICgmc3VidHlwZV9ndWlkLCAmTUVESUFTVUJUWVBFX1dBS0UpIHx8ICAgICAgICAvKiBGSVhNRTogTk9UIHRlc3RlZCAqLwogICAgICBJc0VxdWFsR1VJRCAoJnN1YnR5cGVfZ3VpZCwgJk1FRElBU1VCVFlQRV9DRkNDKSB8fCAgICAgICAgLyogRklYTUU6IE5PVCB0ZXN0ZWQgKi8KICAgICAgSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfSUpQRykpIHsgICAgICAgIC8qIEZJWE1FOiBOT1QgdGVzdGVkICovCiAgICBtZWRpYV90eXBlID0gImltYWdlL2pwZWciOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfUkdCNTU1KSkgewogICAgbWVkaWFfdHlwZSA9ICJ2aWRlby94LXJhdyI7CiAgICBmb3JtYXQgPSAiUkdCMTUiOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfUkdCNTY1KSkgewogICAgbWVkaWFfdHlwZSA9ICJ2aWRlby94LXJhdyI7CiAgICBmb3JtYXQgPSAiUkdCMTYiOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfUkdCMjQpKSB7CiAgICBtZWRpYV90eXBlID0gInZpZGVvL3gtcmF3IjsKICAgIGZvcm1hdCA9ICJSR0J4IjsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmc3VidHlwZV9ndWlkLCAmTUVESUFTVUJUWVBFX1JHQjMyKSkgewogICAgbWVkaWFfdHlwZSA9ICJ2aWRlby94LXJhdyI7CiAgICBmb3JtYXQgPSAiUkdCIjsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmc3VidHlwZV9ndWlkLCAmTUVESUFTVUJUWVBFX0FSR0IzMikpIHsKICAgIG1lZGlhX3R5cGUgPSAidmlkZW8veC1yYXciOwogICAgZm9ybWF0ID0gIkFSR0IiOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfQVJHQjE1NTUpKSB7CiAgICBHU1RfV0FSTklORyAoIlVuc3VwcG9ydGVkIHZpZGVvIGZvcm1hdCBBUkdCMTU1NTUiKTsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmc3VidHlwZV9ndWlkLCAmTUVESUFTVUJUWVBFX0FSR0I0NDQ0KSkgewogICAgR1NUX1dBUk5JTkcgKCJVbnN1cHBvcnRlZCB2aWRlbyBmb3JtYXQgQVJHQjQ0NDQiKTsKICB9IGVsc2UgaWYgKG1lbWNtcCAoJnN1YnR5cGVfZ3VpZC5EYXRhMiwgJk1FRElBU1VCVFlQRV9GT1VSQ0MuRGF0YTIsCiAgICAgICAgICBzaXplb2YgKHN1YnR5cGVfZ3VpZCkgLSBzaXplb2YgKHN1YnR5cGVfZ3VpZC5EYXRhMSkpID09IDApIHsKICAgIGd1aW50OCAqcCA9IChndWludDggKikgJiBzdWJ0eXBlX2d1aWQuRGF0YTE7CiAgICBnY2hhciAqZm9ybWF0ID0gZ19zdHJkdXBfcHJpbnRmICgiJWMlYyVjJWMiLCBwWzBdLCBwWzFdLCBwWzJdLCBwWzNdKTsKICAgIHN0cnVjdHVyZSA9IGdzdF9zdHJ1Y3R1cmVfbmV3ICgidmlkZW8veC1yYXciLCAiZm9ybWF0IiwKICAgICAgICBHX1RZUEVfU1RSSU5HLCBmb3JtYXQsIE5VTEwpOwogICAgZ19mcmVlIChmb3JtYXQpOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZzdWJ0eXBlX2d1aWQsICZNRURJQVNVQlRZUEVfZHZzZCkpIHsKICAgIGlmIChJc0VxdWFsR1VJRCAoJmZvcm1hdF9ndWlkLCAmRk9STUFUX0R2SW5mbykpIHsKICAgICAgc3RydWN0dXJlID0gZ3N0X3N0cnVjdHVyZV9uZXcgKCJ2aWRlby94LWR2IiwKICAgICAgICAgICJzeXN0ZW1zdHJlYW0iLCBHX1RZUEVfQk9PTEVBTiwgVFJVRSwgTlVMTCk7CiAgICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmZm9ybWF0X2d1aWQsICZGT1JNQVRfVmlkZW9JbmZvKSkgewogICAgICBzdHJ1Y3R1cmUgPSBnc3Rfc3RydWN0dXJlX25ldyAoInZpZGVvL3gtZHYiLAogICAgICAgICAgInN5c3RlbXN0cmVhbSIsIEdfVFlQRV9CT09MRUFOLCBGQUxTRSwKICAgICAgICAgICJmb3JtYXQiLCBHX1RZUEVfU1RSSU5HLCAiZHZzZCIsIE5VTEwpOwogICAgfQogIH0KCiAgaWYgKG1lZGlhX3R5cGUpIHsKICAgIHN0cnVjdHVyZSA9IGdzdF9zdHJ1Y3R1cmVfbmV3X2VtcHR5IChtZWRpYV90eXBlKTsKICAgIGlmIChmb3JtYXQpIHsKICAgICAgZ3N0X3N0cnVjdHVyZV9zZXQgKHN0cnVjdHVyZSwgImZvcm1hdCIsIEdfVFlQRV9TVFJJTkcsIGZvcm1hdCwgTlVMTCk7CiAgICB9CiAgfQoKICBpZiAoIXN0cnVjdHVyZSkgewogICAgR1NUX0RFQlVHICgiVW5rbm93biBEaXJlY3RTaG93IFZpZGVvIEdVSUQgIgogICAgICAgICIlMDh4LSUwNHgtJTA0eC0lMDJ4JTAyeC0lMDJ4JTAyeCUwMnglMDJ4JTAyeCUwMngiLAogICAgICAgIChndWludCkgc3VidHlwZV9ndWlkLkRhdGExLCBzdWJ0eXBlX2d1aWQuRGF0YTIsIHN1YnR5cGVfZ3VpZC5EYXRhMywKICAgICAgICBzdWJ0eXBlX2d1aWQuRGF0YTRbMF0sIHN1YnR5cGVfZ3VpZC5EYXRhNFsxXSwgc3VidHlwZV9ndWlkLkRhdGE0WzJdLAogICAgICAgIHN1YnR5cGVfZ3VpZC5EYXRhNFszXSwgc3VidHlwZV9ndWlkLkRhdGE0WzRdLCBzdWJ0eXBlX2d1aWQuRGF0YTRbNV0sCiAgICAgICAgc3VidHlwZV9ndWlkLkRhdGE0WzZdLCBzdWJ0eXBlX2d1aWQuRGF0YTRbN10pOwogIH0KCiAgcmV0dXJuIHN0cnVjdHVyZTsKfQoKc3RhdGljIHZvaWQKZ3Vlc3NfYXNwZWN0IChnaW50IHdpZHRoLCBnaW50IGhlaWdodCwgZ2ludCAqIHBhcl93aWR0aCwgZ2ludCAqIHBhcl9oZWlnaHQpCnsKICAvKgogICAqIEFzIHdlIGRvbnQgaGF2ZSBhY2Nlc3MgdG8gdGhlIGFjdHVhbCBwaXhlbCBhc3BlY3QsIHdlIHdpbGwgdHJ5IHRvIGRvIGEKICAgKiBiZXN0LWVmZm9ydCBndWVzcy4gVGhlIGd1ZXNzIGlzIGJhc2VkIG9uIG1vc3Qgc2Vuc29ycyBiZWluZyBlaXRoZXIgNC8zCiAgICogb3IgMTYvOSwgYW5kIG1vc3QgcGl4ZWwgYXNwZWN0cyBiZWluZyBjbG9zZSB0byAxLzEuCiAgICovCiAgaWYgKCh3aWR0aCA9PSA3NjgpICYmIChoZWlnaHQgPT0gNDQ4KSkgeyAgICAgIC8qIHNwZWNpYWwgY2FzZSBmb3IgdzQ0OHAgKi8KICAgICpwYXJfd2lkdGggPSAyODsKICAgICpwYXJfaGVpZ2h0ID0gMjc7CiAgfSBlbHNlIHsKICAgIGlmICgoKGZsb2F0KSB3aWR0aCAvIChmbG9hdCkgaGVpZ2h0KSA8IDEuMjc3OCkgewogICAgICAqcGFyX3dpZHRoID0gMTI7CiAgICAgICpwYXJfaGVpZ2h0ID0gMTE7CiAgICB9IGVsc2UgewogICAgICAqcGFyX3dpZHRoID0gMTsKICAgICAgKnBhcl9oZWlnaHQgPSAxOwogICAgfQogIH0KfQoKLyogTk9URTogd291bGQgcHJvYmFibHkgYmUgYmV0dGVyIHRvIHVzZSBhIGNvbnRpbnVlZCBmcmFjdGlvbnMgYXBwcm9hY2ggaGVyZSAqLwpzdGF0aWMgdm9pZApjb21wcmVzc19mcmFjdGlvbiAoZ2ludDY0IGluX251bSwgZ2ludDY0IGluX2RlbiwgZ2ludDY0ICogb3V0X251bSwKICAgIGdpbnQ2NCAqIG91dF9kZW4pCnsKICBnZG91YmxlIG9uLCBvZCwgb3JpZzsKICBndWludCBkZW5vbWluYXRvcnNbXSA9IHsgMSwgMiwgMywgNSwgNyB9LCBpOwogIGNvbnN0IGdkb3VibGUgbWF4X2xvc3MgPSAwLjE7CgogIG9uID0gaW5fbnVtOwogIG9kID0gaW5fZGVuOwogIG9yaWcgPSBvbiAvIG9kOwoKICBmb3IgKGkgPSAwOyBpIDwgR19OX0VMRU1FTlRTIChkZW5vbWluYXRvcnMpOyBpKyspIHsKICAgIGdpbnQ2NCBjdXJfbiwgY3VyX2Q7CiAgICBnZG91YmxlIGN1ciwgbG9zczsKCiAgICBjdXJfbiA9IGZsb29yICgob24gLyAob2QgLyAoZ2RvdWJsZSkgZGVub21pbmF0b3JzW2ldKSkgKyAwLjUpOwogICAgY3VyX2QgPSBkZW5vbWluYXRvcnNbaV07CiAgICBjdXIgPSAoZ2RvdWJsZSkgY3VyX24gLyAoZ2RvdWJsZSkgY3VyX2Q7CiAgICBsb3NzID0gZmFicyAoY3VyIC0gb3JpZyk7CgogICAgaWYgKGxvc3MgPD0gbWF4X2xvc3MpIHsKICAgICAgKm91dF9udW0gPSBjdXJfbjsKICAgICAgKm91dF9kZW4gPSBjdXJfZDsKCiAgICAgIHJldHVybjsKICAgIH0KICB9CgogICpvdXRfbnVtID0gaW5fbnVtOwogICpvdXRfZGVuID0gaW5fZGVuOwp9CgpzdGF0aWMgZ2Jvb2xlYW4Ka3NfdmlkZW9fYXBwZW5kX3ZpZGVvX3N0cmVhbV9jZmdfZmllbGRzIChHc3RTdHJ1Y3R1cmUgKiBzdHJ1Y3R1cmUsCiAgICBjb25zdCBLU19WSURFT19TVFJFQU1fQ09ORklHX0NBUFMgKiB2c2NjKQp7CiAgR1ZhbHVlIHZhbCA9IHsgMCwgfTsKICBnaW50NjQgbWluX24sIG1pbl9kOwogIGdpbnQ2NCBtYXhfbiwgbWF4X2Q7CgogIGdfcmV0dXJuX3ZhbF9pZl9mYWlsIChzdHJ1Y3R1cmUsIEZBTFNFKTsKICBnX3JldHVybl92YWxfaWZfZmFpbCAodnNjYywgRkFMU0UpOwoKICAvKiB3aWR0aCAqLwogIGlmICh2c2NjLT5NaW5PdXRwdXRTaXplLmN4ID09IHZzY2MtPk1heE91dHB1dFNpemUuY3gpIHsKICAgIGdzdF9zdHJ1Y3R1cmVfc2V0IChzdHJ1Y3R1cmUsCiAgICAgICAgIndpZHRoIiwgR19UWVBFX0lOVCwgdnNjYy0+TWF4T3V0cHV0U2l6ZS5jeCwgTlVMTCk7CiAgfSBlbHNlIHsKICAgIGdzdF9zdHJ1Y3R1cmVfc2V0IChzdHJ1Y3R1cmUsCiAgICAgICAgIndpZHRoIiwgR1NUX1RZUEVfSU5UX1JBTkdFLAogICAgICAgIHZzY2MtPk1pbk91dHB1dFNpemUuY3gsIHZzY2MtPk1heE91dHB1dFNpemUuY3gsIE5VTEwpOwogIH0KCiAgLyogaGVpZ2h0ICovCiAgaWYgKHZzY2MtPk1pbk91dHB1dFNpemUuY3kgPT0gdnNjYy0+TWF4T3V0cHV0U2l6ZS5jeSkgewogICAgZ3N0X3N0cnVjdHVyZV9zZXQgKHN0cnVjdHVyZSwKICAgICAgICAiaGVpZ2h0IiwgR19UWVBFX0lOVCwgdnNjYy0+TWF4T3V0cHV0U2l6ZS5jeSwgTlVMTCk7CiAgfSBlbHNlIHsKICAgIGdzdF9zdHJ1Y3R1cmVfc2V0IChzdHJ1Y3R1cmUsCiAgICAgICAgImhlaWdodCIsIEdTVF9UWVBFX0lOVF9SQU5HRSwKICAgICAgICB2c2NjLT5NaW5PdXRwdXRTaXplLmN5LCB2c2NjLT5NYXhPdXRwdXRTaXplLmN5LCBOVUxMKTsKICB9CgogIC8qIGZyYW1lcmF0ZSAqLwogIGNvbXByZXNzX2ZyYWN0aW9uIChOQU5PU0VDT05EUywgdnNjYy0+TWluRnJhbWVJbnRlcnZhbCwgJm1pbl9uLCAmbWluX2QpOwogIGNvbXByZXNzX2ZyYWN0aW9uIChOQU5PU0VDT05EUywgdnNjYy0+TWF4RnJhbWVJbnRlcnZhbCwgJm1heF9uLCAmbWF4X2QpOwoKICBpZiAobWluX24gPT0gbWF4X24gJiYgbWluX2QgPT0gbWF4X2QpIHsKICAgIGdfdmFsdWVfaW5pdCAoJnZhbCwgR1NUX1RZUEVfRlJBQ1RJT04pOwogICAgZ3N0X3ZhbHVlX3NldF9mcmFjdGlvbiAoJnZhbCwgbWF4X24sIG1heF9kKTsKICB9IGVsc2UgewogICAgZ192YWx1ZV9pbml0ICgmdmFsLCBHU1RfVFlQRV9GUkFDVElPTl9SQU5HRSk7CiAgICBnc3RfdmFsdWVfc2V0X2ZyYWN0aW9uX3JhbmdlX2Z1bGwgKCZ2YWwsIG1heF9uLCBtYXhfZCwgbWluX24sIG1pbl9kKTsKICB9CgogIGdzdF9zdHJ1Y3R1cmVfc2V0X3ZhbHVlIChzdHJ1Y3R1cmUsICJmcmFtZXJhdGUiLCAmdmFsKTsKICBnX3ZhbHVlX3Vuc2V0ICgmdmFsKTsKCiAgewogICAgZ2ludCBwYXJfd2lkdGgsIHBhcl9oZWlnaHQ7CgogICAgZ3Vlc3NfYXNwZWN0ICh2c2NjLT5NYXhPdXRwdXRTaXplLmN4LCB2c2NjLT5NYXhPdXRwdXRTaXplLmN5LAogICAgICAgICZwYXJfd2lkdGgsICZwYXJfaGVpZ2h0KTsKCiAgICBnc3Rfc3RydWN0dXJlX3NldCAoc3RydWN0dXJlLAogICAgICAgICJwaXhlbC1hc3BlY3QtcmF0aW8iLCBHU1RfVFlQRV9GUkFDVElPTiwgcGFyX3dpZHRoLCBwYXJfaGVpZ2h0LCBOVUxMKTsKICB9CgogIHJldHVybiBUUlVFOwp9CgpLc1ZpZGVvTWVkaWFUeXBlICoKa3NfdmlkZW9fbWVkaWFfdHlwZV9kdXAgKEtzVmlkZW9NZWRpYVR5cGUgKiBtZWRpYV90eXBlKQp7CiAgS3NWaWRlb01lZGlhVHlwZSAqcmVzdWx0ID0gZ19uZXcgKEtzVmlkZW9NZWRpYVR5cGUsIDEpOwoKICBtZW1jcHkgKHJlc3VsdCwgbWVkaWFfdHlwZSwgc2l6ZW9mIChLc1ZpZGVvTWVkaWFUeXBlKSk7CgogIHJlc3VsdC0+cmFuZ2UgPSBnX21hbGxvYyAobWVkaWFfdHlwZS0+cmFuZ2UtPkZvcm1hdFNpemUpOwogIG1lbWNweSAoKGdwb2ludGVyKSByZXN1bHQtPnJhbmdlLCBtZWRpYV90eXBlLT5yYW5nZSwKICAgICAgbWVkaWFfdHlwZS0+cmFuZ2UtPkZvcm1hdFNpemUpOwoKICByZXN1bHQtPmZvcm1hdCA9IGdfbWFsbG9jIChtZWRpYV90eXBlLT5mb3JtYXRfc2l6ZSk7CiAgbWVtY3B5IChyZXN1bHQtPmZvcm1hdCwgbWVkaWFfdHlwZS0+Zm9ybWF0LCBtZWRpYV90eXBlLT5mb3JtYXRfc2l6ZSk7CgogIHJlc3VsdC0+dHJhbnNsYXRlZF9jYXBzID0gZ3N0X2NhcHNfcmVmIChtZWRpYV90eXBlLT50cmFuc2xhdGVkX2NhcHMpOwoKICByZXR1cm4gcmVzdWx0Owp9Cgp2b2lkCmtzX3ZpZGVvX21lZGlhX3R5cGVfZnJlZSAoS3NWaWRlb01lZGlhVHlwZSAqIG1lZGlhX3R5cGUpCnsKICBpZiAobWVkaWFfdHlwZSA9PSBOVUxMKQogICAgcmV0dXJuOwoKICBnX2ZyZWUgKChncG9pbnRlcikgbWVkaWFfdHlwZS0+cmFuZ2UpOwoKICBnX2ZyZWUgKG1lZGlhX3R5cGUtPmZvcm1hdCk7CgogIGlmIChtZWRpYV90eXBlLT50cmFuc2xhdGVkX2NhcHMgIT0gTlVMTCkKICAgIGdzdF9jYXBzX3VucmVmIChtZWRpYV90eXBlLT50cmFuc2xhdGVkX2NhcHMpOwoKICBnX2ZyZWUgKG1lZGlhX3R5cGUpOwp9CgpzdGF0aWMgR0xpc3QgKgprc192aWRlb19tZWRpYV90eXBlX2xpc3RfcmVtb3ZlX2R1cGxpY2F0ZXMgKEdMaXN0ICogbWVkaWFfdHlwZXMpCnsKICBHTGlzdCAqbWFzdGVyLCAqZHVwbGljYXRlczsKCiAgZG8gewogICAgR0xpc3QgKmVudHJ5OwoKICAgIG1hc3RlciA9IGR1cGxpY2F0ZXMgPSBOVUxMOwoKICAgIC8qIEZpbmQgdGhlIGZpcnN0IHNldCBvZiBkdXBsaWNhdGVzIGFuZCB0aGVpciBtYXN0ZXIgKi8KICAgIGZvciAoZW50cnkgPSBtZWRpYV90eXBlczsgZW50cnkgIT0gTlVMTCAmJiBkdXBsaWNhdGVzID09IE5VTEw7CiAgICAgICAgZW50cnkgPSBlbnRyeS0+bmV4dCkgewogICAgICBLc1ZpZGVvTWVkaWFUeXBlICptdCA9IGVudHJ5LT5kYXRhOwogICAgICBHTGlzdCAqb3RoZXJfZW50cnk7CgogICAgICBmb3IgKG90aGVyX2VudHJ5ID0gbWVkaWFfdHlwZXM7IG90aGVyX2VudHJ5ICE9IE5VTEw7CiAgICAgICAgICBvdGhlcl9lbnRyeSA9IG90aGVyX2VudHJ5LT5uZXh0KSB7CiAgICAgICAgS3NWaWRlb01lZGlhVHlwZSAqb3RoZXJfbXQgPSBvdGhlcl9lbnRyeS0+ZGF0YTsKCiAgICAgICAgaWYgKG90aGVyX210ID09IG10KQogICAgICAgICAgY29udGludWU7CgogICAgICAgIGlmIChnc3RfY2Fwc19pc19lcXVhbCAobXQtPnRyYW5zbGF0ZWRfY2Fwcywgb3RoZXJfbXQtPnRyYW5zbGF0ZWRfY2FwcykpCiAgICAgICAgICBkdXBsaWNhdGVzID0gZ19saXN0X3ByZXBlbmQgKGR1cGxpY2F0ZXMsIG90aGVyX210KTsKICAgICAgfQoKICAgICAgaWYgKGR1cGxpY2F0ZXMgIT0gTlVMTCkKICAgICAgICBtYXN0ZXIgPSBlbnRyeTsKICAgIH0KCiAgICBpZiAoZHVwbGljYXRlcyAhPSBOVUxMKSB7CiAgICAgIEtzVmlkZW9NZWRpYVR5cGUgKnNlbGVjdGVkX210ID0gbWFzdGVyLT5kYXRhOwoKICAgICAgLyoKICAgICAgICogUGljayBhIEZPUk1BVF9WaWRlb0luZm8yIGlmIHByZXNlbnQsIGlmIG5vdCB3ZSBqdXN0IHN0YXkgd2l0aCB0aGUKICAgICAgICogZmlyc3QgZW50cnkKICAgICAgICovCiAgICAgIGZvciAoZW50cnkgPSBkdXBsaWNhdGVzOyBlbnRyeSAhPSBOVUxMOyBlbnRyeSA9IGVudHJ5LT5uZXh0KSB7CiAgICAgICAgS3NWaWRlb01lZGlhVHlwZSAqbXQgPSBlbnRyeS0+ZGF0YTsKCiAgICAgICAgaWYgKElzRXF1YWxHVUlEICgmbXQtPnJhbmdlLT5TcGVjaWZpZXIsICZGT1JNQVRfVmlkZW9JbmZvMikpIHsKICAgICAgICAgIGtzX3ZpZGVvX21lZGlhX3R5cGVfZnJlZSAoc2VsZWN0ZWRfbXQpOwogICAgICAgICAgc2VsZWN0ZWRfbXQgPSBtdDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAga3NfdmlkZW9fbWVkaWFfdHlwZV9mcmVlIChtdCk7CiAgICAgICAgfQoKICAgICAgICAvKiBSZW1vdmUgdGhlIGR1cGUgZnJvbSB0aGUgbWFpbiBsaXN0ICovCiAgICAgICAgbWVkaWFfdHlwZXMgPSBnX2xpc3RfcmVtb3ZlIChtZWRpYV90eXBlcywgbXQpOwogICAgICB9CgogICAgICAvKiBVcGRhdGUgbWFzdGVyIG5vZGUgd2l0aCB0aGUgc2VsZWN0ZWQgTWVkaWFUeXBlICovCiAgICAgIG1hc3Rlci0+ZGF0YSA9IHNlbGVjdGVkX210OwoKICAgICAgZ19saXN0X2ZyZWUgKGR1cGxpY2F0ZXMpOwogICAgfQogIH0KICB3aGlsZSAobWFzdGVyICE9IE5VTEwpOwoKICByZXR1cm4gbWVkaWFfdHlwZXM7Cn0KCkdMaXN0ICoKa3NfdmlkZW9fcHJvYmVfZmlsdGVyX2Zvcl9jYXBzIChIQU5ETEUgZmlsdGVyX2hhbmRsZSkKewogIEdMaXN0ICpyZXQgPSBOVUxMOwogIGd1bG9uZyBwaW5fY291bnQ7CiAgZ3VpbnQgcGluX2lkOwoKICBpZiAoIWtzX2ZpbHRlcl9nZXRfcGluX3Byb3BlcnR5IChmaWx0ZXJfaGFuZGxlLCAwLCBLU1BST1BTRVRJRF9QaW4sCiAgICAgICAgICBLU1BST1BFUlRZX1BJTl9DVFlQRVMsICZwaW5fY291bnQsIHNpemVvZiAocGluX2NvdW50KSwgTlVMTCkpCiAgICBnb3RvIGJlYWNoOwoKICBHU1RfREVCVUcgKCJwaW5fY291bnQgPSAlbHUiLCBwaW5fY291bnQpOwoKICBmb3IgKHBpbl9pZCA9IDA7IHBpbl9pZCA8IHBpbl9jb3VudDsgcGluX2lkKyspIHsKICAgIEtTUElOX0NPTU1VTklDQVRJT04gcGluX2NvbW07CiAgICBLU1BJTl9EQVRBRkxPVyBwaW5fZmxvdzsKICAgIEdVSUQgcGluX2NhdDsKCiAgICBpZiAoIWtzX2ZpbHRlcl9nZXRfcGluX3Byb3BlcnR5IChmaWx0ZXJfaGFuZGxlLCBwaW5faWQsIEtTUFJPUFNFVElEX1BpbiwKICAgICAgICAgICAgS1NQUk9QRVJUWV9QSU5fQ09NTVVOSUNBVElPTiwgJnBpbl9jb21tLCBzaXplb2YgKHBpbl9jb21tKSwgTlVMTCkpCiAgICAgIGNvbnRpbnVlOwoKICAgIGlmICgha3NfZmlsdGVyX2dldF9waW5fcHJvcGVydHkgKGZpbHRlcl9oYW5kbGUsIHBpbl9pZCwgS1NQUk9QU0VUSURfUGluLAogICAgICAgICAgICBLU1BST1BFUlRZX1BJTl9EQVRBRkxPVywgJnBpbl9mbG93LCBzaXplb2YgKHBpbl9mbG93KSwgTlVMTCkpCiAgICAgIGNvbnRpbnVlOwoKICAgIGlmICgha3NfZmlsdGVyX2dldF9waW5fcHJvcGVydHkgKGZpbHRlcl9oYW5kbGUsIHBpbl9pZCwgS1NQUk9QU0VUSURfUGluLAogICAgICAgICAgICBLU1BST1BFUlRZX1BJTl9DQVRFR09SWSwgJnBpbl9jYXQsIHNpemVvZiAocGluX2NhdCksIE5VTEwpKQogICAgICBjb250aW51ZTsKCiAgICBHU1RfREVCVUcgKCJwaW5bJXVdOiBwaW5fY29tbT0lZCwgcGluX2Zsb3c9JWQiLCBwaW5faWQsIHBpbl9jb21tLCBwaW5fZmxvdyk7CgogICAgaWYgKHBpbl9mbG93ID09IEtTUElOX0RBVEFGTE9XX09VVCAmJgogICAgICAgIG1lbWNtcCAoJnBpbl9jYXQsICZQSU5OQU1FX0NBUFRVUkUsIHNpemVvZiAoR1VJRCkpID09IDApIHsKICAgICAgS1NNVUxUSVBMRV9JVEVNICppdGVtczsKCiAgICAgIGlmIChrc19maWx0ZXJfZ2V0X3Bpbl9wcm9wZXJ0eV9tdWx0aSAoZmlsdGVyX2hhbmRsZSwgcGluX2lkLAogICAgICAgICAgICAgIEtTUFJPUFNFVElEX1BpbiwgS1NQUk9QRVJUWV9QSU5fREFUQVJBTkdFUywgJml0ZW1zLCBOVUxMKSkgewogICAgICAgIEtTREFUQVJBTkdFICpyYW5nZSA9IChLU0RBVEFSQU5HRSAqKSAoaXRlbXMgKyAxKTsKICAgICAgICBndWludCBpOwoKICAgICAgICBmb3IgKGkgPSAwOyBpIDwgaXRlbXMtPkNvdW50OyBpKyspIHsKICAgICAgICAgIGlmIChJc0VxdWFsR1VJRCAoJnJhbmdlLT5NYWpvckZvcm1hdCwgJk1FRElBVFlQRV9WaWRlbykKICAgICAgICAgICAgICB8fCBJc0VxdWFsR1VJRCAoJnJhbmdlLT5NYWpvckZvcm1hdCwgJk1FRElBVFlQRV9JbnRlcmxlYXZlZCkpIHsKICAgICAgICAgICAgS3NWaWRlb01lZGlhVHlwZSAqZW50cnk7CiAgICAgICAgICAgIGdwb2ludGVyIHNyY192c2NjLCBzcmNfZm9ybWF0OwogICAgICAgICAgICBHc3RTdHJ1Y3R1cmUgKm1lZGlhX3N0cnVjdHVyZTsKCiAgICAgICAgICAgIGVudHJ5ID0gZ19uZXcwIChLc1ZpZGVvTWVkaWFUeXBlLCAxKTsKICAgICAgICAgICAgZW50cnktPnBpbl9pZCA9IHBpbl9pZDsKCiAgICAgICAgICAgIGVudHJ5LT5yYW5nZSA9IGdfbWFsbG9jIChyYW5nZS0+Rm9ybWF0U2l6ZSk7CiAgICAgICAgICAgIG1lbWNweSAoKGdwb2ludGVyKSBlbnRyeS0+cmFuZ2UsIHJhbmdlLCByYW5nZS0+Rm9ybWF0U2l6ZSk7CgogICAgICAgICAgICBpZiAoSXNFcXVhbEdVSUQgKCZyYW5nZS0+U3BlY2lmaWVyLCAmRk9STUFUX1ZpZGVvSW5mbykpIHsKICAgICAgICAgICAgICBLU19EQVRBUkFOR0VfVklERU8gKnZyID0gKEtTX0RBVEFSQU5HRV9WSURFTyAqKSBlbnRyeS0+cmFuZ2U7CgogICAgICAgICAgICAgIHNyY192c2NjID0gJnZyLT5Db25maWdDYXBzOwogICAgICAgICAgICAgIHNyY19mb3JtYXQgPSAmdnItPlZpZGVvSW5mb0hlYWRlcjsKCiAgICAgICAgICAgICAgZW50cnktPmZvcm1hdF9zaXplID0gc2l6ZW9mICh2ci0+VmlkZW9JbmZvSGVhZGVyKTsKICAgICAgICAgICAgICBlbnRyeS0+c2FtcGxlX3NpemUgPSB2ci0+VmlkZW9JbmZvSGVhZGVyLmJtaUhlYWRlci5iaVNpemVJbWFnZTsKICAgICAgICAgICAgfSBlbHNlIGlmIChJc0VxdWFsR1VJRCAoJnJhbmdlLT5TcGVjaWZpZXIsICZGT1JNQVRfVmlkZW9JbmZvMikpIHsKICAgICAgICAgICAgICBLU19EQVRBUkFOR0VfVklERU8yICp2ciA9IChLU19EQVRBUkFOR0VfVklERU8yICopIGVudHJ5LT5yYW5nZTsKCiAgICAgICAgICAgICAgc3JjX3ZzY2MgPSAmdnItPkNvbmZpZ0NhcHM7CiAgICAgICAgICAgICAgc3JjX2Zvcm1hdCA9ICZ2ci0+VmlkZW9JbmZvSGVhZGVyOwoKICAgICAgICAgICAgICBlbnRyeS0+Zm9ybWF0X3NpemUgPSBzaXplb2YgKHZyLT5WaWRlb0luZm9IZWFkZXIpOwogICAgICAgICAgICAgIGVudHJ5LT5zYW1wbGVfc2l6ZSA9IHZyLT5WaWRlb0luZm9IZWFkZXIuYm1pSGVhZGVyLmJpU2l6ZUltYWdlOwogICAgICAgICAgICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmcmFuZ2UtPlNwZWNpZmllciwgJkZPUk1BVF9NUEVHVmlkZW8pKSB7CiAgICAgICAgICAgICAgLyogVW50ZXN0ZWQgYW5kIHByb2JhYmx5IHdyb25nLi4uICovCiAgICAgICAgICAgICAgS1NfREFUQVJBTkdFX01QRUcxX1ZJREVPICp2ciA9CiAgICAgICAgICAgICAgICAgIChLU19EQVRBUkFOR0VfTVBFRzFfVklERU8gKikgZW50cnktPnJhbmdlOwoKICAgICAgICAgICAgICBzcmNfdnNjYyA9ICZ2ci0+Q29uZmlnQ2FwczsKICAgICAgICAgICAgICBzcmNfZm9ybWF0ID0gJnZyLT5WaWRlb0luZm9IZWFkZXI7CgogICAgICAgICAgICAgIGVudHJ5LT5mb3JtYXRfc2l6ZSA9IHNpemVvZiAodnItPlZpZGVvSW5mb0hlYWRlcik7CiAgICAgICAgICAgICAgZW50cnktPnNhbXBsZV9zaXplID0KICAgICAgICAgICAgICAgICAgdnItPlZpZGVvSW5mb0hlYWRlci5oZHIuYm1pSGVhZGVyLmJpU2l6ZUltYWdlOwogICAgICAgICAgICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmcmFuZ2UtPlNwZWNpZmllciwgJkZPUk1BVF9NUEVHMlZpZGVvKSkgewogICAgICAgICAgICAgIEtTX0RBVEFSQU5HRV9NUEVHMl9WSURFTyAqdnIgPQogICAgICAgICAgICAgICAgICAoS1NfREFUQVJBTkdFX01QRUcyX1ZJREVPICopIGVudHJ5LT5yYW5nZTsKICAgICAgICAgICAgICBzcmNfdnNjYyA9ICZ2ci0+Q29uZmlnQ2FwczsKICAgICAgICAgICAgICBzcmNfZm9ybWF0ID0gJnZyLT5WaWRlb0luZm9IZWFkZXI7CgogICAgICAgICAgICAgIGVudHJ5LT5mb3JtYXRfc2l6ZSA9IHNpemVvZiAodnItPlZpZGVvSW5mb0hlYWRlcik7CiAgICAgICAgICAgICAgZW50cnktPnNhbXBsZV9zaXplID0KICAgICAgICAgICAgICAgICAgdnItPlZpZGVvSW5mb0hlYWRlci5oZHIuYm1pSGVhZGVyLmJpU2l6ZUltYWdlOwogICAgICAgICAgICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmcmFuZ2UtPlNwZWNpZmllciwgJkZPUk1BVF9EdkluZm8pKSB7CiAgICAgICAgICAgICAgS1NfREFUQVJBTkdFX0RWVklERU8gKnZyID0gKEtTX0RBVEFSQU5HRV9EVlZJREVPICopIGVudHJ5LT5yYW5nZTsKCiAgICAgICAgICAgICAgc3JjX3ZzY2MgPSBOVUxMOwogICAgICAgICAgICAgIHNyY19mb3JtYXQgPSAmdnItPkRWVmlkZW9JbmZvOwoKICAgICAgICAgICAgICBlbnRyeS0+Zm9ybWF0X3NpemUgPSBzaXplb2YgKHZyLT5EVlZpZGVvSW5mbyk7CiAgICAgICAgICAgICAgZW50cnktPnNhbXBsZV9zaXplID0gdnItPkRhdGFSYW5nZS5TYW1wbGVTaXplOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgIGdjaGFyICpndWlkX3N0cjsKCiAgICAgICAgICAgICAgZ3VpZF9zdHIgPSBrc19ndWlkX3RvX3N0cmluZyAoJnJhbmdlLT5TcGVjaWZpZXIpOwogICAgICAgICAgICAgIEdTVF9ERUJVRyAoInBpblsldV06IGlnbm9yaW5nIHVua25vd24gc3BlY2lmaWVyIEdVSUQgJXMiLAogICAgICAgICAgICAgICAgICBwaW5faWQsIGd1aWRfc3RyKTsKICAgICAgICAgICAgICBnX2ZyZWUgKGd1aWRfc3RyKTsKCiAgICAgICAgICAgICAga3NfdmlkZW9fbWVkaWFfdHlwZV9mcmVlIChlbnRyeSk7CiAgICAgICAgICAgICAgZW50cnkgPSBOVUxMOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAoZW50cnkgIT0gTlVMTCkgewogICAgICAgICAgICAgIGdfYXNzZXJ0IChlbnRyeS0+c2FtcGxlX3NpemUgIT0gMCk7CgogICAgICAgICAgICAgIGlmIChzcmNfdnNjYyAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICBtZW1jcHkgKChncG9pbnRlcikgJiBlbnRyeS0+dnNjYywgc3JjX3ZzY2MsCiAgICAgICAgICAgICAgICAgICAgc2l6ZW9mIChlbnRyeS0+dnNjYykpOwogICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgZW50cnktPmZvcm1hdCA9IGdfbWFsbG9jIChlbnRyeS0+Zm9ybWF0X3NpemUpOwogICAgICAgICAgICAgIG1lbWNweSAoZW50cnktPmZvcm1hdCwgc3JjX2Zvcm1hdCwgZW50cnktPmZvcm1hdF9zaXplKTsKCiAgICAgICAgICAgICAgbWVkaWFfc3RydWN0dXJlID0KICAgICAgICAgICAgICAgICAga3NfdmlkZW9fZm9ybWF0X3RvX3N0cnVjdHVyZSAocmFuZ2UtPlN1YkZvcm1hdCwKICAgICAgICAgICAgICAgICAgcmFuZ2UtPlNwZWNpZmllcik7CgogICAgICAgICAgICAgIGlmIChtZWRpYV9zdHJ1Y3R1cmUgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgZ193YXJuaW5nICgia3NfdmlkZW9fZm9ybWF0X3RvX3N0cnVjdHVyZSByZXR1cm5lZCBOVUxMIik7CiAgICAgICAgICAgICAgICBrc192aWRlb19tZWRpYV90eXBlX2ZyZWUgKGVudHJ5KTsKICAgICAgICAgICAgICAgIGVudHJ5ID0gTlVMTDsKICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNyY192c2NjID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIGVudHJ5LT50cmFuc2xhdGVkX2NhcHMgPSBnc3RfY2Fwc19uZXdfZW1wdHkgKCk7CiAgICAgICAgICAgICAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChlbnRyeS0+dHJhbnNsYXRlZF9jYXBzLAogICAgICAgICAgICAgICAgICAgIG1lZGlhX3N0cnVjdHVyZSk7CiAgICAgICAgICAgICAgfSBlbHNlIGlmIChrc192aWRlb19hcHBlbmRfdmlkZW9fc3RyZWFtX2NmZ19maWVsZHMKICAgICAgICAgICAgICAgICAgKG1lZGlhX3N0cnVjdHVyZSwgJmVudHJ5LT52c2NjKSkgewogICAgICAgICAgICAgICAgZW50cnktPnRyYW5zbGF0ZWRfY2FwcyA9IGdzdF9jYXBzX25ld19lbXB0eSAoKTsKICAgICAgICAgICAgICAgIGdzdF9jYXBzX2FwcGVuZF9zdHJ1Y3R1cmUgKGVudHJ5LT50cmFuc2xhdGVkX2NhcHMsCiAgICAgICAgICAgICAgICAgICAgbWVkaWFfc3RydWN0dXJlKTsKICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgZ3N0X3N0cnVjdHVyZV9mcmVlIChtZWRpYV9zdHJ1Y3R1cmUpOwogICAgICAgICAgICAgICAga3NfdmlkZW9fbWVkaWFfdHlwZV9mcmVlIChlbnRyeSk7CiAgICAgICAgICAgICAgICBlbnRyeSA9IE5VTEw7CiAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICBpZiAoZW50cnkgIT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldCA9IGdfbGlzdF9wcmVwZW5kIChyZXQsIGVudHJ5KTsKICAgICAgICAgICAgfQogICAgICAgICAgfQoKICAgICAgICAgIC8qIFJFVklTSVQ6IEVhY2ggS1NEQVRBUkFOR0Ugc2hvdWxkIHN0YXJ0IG9uIGEgNjQtYml0IGJvdW5kYXJ5ICovCiAgICAgICAgICByYW5nZSA9IChLU0RBVEFSQU5HRSAqKSAoKChndWNoYXIgKikgcmFuZ2UpICsgcmFuZ2UtPkZvcm1hdFNpemUpOwogICAgICAgIH0KCiAgICAgICAgZ19mcmVlIChpdGVtcyk7CiAgICAgIH0KICAgIH0KICB9CgogIGlmIChyZXQgIT0gTlVMTCkgewogICAgcmV0ID0gZ19saXN0X3JldmVyc2UgKHJldCk7CiAgICByZXQgPSBrc192aWRlb19tZWRpYV90eXBlX2xpc3RfcmVtb3ZlX2R1cGxpY2F0ZXMgKHJldCk7CiAgfQoKYmVhY2g6CiAgcmV0dXJuIHJldDsKfQoKS1NQSU5fQ09OTkVDVCAqCmtzX3ZpZGVvX2NyZWF0ZV9waW5fY29ubl9mcm9tX21lZGlhX3R5cGUgKEtzVmlkZW9NZWRpYVR5cGUgKiBtZWRpYV90eXBlKQp7CiAgS1NQSU5fQ09OTkVDVCAqY29ubiA9IE5VTEw7CiAgS1NEQVRBRk9STUFUICpmb3JtYXQgPSBOVUxMOwogIGd1aW50OCAqdmloOwoKICBjb25uID0gZ19tYWxsb2MwIChzaXplb2YgKEtTUElOX0NPTk5FQ1QpICsgc2l6ZW9mIChLU0RBVEFGT1JNQVQpICsKICAgICAgbWVkaWFfdHlwZS0+Zm9ybWF0X3NpemUpOwoKICBjb25uLT5JbnRlcmZhY2UuU2V0ID0gS1NJTlRFUkZBQ0VTRVRJRF9TdGFuZGFyZDsKICBjb25uLT5JbnRlcmZhY2UuSWQgPSBLU0lOVEVSRkFDRV9TVEFOREFSRF9TVFJFQU1JTkc7CiAgY29ubi0+SW50ZXJmYWNlLkZsYWdzID0gMDsKCiAgY29ubi0+TWVkaXVtLlNldCA9IEtTTUVESVVNU0VUSURfU3RhbmRhcmQ7CiAgY29ubi0+TWVkaXVtLklkID0gS1NNRURJVU1fVFlQRV9BTllJTlNUQU5DRTsKICBjb25uLT5NZWRpdW0uRmxhZ3MgPSAwOwoKICBjb25uLT5QaW5JZCA9IG1lZGlhX3R5cGUtPnBpbl9pZDsKICBjb25uLT5QaW5Ub0hhbmRsZSA9IE5VTEw7CiAgY29ubi0+UHJpb3JpdHkuUHJpb3JpdHlDbGFzcyA9IEtTUFJJT1JJVFlfTk9STUFMOwogIGNvbm4tPlByaW9yaXR5LlByaW9yaXR5U3ViQ2xhc3MgPSBLU1BSSU9SSVRZX05PUk1BTDsKCiAgZm9ybWF0ID0gKEtTREFUQUZPUk1BVCAqKSAoY29ubiArIDEpOwogIG1lbWNweSAoZm9ybWF0LCBtZWRpYV90eXBlLT5yYW5nZSwgc2l6ZW9mIChLU0RBVEFGT1JNQVQpKTsKICBmb3JtYXQtPkZvcm1hdFNpemUgPSBzaXplb2YgKEtTREFUQUZPUk1BVCkgKyBtZWRpYV90eXBlLT5mb3JtYXRfc2l6ZTsKCiAgdmloID0gKGd1aW50OCAqKSAoZm9ybWF0ICsgMSk7CiAgbWVtY3B5ICh2aWgsIG1lZGlhX3R5cGUtPmZvcm1hdCwgbWVkaWFfdHlwZS0+Zm9ybWF0X3NpemUpOwoKICByZXR1cm4gY29ubjsKfQoKZ2Jvb2xlYW4Ka3NfdmlkZW9fZml4YXRlX21lZGlhX3R5cGUgKGNvbnN0IEtTREFUQVJBTkdFICogcmFuZ2UsCiAgICBndWludDggKiBmb3JtYXQsIGdpbnQgd2lkdGgsIGdpbnQgaGVpZ2h0LCBnaW50IGZwc19uLCBnaW50IGZwc19kKQp7CiAgS1NfREFUQVJBTkdFX1ZJREVPICp2cjsKICBLU19WSURFT0lORk9IRUFERVIgKnZpaDsKICBLU19CSVRNQVBJTkZPSEVBREVSICpiaWg7CiAgRFdPUkQgZHdSYXRlOwoKICBnX3JldHVybl92YWxfaWZfZmFpbCAoZm9ybWF0ICE9IE5VTEwsIEZBTFNFKTsKCiAgaWYgKElzRXF1YWxHVUlEICgmcmFuZ2UtPlNwZWNpZmllciwgJkZPUk1BVF9WaWRlb0luZm8pKSB7CiAgICBiaWggPSAmKChLU19WSURFT0lORk9IRUFERVIgKikgZm9ybWF0KS0+Ym1pSGVhZGVyOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZyYW5nZS0+U3BlY2lmaWVyLCAmRk9STUFUX1ZpZGVvSW5mbzIpKSB7CiAgICBiaWggPSAmKChLU19WSURFT0lORk9IRUFERVIyICopIGZvcm1hdCktPmJtaUhlYWRlcjsKICB9IGVsc2UgaWYgKElzRXF1YWxHVUlEICgmcmFuZ2UtPlNwZWNpZmllciwgJkZPUk1BVF9NUEVHVmlkZW8pKSB7CiAgICBiaWggPSAmKChLU19NUEVHMVZJREVPSU5GTyAqKSBmb3JtYXQpLT5oZHIuYm1pSGVhZGVyOwogIH0gZWxzZSBpZiAoSXNFcXVhbEdVSUQgKCZyYW5nZS0+U3BlY2lmaWVyLCAmRk9STUFUX01QRUcyVmlkZW8pKSB7CiAgICBiaWggPSAmKChLU19NUEVHVklERU9JTkZPMiAqKSBmb3JtYXQpLT5oZHIuYm1pSGVhZGVyOwogIH0gZWxzZSB7CiAgICByZXR1cm4gRkFMU0U7CiAgfQoKICAvKiBUaGVzZSBmb3JtYXRzJyBzdHJ1Y3R1cmVzIHNoYXJlIHRoZSBtb3N0IGJhc2ljIHN0dWZmICovCiAgdnIgPSAoS1NfREFUQVJBTkdFX1ZJREVPICopIHJhbmdlOwogIHZpaCA9IChLU19WSURFT0lORk9IRUFERVIgKikgZm9ybWF0OwoKICAvKiBGSVhNRTogTmVlZCB0byBmaWd1cmUgb3V0IGhvdyB0byBwcm9wZXJseSBoYW5kbGUgcmFuZ2VzICovCiAgaWYgKGJpaC0+YmlXaWR0aCAhPSB3aWR0aCB8fCBiaWgtPmJpSGVpZ2h0ICE9IGhlaWdodCkKICAgIHJldHVybiBGQUxTRTsKCiAgLyogRnJhbWVyYXRlLCBjbGFtcGVkIGJlY2F1c2Ugb2YgZnJhY3Rpb24gY29udmVyc2lvbiByb3VuZGluZyBlcnJvcnMgKi8KICB2aWgtPkF2Z1RpbWVQZXJGcmFtZSA9CiAgICAgIGdzdF91dGlsX3VpbnQ2NF9zY2FsZV9pbnRfcm91bmQgKE5BTk9TRUNPTkRTLCBmcHNfZCwgZnBzX24pOwogIHZpaC0+QXZnVGltZVBlckZyYW1lID0KICAgICAgTUFYICh2aWgtPkF2Z1RpbWVQZXJGcmFtZSwgdnItPkNvbmZpZ0NhcHMuTWluRnJhbWVJbnRlcnZhbCk7CiAgdmloLT5BdmdUaW1lUGVyRnJhbWUgPQogICAgICBNSU4gKHZpaC0+QXZnVGltZVBlckZyYW1lLCB2ci0+Q29uZmlnQ2Fwcy5NYXhGcmFtZUludGVydmFsKTsKCiAgLyogQml0cmF0ZSwgY2xhbXBlZCBmb3IgdGhlIHNhbWUgcmVhc29uIGFzIGZyYW1lcmF0ZSAqLwogIGR3UmF0ZSA9ICh3aWR0aCAqIGhlaWdodCAqIGZwc19uKSAvIGZwc19kOwogIHZpaC0+ZHdCaXRSYXRlID0gZHdSYXRlICogYmloLT5iaUJpdENvdW50OwogIHZpaC0+ZHdCaXRSYXRlID0gTUFYICh2aWgtPmR3Qml0UmF0ZSwgdnItPkNvbmZpZ0NhcHMuTWluQml0c1BlclNlY29uZCk7CiAgdmloLT5kd0JpdFJhdGUgPSBNSU4gKHZpaC0+ZHdCaXRSYXRlLCB2ci0+Q29uZmlnQ2Fwcy5NYXhCaXRzUGVyU2Vjb25kKTsKCiAgcmV0dXJuIFRSVUU7Cn0KCnN0YXRpYyBHc3RTdHJ1Y3R1cmUgKgprc192aWRlb19hcHBlbmRfdmFyX3ZpZGVvX2ZpZWxkcyAoR3N0U3RydWN0dXJlICogc3RydWN0dXJlKQp7CiAgaWYgKHN0cnVjdHVyZSkgewogICAgZ3N0X3N0cnVjdHVyZV9zZXQgKHN0cnVjdHVyZSwKICAgICAgICAid2lkdGgiLCBHU1RfVFlQRV9JTlRfUkFOR0UsIDEsIEdfTUFYSU5ULAogICAgICAgICJoZWlnaHQiLCBHU1RfVFlQRV9JTlRfUkFOR0UsIDEsIEdfTUFYSU5ULAogICAgICAgICJmcmFtZXJhdGUiLCBHU1RfVFlQRV9GUkFDVElPTl9SQU5HRSwgMCwgMSwgR19NQVhJTlQsIDEsIE5VTEwpOwogIH0KCiAgcmV0dXJuIHN0cnVjdHVyZTsKfQoKR3N0Q2FwcyAqCmtzX3ZpZGVvX2dldF9hbGxfY2FwcyAodm9pZCkKewogIHN0YXRpYyBHc3RDYXBzICpjYXBzID0gTlVMTDsKCiAgaWYgKGNhcHMgPT0gTlVMTCkgewogICAgR3N0U3RydWN0dXJlICpzdHJ1Y3R1cmU7CiAgICBjYXBzID0gZ3N0X2NhcHNfbmV3X2VtcHR5ICgpOwoKICAgIC8qIGZyb20gV2luZG93cyBTREsgNi4wIHV1aWRzLmggKi8KICAgIC8qIFJHQiBmb3JtYXRzICovCiAgICBzdHJ1Y3R1cmUgPQogICAgICAgIGtzX3ZpZGVvX2FwcGVuZF92YXJfdmlkZW9fZmllbGRzIChrc192aWRlb19mb3JtYXRfdG9fc3RydWN0dXJlCiAgICAgICAgKE1FRElBU1VCVFlQRV9SR0I1NTUsIEZPUk1BVF9WaWRlb0luZm8pKTsKICAgIGdzdF9jYXBzX2FwcGVuZF9zdHJ1Y3R1cmUgKGNhcHMsIHN0cnVjdHVyZSk7CgogICAgc3RydWN0dXJlID0KICAgICAgICBrc192aWRlb19hcHBlbmRfdmFyX3ZpZGVvX2ZpZWxkcyAoa3NfdmlkZW9fZm9ybWF0X3RvX3N0cnVjdHVyZQogICAgICAgIChNRURJQVNVQlRZUEVfUkdCNTY1LCBGT1JNQVRfVmlkZW9JbmZvKSk7CiAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChjYXBzLCBzdHJ1Y3R1cmUpOwoKICAgIHN0cnVjdHVyZSA9CiAgICAgICAga3NfdmlkZW9fYXBwZW5kX3Zhcl92aWRlb19maWVsZHMgKGtzX3ZpZGVvX2Zvcm1hdF90b19zdHJ1Y3R1cmUKICAgICAgICAoTUVESUFTVUJUWVBFX1JHQjI0LCBGT1JNQVRfVmlkZW9JbmZvKSk7CiAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChjYXBzLCBzdHJ1Y3R1cmUpOwoKICAgIHN0cnVjdHVyZSA9CiAgICAgICAga3NfdmlkZW9fYXBwZW5kX3Zhcl92aWRlb19maWVsZHMgKGtzX3ZpZGVvX2Zvcm1hdF90b19zdHJ1Y3R1cmUKICAgICAgICAoTUVESUFTVUJUWVBFX1JHQjMyLCBGT1JNQVRfVmlkZW9JbmZvKSk7CiAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChjYXBzLCBzdHJ1Y3R1cmUpOwoKICAgIC8qIFlVViBmb3JtYXRzICovCiAgICBzdHJ1Y3R1cmUgPQogICAgICAgIGtzX3ZpZGVvX2FwcGVuZF92YXJfdmlkZW9fZmllbGRzIChnc3Rfc3RydWN0dXJlX25ld19lbXB0eQogICAgICAgICgidmlkZW8veC1yYXciKSk7CiAgICBnc3RfY2Fwc19hcHBlbmRfc3RydWN0dXJlIChjYXBzLCBzdHJ1Y3R1cmUpOwoKICAgIC8qIE90aGVyIGZvcm1hdHMgKi8KICAgIHN0cnVjdHVyZSA9CiAgICAgICAga3NfdmlkZW9fYXBwZW5kX3Zhcl92aWRlb19maWVsZHMgKGtzX3ZpZGVvX2Zvcm1hdF90b19zdHJ1Y3R1cmUKICAgICAgICAoTUVESUFTVUJUWVBFX01KUEcsIEZPUk1BVF9WaWRlb0luZm8pKTsKICAgIGdzdF9jYXBzX2FwcGVuZF9zdHJ1Y3R1cmUgKGNhcHMsIHN0cnVjdHVyZSk7CgogICAgc3RydWN0dXJlID0KICAgICAgICBrc192aWRlb19hcHBlbmRfdmFyX3ZpZGVvX2ZpZWxkcyAoa3NfdmlkZW9fZm9ybWF0X3RvX3N0cnVjdHVyZQogICAgICAgIChNRURJQVNVQlRZUEVfZHZzZCwgRk9STUFUX1ZpZGVvSW5mbykpOwogICAgZ3N0X2NhcHNfYXBwZW5kX3N0cnVjdHVyZSAoY2Fwcywgc3RydWN0dXJlKTsKCiAgICBzdHJ1Y3R1cmUgPSAgICAgICAgICAgICAgICAgLyogbm8gdmFyaWFibGUgdmlkZW8gZmllbGRzICh3aWR0aCwgaGVpZ2h0LCBmcmFtZXJhdGUpICovCiAgICAgICAga3NfdmlkZW9fZm9ybWF0X3RvX3N0cnVjdHVyZSAoTUVESUFTVUJUWVBFX2R2c2QsIEZPUk1BVF9EdkluZm8pOwogICAgZ3N0X2NhcHNfYXBwZW5kX3N0cnVjdHVyZSAoY2Fwcywgc3RydWN0dXJlKTsKICB9CgogIHJldHVybiBjYXBzOwp9Cg==