LyoKICogIENvcHlyaWdodAkxOTk0CUVyaWMgWW91bmRhbGUgJiBFcmlrIEJvcwogKiAgQ29weXJpZ2h0CTE5OTUJTWFydGluIHZvbiBM9ndpcwogKiAgQ29weXJpZ2h0ICAgMTk5Ni05OCBNYXJjdXMgTWVpc3NuZXIKICoKICoJYmFzZWQgb24gRXJpYyBZb3VuZGFsZSdzIHBlLXRlc3QgYW5kOgogKglmdHAubWljcm9zb2Z0LmNvbTovZGV2ZWxvcHIvTVNETi9PY3RDRC9QRUZJTEUuWklQCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KLyogTm90ZXM6CiAqIEJlZm9yZSB5b3Ugc3RhcnQgY2hhbmdpbmcgc29tZXRoaW5nIGluIHRoaXMgZmlsZSBiZSBhd2FyZSBvZiB0aGUgZm9sbG93aW5nOgogKgogKiAtIFRoZXJlIGFyZSBzZXZlcmFsIGZ1bmN0aW9ucyBjYWxsZWQgcmVjdXJzaXZlbHkuIEluIGEgdmVyeSBzdWJ0bGUgYW5kCiAqICAgb2JzY3VyZSB3YXkuIERMTHMgY2FuIHJlZmVyZW5jZSBlYWNoIG90aGVyIHJlY3Vyc2l2ZWx5IGV0Yy4KICogLSBJZiB5b3Ugd2FudCB0byBlbmhhbmNlLCBzcGVlZCB1cCBvciBjbGVhbiB1cCBzb21ldGhpbmcgaW4gaGVyZSwgdGhpbmsKICogICB0d2ljZSBXSFkgaXQgaXMgaW1wbGVtZW50ZWQgaW4gdGhhdCBzdHJhbmdlIHdheS4gVGhlcmUgaXMgdXN1YWxseSBhIHJlYXNvbi4KICogICBUaG91Z2ggc29tZXRpbWVzIGl0IG1pZ2h0IGp1c3QgYmUgbGF6eW5lc3MgOykKICogLSBJbiBQRV9NYXBJbWFnZSwgcmlnaHQgYmVmb3JlIFBFX2ZpeHVwX2ltcG9ydHMoKSBhbGwgZXh0ZXJuYWwgYW5kIGludGVybmFsCiAqICAgc3RhdGUgTVVTVCBiZSBjb3JyZWN0IHNpbmNlIHRoaXMgZnVuY3Rpb24gY2FuIGJlIGNhbGxlZCB3aXRoIHRoZSBTQU1FIGltYWdlCiAqICAgQUdBSU4uIChUaGF0cyByZWN1cnNpb24gZm9yIHlvdS4pIFRoYXQgbWVhbnMgTU9EUkVGLm1vZHVsZSBhbmQKICogICBORV9NT0RVTEUubW9kdWxlMzIuCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaWZkZWYgSEFWRV9TWVNfTU1BTl9ICiNpbmNsdWRlIDxzeXMvbW1hbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luYmFzZS5oIgojaW5jbHVkZSAid2luZXJyb3IuaCIKI2luY2x1ZGUgInNub29wLmgiCiNpbmNsdWRlICJ3aW5lL3NlcnZlci5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgojaW5jbHVkZSAibnRkbGxfbWlzYy5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwod2luMzIpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChtb2R1bGUpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChyZWxheSk7CgoKLyogY29udmVydCBQRSBpbWFnZSBWaXJ0dWFsQWRkcmVzcyB0byBSZWFsIEFkZHJlc3MgKi8KaW5saW5lIHN0YXRpYyB2b2lkICpnZXRfcnZhKCBITU9EVUxFIG1vZHVsZSwgRFdPUkQgdmEgKQp7CiAgICByZXR1cm4gKHZvaWQgKikoKGNoYXIgKiltb2R1bGUgKyB2YSk7Cn0KCiNkZWZpbmUgQWRqdXN0UHRyKHB0cixkZWx0YSkgKChjaGFyICopKHB0cikgKyAoZGVsdGEpKQoKdm9pZCBkdW1wX2V4cG9ydHMoIEhNT0RVTEUgaE1vZHVsZSApCnsKICBjaGFyCQkqTW9kdWxlOwogIGludAkJaSwgajsKICBXT1JECQkqb3JkaW5hbDsKICBEV09SRAkJKmZ1bmN0aW9uLCpmdW5jdGlvbnM7CiAgRFdPUkQgKm5hbWU7CiAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0czsKICBEV09SRCBydmFfc3RhcnQsIHNpemU7CgogIHBlX2V4cG9ydHMgPSBSdGxJbWFnZURpcmVjdG9yeUVudHJ5VG9EYXRhKCBoTW9kdWxlLCBUUlVFLCBJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JULCAmc2l6ZSApOwogIHJ2YV9zdGFydCA9IChjaGFyICopcGVfZXhwb3J0cyAtIChjaGFyICopaE1vZHVsZTsKCiAgTW9kdWxlID0gZ2V0X3J2YShoTW9kdWxlLCBwZV9leHBvcnRzLT5OYW1lKTsKICBEUFJJTlRGKCIqKioqKioqRVhQT1JUIERBVEEqKioqKioqXG4iKTsKICBEUFJJTlRGKCJNb2R1bGUgbmFtZSBpcyAlcywgJWxkIGZ1bmN0aW9ucywgJWxkIG5hbWVzXG4iLAogICAgICAgICAgTW9kdWxlLCBwZV9leHBvcnRzLT5OdW1iZXJPZkZ1bmN0aW9ucywgcGVfZXhwb3J0cy0+TnVtYmVyT2ZOYW1lcyk7CgogIG9yZGluYWwgPSBnZXRfcnZhKGhNb2R1bGUsIHBlX2V4cG9ydHMtPkFkZHJlc3NPZk5hbWVPcmRpbmFscyk7CiAgZnVuY3Rpb25zID0gZnVuY3Rpb24gPSBnZXRfcnZhKGhNb2R1bGUsIHBlX2V4cG9ydHMtPkFkZHJlc3NPZkZ1bmN0aW9ucyk7CiAgbmFtZSA9IGdldF9ydmEoaE1vZHVsZSwgcGVfZXhwb3J0cy0+QWRkcmVzc09mTmFtZXMpOwoKICBEUFJJTlRGKCIgT3JkICAgIFJWQSAgICAgQWRkciAgIE5hbWVcbiIgKTsKICBmb3IgKGk9MDtpPHBlX2V4cG9ydHMtPk51bWJlck9mRnVuY3Rpb25zO2krKywgZnVuY3Rpb24rKykKICB7CiAgICAgIGlmICghKmZ1bmN0aW9uKSBjb250aW51ZTsgIC8qIE5vIHN1Y2ggZnVuY3Rpb24gKi8KICAgICAgRFBSSU5URiggIiU0bGQgJTA4bHggJXAiLCBpICsgcGVfZXhwb3J0cy0+QmFzZSwgKmZ1bmN0aW9uLCBnZXRfcnZhKGhNb2R1bGUsICpmdW5jdGlvbikgKTsKICAgICAgLyogQ2hlY2sgaWYgd2UgaGF2ZSBhIG5hbWUgZm9yIGl0ICovCiAgICAgIGZvciAoaiA9IDA7IGogPCBwZV9leHBvcnRzLT5OdW1iZXJPZk5hbWVzOyBqKyspCiAgICAgICAgICBpZiAob3JkaW5hbFtqXSA9PSBpKQogICAgICAgICAgewogICAgICAgICAgICAgIERQUklOVEYoICIgICVzIiwgKGNoYXIqKWdldF9ydmEoaE1vZHVsZSwgbmFtZVtqXSkgKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIH0KICAgICAgaWYgKCgqZnVuY3Rpb24gPj0gcnZhX3N0YXJ0KSAmJiAoKmZ1bmN0aW9uIDw9IHJ2YV9zdGFydCArIHNpemUpKQoJICBEUFJJTlRGKCIgKGZvcndhcmRlZCAtPiAlcykiLCAoY2hhciAqKWdldF9ydmEoaE1vZHVsZSwgKmZ1bmN0aW9uKSk7CiAgICAgIERQUklOVEYoIlxuIik7CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJCVBFX0xvYWRJbWFnZQogKiBMb2FkIG9uZSBQRSBmb3JtYXQgRExML0VYRSBpbnRvIG1lbW9yeQogKgogKiBVbmx1Y2tpbHkgd2UgY2FuJ3QganVzdCBtbWFwIHRoZSBzZWN0aW9ucyB3aGVyZSB3ZSB3YW50IHRoZW0sIGZvcgogKiAoYXQgbGVhc3QpIExpbnV4IGRvZXMgb25seSBzdXBwb3J0IG9mZnNldHMgd2hpY2ggYXJlIHBhZ2UtYWxpZ25lZC4KICoKICogQlVUIHdlIGhhdmUgdG8gbWFwIHRoZSB3aG9sZSBpbWFnZSBhbnl3YXksIGZvciBXaW4zMiBwcm9ncmFtcyBzb21ldGltZXMKICogd2FudCB0byBhY2Nlc3MgdGhlbS4gKEhNT0RVTEUgcG9pbnRzIHRvIHRoZSBzdGFydCBvZiBpdCkKICovCkhNT0RVTEUgUEVfTG9hZEltYWdlKCBIQU5ETEUgaEZpbGUsIExQQ1NUUiBmaWxlbmFtZSwgRFdPUkQgZmxhZ3MgKQp7CiAgICBJTUFHRV9OVF9IRUFERVJTICpudDsKICAgIEhNT0RVTEUgaE1vZHVsZTsKICAgIEhBTkRMRSBtYXBwaW5nOwogICAgdm9pZCAqYmFzZSA9IE5VTEw7CiAgICBPQkpFQ1RfQVRUUklCVVRFUyBhdHRyOwogICAgTEFSR0VfSU5URUdFUiBsZ19pbnQ7CiAgICBEV09SRCBsZW4gPSAwOwogICAgTlRTVEFUVVMgbnRzOwoKICAgIFRSQUNFXyhtb2R1bGUpKCAibG9hZGluZyAlc1xuIiwgZmlsZW5hbWUgKTsKCiAgICBhdHRyLkxlbmd0aCAgICAgICAgICAgICAgICAgICA9IHNpemVvZihhdHRyKTsKICAgIGF0dHIuUm9vdERpcmVjdG9yeSAgICAgICAgICAgID0gMDsKICAgIGF0dHIuT2JqZWN0TmFtZSAgICAgICAgICAgICAgID0gTlVMTDsKICAgIGF0dHIuQXR0cmlidXRlcyAgICAgICAgICAgICAgID0gMDsKICAgIGF0dHIuU2VjdXJpdHlEZXNjcmlwdG9yICAgICAgID0gTlVMTDsKICAgIGF0dHIuU2VjdXJpdHlRdWFsaXR5T2ZTZXJ2aWNlID0gTlVMTDsKICAgIAogICAgbGdfaW50LlF1YWRQYXJ0ID0gMDsKCiAgICBpZiAoTnRDcmVhdGVTZWN0aW9uKCAmbWFwcGluZywgCiAgICAgICAgICAgICAgICAgICAgICAgICBTVEFOREFSRF9SSUdIVFNfUkVRVUlSRUQgfCBTRUNUSU9OX1FVRVJZIHwgU0VDVElPTl9NQVBfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICZhdHRyLCAmbGdfaW50LCAwLCBTRUNfSU1BR0UsIGhGaWxlICkgIT0gU1RBVFVTX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIDA7CgogICAgbnRzID0gTnRNYXBWaWV3T2ZTZWN0aW9uKCBtYXBwaW5nLCBHZXRDdXJyZW50UHJvY2VzcygpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYmFzZSwgMCwgMCwgJmxnX2ludCwgJmxlbiwgVmlld1NoYXJlLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQQUdFX1JFQURPTkxZICk7CiAgICAKICAgIE50Q2xvc2UoIG1hcHBpbmcgKTsKICAgIGlmIChudHMgIT0gU1RBVFVTX1NVQ0NFU1MpIHJldHVybiAwOwoKICAgIC8qIHZpcnVzIGNoZWNrICovCgogICAgaE1vZHVsZSA9IChITU9EVUxFKWJhc2U7CiAgICBudCA9IFJ0bEltYWdlTnRIZWFkZXIoIGhNb2R1bGUgKTsKCiAgICBpZiAobnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQpCiAgICB7CiAgICAgICAgaWYgKCFSdGxJbWFnZVJ2YVRvU2VjdGlvbiggbnQsIGhNb2R1bGUsIG50LT5PcHRpb25hbEhlYWRlci5BZGRyZXNzT2ZFbnRyeVBvaW50ICkpCiAgICAgICAgICAgIE1FU1NBR0UoIlZJUlVTIFdBUk5JTkc6IFBFIG1vZHVsZSBoYXMgYW4gaW52YWxpZCBlbnRyeXBvaW50ICgweCUwOGx4KSAiCiAgICAgICAgICAgICAgICAgICAgIm91dHNpZGUgYWxsIHNlY3Rpb25zIChwb3NzaWJseSBpbmZlY3RlZCBieSBUY2hlcm5vYnlsL1NwYWNlRmlsbGVyIHZpcnVzKSFcbiIsCiAgICAgICAgICAgICAgICAgICAgbnQtPk9wdGlvbmFsSGVhZGVyLkFkZHJlc3NPZkVudHJ5UG9pbnQgKTsKICAgIH0KCiAgICByZXR1cm4gaE1vZHVsZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgICAgICAgIFBFX0NyZWF0ZU1vZHVsZQogKgogKiBDcmVhdGUgV0lORV9NT0RSRUYgc3RydWN0dXJlIGZvciBsb2FkZWQgSE1PRFVMRSwgbGluayBpdCBpbnRvCiAqIHByb2Nlc3MgbW9kcmVmX2xpc3QsIGFuZCBmaXh1cCBhbGwgaW1wb3J0cy4KICoKICogTm90ZTogaE1vZHVsZSBtdXN0IHBvaW50IHRvIGEgY29ycmVjdGx5IGFsbG9jYXRlZCBQRSBpbWFnZSwKICogICAgICAgd2l0aCBiYXNlIHJlbG9jYXRpb25zIGFwcGxpZWQ7IHRoZSAxNi1iaXQgZHVtbXkgbW9kdWxlCiAqICAgICAgIGFzc29jaWF0ZWQgdG8gaE1vZHVsZSBtdXN0IGFscmVhZHkgZXhpc3QuCiAqCiAqIE5vdGU6IFRoaXMgcm91dGluZSBtdXN0IGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIGNvbnRleHQgb2YgdGhlCiAqICAgICAgIHByb2Nlc3MgdGhhdCBpcyB0byBvd24gdGhlIG1vZHVsZSB0byBiZSBjcmVhdGVkLgogKgogKiBOb3RlOiBBc3N1bWVzIHRoYXQgdGhlIHByb2Nlc3MgY3JpdGljYWwgc2VjdGlvbiBpcyBoZWxkCiAqLwpXSU5FX01PRFJFRiAqUEVfQ3JlYXRlTW9kdWxlKCBITU9EVUxFIGhNb2R1bGUsIExQQ1NUUiBmaWxlbmFtZSwgRFdPUkQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEhBTkRMRSBoRmlsZSwgQk9PTCBidWlsdGluICkKewogICAgSU1BR0VfTlRfSEVBREVSUyAqbnQ7CiAgICBJTUFHRV9EQVRBX0RJUkVDVE9SWSAqZGlyOwogICAgSU1BR0VfRVhQT1JUX0RJUkVDVE9SWSAqcGVfZXhwb3J0ID0gTlVMTDsKICAgIFdJTkVfTU9EUkVGICp3bTsKCiAgICAvKiBSZXRyaWV2ZSBEYXRhRGlyZWN0b3J5IGVudHJpZXMgKi8KCiAgICBudCA9IFJ0bEltYWdlTnRIZWFkZXIoaE1vZHVsZSk7CiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhQT1JUOwogICAgaWYgKGRpci0+U2l6ZSkgcGVfZXhwb3J0ID0gZ2V0X3J2YShoTW9kdWxlLCBkaXItPlZpcnR1YWxBZGRyZXNzKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeStJTUFHRV9ESVJFQ1RPUllfRU5UUllfRVhDRVBUSU9OOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkV4Y2VwdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9TRUNVUklUWTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJTZWN1cml0eSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9CQVNFUkVMT0MgaGFuZGxlZCBpbiBQRV9Mb2FkSW1hZ2UgKi8KICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUJVRyBoYW5kbGVkIGJ5IGRlYnVnZ2VyICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0dMT0JBTFBUUjsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJHbG9iYWwgUG9pbnRlciAoTUlQUykgaWdub3JlZFxuIiApOwoKICAgIC8qIElNQUdFX0RJUkVDVE9SWV9FTlRSWV9UTFMgaGFuZGxlZCBpbiBQRV9UbHNJbml0ICovCgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0xPQURfQ09ORklHOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIkxvYWQgQ29uZmlndXJhdGlvbiBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9CT1VORF9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKSBUUkFDRSgiQm91bmQgSW1wb3J0IGRpcmVjdG9yeSBpZ25vcmVkXG4iICk7CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0lBVDsKICAgIGlmIChkaXItPlNpemUpIFRSQUNFKCJJbXBvcnQgQWRkcmVzcyBUYWJsZSBkaXJlY3RvcnkgaWdub3JlZFxuIiApOwoKICAgIGRpciA9IG50LT5PcHRpb25hbEhlYWRlci5EYXRhRGlyZWN0b3J5K0lNQUdFX0RJUkVDVE9SWV9FTlRSWV9ERUxBWV9JTVBPUlQ7CiAgICBpZiAoZGlyLT5TaXplKQogICAgewogICAgICAgIFRSQUNFKCJEZWxheWVkIGltcG9ydCwgc3R1YiBjYWxscyBMb2FkTGlicmFyeVxuIiApOwogICAgICAgIC8qCiAgICAgICAgICogTm90aGluZyB0byBkbyBoZXJlLgogICAgICAgICAqLwoKI2lmZGVmIEltZ0RlbGF5RGVzY3IKICAgICAgICAvKgogICAgICAgICAqIFRoaXMgY29kZSBpcyB1c2VmdWwgdG8gb2JzZXJ2ZSB3aGF0IHRoZSBoZWNrIGlzIGdvaW5nIG9uLgogICAgICAgICAqLwogICAgICAgIHsKICAgICAgICAgICAgSW1nRGVsYXlEZXNjciAqcGVfZGVsYXkgPSBOVUxMOwogICAgICAgICAgICBwZV9kZWxheSA9IGdldF9ydmEoaE1vZHVsZSwgZGlyLT5WaXJ0dWFsQWRkcmVzcyk7CiAgICAgICAgICAgIFRSQUNFKCJwZV9kZWxheS0+Z3JBdHRycyA9ICUwOHhcbiIsIHBlX2RlbGF5LT5nckF0dHJzKTsKICAgICAgICAgICAgVFJBQ0UoInBlX2RlbGF5LT5zek5hbWUgPSAlc1xuIiwgcGVfZGVsYXktPnN6TmFtZSk7CiAgICAgICAgICAgIFRSQUNFKCJwZV9kZWxheS0+cGhtb2QgPSAlMDh4XG4iLCBwZV9kZWxheS0+cGhtb2QpOwogICAgICAgICAgICBUUkFDRSgicGVfZGVsYXktPnBJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cElBVCk7CiAgICAgICAgICAgIFRSQUNFKCJwZV9kZWxheS0+cElOVCA9ICUwOHhcbiIsIHBlX2RlbGF5LT5wSU5UKTsKICAgICAgICAgICAgVFJBQ0UoInBlX2RlbGF5LT5wQm91bmRJQVQgPSAlMDh4XG4iLCBwZV9kZWxheS0+cEJvdW5kSUFUKTsKICAgICAgICAgICAgVFJBQ0UoInBlX2RlbGF5LT5wVW5sb2FkSUFUID0gJTA4eFxuIiwgcGVfZGVsYXktPnBVbmxvYWRJQVQpOwogICAgICAgICAgICBUUkFDRSgicGVfZGVsYXktPmR3VGltZVN0YW1wID0gJTA4eFxuIiwgcGVfZGVsYXktPmR3VGltZVN0YW1wKTsKICAgICAgICB9CiNlbmRpZiAvKiBJbWdEZWxheURlc2NyICovCiAgICB9CgogICAgZGlyID0gbnQtPk9wdGlvbmFsSGVhZGVyLkRhdGFEaXJlY3RvcnkrSU1BR0VfRElSRUNUT1JZX0VOVFJZX0NPTV9ERVNDUklQVE9SOwogICAgaWYgKGRpci0+U2l6ZSkgRklYTUUoIlVua25vd24gZGlyZWN0b3J5IDE0IGlnbm9yZWRcbiIgKTsKCiAgICBkaXIgPSBudC0+T3B0aW9uYWxIZWFkZXIuRGF0YURpcmVjdG9yeSsxNTsKICAgIGlmIChkaXItPlNpemUpIEZJWE1FKCJVbmtub3duIGRpcmVjdG9yeSAxNSBpZ25vcmVkXG4iICk7CgogICAgLyogQWxsb2NhdGUgYW5kIGZpbGwgV0lORV9NT0RSRUYgKi8KCiAgICBpZiAoISh3bSA9IE1PRFVMRV9BbGxvY01vZFJlZiggaE1vZHVsZSwgZmlsZW5hbWUgKSkpIHJldHVybiBOVUxMOwoKICAgIGlmICggYnVpbHRpbiApCiAgICAgICAgd20tPmxkci5GbGFncyB8PSBMRFJfV0lORV9JTlRFUk5BTDsKICAgIGVsc2UgaWYgKCBmbGFncyAmIERPTlRfUkVTT0xWRV9ETExfUkVGRVJFTkNFUyApCiAgICAgICAgd20tPmxkci5GbGFncyB8PSBMRFJfRE9OVF9SRVNPTFZFX1JFRlM7CgogICAgLyogRHVtcCBFeHBvcnRzICovCgogICAgaWYgKHBlX2V4cG9ydCAmJiBUUkFDRV9PTih3aW4zMikpCiAgICAgICAgZHVtcF9leHBvcnRzKCBoTW9kdWxlICk7CgogICAgLyogRml4dXAgSW1wb3J0cyAqLwoKICAgIGlmICghKHdtLT5sZHIuRmxhZ3MgJiBMRFJfRE9OVF9SRVNPTFZFX1JFRlMpICYmCiAgICAgICAgUEVfZml4dXBfaW1wb3J0cyggd20gKSkKICAgIHsKICAgICAgICAvKiB0aGUgbW9kdWxlIGhhcyBvbmx5IGJlIGluc2VydGVkIGluIHRoZSBsb2FkICYgbWVtb3J5IG9yZGVyIGxpc3RzICovCiAgICAgICAgUmVtb3ZlRW50cnlMaXN0KCZ3bS0+bGRyLkluTG9hZE9yZGVyTW9kdWxlTGlzdCk7CiAgICAgICAgUmVtb3ZlRW50cnlMaXN0KCZ3bS0+bGRyLkluTWVtb3J5T3JkZXJNb2R1bGVMaXN0KTsKCiAgICAgICAgLyogRklYTUU6IHRoZXJlIGFyZSBzZXZlcmFsIG1vcmUgZGFuZ2xpbmcgcmVmZXJlbmNlcwogICAgICAgICAqIGxlZnQuIEluY2x1ZGluZyBkbGxzIGxvYWRlZCBieSB0aGlzIGRsbCBiZWZvcmUgdGhlCiAgICAgICAgICogZmFpbGVkIG9uZS4gVW5yb2xsaW5nIGlzIHJhdGhlciBkaWZmaWN1bHQgd2l0aCB0aGUKICAgICAgICAgKiBjdXJyZW50IHN0cnVjdHVyZSBhbmQgd2UgY2FuIGxlYXZlIHRoZW0gbHlpbmcKICAgICAgICAgKiBhcm91bmQgd2l0aCBubyBwcm9ibGVtcywgc28gd2UgZG9uJ3QgY2FyZS4KICAgICAgICAgKiBBcyB0aGVzZSBtaWdodCByZWZlcmVuY2Ugb3VyIHdtLCB3ZSBkb24ndCBmcmVlIGl0LgogICAgICAgICAqLwogICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoIWJ1aWx0aW4gJiYgcGVfZXhwb3J0KQogICAgICAgIFNOT09QX1JlZ2lzdGVyRExMKCBoTW9kdWxlLCB3bS0+bW9kbmFtZSwgcGVfZXhwb3J0LT5CYXNlLCBwZV9leHBvcnQtPk51bWJlck9mRnVuY3Rpb25zICk7CgogICAgLyogU2VuZCBETEwgbG9hZCBldmVudCAqLwogICAgLyogd2UgZG9uJ3QgbmVlZCB0byBzZW5kIGEgZGxsIGV2ZW50IGZvciB0aGUgbWFpbiBleGUgKi8KCiAgICBpZiAobnQtPkZpbGVIZWFkZXIuQ2hhcmFjdGVyaXN0aWNzICYgSU1BR0VfRklMRV9ETEwpCiAgICB7CiAgICAgICAgaWYgKGhGaWxlKQogICAgICAgIHsKICAgICAgICAgICAgVUlOVCBkcml2ZV90eXBlID0gR2V0RHJpdmVUeXBlQSggd20tPnNob3J0X2ZpbGVuYW1lICk7CiAgICAgICAgICAgIC8qIGRvbid0IGtlZXAgdGhlIGZpbGUgaGFuZGxlIG9wZW4gb24gcmVtb3ZhYmxlIG1lZGlhICovCiAgICAgICAgICAgIGlmIChkcml2ZV90eXBlID09IERSSVZFX1JFTU9WQUJMRSB8fCBkcml2ZV90eXBlID09IERSSVZFX0NEUk9NKSBoRmlsZSA9IDA7CiAgICAgICAgfQogICAgICAgIFNFUlZFUl9TVEFSVF9SRVEoIGxvYWRfZGxsICkKICAgICAgICB7CiAgICAgICAgICAgIHJlcS0+aGFuZGxlICAgICA9IGhGaWxlOwogICAgICAgICAgICByZXEtPmJhc2UgICAgICAgPSAodm9pZCAqKWhNb2R1bGU7CiAgICAgICAgICAgIHJlcS0+c2l6ZSAgICAgICA9IG50LT5PcHRpb25hbEhlYWRlci5TaXplT2ZJbWFnZTsKICAgICAgICAgICAgcmVxLT5kYmdfb2Zmc2V0ID0gbnQtPkZpbGVIZWFkZXIuUG9pbnRlclRvU3ltYm9sVGFibGU7CiAgICAgICAgICAgIHJlcS0+ZGJnX3NpemUgICA9IG50LT5GaWxlSGVhZGVyLk51bWJlck9mU3ltYm9sczsKICAgICAgICAgICAgcmVxLT5uYW1lICAgICAgID0gJndtLT5maWxlbmFtZTsKICAgICAgICAgICAgd2luZV9zZXJ2ZXJfYWRkX2RhdGEoIHJlcSwgd20tPmZpbGVuYW1lLCBzdHJsZW4od20tPmZpbGVuYW1lKSApOwogICAgICAgICAgICB3aW5lX3NlcnZlcl9jYWxsKCByZXEgKTsKICAgICAgICB9CiAgICAgICAgU0VSVkVSX0VORF9SRVE7CiAgICB9CgogICAgcmV0dXJuIHdtOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFRoZSBQRSBMaWJyYXJ5IExvYWRlciBmcm9udGVuZC4KICogRklYTUU6IGhhbmRsZSB0aGUgZmxhZ3MuCiAqLwpOVFNUQVRVUyBQRV9Mb2FkTGlicmFyeUV4QSAoTFBDU1RSIG5hbWUsIERXT1JEIGZsYWdzLCBXSU5FX01PRFJFRioqIHB3bSkKewoJSE1PRFVMRQkJaE1vZHVsZTMyOwoJSEFORExFCQloRmlsZTsKCgloRmlsZSA9IENyZWF0ZUZpbGVBKCBuYW1lLCBHRU5FUklDX1JFQUQsIEZJTEVfU0hBUkVfUkVBRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBPUEVOX0VYSVNUSU5HLCAwLCAwICk7CglpZiAoIGhGaWxlID09IElOVkFMSURfSEFORExFX1ZBTFVFICkgCiAgICAgICAgewogICAgICAgICAgICAvKiBrZWVwIGl0IHRoYXQgd2F5IHVudGlsIHdlIHRyYW5zZm9ybSBDcmVhdGVGaWxlIGludG8gTnRDcmVhdGVGaWxlICovCiAgICAgICAgICAgIHJldHVybiAoR2V0TGFzdEVycm9yKCkgPT0gRVJST1JfRklMRV9OT1RfRk9VTkQpID8gCiAgICAgICAgICAgICAgICBTVEFUVVNfTk9fU1VDSF9GSUxFIDogU1RBVFVTX0lOVEVSTkFMX0VSUk9SOwogICAgICAgIH0KCgkvKiBMb2FkIFBFIG1vZHVsZSAqLwoJaE1vZHVsZTMyID0gUEVfTG9hZEltYWdlKCBoRmlsZSwgbmFtZSwgZmxhZ3MgKTsKCWlmICghaE1vZHVsZTMyKQoJewogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJcmV0dXJuIFNUQVRVU19JTlRFUk5BTF9FUlJPUjsKCX0KCgkvKiBDcmVhdGUgMzItYml0IE1PRFJFRiAqLwoJaWYgKCAhKCpwd20gPSBQRV9DcmVhdGVNb2R1bGUoIGhNb2R1bGUzMiwgbmFtZSwgZmxhZ3MsIGhGaWxlLCBGQUxTRSApKSApCgl7CgkJRVJSKCAiY2FuJ3QgbG9hZCAlc1xuIiwgbmFtZSApOwogICAgICAgICAgICAgICAgQ2xvc2VIYW5kbGUoIGhGaWxlICk7CgkJcmV0dXJuIFNUQVRVU19OT19NRU1PUlk7IC8qIEZJWE1FICovCgl9CgogICAgICAgIENsb3NlSGFuZGxlKCBoRmlsZSApOwoJcmV0dXJuIFNUQVRVU19TVUNDRVNTOwp9Cg==