LyoqDQogICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KICAqIEBmaWxlICAgIHN0bTMyZjd4eF9sbF91c2IuYw0KICAqIEBhdXRob3IgIE1DRCBBcHBsaWNhdGlvbiBUZWFtDQogICogQHZlcnNpb24gVjEuMi4wDQogICogQGRhdGUgICAgMzAtRGVjZW1iZXItMjAxNg0KICAqIEBicmllZiAgIFVTQiBMb3cgTGF5ZXIgSEFMIG1vZHVsZSBkcml2ZXIuDQogICogICAgDQogICogICAgICAgICAgVGhpcyBmaWxlIHByb3ZpZGVzIGZpcm13YXJlIGZ1bmN0aW9ucyB0byBtYW5hZ2UgdGhlIGZvbGxvd2luZyANCiAgKiAgICAgICAgICBmdW5jdGlvbmFsaXRpZXMgb2YgdGhlIFVTQiBQZXJpcGhlcmFsIENvbnRyb2xsZXI6DQogICogICAgICAgICAgICsgSW5pdGlhbGl6YXRpb24vZGUtaW5pdGlhbGl6YXRpb24gZnVuY3Rpb25zDQogICogICAgICAgICAgICsgSS9PIG9wZXJhdGlvbiBmdW5jdGlvbnMNCiAgKiAgICAgICAgICAgKyBQZXJpcGhlcmFsIENvbnRyb2wgZnVuY3Rpb25zIA0KICAqICAgICAgICAgICArIFBlcmlwaGVyYWwgU3RhdGUgZnVuY3Rpb25zDQogICogICAgICAgICANCiAgQHZlcmJhdGltDQogID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KICAgICAgICAgICAgICAgICAgICAjIyMjIyBIb3cgdG8gdXNlIHRoaXMgZHJpdmVyICMjIyMjDQogID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQ0KICAgIFsuLl0NCiAgICAgICgjKSBGaWxsIHBhcmFtZXRlcnMgb2YgSW5pdCBzdHJ1Y3R1cmUgaW4gVVNCX09UR19DZmdUeXBlRGVmIHN0cnVjdHVyZS4NCiAgDQogICAgICAoIykgQ2FsbCBVU0JfQ29yZUluaXQoKSBBUEkgdG8gaW5pdGlhbGl6ZSB0aGUgVVNCIENvcmUgcGVyaXBoZXJhbC4NCg0KICAgICAgKCMpIFRoZSB1cHBlciBIQUwgSENEL1BDRCBkcml2ZXIgd2lsbCBjYWxsIHRoZSByaWdodCByb3V0aW5lcyBmb3IgaXRzIGludGVybmFsIHByb2Nlc3Nlcy4NCg0KICBAZW5kdmVyYmF0aW0NCiAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogICogQGF0dGVudGlvbg0KICAqDQogICogPGgyPjxjZW50ZXI+JmNvcHk7IENPUFlSSUdIVChjKSAyMDE2IFNUTWljcm9lbGVjdHJvbmljczwvY2VudGVyPjwvaDI+DQogICoNCiAgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQgbW9kaWZpY2F0aW9uLA0KICAqIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoNCiAgKiAgIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSwNCiAgKiAgICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuDQogICogICAyLiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsDQogICogICAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uDQogICogICAgICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4NCiAgKiAgIDMuIE5laXRoZXIgdGhlIG5hbWUgb2YgU1RNaWNyb2VsZWN0cm9uaWNzIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycw0KICAqICAgICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlDQogICogICAgICB3aXRob3V0IHNwZWNpZmljIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbi4NCiAgKg0KICAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgIkFTIElTIg0KICAqIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUNCiAgKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUNCiAgKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFDQogICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwNCiAgKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUg0KICAqIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSDQogICogQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwNCiAgKiBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQ0KICAqIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuDQogICoNCiAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqDQogICovIA0KDQovKiBJbmNsdWRlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KI2luY2x1ZGUgInN0bTMyZjd4eF9oYWwuaCINCg0KLyoqIEBhZGR0b2dyb3VwIFNUTTMyRjd4eF9MTF9VU0JfRFJJVkVSDQogICogQHsNCiAgKi8NCg0KI2lmIGRlZmluZWQgKEhBTF9QQ0RfTU9EVUxFX0VOQUJMRUQpIHx8IGRlZmluZWQgKEhBTF9IQ0RfTU9EVUxFX0VOQUJMRUQpDQoNCi8qIFByaXZhdGUgdHlwZWRlZiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQovKiBQcml2YXRlIGRlZmluZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KLyogUHJpdmF0ZSBtYWNybyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCi8qIFByaXZhdGUgdmFyaWFibGVzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovDQovKiBQcml2YXRlIGZ1bmN0aW9uIHByb3RvdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KLyogUHJpdmF0ZSBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8NCnN0YXRpYyBIQUxfU3RhdHVzVHlwZURlZiBVU0JfQ29yZVJlc2V0KFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCk7DQoNCiNpZmRlZiBVU0JfSFNfUEhZQyANCnN0YXRpYyBIQUxfU3RhdHVzVHlwZURlZiBVU0JfSFNfUEhZQ0luaXQoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4KTsNCiNlbmRpZg0KDQovKiBFeHBvcnRlZCBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLw0KLyoqIEBkZWZncm91cCBMTF9VU0JfRXhwb3J0ZWRfRnVuY3Rpb25zIFVTQiBMb3cgTGF5ZXIgRXhwb3J0ZWQgRnVuY3Rpb25zDQogICogQHsNCiAgKi8NCg0KLyoqIEBkZWZncm91cCBMTF9VU0JfR3JvdXAxIEluaXRpYWxpemF0aW9uL2RlLWluaXRpYWxpemF0aW9uIGZ1bmN0aW9ucyANCiAqICBAYnJpZWYgICAgSW5pdGlhbGl6YXRpb24gYW5kIENvbmZpZ3VyYXRpb24gZnVuY3Rpb25zIA0KICoNCkB2ZXJiYXRpbSAgICANCiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09DQogICAgICAgICAgICAgICMjIyMjIEluaXRpYWxpemF0aW9uL2RlLWluaXRpYWxpemF0aW9uIGZ1bmN0aW9ucyAjIyMjIw0KID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0NCiAgICBbLi5dICBUaGlzIHNlY3Rpb24gcHJvdmlkZXMgZnVuY3Rpb25zIGFsbG93aW5nIHRvOg0KIA0KQGVuZHZlcmJhdGltDQogICogQHsNCiAgKi8NCg0KLyoqDQogICogQGJyaWVmICBJbml0aWFsaXplcyB0aGUgVVNCIENvcmUNCiAgKiBAcGFyYW0gIFVTQng6IFVTQiBJbnN0YW5jZQ0KICAqIEBwYXJhbSAgY2ZnIDogcG9pbnRlciB0byBhIFVTQl9PVEdfQ2ZnVHlwZURlZiBzdHJ1Y3R1cmUgdGhhdCBjb250YWlucw0KICAqICAgICAgICAgdGhlIGNvbmZpZ3VyYXRpb24gaW5mb3JtYXRpb24gZm9yIHRoZSBzcGVjaWZpZWQgVVNCeCBwZXJpcGhlcmFsLg0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0NvcmVJbml0KFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgVVNCX09UR19DZmdUeXBlRGVmIGNmZykNCnsNCiAgaWYgKGNmZy5waHlfaXRmYWNlID09IFVTQl9PVEdfVUxQSV9QSFkpDQogIHsNCiAgICANCiAgICBVU0J4LT5HQ0NGRyAmPSB+KFVTQl9PVEdfR0NDRkdfUFdSRFdOKTsNCg0KICAgIC8qIEluaXQgVGhlIFVMUEkgSW50ZXJmYWNlICovDQogICAgVVNCeC0+R1VTQkNGRyAmPSB+KFVTQl9PVEdfR1VTQkNGR19UU0RQUyB8IFVTQl9PVEdfR1VTQkNGR19VTFBJRlNMUyB8IFVTQl9PVEdfR1VTQkNGR19QSFlTRUwpOw0KICAgDQogICAgLyogU2VsZWN0IHZidXMgc291cmNlICovDQogICAgVVNCeC0+R1VTQkNGRyAmPSB+KFVTQl9PVEdfR1VTQkNGR19VTFBJRVZCVVNEIHwgVVNCX09UR19HVVNCQ0ZHX1VMUElFVkJVU0kpOw0KICAgIGlmKGNmZy51c2VfZXh0ZXJuYWxfdmJ1cyA9PSAxKQ0KICAgIHsNCiAgICAgIFVTQngtPkdVU0JDRkcgfD0gVVNCX09UR19HVVNCQ0ZHX1VMUElFVkJVU0Q7DQogICAgfQ0KICAgIC8qIFJlc2V0IGFmdGVyIGEgUEhZIHNlbGVjdCAgKi8NCiAgICBVU0JfQ29yZVJlc2V0KFVTQngpOyANCiAgfQ0KI2lmZGVmIFVTQl9IU19QSFlDIA0KICANCiAgZWxzZSBpZiAoY2ZnLnBoeV9pdGZhY2UgPT0gVVNCX09UR19IU19FTUJFRERFRF9QSFkpDQogIHsNCiAgICBVU0J4LT5HQ0NGRyAmPSB+KFVTQl9PVEdfR0NDRkdfUFdSRFdOKTsNCiAgICANCiAgICAvKiBJbml0IFRoZSBVVE1JIEludGVyZmFjZSAqLw0KICAgIFVTQngtPkdVU0JDRkcgJj0gfihVU0JfT1RHX0dVU0JDRkdfVFNEUFMgfCBVU0JfT1RHX0dVU0JDRkdfVUxQSUZTTFMgfCBVU0JfT1RHX0dVU0JDRkdfUEhZU0VMKTsNCiAgICANCiAgICAvKiBTZWxlY3QgdmJ1cyBzb3VyY2UgKi8NCiAgICBVU0J4LT5HVVNCQ0ZHICY9IH4oVVNCX09UR19HVVNCQ0ZHX1VMUElFVkJVU0QgfCBVU0JfT1RHX0dVU0JDRkdfVUxQSUVWQlVTSSk7DQogICAgDQogICAgLyogU2VsZWN0IFVUTUkgSW50ZXJhY2UgKi8NCiAgICBVU0J4LT5HVVNCQ0ZHICY9IH4gVVNCX09UR19HVVNCQ0ZHX1VMUElfVVRNSV9TRUw7DQogICAgVVNCeC0+R0NDRkcgfD0gVVNCX09UR19HQ0NGR19QSFlIU0VOOw0KICAgIA0KICAgIC8qIEVuYWJsZXMgY29udHJvbCBvZiBhIEhpZ2ggU3BlZWQgVVNCIFBIWSAqLw0KICAgIFVTQl9IU19QSFlDSW5pdChVU0J4KTsNCiAgICANCiAgICBpZihjZmcudXNlX2V4dGVybmFsX3ZidXMgPT0gMSkNCiAgICB7DQogICAgICBVU0J4LT5HVVNCQ0ZHIHw9IFVTQl9PVEdfR1VTQkNGR19VTFBJRVZCVVNEOw0KICAgIH0NCiAgICAvKiBSZXNldCBhZnRlciBhIFBIWSBzZWxlY3QgICovDQogICAgVVNCX0NvcmVSZXNldChVU0J4KTsgDQogICAgDQogIH0NCiNlbmRpZg0KICBlbHNlIC8qIEZTIGludGVyZmFjZSAoZW1iZWRkZWQgUGh5KSAqLw0KICB7DQogICAgLyogU2VsZWN0IEZTIEVtYmVkZGVkIFBIWSAqLw0KICAgIFVTQngtPkdVU0JDRkcgfD0gVVNCX09UR19HVVNCQ0ZHX1BIWVNFTDsNCiAgICANCiAgICAvKiBSZXNldCBhZnRlciBhIFBIWSBzZWxlY3QgYW5kIHNldCBIb3N0IG1vZGUgKi8NCiAgICBVU0JfQ29yZVJlc2V0KFVTQngpOw0KICAgIA0KICAgIC8qIERlYWN0aXZhdGUgdGhlIHBvd2VyIGRvd24qLw0KICAgIFVTQngtPkdDQ0ZHID0gVVNCX09UR19HQ0NGR19QV1JEV047DQogIH0NCiANCiAgaWYoY2ZnLmRtYV9lbmFibGUgPT0gRU5BQkxFKQ0KICB7DQogICAgVVNCeC0+R0FIQkNGRyB8PSBVU0JfT1RHX0dBSEJDRkdfSEJTVExFTl8yOw0KICAgIFVTQngtPkdBSEJDRkcgfD0gVVNCX09UR19HQUhCQ0ZHX0RNQUVOOw0KICB9ICANCg0KICByZXR1cm4gSEFMX09LOw0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFVTQl9FbmFibGVHbG9iYWxJbnQNCiAgKiAgICAgICAgIEVuYWJsZXMgdGhlIGNvbnRyb2xsZXIncyBHbG9iYWwgSW50IGluIHRoZSBBSEIgQ29uZmlnIHJlZw0KICAqIEBwYXJhbSAgVVNCeCA6IFNlbGVjdGVkIGRldmljZQ0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0VuYWJsZUdsb2JhbEludChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngpDQp7DQogIFVTQngtPkdBSEJDRkcgfD0gVVNCX09UR19HQUhCQ0ZHX0dJTlQ7DQogIHJldHVybiBIQUxfT0s7DQp9DQoNCg0KLyoqDQogICogQGJyaWVmICBVU0JfRGlzYWJsZUdsb2JhbEludA0KICAqICAgICAgICAgRGlzYWJsZSB0aGUgY29udHJvbGxlcidzIEdsb2JhbCBJbnQgaW4gdGhlIEFIQiBDb25maWcgcmVnDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQoqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0Rpc2FibGVHbG9iYWxJbnQoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4KQ0Kew0KICBVU0J4LT5HQUhCQ0ZHICY9IH5VU0JfT1RHX0dBSEJDRkdfR0lOVDsNCiAgcmV0dXJuIEhBTF9PSzsNCn0NCiAgIA0KLyoqDQogICogQGJyaWVmICBVU0JfU2V0Q3VycmVudE1vZGUgOiBTZXQgZnVuY3Rpb25hbCBtb2RlDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBtb2RlIDogIGN1cnJlbnQgY29yZSBtb2RlDQogICogICAgICAgICAgVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIG9uZSBvZiB0aGVzZSB2YWx1ZXM6DQogICogICAgICAgICAgICBAYXJnIFVTQl9PVEdfREVWSUNFX01PREU6IFBlcmlwaGVyYWwgbW9kZQ0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX0hPU1RfTU9ERTogSG9zdCBtb2RlDQogICogICAgICAgICAgICBAYXJnIFVTQl9PVEdfRFJEX01PREU6IER1YWwgUm9sZSBEZXZpY2UgbW9kZSAgDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQpIQUxfU3RhdHVzVHlwZURlZiBVU0JfU2V0Q3VycmVudE1vZGUoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4ICwgVVNCX09UR19Nb2RlVHlwZURlZiBtb2RlKQ0Kew0KICBVU0J4LT5HVVNCQ0ZHICY9IH4oVVNCX09UR19HVVNCQ0ZHX0ZITU9EIHwgVVNCX09UR19HVVNCQ0ZHX0ZETU9EKTsgDQogIA0KICBpZiAoIG1vZGUgPT0gVVNCX09UR19IT1NUX01PREUpDQogIHsNCiAgICBVU0J4LT5HVVNCQ0ZHIHw9IFVTQl9PVEdfR1VTQkNGR19GSE1PRDsgDQogIH0NCiAgZWxzZSBpZiAoIG1vZGUgPT0gVVNCX09UR19ERVZJQ0VfTU9ERSkNCiAgew0KICAgIFVTQngtPkdVU0JDRkcgfD0gVVNCX09UR19HVVNCQ0ZHX0ZETU9EOyANCiAgfQ0KICBIQUxfRGVsYXkoNTApOw0KICANCiAgcmV0dXJuIEhBTF9PSzsNCn0NCg0KLyoqDQogICogQGJyaWVmICBVU0JfRGV2SW5pdCA6IEluaXRpYWxpemVzIHRoZSBVU0JfT1RHIGNvbnRyb2xsZXIgcmVnaXN0ZXJzIA0KICAqICAgICAgICAgZm9yIGRldmljZSBtb2RlDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBjZmcgIDogcG9pbnRlciB0byBhIFVTQl9PVEdfQ2ZnVHlwZURlZiBzdHJ1Y3R1cmUgdGhhdCBjb250YWlucw0KICAqICAgICAgICAgdGhlIGNvbmZpZ3VyYXRpb24gaW5mb3JtYXRpb24gZm9yIHRoZSBzcGVjaWZpZWQgVVNCeCBwZXJpcGhlcmFsLg0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0RldkluaXQgKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgVVNCX09UR19DZmdUeXBlRGVmIGNmZykNCnsNCiAgdWludDMyX3QgaSA9IDA7DQoNCiAgLypBY3RpdmF0ZSBWQlVTIFNlbnNpbmcgQiAqLw0KICBVU0J4LT5HQ0NGRyB8PSBVU0JfT1RHX0dDQ0ZHX1ZCREVOOw0KICANCiAgaWYgKGNmZy52YnVzX3NlbnNpbmdfZW5hYmxlID09IDApDQogIHsNCiAgICAvKiBEZWFjdGl2YXRlIFZCVVMgU2Vuc2luZyBCICovDQogICAgVVNCeC0+R0NDRkcgJj0gfiBVU0JfT1RHX0dDQ0ZHX1ZCREVOOw0KICAgIA0KICAgIC8qIEItcGVyaXBoZXJhbCBzZXNzaW9uIHZhbGlkIG92ZXJyaWRlIGVuYWJsZSovIA0KICAgIFVTQngtPkdPVEdDVEwgfD0gVVNCX09UR19HT1RHQ1RMX0JWQUxPRU47DQogICAgVVNCeC0+R09UR0NUTCB8PSBVU0JfT1RHX0dPVEdDVExfQlZBTE9WQUw7DQogIH0NCiAgIA0KICAvKiBSZXN0YXJ0IHRoZSBQaHkgQ2xvY2sgKi8NCiAgVVNCeF9QQ0dDQ1RMID0gMDsNCg0KICAvKiBEZXZpY2UgbW9kZSBjb25maWd1cmF0aW9uICovDQogIFVTQnhfREVWSUNFLT5EQ0ZHIHw9IERDRkdfRlJBTUVfSU5URVJWQUxfODA7DQogIA0KICBpZihjZmcucGh5X2l0ZmFjZSAgPT0gVVNCX09UR19VTFBJX1BIWSkNCiAgew0KICAgIGlmKGNmZy5zcGVlZCA9PSBVU0JfT1RHX1NQRUVEX0hJR0gpDQogICAgeyAgICAgIA0KICAgICAgLyogU2V0IEhpZ2ggc3BlZWQgcGh5ICovDQogICAgICBVU0JfU2V0RGV2U3BlZWQgKFVTQnggLCBVU0JfT1RHX1NQRUVEX0hJR0gpOw0KICAgIH0NCiAgICBlbHNlIA0KICAgIHsNCiAgICAgIC8qIHNldCBIaWdoIHNwZWVkIHBoeSBpbiBGdWxsIHNwZWVkIG1vZGUgKi8NCiAgICAgIFVTQl9TZXREZXZTcGVlZCAoVVNCeCAsIFVTQl9PVEdfU1BFRURfSElHSF9JTl9GVUxMKTsNCiAgICB9DQogIH0NCiAgDQogIGVsc2UgaWYoY2ZnLnBoeV9pdGZhY2UgID09IFVTQl9PVEdfSFNfRU1CRURERURfUEhZKQ0KICB7DQogICAgaWYoY2ZnLnNwZWVkID09IFVTQl9PVEdfU1BFRURfSElHSCkNCiAgICB7ICAgICAgDQogICAgICAvKiBTZXQgSGlnaCBzcGVlZCBwaHkgKi8NCiAgICAgIFVTQl9TZXREZXZTcGVlZCAoVVNCeCAsIFVTQl9PVEdfU1BFRURfSElHSCk7DQogICAgfQ0KICAgIGVsc2UgDQogICAgew0KICAgICAgLyogc2V0IEhpZ2ggc3BlZWQgcGh5IGluIEZ1bGwgc3BlZWQgbW9kZSAqLw0KICAgICAgVVNCX1NldERldlNwZWVkIChVU0J4ICwgVVNCX09UR19TUEVFRF9ISUdIX0lOX0ZVTEwpOw0KICAgIH0NCiAgfQ0KICANCiAgZWxzZQ0KICB7DQogICAgLyogU2V0IEZ1bGwgc3BlZWQgcGh5ICovDQogICAgVVNCX1NldERldlNwZWVkIChVU0J4ICwgVVNCX09UR19TUEVFRF9GVUxMKTsNCiAgfQ0KDQogIC8qIEZsdXNoIHRoZSBGSUZPcyAqLw0KICBVU0JfRmx1c2hUeEZpZm8oVVNCeCAsIDB4MTApOyAvKiBhbGwgVHggRklGT3MgKi8NCiAgVVNCX0ZsdXNoUnhGaWZvKFVTQngpOw0KICANCiAgLyogQ2xlYXIgYWxsIHBlbmRpbmcgRGV2aWNlIEludGVycnVwdHMgKi8NCiAgVVNCeF9ERVZJQ0UtPkRJRVBNU0sgPSAwOw0KICBVU0J4X0RFVklDRS0+RE9FUE1TSyA9IDA7DQogIFVTQnhfREVWSUNFLT5EQUlOVCA9IDB4RkZGRkZGRkY7DQogIFVTQnhfREVWSUNFLT5EQUlOVE1TSyA9IDA7DQogIA0KICBmb3IgKGkgPSAwOyBpIDwgY2ZnLmRldl9lbmRwb2ludHM7IGkrKykNCiAgew0KICAgIGlmICgoVVNCeF9JTkVQKGkpLT5ESUVQQ1RMICYgVVNCX09UR19ESUVQQ1RMX0VQRU5BKSA9PSBVU0JfT1RHX0RJRVBDVExfRVBFTkEpDQogICAgew0KICAgICAgVVNCeF9JTkVQKGkpLT5ESUVQQ1RMID0gKFVTQl9PVEdfRElFUENUTF9FUERJUyB8IFVTQl9PVEdfRElFUENUTF9TTkFLKTsNCiAgICB9DQogICAgZWxzZQ0KICAgIHsNCiAgICAgIFVTQnhfSU5FUChpKS0+RElFUENUTCA9IDA7DQogICAgfQ0KICAgIA0KICAgIFVTQnhfSU5FUChpKS0+RElFUFRTSVogPSAwOw0KICAgIFVTQnhfSU5FUChpKS0+RElFUElOVCAgPSAweEZGOw0KICB9DQogIA0KICBmb3IgKGkgPSAwOyBpIDwgY2ZnLmRldl9lbmRwb2ludHM7IGkrKykNCiAgew0KICAgIGlmICgoVVNCeF9PVVRFUChpKS0+RE9FUENUTCAmIFVTQl9PVEdfRE9FUENUTF9FUEVOQSkgPT0gVVNCX09UR19ET0VQQ1RMX0VQRU5BKQ0KICAgIHsNCiAgICAgIFVTQnhfT1VURVAoaSktPkRPRVBDVEwgPSAoVVNCX09UR19ET0VQQ1RMX0VQRElTIHwgVVNCX09UR19ET0VQQ1RMX1NOQUspOw0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgVVNCeF9PVVRFUChpKS0+RE9FUENUTCA9IDA7DQogICAgfQ0KICAgIA0KICAgIFVTQnhfT1VURVAoaSktPkRPRVBUU0laID0gMDsNCiAgICBVU0J4X09VVEVQKGkpLT5ET0VQSU5UICA9IDB4RkY7DQogIH0NCiAgDQogIFVTQnhfREVWSUNFLT5ESUVQTVNLICY9IH4oVVNCX09UR19ESUVQTVNLX1RYRlVSTSk7DQogIA0KICBpZiAoY2ZnLmRtYV9lbmFibGUgPT0gMSkNCiAgew0KICAgIC8qU2V0IHRocmVzaG9sZCBwYXJhbWV0ZXJzICovDQogICAgVVNCeF9ERVZJQ0UtPkRUSFJDVEwgPSAoVVNCX09UR19EVEhSQ1RMX1RYVEhSTEVOXzYgfCBVU0JfT1RHX0RUSFJDVExfUlhUSFJMRU5fNik7DQogICAgVVNCeF9ERVZJQ0UtPkRUSFJDVEwgfD0gKFVTQl9PVEdfRFRIUkNUTF9SWFRIUkVOIHwgVVNCX09UR19EVEhSQ1RMX0lTT1RIUkVOIHwgVVNCX09UR19EVEhSQ1RMX05PTklTT1RIUkVOKTsNCiAgICANCiAgICBpPSBVU0J4X0RFVklDRS0+RFRIUkNUTDsNCiAgfQ0KICANCiAgLyogRGlzYWJsZSBhbGwgaW50ZXJydXB0cy4gKi8NCiAgVVNCeC0+R0lOVE1TSyA9IDA7DQogIA0KICAvKiBDbGVhciBhbnkgcGVuZGluZyBpbnRlcnJ1cHRzICovDQogIFVTQngtPkdJTlRTVFMgPSAweEJGRkZGRkZGOw0KDQogIC8qIEVuYWJsZSB0aGUgY29tbW9uIGludGVycnVwdHMgKi8NCiAgaWYgKGNmZy5kbWFfZW5hYmxlID09IERJU0FCTEUpDQogIHsNCiAgICBVU0J4LT5HSU5UTVNLIHw9IFVTQl9PVEdfR0lOVE1TS19SWEZMVkxNOyANCiAgfQ0KICANCiAgLyogRW5hYmxlIGludGVycnVwdHMgbWF0Y2hpbmcgdG8gdGhlIERldmljZSBtb2RlIE9OTFkgKi8NCiAgVVNCeC0+R0lOVE1TSyB8PSAoVVNCX09UR19HSU5UTVNLX1VTQlNVU1BNIHwgVVNCX09UR19HSU5UTVNLX1VTQlJTVCB8XA0KICAgICAgICAgICAgICAgICAgICBVU0JfT1RHX0dJTlRNU0tfRU5VTURORU0gfCBVU0JfT1RHX0dJTlRNU0tfSUVQSU5UIHxcDQogICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfR0lOVE1TS19PRVBJTlQgICB8IFVTQl9PVEdfR0lOVE1TS19JSVNPSVhGUk18XA0KICAgICAgICAgICAgICAgICAgICBVU0JfT1RHX0dJTlRNU0tfUFhGUk1fSUlTT09YRlJNIHwgVVNCX09UR19HSU5UTVNLX1dVSU0pOw0KICANCiAgaWYoY2ZnLlNvZl9lbmFibGUpDQogIHsNCiAgICBVU0J4LT5HSU5UTVNLIHw9IFVTQl9PVEdfR0lOVE1TS19TT0ZNOw0KICB9DQoNCiAgaWYgKGNmZy52YnVzX3NlbnNpbmdfZW5hYmxlID09IEVOQUJMRSkNCiAgew0KICAgIFVTQngtPkdJTlRNU0sgfD0gKFVTQl9PVEdfR0lOVE1TS19TUlFJTSB8IFVTQl9PVEdfR0lOVE1TS19PVEdJTlQpOyANCiAgfQ0KICANCiAgcmV0dXJuIEhBTF9PSzsNCn0NCg0KDQovKioNCiAgKiBAYnJpZWYgIFVTQl9PVEdfRmx1c2hUeEZpZm8gOiBGbHVzaCBhIFR4IEZJRk8NCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcGFyYW0gIG51bSA6IEZJRk8gbnVtYmVyDQogICogICAgICAgICBUaGlzIHBhcmFtZXRlciBjYW4gYmUgYSB2YWx1ZSBmcm9tIDEgdG8gMTUNCiAgICAgICAgICAgIDE1IG1lYW5zIEZsdXNoIGFsbCBUeCBGSUZPcw0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0ZsdXNoVHhGaWZvIChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngsIHVpbnQzMl90IG51bSApDQp7DQogIHVpbnQzMl90IGNvdW50ID0gMDsNCiANCiAgVVNCeC0+R1JTVENUTCA9ICggVVNCX09UR19HUlNUQ1RMX1RYRkZMU0ggfCh1aW50MzJfdCkoIG51bSA8PCA2KSk7IA0KIA0KICBkbw0KICB7DQogICAgaWYgKCsrY291bnQgPiAyMDAwMDApDQogICAgew0KICAgICAgcmV0dXJuIEhBTF9USU1FT1VUOw0KICAgIH0NCiAgfQ0KICB3aGlsZSAoKFVTQngtPkdSU1RDVEwgJiBVU0JfT1RHX0dSU1RDVExfVFhGRkxTSCkgPT0gVVNCX09UR19HUlNUQ1RMX1RYRkZMU0gpOw0KICANCiAgcmV0dXJuIEhBTF9PSzsNCn0NCg0KDQovKioNCiAgKiBAYnJpZWYgIFVTQl9GbHVzaFJ4RmlmbyA6IEZsdXNoIFJ4IEZJRk8NCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcmV0dmFsIEhBTCBzdGF0dXMNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmIFVTQl9GbHVzaFJ4RmlmbyhVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngpDQp7DQogIHVpbnQzMl90IGNvdW50ID0gMDsNCiAgDQogIFVTQngtPkdSU1RDVEwgPSBVU0JfT1RHX0dSU1RDVExfUlhGRkxTSDsNCiAgDQogIGRvDQogIHsNCiAgICBpZiAoKytjb3VudCA+IDIwMDAwMCkNCiAgICB7DQogICAgICByZXR1cm4gSEFMX1RJTUVPVVQ7DQogICAgfQ0KICB9DQogIHdoaWxlICgoVVNCeC0+R1JTVENUTCAmIFVTQl9PVEdfR1JTVENUTF9SWEZGTFNIKSA9PSBVU0JfT1RHX0dSU1RDVExfUlhGRkxTSCk7DQogIA0KICByZXR1cm4gSEFMX09LOw0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFVTQl9TZXREZXZTcGVlZCA6SW5pdGlhbGl6ZXMgdGhlIERldlNwZCBmaWVsZCBvZiBEQ0ZHIHJlZ2lzdGVyIA0KICAqICAgICAgICAgZGVwZW5kaW5nIHRoZSBQSFkgdHlwZSBhbmQgdGhlIGVudW1lcmF0aW9uIHNwZWVkIG9mIHRoZSBkZXZpY2UuDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBzcGVlZCA6IGRldmljZSBzcGVlZA0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBvbmUgb2YgdGhlc2UgdmFsdWVzOg0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0hJR0g6IEhpZ2ggc3BlZWQgbW9kZQ0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0hJR0hfSU5fRlVMTDogSGlnaCBzcGVlZCBjb3JlIGluIEZ1bGwgU3BlZWQgbW9kZQ0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0ZVTEw6IEZ1bGwgc3BlZWQgbW9kZQ0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0xPVzogTG93IHNwZWVkIG1vZGUNCiAgKiBAcmV0dmFsICBIYWwgc3RhdHVzDQogICovDQpIQUxfU3RhdHVzVHlwZURlZiBVU0JfU2V0RGV2U3BlZWQoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4ICwgdWludDhfdCBzcGVlZCkNCnsNCiAgVVNCeF9ERVZJQ0UtPkRDRkcgfD0gc3BlZWQ7DQogIHJldHVybiBIQUxfT0s7DQp9DQoNCi8qKg0KICAqIEBicmllZiAgVVNCX0dldERldlNwZWVkIDpSZXR1cm4gdGhlICBEZXYgU3BlZWQgDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBzcGVlZCA6IGRldmljZSBzcGVlZA0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBvbmUgb2YgdGhlc2UgdmFsdWVzOg0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0hJR0g6IEhpZ2ggc3BlZWQgbW9kZQ0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0ZVTEw6IEZ1bGwgc3BlZWQgbW9kZQ0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0xPVzogTG93IHNwZWVkIG1vZGUNCiAgKi8NCnVpbnQ4X3QgVVNCX0dldERldlNwZWVkKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCkNCnsNCiAgdWludDhfdCBzcGVlZCA9IDA7DQogIA0KICBpZigoVVNCeF9ERVZJQ0UtPkRTVFMgJiBVU0JfT1RHX0RTVFNfRU5VTVNQRCkgPT0gRFNUU19FTlVNU1BEX0hTX1BIWV8zME1IWl9PUl82ME1IWikNCiAgew0KICAgIHNwZWVkID0gVVNCX09UR19TUEVFRF9ISUdIOw0KICB9DQogIGVsc2UgaWYgKCgoVVNCeF9ERVZJQ0UtPkRTVFMgJiBVU0JfT1RHX0RTVFNfRU5VTVNQRCkgPT0gRFNUU19FTlVNU1BEX0ZTX1BIWV8zME1IWl9PUl82ME1IWil8fA0KICAgICAgICAgICAoKFVTQnhfREVWSUNFLT5EU1RTICYgVVNCX09UR19EU1RTX0VOVU1TUEQpID09IERTVFNfRU5VTVNQRF9GU19QSFlfNDhNSFopKQ0KICB7DQogICAgc3BlZWQgPSBVU0JfT1RHX1NQRUVEX0ZVTEw7DQogIH0NCiAgZWxzZSBpZigoVVNCeF9ERVZJQ0UtPkRTVFMgJiBVU0JfT1RHX0RTVFNfRU5VTVNQRCkgPT0gRFNUU19FTlVNU1BEX0xTX1BIWV82TUhaKQ0KICB7DQogICAgc3BlZWQgPSBVU0JfT1RHX1NQRUVEX0xPVzsNCiAgfQ0KICANCiAgcmV0dXJuIHNwZWVkOw0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIEFjdGl2YXRlIGFuZCBjb25maWd1cmUgYW4gZW5kcG9pbnQNCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcGFyYW0gIGVwOiBwb2ludGVyIHRvIGVuZHBvaW50IHN0cnVjdHVyZQ0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0FjdGl2YXRlRW5kcG9pbnQoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4LCBVU0JfT1RHX0VQVHlwZURlZiAqZXApDQp7DQogIGlmIChlcC0+aXNfaW4gPT0gMSkNCiAgew0KICAgVVNCeF9ERVZJQ0UtPkRBSU5UTVNLIHw9IFVTQl9PVEdfREFJTlRNU0tfSUVQTSAmICgoMSA8PCAoZXAtPm51bSkpKTsNCiAgIA0KICAgIGlmICgoKFVTQnhfSU5FUChlcC0+bnVtKS0+RElFUENUTCkgJiBVU0JfT1RHX0RJRVBDVExfVVNCQUVQKSA9PSAwKQ0KICAgIHsNCiAgICAgIFVTQnhfSU5FUChlcC0+bnVtKS0+RElFUENUTCB8PSAoKGVwLT5tYXhwYWNrZXQgJiBVU0JfT1RHX0RJRVBDVExfTVBTSVogKSB8IChlcC0+dHlwZSA8PCAxOCApIHxcDQogICAgICAgICgoZXAtPm51bSkgPDwgMjIgKSB8IChVU0JfT1RHX0RJRVBDVExfU0QwUElEX1NFVk5GUk0pIHwgKFVTQl9PVEdfRElFUENUTF9VU0JBRVApKTsgDQogICAgfSANCg0KICB9DQogIGVsc2UNCiAgew0KICAgICBVU0J4X0RFVklDRS0+REFJTlRNU0sgfD0gVVNCX09UR19EQUlOVE1TS19PRVBNICYgKCgxIDw8IChlcC0+bnVtKSkgPDwgMTYpOw0KICAgICANCiAgICBpZiAoKChVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQQ1RMKSAmIFVTQl9PVEdfRE9FUENUTF9VU0JBRVApID09IDApDQogICAgew0KICAgICAgVVNCeF9PVVRFUChlcC0+bnVtKS0+RE9FUENUTCB8PSAoKGVwLT5tYXhwYWNrZXQgJiBVU0JfT1RHX0RPRVBDVExfTVBTSVogKSB8IChlcC0+dHlwZSA8PCAxOCApIHxcDQogICAgICAgKFVTQl9PVEdfRElFUENUTF9TRDBQSURfU0VWTkZSTSl8IChVU0JfT1RHX0RPRVBDVExfVVNCQUVQKSk7DQogICAgfSANCiAgfQ0KICByZXR1cm4gSEFMX09LOw0KfQ0KLyoqDQogICogQGJyaWVmICBBY3RpdmF0ZSBhbmQgY29uZmlndXJlIGEgZGVkaWNhdGVkIGVuZHBvaW50DQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBlcDogcG9pbnRlciB0byBlbmRwb2ludCBzdHJ1Y3R1cmUNCiAgKiBAcmV0dmFsIEhBTCBzdGF0dXMNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmIFVTQl9BY3RpdmF0ZURlZGljYXRlZEVuZHBvaW50KFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgVVNCX09UR19FUFR5cGVEZWYgKmVwKQ0Kew0KICBzdGF0aWMgX19JTyB1aW50MzJfdCBkZWJ1ZyA9IDA7DQogIA0KICAvKiBSZWFkIERFUENUTG4gcmVnaXN0ZXIgKi8NCiAgaWYgKGVwLT5pc19pbiA9PSAxKQ0KICB7DQogICAgaWYgKCgoVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQQ1RMKSAmIFVTQl9PVEdfRElFUENUTF9VU0JBRVApID09IDApDQogICAgew0KICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQQ1RMIHw9ICgoZXAtPm1heHBhY2tldCAmIFVTQl9PVEdfRElFUENUTF9NUFNJWiApIHwgKGVwLT50eXBlIDw8IDE4ICkgfFwNCiAgICAgICAgKChlcC0+bnVtKSA8PCAyMiApIHwgKFVTQl9PVEdfRElFUENUTF9TRDBQSURfU0VWTkZSTSkgfCAoVVNCX09UR19ESUVQQ1RMX1VTQkFFUCkpOyANCiAgICB9IA0KICAgIA0KICAgIA0KICAgIGRlYnVnICB8PSAoKGVwLT5tYXhwYWNrZXQgJiBVU0JfT1RHX0RJRVBDVExfTVBTSVogKSB8IChlcC0+dHlwZSA8PCAxOCApIHxcDQogICAgICAgICgoZXAtPm51bSkgPDwgMjIgKSB8IChVU0JfT1RHX0RJRVBDVExfU0QwUElEX1NFVk5GUk0pIHwgKFVTQl9PVEdfRElFUENUTF9VU0JBRVApKTsgDQogICAgDQogICBVU0J4X0RFVklDRS0+REVBQ0hNU0sgfD0gVVNCX09UR19EQUlOVE1TS19JRVBNICYgKCgxIDw8IChlcC0+bnVtKSkpOw0KICB9DQogIGVsc2UNCiAgew0KICAgIGlmICgoKFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBDVEwpICYgVVNCX09UR19ET0VQQ1RMX1VTQkFFUCkgPT0gMCkNCiAgICB7DQogICAgICBVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQQ1RMIHw9ICgoZXAtPm1heHBhY2tldCAmIFVTQl9PVEdfRE9FUENUTF9NUFNJWiApIHwgKGVwLT50eXBlIDw8IDE4ICkgfFwNCiAgICAgICAgKChlcC0+bnVtKSA8PCAyMiApIHwgKFVTQl9PVEdfRE9FUENUTF9VU0JBRVApKTsNCiAgICAgIA0KICAgICAgZGVidWcgPSAodWludDMyX3QpKCgodWludDMyX3QgKVVTQngpICsgVVNCX09UR19PVVRfRU5EUE9JTlRfQkFTRSArICgwKSpVU0JfT1RHX0VQX1JFR19TSVpFKTsNCiAgICAgIGRlYnVnID0gKHVpbnQzMl90ICkmVVNCeF9PVVRFUChlcC0+bnVtKS0+RE9FUENUTDsNCiAgICAgIGRlYnVnIHw9ICgoZXAtPm1heHBhY2tldCAmIFVTQl9PVEdfRE9FUENUTF9NUFNJWiApIHwgKGVwLT50eXBlIDw8IDE4ICkgfFwNCiAgICAgICAgKChlcC0+bnVtKSA8PCAyMiApIHwgKFVTQl9PVEdfRE9FUENUTF9VU0JBRVApKTsgDQogICAgfSANCiAgICANCiAgICAgVVNCeF9ERVZJQ0UtPkRFQUNITVNLIHw9IFVTQl9PVEdfREFJTlRNU0tfT0VQTSAmICgoMSA8PCAoZXAtPm51bSkpIDw8IDE2KTsNCiAgfQ0KDQogIHJldHVybiBIQUxfT0s7DQp9DQovKioNCiAgKiBAYnJpZWYgIERlLWFjdGl2YXRlIGFuZCBkZS1pbml0aWFsaXplIGFuIGVuZHBvaW50DQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBlcDogcG9pbnRlciB0byBlbmRwb2ludCBzdHJ1Y3R1cmUNCiAgKiBAcmV0dmFsIEhBTCBzdGF0dXMNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmIFVTQl9EZWFjdGl2YXRlRW5kcG9pbnQoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4LCBVU0JfT1RHX0VQVHlwZURlZiAqZXApDQp7DQogIC8qIFJlYWQgREVQQ1RMbiByZWdpc3RlciAqLw0KICBpZiAoZXAtPmlzX2luID09IDEpDQogIHsNCiAgIFVTQnhfREVWSUNFLT5ERUFDSE1TSyAmPSB+KFVTQl9PVEdfREFJTlRNU0tfSUVQTSAmICgoMSA8PCAoZXAtPm51bSkpKSk7DQogICBVU0J4X0RFVklDRS0+REFJTlRNU0sgJj0gfihVU0JfT1RHX0RBSU5UTVNLX0lFUE0gJiAoKDEgPDwgKGVwLT5udW0pKSkpOyAgIA0KICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQQ1RMICY9IH4gVVNCX09UR19ESUVQQ1RMX1VTQkFFUDsgICANCiAgfQ0KICBlbHNlDQogIHsNCiAgICAgVVNCeF9ERVZJQ0UtPkRFQUNITVNLICY9IH4oVVNCX09UR19EQUlOVE1TS19PRVBNICYgKCgxIDw8IChlcC0+bnVtKSkgPDwgMTYpKTsNCiAgICAgVVNCeF9ERVZJQ0UtPkRBSU5UTVNLICY9IH4oVVNCX09UR19EQUlOVE1TS19PRVBNICYgKCgxIDw8IChlcC0+bnVtKSkgPDwgMTYpKTsgICAgIA0KICAgICBVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQQ1RMICY9IH5VU0JfT1RHX0RPRVBDVExfVVNCQUVQOyAgICAgIA0KICB9DQogIHJldHVybiBIQUxfT0s7DQp9DQoNCi8qKg0KICAqIEBicmllZiAgRGUtYWN0aXZhdGUgYW5kIGRlLWluaXRpYWxpemUgYSBkZWRpY2F0ZWQgZW5kcG9pbnQNCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcGFyYW0gIGVwOiBwb2ludGVyIHRvIGVuZHBvaW50IHN0cnVjdHVyZQ0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0RlYWN0aXZhdGVEZWRpY2F0ZWRFbmRwb2ludChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngsIFVTQl9PVEdfRVBUeXBlRGVmICplcCkNCnsNCiAgLyogUmVhZCBERVBDVExuIHJlZ2lzdGVyICovDQogIGlmIChlcC0+aXNfaW4gPT0gMSkNCiAgew0KICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQQ1RMICY9IH4gVVNCX09UR19ESUVQQ1RMX1VTQkFFUDsNCiAgIFVTQnhfREVWSUNFLT5EQUlOVE1TSyAmPSB+KFVTQl9PVEdfREFJTlRNU0tfSUVQTSAmICgoMSA8PCAoZXAtPm51bSkpKSk7DQogIH0NCiAgZWxzZQ0KICB7DQogICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBDVEwgJj0gflVTQl9PVEdfRE9FUENUTF9VU0JBRVA7IA0KICAgICBVU0J4X0RFVklDRS0+REFJTlRNU0sgJj0gfihVU0JfT1RHX0RBSU5UTVNLX09FUE0gJiAoKDEgPDwgKGVwLT5udW0pKSA8PCAxNikpOw0KICB9DQogIHJldHVybiBIQUxfT0s7DQp9DQoNCi8qKg0KICAqIEBicmllZiAgVVNCX0VQU3RhcnRYZmVyIDogc2V0dXAgYW5kIHN0YXJ0cyBhIHRyYW5zZmVyIG92ZXIgYW4gRVANCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcGFyYW0gIGVwOiBwb2ludGVyIHRvIGVuZHBvaW50IHN0cnVjdHVyZQ0KICAqIEBwYXJhbSAgZG1hOiBVU0IgZG1hIGVuYWJsZWQgb3IgZGlzYWJsZWQgDQogICogICAgICAgICAgVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIG9uZSBvZiB0aGVzZSB2YWx1ZXM6DQogICogICAgICAgICAgIDAgOiBETUEgZmVhdHVyZSBub3QgdXNlZCANCiAgKiAgICAgICAgICAgMSA6IERNQSBmZWF0dXJlIHVzZWQgIA0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0VQU3RhcnRYZmVyKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCAsIFVTQl9PVEdfRVBUeXBlRGVmICplcCwgdWludDhfdCBkbWEpDQp7DQogIHVpbnQxNl90IHBrdGNudCA9IDA7DQogIA0KICAvKiBJTiBlbmRwb2ludCAqLw0KICBpZiAoZXAtPmlzX2luID09IDEpDQogIHsNCiAgICAvKiBaZXJvIExlbmd0aCBQYWNrZXQ/ICovDQogICAgaWYgKGVwLT54ZmVyX2xlbiA9PSAwKQ0KICAgIHsNCiAgICAgIFVTQnhfSU5FUChlcC0+bnVtKS0+RElFUFRTSVogJj0gfihVU0JfT1RHX0RJRVBUU0laX1BLVENOVCk7IA0KICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQVFNJWiB8PSAoVVNCX09UR19ESUVQVFNJWl9QS1RDTlQgJiAoMSA8PCAxOSkpIDsNCiAgICAgIFVTQnhfSU5FUChlcC0+bnVtKS0+RElFUFRTSVogJj0gfihVU0JfT1RHX0RJRVBUU0laX1hGUlNJWik7IA0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgLyogUHJvZ3JhbSB0aGUgdHJhbnNmZXIgc2l6ZSBhbmQgcGFja2V0IGNvdW50DQogICAgICAqIGFzIGZvbGxvd3M6IHhmZXJzaXplID0gTiAqIG1heHBhY2tldCArDQogICAgICAqIHNob3J0X3BhY2tldCBwa3RjbnQgPSBOICsgKHNob3J0X3BhY2tldA0KICAgICAgKiBleGlzdCA/IDEgOiAwKQ0KICAgICAgKi8NCiAgICAgIFVTQnhfSU5FUChlcC0+bnVtKS0+RElFUFRTSVogJj0gfihVU0JfT1RHX0RJRVBUU0laX1hGUlNJWik7DQogICAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBUU0laICY9IH4oVVNCX09UR19ESUVQVFNJWl9QS1RDTlQpOyANCiAgICAgIFVTQnhfSU5FUChlcC0+bnVtKS0+RElFUFRTSVogfD0gKFVTQl9PVEdfRElFUFRTSVpfUEtUQ05UICYgKCgoZXAtPnhmZXJfbGVuICsgZXAtPm1heHBhY2tldCAtMSkvIGVwLT5tYXhwYWNrZXQpIDw8IDE5KSkgOw0KICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQVFNJWiB8PSAoVVNCX09UR19ESUVQVFNJWl9YRlJTSVogJiBlcC0+eGZlcl9sZW4pOyANCiAgICAgIA0KICAgICAgaWYgKGVwLT50eXBlID09IEVQX1RZUEVfSVNPQykNCiAgICAgIHsNCiAgICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQVFNJWiAmPSB+KFVTQl9PVEdfRElFUFRTSVpfTVVMQ05UKTsgDQogICAgICAgIFVTQnhfSU5FUChlcC0+bnVtKS0+RElFUFRTSVogfD0gKFVTQl9PVEdfRElFUFRTSVpfTVVMQ05UICYgKDEgPDwgMjkpKTsgDQogICAgICB9ICAgICAgIA0KICAgIH0NCg0KICAgIGlmIChkbWEgPT0gMSkNCiAgICB7DQogICAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBETUEgPSAodWludDMyX3QpKGVwLT5kbWFfYWRkcik7DQogICAgfQ0KICAgIGVsc2UNCiAgICB7DQogICAgICBpZiAoZXAtPnR5cGUgIT0gRVBfVFlQRV9JU09DKQ0KICAgICAgew0KICAgICAgICAvKiBFbmFibGUgdGhlIFR4IEZJRk8gRW1wdHkgSW50ZXJydXB0IGZvciB0aGlzIEVQICovDQogICAgICAgIGlmIChlcC0+eGZlcl9sZW4gPiAwKQ0KICAgICAgICB7DQogICAgICAgICAgVVNCeF9ERVZJQ0UtPkRJRVBFTVBNU0sgfD0gMSA8PCBlcC0+bnVtOw0KICAgICAgICB9DQogICAgICB9DQogICAgfQ0KDQogICAgaWYgKGVwLT50eXBlID09IEVQX1RZUEVfSVNPQykNCiAgICB7DQogICAgICBpZiAoKFVTQnhfREVWSUNFLT5EU1RTICYgKCAxIDw8IDggKSkgPT0gMCkNCiAgICAgIHsNCiAgICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQQ1RMIHw9IFVTQl9PVEdfRElFUENUTF9TT0RERlJNOw0KICAgICAgfQ0KICAgICAgZWxzZQ0KICAgICAgew0KICAgICAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBDVEwgfD0gVVNCX09UR19ESUVQQ1RMX1NEMFBJRF9TRVZORlJNOw0KICAgICAgfQ0KICAgIH0gDQogICAgDQogICAgLyogRVAgZW5hYmxlLCBJTiBkYXRhIGluIEZJRk8gKi8NCiAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBDVEwgfD0gKFVTQl9PVEdfRElFUENUTF9DTkFLIHwgVVNCX09UR19ESUVQQ1RMX0VQRU5BKTsNCiAgICANCiAgICBpZiAoZXAtPnR5cGUgPT0gRVBfVFlQRV9JU09DKQ0KICAgIHsNCiAgICAgIFVTQl9Xcml0ZVBhY2tldChVU0J4LCBlcC0+eGZlcl9idWZmLCBlcC0+bnVtLCBlcC0+eGZlcl9sZW4sIGRtYSk7ICAgDQogICAgfSAgICANCiAgfQ0KICBlbHNlIC8qIE9VVCBlbmRwb2ludCAqLw0KICB7DQogICAgLyogUHJvZ3JhbSB0aGUgdHJhbnNmZXIgc2l6ZSBhbmQgcGFja2V0IGNvdW50IGFzIGZvbGxvd3M6DQogICAgKiBwa3RjbnQgPSBODQogICAgKiB4ZmVyc2l6ZSA9IE4gKiBtYXhwYWNrZXQNCiAgICAqLyAgDQogICAgVVNCeF9PVVRFUChlcC0+bnVtKS0+RE9FUFRTSVogJj0gfihVU0JfT1RHX0RPRVBUU0laX1hGUlNJWik7IA0KICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBUU0laICY9IH4oVVNCX09UR19ET0VQVFNJWl9QS1RDTlQpOyANCiAgICAgIA0KICAgIGlmIChlcC0+eGZlcl9sZW4gPT0gMCkNCiAgICB7DQogICAgICBVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQVFNJWiB8PSAoVVNCX09UR19ET0VQVFNJWl9YRlJTSVogJiBlcC0+bWF4cGFja2V0KTsNCiAgICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBUU0laIHw9IChVU0JfT1RHX0RPRVBUU0laX1BLVENOVCAmICgxIDw8IDE5KSkgOyAgICAgIA0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgcGt0Y250ID0gKGVwLT54ZmVyX2xlbiArIGVwLT5tYXhwYWNrZXQgLTEpLyBlcC0+bWF4cGFja2V0OyANCiAgICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBUU0laIHw9IChVU0JfT1RHX0RPRVBUU0laX1BLVENOVCAmIChwa3RjbnQgPDwgMTkpKTsNCiAgICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBUU0laIHw9IChVU0JfT1RHX0RPRVBUU0laX1hGUlNJWiAmIChlcC0+bWF4cGFja2V0ICogcGt0Y250KSk7IA0KICAgIH0NCg0KICAgIGlmIChkbWEgPT0gMSkNCiAgICB7DQogICAgICBVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQRE1BID0gKHVpbnQzMl90KWVwLT54ZmVyX2J1ZmY7DQogICAgfQ0KICAgIA0KICAgIGlmIChlcC0+dHlwZSA9PSBFUF9UWVBFX0lTT0MpDQogICAgew0KICAgICAgaWYgKChVU0J4X0RFVklDRS0+RFNUUyAmICggMSA8PCA4ICkpID09IDApDQogICAgICB7DQogICAgICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBDVEwgfD0gVVNCX09UR19ET0VQQ1RMX1NPRERGUk07DQogICAgICB9DQogICAgICBlbHNlDQogICAgICB7DQogICAgICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBDVEwgfD0gVVNCX09UR19ET0VQQ1RMX1NEMFBJRF9TRVZORlJNOw0KICAgICAgfQ0KICAgIH0NCiAgICAvKiBFUCBlbmFibGUgKi8NCiAgICBVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQQ1RMIHw9IChVU0JfT1RHX0RPRVBDVExfQ05BSyB8IFVTQl9PVEdfRE9FUENUTF9FUEVOQSk7DQogIH0NCiAgcmV0dXJuIEhBTF9PSzsNCn0NCg0KLyoqDQogICogQGJyaWVmICBVU0JfRVAwU3RhcnRYZmVyIDogc2V0dXAgYW5kIHN0YXJ0cyBhIHRyYW5zZmVyIG92ZXIgdGhlIEVQICAwDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBlcDogcG9pbnRlciB0byBlbmRwb2ludCBzdHJ1Y3R1cmUNCiAgKiBAcGFyYW0gIGRtYTogVVNCIGRtYSBlbmFibGVkIG9yIGRpc2FibGVkIA0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBvbmUgb2YgdGhlc2UgdmFsdWVzOg0KICAqICAgICAgICAgICAwIDogRE1BIGZlYXR1cmUgbm90IHVzZWQgDQogICogICAgICAgICAgIDEgOiBETUEgZmVhdHVyZSB1c2VkICANCiAgKiBAcmV0dmFsIEhBTCBzdGF0dXMNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmIFVTQl9FUDBTdGFydFhmZXIoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4ICwgVVNCX09UR19FUFR5cGVEZWYgKmVwLCB1aW50OF90IGRtYSkNCnsNCiAgLyogSU4gZW5kcG9pbnQgKi8NCiAgaWYgKGVwLT5pc19pbiA9PSAxKQ0KICB7DQogICAgLyogWmVybyBMZW5ndGggUGFja2V0PyAqLw0KICAgIGlmIChlcC0+eGZlcl9sZW4gPT0gMCkNCiAgICB7DQogICAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBUU0laICY9IH4oVVNCX09UR19ESUVQVFNJWl9QS1RDTlQpOyANCiAgICAgIFVTQnhfSU5FUChlcC0+bnVtKS0+RElFUFRTSVogfD0gKFVTQl9PVEdfRElFUFRTSVpfUEtUQ05UICYgKDEgPDwgMTkpKSA7DQogICAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBUU0laICY9IH4oVVNCX09UR19ESUVQVFNJWl9YRlJTSVopOyANCiAgICB9DQogICAgZWxzZQ0KICAgIHsNCiAgICAgIC8qIFByb2dyYW0gdGhlIHRyYW5zZmVyIHNpemUgYW5kIHBhY2tldCBjb3VudA0KICAgICAgKiBhcyBmb2xsb3dzOiB4ZmVyc2l6ZSA9IE4gKiBtYXhwYWNrZXQgKw0KICAgICAgKiBzaG9ydF9wYWNrZXQgcGt0Y250ID0gTiArIChzaG9ydF9wYWNrZXQNCiAgICAgICogZXhpc3QgPyAxIDogMCkNCiAgICAgICovDQogICAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBUU0laICY9IH4oVVNCX09UR19ESUVQVFNJWl9YRlJTSVopOw0KICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQVFNJWiAmPSB+KFVTQl9PVEdfRElFUFRTSVpfUEtUQ05UKTsgDQogICAgICANCiAgICAgIGlmKGVwLT54ZmVyX2xlbiA+IGVwLT5tYXhwYWNrZXQpDQogICAgICB7DQogICAgICAgIGVwLT54ZmVyX2xlbiA9IGVwLT5tYXhwYWNrZXQ7DQogICAgICB9DQogICAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBUU0laIHw9IChVU0JfT1RHX0RJRVBUU0laX1BLVENOVCAmICgxIDw8IDE5KSkgOw0KICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQVFNJWiB8PSAoVVNCX09UR19ESUVQVFNJWl9YRlJTSVogJiBlcC0+eGZlcl9sZW4pOyANCiAgICANCiAgICB9DQogICAgDQogICAgLyogRVAgZW5hYmxlLCBJTiBkYXRhIGluIEZJRk8gKi8NCiAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBDVEwgfD0gKFVTQl9PVEdfRElFUENUTF9DTkFLIHwgVVNCX09UR19ESUVQQ1RMX0VQRU5BKTsNCiAgICANCiAgICBpZiAoZG1hID09IDEpDQogICAgew0KICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQRE1BID0gKHVpbnQzMl90KShlcC0+ZG1hX2FkZHIpOw0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgLyogRW5hYmxlIHRoZSBUeCBGSUZPIEVtcHR5IEludGVycnVwdCBmb3IgdGhpcyBFUCAqLw0KICAgICAgaWYgKGVwLT54ZmVyX2xlbiA+IDBVKQ0KICAgICAgew0KICAgICAgICBVU0J4X0RFVklDRS0+RElFUEVNUE1TSyB8PSAxVSA8PCAoZXAtPm51bSk7DQogICAgICB9DQogICAgfSAgDQogIH0NCiAgZWxzZSAvKiBPVVQgZW5kcG9pbnQgKi8NCiAgew0KICAgIC8qIFByb2dyYW0gdGhlIHRyYW5zZmVyIHNpemUgYW5kIHBhY2tldCBjb3VudCBhcyBmb2xsb3dzOg0KICAgICogcGt0Y250ID0gTg0KICAgICogeGZlcnNpemUgPSBOICogbWF4cGFja2V0DQogICAgKi8NCiAgICBVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQVFNJWiAmPSB+KFVTQl9PVEdfRE9FUFRTSVpfWEZSU0laKTsgDQogICAgVVNCeF9PVVRFUChlcC0+bnVtKS0+RE9FUFRTSVogJj0gfihVU0JfT1RHX0RPRVBUU0laX1BLVENOVCk7IA0KICAgICAgDQogICAgaWYgKGVwLT54ZmVyX2xlbiA+IDApDQogICAgew0KICAgICAgZXAtPnhmZXJfbGVuID0gZXAtPm1heHBhY2tldDsNCiAgICB9DQogICAgDQogICAgVVNCeF9PVVRFUChlcC0+bnVtKS0+RE9FUFRTSVogfD0gKFVTQl9PVEdfRE9FUFRTSVpfUEtUQ05UICYgKDEgPDwgMTkpKTsNCiAgICBVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQVFNJWiB8PSAoVVNCX09UR19ET0VQVFNJWl9YRlJTSVogJiAoZXAtPm1heHBhY2tldCkpOyANCiAgICANCg0KICAgIGlmIChkbWEgPT0gMSkNCiAgICB7DQogICAgICBVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQRE1BID0gKHVpbnQzMl90KShlcC0+eGZlcl9idWZmKTsNCiAgICB9DQogICAgDQogICAgLyogRVAgZW5hYmxlICovDQogICAgVVNCeF9PVVRFUChlcC0+bnVtKS0+RE9FUENUTCB8PSAoVVNCX09UR19ET0VQQ1RMX0NOQUsgfCBVU0JfT1RHX0RPRVBDVExfRVBFTkEpOyAgICANCiAgfQ0KICByZXR1cm4gSEFMX09LOw0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFVTQl9Xcml0ZVBhY2tldCA6IFdyaXRlcyBhIHBhY2tldCBpbnRvIHRoZSBUeCBGSUZPIGFzc29jaWF0ZWQgDQogICogICAgICAgICB3aXRoIHRoZSBFUC9jaGFubmVsDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlICAgICAgICAgICANCiAgKiBAcGFyYW0gIHNyYyA6ICBwb2ludGVyIHRvIHNvdXJjZSBidWZmZXINCiAgKiBAcGFyYW0gIGNoX2VwX251bSA6IGVuZHBvaW50IG9yIGhvc3QgY2hhbm5lbCBudW1iZXINCiAgKiBAcGFyYW0gIGxlbiA6IE51bWJlciBvZiBieXRlcyB0byB3cml0ZQ0KICAqIEBwYXJhbSAgZG1hOiBVU0IgZG1hIGVuYWJsZWQgb3IgZGlzYWJsZWQgDQogICogICAgICAgICAgVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIG9uZSBvZiB0aGVzZSB2YWx1ZXM6DQogICogICAgICAgICAgIDAgOiBETUEgZmVhdHVyZSBub3QgdXNlZCANCiAgKiAgICAgICAgICAgMSA6IERNQSBmZWF0dXJlIHVzZWQgIA0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX1dyaXRlUGFja2V0KFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgdWludDhfdCAqc3JjLCB1aW50OF90IGNoX2VwX251bSwgdWludDE2X3QgbGVuLCB1aW50OF90IGRtYSkNCnsNCiAgdWludDMyX3QgY291bnQzMmI9IDAgLCBpPSAwOw0KICANCiAgaWYgKGRtYSA9PSAwKQ0KICB7DQogICAgY291bnQzMmIgPSAgKGxlbiArIDMpIC8gNDsNCiAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQzMmI7IGkrKywgc3JjICs9IDQpDQogICAgew0KICAgICAgVVNCeF9ERklGTyhjaF9lcF9udW0pID0gKigoX19wYWNrZWQgdWludDMyX3QgKilzcmMpOw0KICAgIH0NCiAgfQ0KICByZXR1cm4gSEFMX09LOw0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFVTQl9SZWFkUGFja2V0IDogcmVhZCBhIHBhY2tldCBmcm9tIHRoZSBUeCBGSUZPIGFzc29jaWF0ZWQgDQogICogICAgICAgICB3aXRoIHRoZSBFUC9jaGFubmVsDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlICANCiAgKiBAcGFyYW0gIHNyYyA6IHNvdXJjZSBwb2ludGVyDQogICogQHBhcmFtICBjaF9lcF9udW0gOiBlbmRwb2ludCBvciBob3N0IGNoYW5uZWwgbnVtYmVyDQogICogQHBhcmFtICBsZW4gOiBOdW1iZXIgb2YgYnl0ZXMgdG8gcmVhZA0KICAqIEBwYXJhbSAgZG1hOiBVU0IgZG1hIGVuYWJsZWQgb3IgZGlzYWJsZWQgDQogICogICAgICAgICAgVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIG9uZSBvZiB0aGVzZSB2YWx1ZXM6DQogICogICAgICAgICAgIDAgOiBETUEgZmVhdHVyZSBub3QgdXNlZCANCiAgKiAgICAgICAgICAgMSA6IERNQSBmZWF0dXJlIHVzZWQgIA0KICAqIEByZXR2YWwgcG9pbnRlciB0byBkZXN0aW5hdGlvbiBidWZmZXINCiAgKi8NCnZvaWQgKlVTQl9SZWFkUGFja2V0KFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgdWludDhfdCAqZGVzdCwgdWludDE2X3QgbGVuKQ0Kew0KICB1aW50MzJfdCBpPTA7DQogIHVpbnQzMl90IGNvdW50MzJiID0gKGxlbiArIDMpIC8gNDsNCiAgDQogIGZvciAoIGkgPSAwOyBpIDwgY291bnQzMmI7IGkrKywgZGVzdCArPSA0ICkNCiAgew0KICAgICooX19wYWNrZWQgdWludDMyX3QgKilkZXN0ID0gVVNCeF9ERklGTygwKTsNCiAgICANCiAgfQ0KICByZXR1cm4gKCh2b2lkICopZGVzdCk7DQp9DQoNCi8qKg0KICAqIEBicmllZiAgVVNCX0VQU2V0U3RhbGwgOiBzZXQgYSBzdGFsbCBjb25kaXRpb24gb3ZlciBhbiBFUA0KICAqIEBwYXJhbSAgVVNCeCA6IFNlbGVjdGVkIGRldmljZQ0KICAqIEBwYXJhbSAgZXA6IHBvaW50ZXIgdG8gZW5kcG9pbnQgc3RydWN0dXJlICAgDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQpIQUxfU3RhdHVzVHlwZURlZiBVU0JfRVBTZXRTdGFsbChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQnggLCBVU0JfT1RHX0VQVHlwZURlZiAqZXApDQp7DQogIGlmIChlcC0+aXNfaW4gPT0gMSkNCiAgew0KICAgIGlmICgoKFVTQnhfSU5FUChlcC0+bnVtKS0+RElFUENUTCkgJiBVU0JfT1RHX0RJRVBDVExfRVBFTkEpID09IDApDQogICAgew0KICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQQ1RMICY9IH4oVVNCX09UR19ESUVQQ1RMX0VQRElTKTsgDQogICAgfSANCiAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBDVEwgfD0gVVNCX09UR19ESUVQQ1RMX1NUQUxMOw0KICB9DQogIGVsc2UNCiAgew0KICAgIGlmICgoKFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBDVEwpICYgVVNCX09UR19ET0VQQ1RMX0VQRU5BKSA9PSAwKQ0KICAgIHsNCiAgICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBDVEwgJj0gfihVU0JfT1RHX0RPRVBDVExfRVBESVMpOyANCiAgICB9IA0KICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBDVEwgfD0gVVNCX09UR19ET0VQQ1RMX1NUQUxMOw0KICB9DQogIHJldHVybiBIQUxfT0s7DQp9DQoNCg0KLyoqDQogICogQGJyaWVmICBVU0JfRVBDbGVhclN0YWxsIDogQ2xlYXIgYSBzdGFsbCBjb25kaXRpb24gb3ZlciBhbiBFUA0KICAqIEBwYXJhbSAgVVNCeCA6IFNlbGVjdGVkIGRldmljZQ0KICAqIEBwYXJhbSAgZXA6IHBvaW50ZXIgdG8gZW5kcG9pbnQgc3RydWN0dXJlICAgDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQpIQUxfU3RhdHVzVHlwZURlZiBVU0JfRVBDbGVhclN0YWxsKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgVVNCX09UR19FUFR5cGVEZWYgKmVwKQ0Kew0KICBpZiAoZXAtPmlzX2luID09IDEpDQogIHsNCiAgICBVU0J4X0lORVAoZXAtPm51bSktPkRJRVBDVEwgJj0gflVTQl9PVEdfRElFUENUTF9TVEFMTDsNCiAgICBpZiAoZXAtPnR5cGUgPT0gRVBfVFlQRV9JTlRSIHx8IGVwLT50eXBlID09IEVQX1RZUEVfQlVMSykNCiAgICB7DQogICAgICAgVVNCeF9JTkVQKGVwLT5udW0pLT5ESUVQQ1RMIHw9IFVTQl9PVEdfRElFUENUTF9TRDBQSURfU0VWTkZSTTsgLyogREFUQTAgKi8NCiAgICB9ICAgIA0KICB9DQogIGVsc2UNCiAgew0KICAgIFVTQnhfT1VURVAoZXAtPm51bSktPkRPRVBDVEwgJj0gflVTQl9PVEdfRE9FUENUTF9TVEFMTDsNCiAgICBpZiAoZXAtPnR5cGUgPT0gRVBfVFlQRV9JTlRSIHx8IGVwLT50eXBlID09IEVQX1RZUEVfQlVMSykNCiAgICB7DQogICAgICBVU0J4X09VVEVQKGVwLT5udW0pLT5ET0VQQ1RMIHw9IFVTQl9PVEdfRE9FUENUTF9TRDBQSURfU0VWTkZSTTsgLyogREFUQTAgKi8NCiAgICB9ICAgIA0KICB9DQogIHJldHVybiBIQUxfT0s7DQp9DQoNCi8qKg0KICAqIEBicmllZiAgVVNCX1N0b3BEZXZpY2UgOiBTdG9wIHRoZSB1c2IgZGV2aWNlIG1vZGUNCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcmV0dmFsIEhBTCBzdGF0dXMNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmIFVTQl9TdG9wRGV2aWNlKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCkNCnsNCiAgdWludDMyX3QgaTsNCiAgDQogIC8qIENsZWFyIFBlbmRpbmcgaW50ZXJydXB0ICovDQogIGZvciAoaSA9IDA7IGkgPCAxNSA7IGkrKykNCiAgew0KICAgIFVTQnhfSU5FUChpKS0+RElFUElOVCAgPSAweEZGOw0KICAgIFVTQnhfT1VURVAoaSktPkRPRVBJTlQgID0gMHhGRjsNCiAgfQ0KICBVU0J4X0RFVklDRS0+REFJTlQgPSAweEZGRkZGRkZGOw0KICANCiAgLyogQ2xlYXIgaW50ZXJydXB0IG1hc2tzICovDQogIFVTQnhfREVWSUNFLT5ESUVQTVNLICA9IDA7DQogIFVTQnhfREVWSUNFLT5ET0VQTVNLICA9IDA7DQogIFVTQnhfREVWSUNFLT5EQUlOVE1TSyA9IDA7DQogIA0KICAvKiBGbHVzaCB0aGUgRklGTyAqLw0KICBVU0JfRmx1c2hSeEZpZm8oVVNCeCk7DQogIFVTQl9GbHVzaFR4RmlmbyhVU0J4ICwgIDB4MTAgKTsgIA0KICANCiAgcmV0dXJuIEhBTF9PSzsNCn0NCg0KLyoqDQogICogQGJyaWVmICBVU0JfU2V0RGV2QWRkcmVzcyA6IFN0b3AgdGhlIHVzYiBkZXZpY2UgbW9kZQ0KICAqIEBwYXJhbSAgVVNCeCA6IFNlbGVjdGVkIGRldmljZQ0KICAqIEBwYXJhbSAgYWRkcmVzcyA6IG5ldyBkZXZpY2UgYWRkcmVzcyB0byBiZSBhc3NpZ25lZA0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBhIHZhbHVlIGZyb20gMCB0byAyNTUNCiAgKiBAcmV0dmFsIEhBTCBzdGF0dXMNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmICBVU0JfU2V0RGV2QWRkcmVzcyAoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4LCB1aW50OF90IGFkZHJlc3MpDQp7DQogIFVTQnhfREVWSUNFLT5EQ0ZHICY9IH4gKFVTQl9PVEdfRENGR19EQUQpOw0KICBVU0J4X0RFVklDRS0+RENGRyB8PSAoYWRkcmVzcyA8PCA0KSAmIFVTQl9PVEdfRENGR19EQUQgOw0KICANCiAgcmV0dXJuIEhBTF9PSzsgIA0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFVTQl9EZXZDb25uZWN0IDogQ29ubmVjdCB0aGUgVVNCIGRldmljZSBieSBlbmFibGluZyB0aGUgcHVsbC11cC9wdWxsLWRvd24NCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcmV0dmFsIEhBTCBzdGF0dXMNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmICBVU0JfRGV2Q29ubmVjdCAoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4KQ0Kew0KICBVU0J4X0RFVklDRS0+RENUTCAmPSB+VVNCX09UR19EQ1RMX1NESVMgOw0KICBIQUxfRGVsYXkoMyk7DQogIA0KICByZXR1cm4gSEFMX09LOyAgDQp9DQoNCi8qKg0KICAqIEBicmllZiAgVVNCX0RldkRpc2Nvbm5lY3QgOiBEaXNjb25uZWN0IHRoZSBVU0IgZGV2aWNlIGJ5IGRpc2FibGluZyB0aGUgcHVsbC11cC9wdWxsLWRvd24NCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcmV0dmFsIEhBTCBzdGF0dXMNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmICBVU0JfRGV2RGlzY29ubmVjdCAoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4KQ0Kew0KICBVU0J4X0RFVklDRS0+RENUTCB8PSBVU0JfT1RHX0RDVExfU0RJUyA7DQogIEhBTF9EZWxheSgzKTsNCiAgDQogIHJldHVybiBIQUxfT0s7ICANCn0NCg0KLyoqDQogICogQGJyaWVmICBVU0JfUmVhZEludGVycnVwdHM6IHJldHVybiB0aGUgZ2xvYmFsIFVTQiBpbnRlcnJ1cHQgc3RhdHVzDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQp1aW50MzJfdCAgVVNCX1JlYWRJbnRlcnJ1cHRzIChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngpDQp7DQogIHVpbnQzMl90IHYgPSAwOw0KICANCiAgdiA9IFVTQngtPkdJTlRTVFM7DQogIHYgJj0gVVNCeC0+R0lOVE1TSzsNCiAgcmV0dXJuIHY7ICANCn0NCg0KLyoqDQogICogQGJyaWVmICBVU0JfUmVhZERldkFsbE91dEVwSW50ZXJydXB0OiByZXR1cm4gdGhlIFVTQiBkZXZpY2UgT1VUIGVuZHBvaW50cyBpbnRlcnJ1cHQgc3RhdHVzDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQp1aW50MzJfdCBVU0JfUmVhZERldkFsbE91dEVwSW50ZXJydXB0IChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngpDQp7DQogIHVpbnQzMl90IHY7DQogIHYgID0gVVNCeF9ERVZJQ0UtPkRBSU5UOw0KICB2ICY9IFVTQnhfREVWSUNFLT5EQUlOVE1TSzsNCiAgcmV0dXJuICgodiAmIDB4ZmZmZjAwMDApID4+IDE2KTsNCn0NCg0KLyoqDQogICogQGJyaWVmICBVU0JfUmVhZERldkFsbEluRXBJbnRlcnJ1cHQ6IHJldHVybiB0aGUgVVNCIGRldmljZSBJTiBlbmRwb2ludHMgaW50ZXJydXB0IHN0YXR1cw0KICAqIEBwYXJhbSAgVVNCeCA6IFNlbGVjdGVkIGRldmljZQ0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KdWludDMyX3QgVVNCX1JlYWREZXZBbGxJbkVwSW50ZXJydXB0IChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngpDQp7DQogIHVpbnQzMl90IHY7DQogIHYgID0gVVNCeF9ERVZJQ0UtPkRBSU5UOw0KICB2ICY9IFVTQnhfREVWSUNFLT5EQUlOVE1TSzsNCiAgcmV0dXJuICgodiAmIDB4RkZGRikpOw0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFJldHVybnMgRGV2aWNlIE9VVCBFUCBJbnRlcnJ1cHQgcmVnaXN0ZXINCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcGFyYW0gIGVwbnVtIDogZW5kcG9pbnQgbnVtYmVyDQogICogICAgICAgICAgVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIGEgdmFsdWUgZnJvbSAwIHRvIDE1DQogICogQHJldHZhbCBEZXZpY2UgT1VUIEVQIEludGVycnVwdCByZWdpc3Rlcg0KICAqLw0KdWludDMyX3QgVVNCX1JlYWREZXZPdXRFUEludGVycnVwdCAoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4ICwgdWludDhfdCBlcG51bSkNCnsNCiAgdWludDMyX3QgdjsNCiAgdiAgPSBVU0J4X09VVEVQKGVwbnVtKS0+RE9FUElOVDsNCiAgdiAmPSBVU0J4X0RFVklDRS0+RE9FUE1TSzsNCiAgcmV0dXJuIHY7DQp9DQoNCi8qKg0KICAqIEBicmllZiAgUmV0dXJucyBEZXZpY2UgSU4gRVAgSW50ZXJydXB0IHJlZ2lzdGVyDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBlcG51bSA6IGVuZHBvaW50IG51bWJlcg0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBhIHZhbHVlIGZyb20gMCB0byAxNQ0KICAqIEByZXR2YWwgRGV2aWNlIElOIEVQIEludGVycnVwdCByZWdpc3Rlcg0KICAqLw0KdWludDMyX3QgVVNCX1JlYWREZXZJbkVQSW50ZXJydXB0IChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQnggLCB1aW50OF90IGVwbnVtKQ0Kew0KICB1aW50MzJfdCB2LCBtc2ssIGVtcDsNCiAgDQogIG1zayA9IFVTQnhfREVWSUNFLT5ESUVQTVNLOw0KICBlbXAgPSBVU0J4X0RFVklDRS0+RElFUEVNUE1TSzsNCiAgbXNrIHw9ICgoZW1wID4+IGVwbnVtKSAmIDB4MSkgPDwgNzsNCiAgdiA9IFVTQnhfSU5FUChlcG51bSktPkRJRVBJTlQgJiBtc2s7DQogIHJldHVybiB2Ow0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFVTQl9DbGVhckludGVycnVwdHM6IGNsZWFyIGEgVVNCIGludGVycnVwdA0KICAqIEBwYXJhbSAgVVNCeCA6IFNlbGVjdGVkIGRldmljZQ0KICAqIEBwYXJhbSAgaW50ZXJydXB0IDogaW50ZXJydXB0IGZsYWcNCiAgKiBAcmV0dmFsIE5vbmUNCiAgKi8NCnZvaWQgIFVTQl9DbGVhckludGVycnVwdHMgKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgdWludDMyX3QgaW50ZXJydXB0KQ0Kew0KICBVU0J4LT5HSU5UU1RTIHw9IGludGVycnVwdDsgDQp9DQoNCi8qKg0KICAqIEBicmllZiAgUmV0dXJucyBVU0IgY29yZSBtb2RlDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCByZXR1cm4gY29yZSBtb2RlIDogSG9zdCBvciBEZXZpY2UNCiAgKiAgICAgICAgICBUaGlzIHBhcmFtZXRlciBjYW4gYmUgb25lIG9mIHRoZXNlIHZhbHVlczoNCiAgKiAgICAgICAgICAgMCA6IEhvc3QgDQogICogICAgICAgICAgIDEgOiBEZXZpY2UNCiAgKi8NCnVpbnQzMl90IFVTQl9HZXRNb2RlKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCkNCnsNCiAgcmV0dXJuICgoVVNCeC0+R0lOVFNUUyApICYgMHgxKTsNCn0NCg0KDQovKioNCiAgKiBAYnJpZWYgIEFjdGl2YXRlIEVQMCBmb3IgU2V0dXAgdHJhbnNhY3Rpb25zDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQpIQUxfU3RhdHVzVHlwZURlZiAgVVNCX0FjdGl2YXRlU2V0dXAgKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCkNCnsNCiAgLyogU2V0IHRoZSBNUFMgb2YgdGhlIElOIEVQIGJhc2VkIG9uIHRoZSBlbnVtZXJhdGlvbiBzcGVlZCAqLw0KICBVU0J4X0lORVAoMCktPkRJRVBDVEwgJj0gflVTQl9PVEdfRElFUENUTF9NUFNJWjsNCiAgDQogIGlmKChVU0J4X0RFVklDRS0+RFNUUyAmIFVTQl9PVEdfRFNUU19FTlVNU1BEKSA9PSBEU1RTX0VOVU1TUERfTFNfUEhZXzZNSFopDQogIHsNCiAgICBVU0J4X0lORVAoMCktPkRJRVBDVEwgfD0gMzsNCiAgfQ0KICBVU0J4X0RFVklDRS0+RENUTCB8PSBVU0JfT1RHX0RDVExfQ0dJTkFLOw0KDQogIHJldHVybiBIQUxfT0s7DQp9DQoNCg0KLyoqDQogICogQGJyaWVmICBQcmVwYXJlIHRoZSBFUDAgdG8gc3RhcnQgdGhlIGZpcnN0IGNvbnRyb2wgc2V0dXANCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcGFyYW0gIGRtYTogVVNCIGRtYSBlbmFibGVkIG9yIGRpc2FibGVkIA0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBvbmUgb2YgdGhlc2UgdmFsdWVzOg0KICAqICAgICAgICAgICAwIDogRE1BIGZlYXR1cmUgbm90IHVzZWQgDQogICogICAgICAgICAgIDEgOiBETUEgZmVhdHVyZSB1c2VkICANCiAgKiBAcGFyYW0gIHBzZXR1cCA6IHBvaW50ZXIgdG8gc2V0dXAgcGFja2V0DQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQpIQUxfU3RhdHVzVHlwZURlZiBVU0JfRVAwX091dFN0YXJ0KFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgdWludDhfdCBkbWEsIHVpbnQ4X3QgKnBzZXR1cCkNCnsNCiAgVVNCeF9PVVRFUCgwKS0+RE9FUFRTSVogPSAwOw0KICBVU0J4X09VVEVQKDApLT5ET0VQVFNJWiB8PSAoVVNCX09UR19ET0VQVFNJWl9QS1RDTlQgJiAoMSA8PCAxOSkpIDsNCiAgVVNCeF9PVVRFUCgwKS0+RE9FUFRTSVogfD0gKDMgKiA4KTsNCiAgVVNCeF9PVVRFUCgwKS0+RE9FUFRTSVogfD0gIFVTQl9PVEdfRE9FUFRTSVpfU1RVUENOVDsgIA0KICANCiAgaWYgKGRtYSA9PSAxKQ0KICB7DQogICAgVVNCeF9PVVRFUCgwKS0+RE9FUERNQSA9ICh1aW50MzJfdClwc2V0dXA7DQogICAgLyogRVAgZW5hYmxlICovDQogICAgVVNCeF9PVVRFUCgwKS0+RE9FUENUTCA9IDB4ODAwMDgwMDA7DQogIH0NCiAgDQogIHJldHVybiBIQUxfT0s7ICANCn0NCg0KDQovKioNCiAgKiBAYnJpZWYgIFJlc2V0IHRoZSBVU0IgQ29yZSAobmVlZGVkIGFmdGVyIFVTQiBjbG9jayBzZXR0aW5ncyBjaGFuZ2UpDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQpzdGF0aWMgSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0NvcmVSZXNldChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngpDQp7DQogIHVpbnQzMl90IGNvdW50ID0gMDsNCg0KICAvKiBXYWl0IGZvciBBSEIgbWFzdGVyIElETEUgc3RhdGUuICovDQogIGRvDQogIHsNCiAgICBpZiAoKytjb3VudCA+IDIwMDAwMCkNCiAgICB7DQogICAgICByZXR1cm4gSEFMX1RJTUVPVVQ7DQogICAgfQ0KICB9DQogIHdoaWxlICgoVVNCeC0+R1JTVENUTCAmIFVTQl9PVEdfR1JTVENUTF9BSEJJREwpID09IDApOw0KICANCiAgLyogQ29yZSBTb2Z0IFJlc2V0ICovDQogIGNvdW50ID0gMDsNCiAgVVNCeC0+R1JTVENUTCB8PSBVU0JfT1RHX0dSU1RDVExfQ1NSU1Q7DQoNCiAgZG8NCiAgew0KICAgIGlmICgrK2NvdW50ID4gMjAwMDAwKQ0KICAgIHsNCiAgICAgIHJldHVybiBIQUxfVElNRU9VVDsNCiAgICB9DQogIH0NCiAgd2hpbGUgKChVU0J4LT5HUlNUQ1RMICYgVVNCX09UR19HUlNUQ1RMX0NTUlNUKSA9PSBVU0JfT1RHX0dSU1RDVExfQ1NSU1QpOw0KICANCiAgcmV0dXJuIEhBTF9PSzsNCn0NCg0KI2lmZGVmIFVTQl9IU19QSFlDIA0KLyoqDQogICogQGJyaWVmICBFbmFibGVzIGNvbnRyb2wgb2YgYSBIaWdoIFNwZWVkIFVTQiBQSFmScw0KICAqICAgICAgICAgSW5pdCB0aGUgbG93IGxldmVsIGhhcmR3YXJlIDogR1BJTywgQ0xPQ0ssIE5WSUMuLi4gDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQpzdGF0aWMgSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0hTX1BIWUNJbml0KFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCkNCnsNCiAgdWludDMyX3QgY291bnQgPSAwOw0KICANCiAgLyogRW5hYmxlIExETyAqLw0KICBVU0JfSFNfUEhZQy0+VVNCX0hTX1BIWUNfTERPIHw9IFVTQl9IU19QSFlDX0xET19FTkFCTEU7DQogIA0KICAvKiB3YWl0IGZvciBMRE8gUmVhZHkgKi8NCiAgd2hpbGUoKFVTQl9IU19QSFlDLT5VU0JfSFNfUEhZQ19MRE8gJiBVU0JfSFNfUEhZQ19MRE9fU1RBVFVTKSA9PSBSRVNFVCkNCiAgew0KICAgIGlmICgrK2NvdW50ID4gMjAwMDAwKQ0KICAgIHsNCiAgICAgIHJldHVybiBIQUxfVElNRU9VVDsNCiAgICB9DQogIH0NCg0KICAvKiBDb250cm9scyBQSFkgZnJlcXVlbmN5IG9wZXJhdGlvbiBzZWxlY3Rpb24gKi8NCiAgaWYgKEhTRV9WQUxVRSA9PSAxMjAwMDAwMCkgLyogSFNFID0gMTJNSHogKi8NCiAgew0KICAgIFVTQl9IU19QSFlDLT5VU0JfSFNfUEhZQ19QTEwgPSAodWludDMyX3QpKDB4MCA8PCAxKTsNCiAgfQ0KICBlbHNlIGlmIChIU0VfVkFMVUUgPT0gMTI1MDAwMDApIC8qIEhTRSA9IDEyLjVNSHogKi8NCiAgew0KICAgIFVTQl9IU19QSFlDLT5VU0JfSFNfUEhZQ19QTEwgPSAodWludDMyX3QpKDB4MiA8PCAxKTsNCiAgfQ0KICBlbHNlIGlmIChIU0VfVkFMVUUgPT0gMTYwMDAwMDApIC8qIEhTRSA9IDE2TUh6ICovDQogIHsNCiAgICBVU0JfSFNfUEhZQy0+VVNCX0hTX1BIWUNfUExMID0gKHVpbnQzMl90KSgweDMgPDwgMSk7DQogIH0NCiAgDQogIGVsc2UgaWYgKEhTRV9WQUxVRSA9PSAyNDAwMDAwMCkgLyogSFNFID0gMjRNSHogKi8NCiAgew0KICAgIFVTQl9IU19QSFlDLT5VU0JfSFNfUEhZQ19QTEwgPSAodWludDMyX3QpKDB4NCA8PCAxKTsNCiAgfQ0KICBlbHNlIGlmIChIU0VfVkFMVUUgPT0gMjUwMDAwMDApIC8qIEhTRSA9IDI1TUh6ICovDQogIHsNCiAgICBVU0JfSFNfUEhZQy0+VVNCX0hTX1BIWUNfUExMID0gKHVpbnQzMl90KSgweDUgPDwgMSk7DQogIH0NCiAgZWxzZSBpZiAoSFNFX1ZBTFVFID09IDMyMDAwMDAwKSAvKiBIU0UgPSAzMk1IeiAqLw0KICB7DQogICAgVVNCX0hTX1BIWUMtPlVTQl9IU19QSFlDX1BMTCA9ICh1aW50MzJfdCkoMHg3IDw8IDEpOw0KICB9DQogIA0KICAvKiBDb250cm9sIHRoZSB0dW5pbmcgaW50ZXJmYWNlIG9mIHRoZSBIaWdoIFNwZWVkIFBIWSAqLw0KICBVU0JfSFNfUEhZQy0+VVNCX0hTX1BIWUNfVFVORSB8PSBVU0JfSFNfUEhZQ19UVU5FX1ZBTFVFOw0KICANCiAgLyogRW5hYmxlIFBMTCBpbnRlcm5hbCBQSFkgKi8NCiAgVVNCX0hTX1BIWUMtPlVTQl9IU19QSFlDX1BMTCB8PSBVU0JfSFNfUEhZQ19QTExfUExMRU47DQoNCiAgLyogMm1zIERlbGF5IHJlcXVpcmVkIHRvIGdldCBpbnRlcm5hbCBwaHkgY2xvY2sgc3RhYmxlICovDQogIEhBTF9EZWxheSgyKTsNCiAgDQogIHJldHVybiBIQUxfT0s7DQp9DQoNCiNlbmRpZiAvKiBVU0JfSFNfUEhZQyAqLw0KLyoqDQogICogQGJyaWVmICBVU0JfSG9zdEluaXQgOiBJbml0aWFsaXplcyB0aGUgVVNCIE9URyBjb250cm9sbGVyIHJlZ2lzdGVycyANCiAgKiAgICAgICAgIGZvciBIb3N0IG1vZGUgDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBjZmcgIDogcG9pbnRlciB0byBhIFVTQl9PVEdfQ2ZnVHlwZURlZiBzdHJ1Y3R1cmUgdGhhdCBjb250YWlucw0KICAqICAgICAgICAgdGhlIGNvbmZpZ3VyYXRpb24gaW5mb3JtYXRpb24gZm9yIHRoZSBzcGVjaWZpZWQgVVNCeCBwZXJpcGhlcmFsLg0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0hvc3RJbml0IChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngsIFVTQl9PVEdfQ2ZnVHlwZURlZiBjZmcpDQp7DQogIHVpbnQzMl90IGk7DQogIA0KICAvKiBSZXN0YXJ0IHRoZSBQaHkgQ2xvY2sgKi8NCiAgVVNCeF9QQ0dDQ1RMID0gMDsNCiAgDQogIC8qQWN0aXZhdGUgVkJVUyBTZW5zaW5nIEIgKi8NCiAgVVNCeC0+R0NDRkcgfD0gVVNCX09UR19HQ0NGR19WQkRFTjsNCiAgDQogIC8qIERpc2FibGUgdGhlIEZTL0xTIHN1cHBvcnQgbW9kZSBvbmx5ICovDQogIGlmKChjZmcuc3BlZWQgPT0gVVNCX09UR19TUEVFRF9GVUxMKSYmDQogICAgIChVU0J4ICE9IFVTQl9PVEdfRlMpKQ0KICB7DQogICAgVVNCeF9IT1NULT5IQ0ZHIHw9IFVTQl9PVEdfSENGR19GU0xTUzsgDQogIH0NCiAgZWxzZQ0KICB7DQogICAgVVNCeF9IT1NULT5IQ0ZHICY9IH4oVVNCX09UR19IQ0ZHX0ZTTFNTKTsgIA0KICB9DQoNCiAgLyogTWFrZSBzdXJlIHRoZSBGSUZPcyBhcmUgZmx1c2hlZC4gKi8NCiAgVVNCX0ZsdXNoVHhGaWZvKFVTQngsIDB4MTAgKTsgLyogYWxsIFR4IEZJRk9zICovDQogIFVTQl9GbHVzaFJ4RmlmbyhVU0J4KTsNCg0KICAvKiBDbGVhciBhbGwgcGVuZGluZyBIQyBJbnRlcnJ1cHRzICovDQogIGZvciAoaSA9IDA7IGkgPCBjZmcuSG9zdF9jaGFubmVsczsgaSsrKQ0KICB7DQogICAgVVNCeF9IQyhpKS0+SENJTlQgPSAweEZGRkZGRkZGOw0KICAgIFVTQnhfSEMoaSktPkhDSU5UTVNLID0gMDsNCiAgfQ0KICANCiAgLyogRW5hYmxlIFZCVVMgZHJpdmluZyAqLw0KICBVU0JfRHJpdmVWYnVzKFVTQngsIDEpOw0KICANCiAgSEFMX0RlbGF5KDIwMCk7DQogIA0KICAvKiBEaXNhYmxlIGFsbCBpbnRlcnJ1cHRzLiAqLw0KICBVU0J4LT5HSU5UTVNLID0gMDsNCiAgDQogIC8qIENsZWFyIGFueSBwZW5kaW5nIGludGVycnVwdHMgKi8NCiAgVVNCeC0+R0lOVFNUUyA9IDB4RkZGRkZGRkY7DQogIA0KICBpZihVU0J4ID09IFVTQl9PVEdfRlMpDQogIHsNCiAgICAvKiBzZXQgUnggRklGTyBzaXplICovDQogICAgVVNCeC0+R1JYRlNJWiAgPSAodWludDMyX3QgKTB4ODA7IA0KICAgIFVTQngtPkRJRVBUWEYwX0hOUFRYRlNJWiA9ICh1aW50MzJfdCApKCgoMHg2MCA8PCAxNikmIFVTQl9PVEdfTlBUWEZEKSB8IDB4ODApOw0KICAgIFVTQngtPkhQVFhGU0laID0gKHVpbnQzMl90ICkoKCgweDQwIDw8IDE2KSYgVVNCX09UR19IUFRYRlNJWl9QVFhGRCkgfCAweEUwKTsNCiAgfQ0KICBlbHNlDQogIHsNCiAgICAvKiBzZXQgUnggRklGTyBzaXplICovDQogICAgVVNCeC0+R1JYRlNJWiAgPSAodWludDMyX3QgKTB4MjAwOyANCiAgICBVU0J4LT5ESUVQVFhGMF9ITlBUWEZTSVogPSAodWludDMyX3QgKSgoKDB4MTAwIDw8IDE2KSYgVVNCX09UR19OUFRYRkQpIHwgMHgyMDApOw0KICAgIFVTQngtPkhQVFhGU0laID0gKHVpbnQzMl90ICkoKCgweEUwIDw8IDE2KSYgVVNCX09UR19IUFRYRlNJWl9QVFhGRCkgfCAweDMwMCk7DQogIH0NCiAgDQogIC8qIEVuYWJsZSB0aGUgY29tbW9uIGludGVycnVwdHMgKi8NCiAgaWYgKGNmZy5kbWFfZW5hYmxlID09IERJU0FCTEUpDQogIHsNCiAgICBVU0J4LT5HSU5UTVNLIHw9IFVTQl9PVEdfR0lOVE1TS19SWEZMVkxNOyANCiAgfQ0KICANCiAgLyogRW5hYmxlIGludGVycnVwdHMgbWF0Y2hpbmcgdG8gdGhlIEhvc3QgbW9kZSBPTkxZICovDQogIFVTQngtPkdJTlRNU0sgfD0gKFVTQl9PVEdfR0lOVE1TS19QUlRJTSAgICAgICAgICAgIHwgVVNCX09UR19HSU5UTVNLX0hDSU0gfFwNCiAgICAgICAgICAgICAgICAgICAgVVNCX09UR19HSU5UTVNLX1NPRk0gICAgICAgICAgICAgfFVTQl9PVEdfR0lOVFNUU19ESVNDSU5UfFwNCiAgICAgICAgICAgICAgICAgICAgVVNCX09UR19HSU5UTVNLX1BYRlJNX0lJU09PWEZSTSAgfCBVU0JfT1RHX0dJTlRNU0tfV1VJTSk7DQoNCiAgcmV0dXJuIEhBTF9PSzsNCn0NCg0KLyoqDQogICogQGJyaWVmICBVU0JfSW5pdEZTTFNQQ2xrU2VsIDogSW5pdGlhbGl6ZXMgdGhlIEZTTFNQQ2xrU2VsIGZpZWxkIG9mIHRoZSANCiAgKiAgICAgICAgIEhDRkcgcmVnaXN0ZXIgb24gdGhlIFBIWSB0eXBlIGFuZCBzZXQgdGhlIHJpZ2h0IGZyYW1lIGludGVydmFsDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBmcmVxIDogY2xvY2sgZnJlcXVlbmN5DQogICogICAgICAgICAgVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIG9uZSBvZiB0aGVzZSB2YWx1ZXM6DQogICogICAgICAgICAgIEhDRkdfNDhfTUhaIDogRnVsbCBTcGVlZCA0OCBNSHogQ2xvY2sgDQogICogICAgICAgICAgIEhDRkdfNl9NSFogOiBMb3cgU3BlZWQgNiBNSHogQ2xvY2sgDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICovDQpIQUxfU3RhdHVzVHlwZURlZiBVU0JfSW5pdEZTTFNQQ2xrU2VsKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCAsIHVpbnQ4X3QgZnJlcSkNCnsNCiAgVVNCeF9IT1NULT5IQ0ZHICY9IH4oVVNCX09UR19IQ0ZHX0ZTTFNQQ1MpOw0KICBVU0J4X0hPU1QtPkhDRkcgfD0gKGZyZXEgJiBVU0JfT1RHX0hDRkdfRlNMU1BDUyk7DQogIA0KICBpZiAoZnJlcSA9PSAgSENGR180OF9NSFopDQogIHsNCiAgICBVU0J4X0hPU1QtPkhGSVIgPSAodWludDMyX3QpNDgwMDA7DQogIH0NCiAgZWxzZSBpZiAoZnJlcSA9PSAgSENGR182X01IWikNCiAgew0KICAgIFVTQnhfSE9TVC0+SEZJUiA9ICh1aW50MzJfdCk2MDAwOw0KICB9IA0KICByZXR1cm4gSEFMX09LOyAgDQp9DQoNCi8qKg0KKiBAYnJpZWYgIFVTQl9PVEdfUmVzZXRQb3J0IDogUmVzZXQgSG9zdCBQb3J0DQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBIQUwgc3RhdHVzDQogICogQG5vdGUgOiAoMSlUaGUgYXBwbGljYXRpb24gbXVzdCB3YWl0IGF0IGxlYXN0IDEwIG1zDQogICogICBiZWZvcmUgY2xlYXJpbmcgdGhlIHJlc2V0IGJpdC4NCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmIFVTQl9SZXNldFBvcnQoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4KQ0Kew0KICBfX0lPIHVpbnQzMl90IGhwcnQwOw0KDQogIGhwcnQwID0gVVNCeF9IUFJUMDsNCg0KICBocHJ0MCAmPSB+KFVTQl9PVEdfSFBSVF9QRU5BIHwgVVNCX09UR19IUFJUX1BDREVUIHwNCiAgICAgICAgICAgICBVU0JfT1RHX0hQUlRfUEVOQ0hORyB8IFVTQl9PVEdfSFBSVF9QT0NDSE5HKTsNCg0KICBVU0J4X0hQUlQwID0gKFVTQl9PVEdfSFBSVF9QUlNUIHwgaHBydDApOyAgDQogIEhBTF9EZWxheSAoMTAwKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNlZSBOb3RlICMxICovDQogIFVTQnhfSFBSVDAgPSAoKH5VU0JfT1RHX0hQUlRfUFJTVCkgJiBocHJ0MCk7IA0KICBIQUxfRGVsYXkgKDEwKTsNCg0KICByZXR1cm4gSEFMX09LOw0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFVTQl9Ecml2ZVZidXMgOiBhY3RpdmF0ZSBvciBkZS1hY3RpdmF0ZSB2YnVzDQogICogQHBhcmFtICBzdGF0ZSA6IFZCVVMgc3RhdGUNCiAgKiAgICAgICAgICBUaGlzIHBhcmFtZXRlciBjYW4gYmUgb25lIG9mIHRoZXNlIHZhbHVlczoNCiAgKiAgICAgICAgICAgMCA6IFZCVVMgQWN0aXZlIA0KICAqICAgICAgICAgICAxIDogVkJVUyBJbmFjdGl2ZQ0KICAqIEByZXR2YWwgSEFMIHN0YXR1cw0KKi8NCkhBTF9TdGF0dXNUeXBlRGVmIFVTQl9Ecml2ZVZidXMgKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgdWludDhfdCBzdGF0ZSkNCnsNCiAgX19JTyB1aW50MzJfdCBocHJ0MDsNCg0KICBocHJ0MCA9IFVTQnhfSFBSVDA7DQoNCiAgaHBydDAgJj0gfihVU0JfT1RHX0hQUlRfUEVOQSB8IFVTQl9PVEdfSFBSVF9QQ0RFVCB8DQogICAgICAgICAgICAgVVNCX09UR19IUFJUX1BFTkNITkcgfCBVU0JfT1RHX0hQUlRfUE9DQ0hORyk7DQoNCiAgaWYgKCgoaHBydDAgJiBVU0JfT1RHX0hQUlRfUFBXUikgPT0gMCApICYmIChzdGF0ZSA9PSAxICkpDQogIHsNCiAgICBVU0J4X0hQUlQwID0gKFVTQl9PVEdfSFBSVF9QUFdSIHwgaHBydDApOyANCiAgfQ0KICBpZiAoKChocHJ0MCAmIFVTQl9PVEdfSFBSVF9QUFdSKSA9PSBVU0JfT1RHX0hQUlRfUFBXUikgJiYgKHN0YXRlID09IDAgKSkNCiAgew0KICAgIFVTQnhfSFBSVDAgPSAoKH5VU0JfT1RHX0hQUlRfUFBXUikgJiBocHJ0MCk7IA0KICB9DQogIHJldHVybiBIQUxfT0s7IA0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFJldHVybiBIb3N0IENvcmUgc3BlZWQNCiAgKiBAcGFyYW0gIFVTQnggOiBTZWxlY3RlZCBkZXZpY2UNCiAgKiBAcmV0dmFsIHNwZWVkIDogSG9zdCBzcGVlZA0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBvbmUgb2YgdGhlc2UgdmFsdWVzOg0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0hJR0g6IEhpZ2ggc3BlZWQgbW9kZQ0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0ZVTEw6IEZ1bGwgc3BlZWQgbW9kZQ0KICAqICAgICAgICAgICAgQGFyZyBVU0JfT1RHX1NQRUVEX0xPVzogTG93IHNwZWVkIG1vZGUNCiAgKi8NCnVpbnQzMl90IFVTQl9HZXRIb3N0U3BlZWQgKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCkNCnsNCiAgX19JTyB1aW50MzJfdCBocHJ0MDsNCiAgDQogIGhwcnQwID0gVVNCeF9IUFJUMDsNCiAgcmV0dXJuICgoaHBydDAgJiBVU0JfT1RHX0hQUlRfUFNQRCkgPj4gMTcpOw0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFJldHVybiBIb3N0IEN1cnJlbnQgRnJhbWUgbnVtYmVyDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBjdXJyZW50IGZyYW1lIG51bWJlcg0KKi8NCnVpbnQzMl90IFVTQl9HZXRDdXJyZW50RnJhbWUgKFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCkNCnsNCiAgcmV0dXJuIChVU0J4X0hPU1QtPkhGTlVNICYgVVNCX09UR19IRk5VTV9GUk5VTSk7DQp9DQoNCi8qKg0KICAqIEBicmllZiAgSW5pdGlhbGl6ZSBhIGhvc3QgY2hhbm5lbA0KICAqIEBwYXJhbSAgVVNCeCA6IFNlbGVjdGVkIGRldmljZQ0KICAqIEBwYXJhbSAgY2hfbnVtIDogQ2hhbm5lbCBudW1iZXINCiAgKiAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBhIHZhbHVlIGZyb20gMSB0byAxNQ0KICAqIEBwYXJhbSAgZXBudW0gOiBFbmRwb2ludCBudW1iZXINCiAgKiAgICAgICAgICBUaGlzIHBhcmFtZXRlciBjYW4gYmUgYSB2YWx1ZSBmcm9tIDEgdG8gMTUNCiAgKiBAcGFyYW0gIGRldl9hZGRyZXNzIDogQ3VycmVudCBkZXZpY2UgYWRkcmVzcw0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBhIHZhbHVlIGZyb20gMCB0byAyNTUNCiAgKiBAcGFyYW0gIHNwZWVkIDogQ3VycmVudCBkZXZpY2Ugc3BlZWQNCiAgKiAgICAgICAgICBUaGlzIHBhcmFtZXRlciBjYW4gYmUgb25lIG9mIHRoZXNlIHZhbHVlczoNCiAgKiAgICAgICAgICAgIEBhcmcgVVNCX09UR19TUEVFRF9ISUdIOiBIaWdoIHNwZWVkIG1vZGUNCiAgKiAgICAgICAgICAgIEBhcmcgVVNCX09UR19TUEVFRF9GVUxMOiBGdWxsIHNwZWVkIG1vZGUNCiAgKiAgICAgICAgICAgIEBhcmcgVVNCX09UR19TUEVFRF9MT1c6IExvdyBzcGVlZCBtb2RlDQogICogQHBhcmFtICBlcF90eXBlIDogRW5kcG9pbnQgVHlwZQ0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBvbmUgb2YgdGhlc2UgdmFsdWVzOg0KICAqICAgICAgICAgICAgQGFyZyBFUF9UWVBFX0NUUkw6IENvbnRyb2wgdHlwZQ0KICAqICAgICAgICAgICAgQGFyZyBFUF9UWVBFX0lTT0M6IElzb2Nocm9ub3VzIHR5cGUNCiAgKiAgICAgICAgICAgIEBhcmcgRVBfVFlQRV9CVUxLOiBCdWxrIHR5cGUNCiAgKiAgICAgICAgICAgIEBhcmcgRVBfVFlQRV9JTlRSOiBJbnRlcnJ1cHQgdHlwZQ0KICAqIEBwYXJhbSAgbXBzIDogTWF4IFBhY2tldCBTaXplDQogICogICAgICAgICAgVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIGEgdmFsdWUgZnJvbSAwIHRvMzJLDQogICogQHJldHZhbCBIQUwgc3RhdGUNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmIFVTQl9IQ19Jbml0KFVTQl9PVEdfR2xvYmFsVHlwZURlZiAqVVNCeCwgIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCBjaF9udW0sDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90IGVwbnVtLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCBkZXZfYWRkcmVzcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3Qgc3BlZWQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90IGVwX3R5cGUsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MTZfdCBtcHMpDQp7DQogICAgDQogIC8qIENsZWFyIG9sZCBpbnRlcnJ1cHQgY29uZGl0aW9ucyBmb3IgdGhpcyBob3N0IGNoYW5uZWwuICovDQogIFVTQnhfSEMoY2hfbnVtKS0+SENJTlQgPSAweEZGRkZGRkZGOw0KICANCiAgLyogRW5hYmxlIGNoYW5uZWwgaW50ZXJydXB0cyByZXF1aXJlZCBmb3IgdGhpcyB0cmFuc2Zlci4gKi8NCiAgc3dpdGNoIChlcF90eXBlKSANCiAgew0KICBjYXNlIEVQX1RZUEVfQ1RSTDoNCiAgY2FzZSBFUF9UWVBFX0JVTEs6DQogICAgDQogICAgVVNCeF9IQyhjaF9udW0pLT5IQ0lOVE1TSyA9IFVTQl9PVEdfSENJTlRNU0tfWEZSQ00gIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfU1RBTExNIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfVFhFUlJNIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfRFRFUlJNIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfQUhCRVJSIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfTkFLTSA7DQogDQogICAgaWYgKGVwbnVtICYgMHg4MCkgDQogICAgew0KICAgICAgVVNCeF9IQyhjaF9udW0pLT5IQ0lOVE1TSyB8PSBVU0JfT1RHX0hDSU5UTVNLX0JCRVJSTTsNCiAgICB9IA0KICAgIGVsc2UgDQogICAgew0KICAgICAgaWYoVVNCeCAhPSBVU0JfT1RHX0ZTKQ0KICAgICAgew0KICAgICAgICBVU0J4X0hDKGNoX251bSktPkhDSU5UTVNLIHw9IChVU0JfT1RHX0hDSU5UTVNLX05ZRVQgfCBVU0JfT1RHX0hDSU5UTVNLX0FDS00pOw0KICAgICAgfQ0KICAgIH0NCiAgICBicmVhazsNCiAgICANCiAgY2FzZSBFUF9UWVBFX0lOVFI6DQogICAgDQogICAgVVNCeF9IQyhjaF9udW0pLT5IQ0lOVE1TSyA9IFVTQl9PVEdfSENJTlRNU0tfWEZSQ00gIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfU1RBTExNIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfVFhFUlJNIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfRFRFUlJNIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfTkFLTSAgIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfQUhCRVJSIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENJTlRNU0tfRlJNT1JNIDsgICAgDQogICAgDQogICAgaWYgKGVwbnVtICYgMHg4MCkgDQogICAgew0KICAgICAgVVNCeF9IQyhjaF9udW0pLT5IQ0lOVE1TSyB8PSBVU0JfT1RHX0hDSU5UTVNLX0JCRVJSTTsNCiAgICB9DQogICAgDQogICAgYnJlYWs7DQogIGNhc2UgRVBfVFlQRV9JU09DOg0KICAgIA0KICAgIFVTQnhfSEMoY2hfbnVtKS0+SENJTlRNU0sgPSBVU0JfT1RHX0hDSU5UTVNLX1hGUkNNICB8XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0JfT1RHX0hDSU5UTVNLX0FDS00gICB8XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0JfT1RHX0hDSU5UTVNLX0FIQkVSUiB8XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVU0JfT1RHX0hDSU5UTVNLX0ZSTU9STSA7ICAgDQogICAgDQogICAgaWYgKGVwbnVtICYgMHg4MCkgDQogICAgew0KICAgICAgVVNCeF9IQyhjaF9udW0pLT5IQ0lOVE1TSyB8PSAoVVNCX09UR19IQ0lOVE1TS19UWEVSUk0gfCBVU0JfT1RHX0hDSU5UTVNLX0JCRVJSTSk7ICAgICAgDQogICAgfQ0KICAgIGJyZWFrOw0KICB9DQogIA0KICAvKiBFbmFibGUgdGhlIHRvcCBsZXZlbCBob3N0IGNoYW5uZWwgaW50ZXJydXB0LiAqLw0KICBVU0J4X0hPU1QtPkhBSU5UTVNLIHw9ICgxIDw8IGNoX251bSk7DQogIA0KICAvKiBNYWtlIHN1cmUgaG9zdCBjaGFubmVsIGludGVycnVwdHMgYXJlIGVuYWJsZWQuICovDQogIFVTQngtPkdJTlRNU0sgfD0gVVNCX09UR19HSU5UTVNLX0hDSU07DQogIA0KICAvKiBQcm9ncmFtIHRoZSBIQ0NIQVIgcmVnaXN0ZXIgKi8NCiAgVVNCeF9IQyhjaF9udW0pLT5IQ0NIQVIgPSAoKChkZXZfYWRkcmVzcyA8PCAyMikgJiBVU0JfT1RHX0hDQ0hBUl9EQUQpICB8XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKChlcG51bSAmIDB4N0YpPDwgMTEpICYgVVNCX09UR19IQ0NIQVJfRVBOVU0pfFwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCgoKGVwbnVtICYgMHg4MCkgPT0gMHg4MCk8PCAxNSkgJiBVU0JfT1RHX0hDQ0hBUl9FUERJUil8XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKChzcGVlZCA9PSBIUFJUMF9QUlRTUERfTE9XX1NQRUVEKTw8IDE3KSAmIFVTQl9PVEdfSENDSEFSX0xTREVWKXxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoZXBfdHlwZSA8PCAxOCkgJiBVU0JfT1RHX0hDQ0hBUl9FUFRZUCl8XA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobXBzICYgVVNCX09UR19IQ0NIQVJfTVBTSVopKTsNCiAgICANCiAgaWYgKGVwX3R5cGUgPT0gRVBfVFlQRV9JTlRSKQ0KICB7DQogICAgVVNCeF9IQyhjaF9udW0pLT5IQ0NIQVIgfD0gVVNCX09UR19IQ0NIQVJfT0RERlJNIDsNCiAgfQ0KDQogIHJldHVybiBIQUxfT0s7IA0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFN0YXJ0IGEgdHJhbnNmZXIgb3ZlciBhIGhvc3QgY2hhbm5lbA0KICAqIEBwYXJhbSAgVVNCeCA6IFNlbGVjdGVkIGRldmljZQ0KICAqIEBwYXJhbSAgaGMgOiBwb2ludGVyIHRvIGhvc3QgY2hhbm5lbCBzdHJ1Y3R1cmUNCiAgKiBAcGFyYW0gIGRtYTogVVNCIGRtYSBlbmFibGVkIG9yIGRpc2FibGVkIA0KICAqICAgICAgICAgIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSBvbmUgb2YgdGhlc2UgdmFsdWVzOg0KICAqICAgICAgICAgICAwIDogRE1BIGZlYXR1cmUgbm90IHVzZWQgDQogICogICAgICAgICAgIDEgOiBETUEgZmVhdHVyZSB1c2VkICANCiAgKiBAcmV0dmFsIEhBTCBzdGF0ZQ0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0hDX1N0YXJ0WGZlcihVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngsIFVTQl9PVEdfSENUeXBlRGVmICpoYywgdWludDhfdCBkbWEpDQp7DQogIHN0YXRpYyBfX0lPIHVpbnQzMl90IHRtcHJlZyA9IDA7DQogIHVpbnQ4X3QgIGlzX29kZGZyYW1lID0gMDsgDQogIHVpbnQxNl90IGxlbl93b3JkcyA9IDA7ICAgDQogIHVpbnQxNl90IG51bV9wYWNrZXRzID0gMDsNCiAgdWludDE2X3QgbWF4X2hjX3BrdF9jb3VudCA9IDI1NjsNCiAgICANCiAgaWYoKFVTQnggIT0gVVNCX09UR19GUykgJiYgKGhjLT5zcGVlZCA9PSBVU0JfT1RHX1NQRUVEX0hJR0gpKQ0KICB7DQogICAgaWYoKGRtYSA9PSAwKSAmJiAoaGMtPmRvX3BpbmcgPT0gMSkpDQogICAgew0KICAgICAgVVNCX0RvUGluZyhVU0J4LCBoYy0+Y2hfbnVtKTsNCiAgICAgIHJldHVybiBIQUxfT0s7DQogICAgfQ0KICAgIGVsc2UgaWYoZG1hID09IDEpDQogICAgew0KICAgICAgVVNCeF9IQyhoYy0+Y2hfbnVtKS0+SENJTlRNU0sgJj0gfihVU0JfT1RHX0hDSU5UTVNLX05ZRVQgfCBVU0JfT1RHX0hDSU5UTVNLX0FDS00pOw0KICAgICAgaGMtPmRvX3BpbmcgPSAwOw0KICAgIH0NCiAgfQ0KICANCiAgLyogQ29tcHV0ZSB0aGUgZXhwZWN0ZWQgbnVtYmVyIG9mIHBhY2tldHMgYXNzb2NpYXRlZCB0byB0aGUgdHJhbnNmZXIgKi8NCiAgaWYgKGhjLT54ZmVyX2xlbiA+IDApDQogIHsNCiAgICBudW1fcGFja2V0cyA9IChoYy0+eGZlcl9sZW4gKyBoYy0+bWF4X3BhY2tldCAtIDEpIC8gaGMtPm1heF9wYWNrZXQ7DQogICAgDQogICAgaWYgKG51bV9wYWNrZXRzID4gbWF4X2hjX3BrdF9jb3VudCkNCiAgICB7DQogICAgICBudW1fcGFja2V0cyA9IG1heF9oY19wa3RfY291bnQ7DQogICAgICBoYy0+eGZlcl9sZW4gPSBudW1fcGFja2V0cyAqIGhjLT5tYXhfcGFja2V0Ow0KICAgIH0NCiAgfQ0KICBlbHNlDQogIHsNCiAgICBudW1fcGFja2V0cyA9IDE7DQogIH0NCiAgaWYgKGhjLT5lcF9pc19pbikNCiAgew0KICAgIGhjLT54ZmVyX2xlbiA9IG51bV9wYWNrZXRzICogaGMtPm1heF9wYWNrZXQ7DQogIH0NCiAgDQogIC8qIEluaXRpYWxpemUgdGhlIEhDVFNJWm4gcmVnaXN0ZXIgKi8NCiAgVVNCeF9IQyhoYy0+Y2hfbnVtKS0+SENUU0laID0gKCgoaGMtPnhmZXJfbGVuKSAmIFVTQl9PVEdfSENUU0laX1hGUlNJWikpIHxcDQogICAgKChudW1fcGFja2V0cyA8PCAxOSkgJiBVU0JfT1RHX0hDVFNJWl9QS1RDTlQpIHxcDQogICAgICAoKChoYy0+ZGF0YV9waWQpIDw8IDI5KSAmIFVTQl9PVEdfSENUU0laX0RQSUQpOw0KICANCiAgaWYgKGRtYSkNCiAgew0KICAgIC8qIHhmZXJfYnVmZiBNVVNUIGJlIDMyLWJpdHMgYWxpZ25lZCAqLw0KICAgIFVTQnhfSEMoaGMtPmNoX251bSktPkhDRE1BID0gKHVpbnQzMl90KWhjLT54ZmVyX2J1ZmY7DQogIH0NCiAgDQogIGlzX29kZGZyYW1lID0gKFVTQnhfSE9TVC0+SEZOVU0gJiAweDAxKSA/IDAgOiAxOw0KICBVU0J4X0hDKGhjLT5jaF9udW0pLT5IQ0NIQVIgJj0gflVTQl9PVEdfSENDSEFSX09EREZSTTsNCiAgVVNCeF9IQyhoYy0+Y2hfbnVtKS0+SENDSEFSIHw9IChpc19vZGRmcmFtZSA8PCAyOSk7DQogIA0KICAvKiBTZXQgaG9zdCBjaGFubmVsIGVuYWJsZSAqLw0KICB0bXByZWcgPSBVU0J4X0hDKGhjLT5jaF9udW0pLT5IQ0NIQVI7DQogIHRtcHJlZyAmPSB+VVNCX09UR19IQ0NIQVJfQ0hESVM7DQogIHRtcHJlZyB8PSBVU0JfT1RHX0hDQ0hBUl9DSEVOQTsNCiAgVVNCeF9IQyhoYy0+Y2hfbnVtKS0+SENDSEFSID0gdG1wcmVnOw0KICANCiAgaWYgKGRtYSA9PSAwKSAvKiBTbGF2ZSBtb2RlICovDQogIHsgIA0KICAgIGlmKChoYy0+ZXBfaXNfaW4gPT0gMCkgJiYgKGhjLT54ZmVyX2xlbiA+IDApKQ0KICAgIHsNCiAgICAgIHN3aXRjaChoYy0+ZXBfdHlwZSkgDQogICAgICB7DQogICAgICAgIC8qIE5vbiBwZXJpb2RpYyB0cmFuc2ZlciAqLw0KICAgICAgY2FzZSBFUF9UWVBFX0NUUkw6DQogICAgICBjYXNlIEVQX1RZUEVfQlVMSzoNCiAgICAgICAgDQogICAgICAgIGxlbl93b3JkcyA9IChoYy0+eGZlcl9sZW4gKyAzKSAvIDQ7DQogICAgICAgIA0KICAgICAgICAvKiBjaGVjayBpZiB0aGVyZSBpcyBlbm91Z2ggc3BhY2UgaW4gRklGTyBzcGFjZSAqLw0KICAgICAgICBpZihsZW5fd29yZHMgPiAoVVNCeC0+SE5QVFhTVFMgJiAweEZGRkYpKQ0KICAgICAgICB7DQogICAgICAgICAgLyogbmVlZCB0byBwcm9jZXNzIGRhdGEgaW4gbnB0eGZlbXB0eSBpbnRlcnJ1cHQgKi8NCiAgICAgICAgICBVU0J4LT5HSU5UTVNLIHw9IFVTQl9PVEdfR0lOVE1TS19OUFRYRkVNOw0KICAgICAgICB9DQogICAgICAgIGJyZWFrOw0KICAgICAgICAvKiBQZXJpb2RpYyB0cmFuc2ZlciAqLw0KICAgICAgY2FzZSBFUF9UWVBFX0lOVFI6DQogICAgICBjYXNlIEVQX1RZUEVfSVNPQzoNCiAgICAgICAgbGVuX3dvcmRzID0gKGhjLT54ZmVyX2xlbiArIDMpIC8gNDsNCiAgICAgICAgLyogY2hlY2sgaWYgdGhlcmUgaXMgZW5vdWdoIHNwYWNlIGluIEZJRk8gc3BhY2UgKi8NCiAgICAgICAgaWYobGVuX3dvcmRzID4gKFVTQnhfSE9TVC0+SFBUWFNUUyAmIDB4RkZGRikpIC8qIHNwbGl0IHRoZSB0cmFuc2ZlciAqLw0KICAgICAgICB7DQogICAgICAgICAgLyogbmVlZCB0byBwcm9jZXNzIGRhdGEgaW4gcHR4ZmVtcHR5IGludGVycnVwdCAqLw0KICAgICAgICAgIFVTQngtPkdJTlRNU0sgfD0gVVNCX09UR19HSU5UTVNLX1BUWEZFTTsgICAgICAgICAgDQogICAgICAgIH0NCiAgICAgICAgYnJlYWs7DQogICAgICAgIA0KICAgICAgZGVmYXVsdDoNCiAgICAgICAgYnJlYWs7DQogICAgICB9DQogICAgICANCiAgICAgIC8qIFdyaXRlIHBhY2tldCBpbnRvIHRoZSBUeCBGSUZPLiAqLw0KICAgICAgVVNCX1dyaXRlUGFja2V0KFVTQngsIGhjLT54ZmVyX2J1ZmYsIGhjLT5jaF9udW0sIGhjLT54ZmVyX2xlbiwgMCk7DQogICAgfQ0KICB9DQogIA0KICByZXR1cm4gSEFMX09LOw0KfQ0KDQovKioNCiAgKiBAYnJpZWYgUmVhZCBhbGwgaG9zdCBjaGFubmVsIGludGVycnVwdHMgc3RhdHVzDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBIQUwgc3RhdGUNCiAgKi8NCnVpbnQzMl90IFVTQl9IQ19SZWFkSW50ZXJydXB0IChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngpDQp7DQogIHJldHVybiAoKFVTQnhfSE9TVC0+SEFJTlQpICYgMHhGRkZGKTsNCn0NCg0KLyoqDQogICogQGJyaWVmICBIYWx0IGEgaG9zdCBjaGFubmVsDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBoY19udW0gOiBIb3N0IENoYW5uZWwgbnVtYmVyDQogICogICAgICAgICBUaGlzIHBhcmFtZXRlciBjYW4gYmUgYSB2YWx1ZSBmcm9tIDEgdG8gMTUNCiAgKiBAcmV0dmFsIEhBTCBzdGF0ZQ0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0hDX0hhbHQoVVNCX09UR19HbG9iYWxUeXBlRGVmICpVU0J4ICwgdWludDhfdCBoY19udW0pDQp7DQogIHVpbnQzMl90IGNvdW50ID0gMDsNCiAgDQogIC8qIENoZWNrIGZvciBzcGFjZSBpbiB0aGUgcmVxdWVzdCBxdWV1ZSB0byBpc3N1ZSB0aGUgaGFsdC4gKi8NCiAgaWYgKCgoKChVU0J4X0hDKGhjX251bSktPkhDQ0hBUikgJiBVU0JfT1RHX0hDQ0hBUl9FUFRZUCkgPj4gMTgpID09IEhDQ0hBUl9DVFJMKSB8fA0KICAgICAoKCgoKFVTQnhfSEMoaGNfbnVtKS0+SENDSEFSKSAmIFVTQl9PVEdfSENDSEFSX0VQVFlQKSA+PiAxOCkgPT0gSENDSEFSX0JVTEspKSkNCiAgew0KICAgIFVTQnhfSEMoaGNfbnVtKS0+SENDSEFSIHw9IFVTQl9PVEdfSENDSEFSX0NIRElTOw0KICAgIA0KICAgIGlmICgoVVNCeC0+SE5QVFhTVFMgJiAweEZGRkYpID09IDApDQogICAgew0KICAgICAgVVNCeF9IQyhoY19udW0pLT5IQ0NIQVIgJj0gflVTQl9PVEdfSENDSEFSX0NIRU5BOw0KICAgICAgVVNCeF9IQyhoY19udW0pLT5IQ0NIQVIgfD0gVVNCX09UR19IQ0NIQVJfQ0hFTkE7ICANCiAgICAgIFVTQnhfSEMoaGNfbnVtKS0+SENDSEFSICY9IH5VU0JfT1RHX0hDQ0hBUl9FUERJUjsNCiAgICAgIGRvIA0KICAgICAgew0KICAgICAgICBpZiAoKytjb3VudCA+IDEwMDApIA0KICAgICAgICB7DQogICAgICAgICAgYnJlYWs7DQogICAgICAgIH0NCiAgICAgIH0gDQogICAgICB3aGlsZSAoKFVTQnhfSEMoaGNfbnVtKS0+SENDSEFSICYgVVNCX09UR19IQ0NIQVJfQ0hFTkEpID09IFVTQl9PVEdfSENDSEFSX0NIRU5BKTsgICAgIA0KICAgIH0NCiAgICBlbHNlDQogICAgew0KICAgICAgVVNCeF9IQyhoY19udW0pLT5IQ0NIQVIgfD0gVVNCX09UR19IQ0NIQVJfQ0hFTkE7IA0KICAgIH0NCiAgfQ0KICBlbHNlDQogIHsNCiAgICBVU0J4X0hDKGhjX251bSktPkhDQ0hBUiB8PSBVU0JfT1RHX0hDQ0hBUl9DSERJUzsNCiAgICANCiAgICBpZiAoKFVTQnhfSE9TVC0+SFBUWFNUUyAmIDB4RkZGRikgPT0gMCkNCiAgICB7DQogICAgICBVU0J4X0hDKGhjX251bSktPkhDQ0hBUiAmPSB+VVNCX09UR19IQ0NIQVJfQ0hFTkE7DQogICAgICBVU0J4X0hDKGhjX251bSktPkhDQ0hBUiB8PSBVU0JfT1RHX0hDQ0hBUl9DSEVOQTsgIA0KICAgICAgVVNCeF9IQyhoY19udW0pLT5IQ0NIQVIgJj0gflVTQl9PVEdfSENDSEFSX0VQRElSOw0KICAgICAgZG8gDQogICAgICB7DQogICAgICAgIGlmICgrK2NvdW50ID4gMTAwMCkgDQogICAgICAgIHsNCiAgICAgICAgICBicmVhazsNCiAgICAgICAgfQ0KICAgICAgfSANCiAgICAgIHdoaWxlICgoVVNCeF9IQyhoY19udW0pLT5IQ0NIQVIgJiBVU0JfT1RHX0hDQ0hBUl9DSEVOQSkgPT0gVVNCX09UR19IQ0NIQVJfQ0hFTkEpOyAgICAgDQogICAgfQ0KICAgIGVsc2UNCiAgICB7DQogICAgICAgVVNCeF9IQyhoY19udW0pLT5IQ0NIQVIgfD0gVVNCX09UR19IQ0NIQVJfQ0hFTkE7IA0KICAgIH0NCiAgfQ0KICANCiAgcmV0dXJuIEhBTF9PSzsNCn0NCg0KLyoqDQogICogQGJyaWVmICBJbml0aWF0ZSBEbyBQaW5nIHByb3RvY29sDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHBhcmFtICBoY19udW0gOiBIb3N0IENoYW5uZWwgbnVtYmVyDQogICogICAgICAgICBUaGlzIHBhcmFtZXRlciBjYW4gYmUgYSB2YWx1ZSBmcm9tIDEgdG8gMTUNCiAgKiBAcmV0dmFsIEhBTCBzdGF0ZQ0KICAqLw0KSEFMX1N0YXR1c1R5cGVEZWYgVVNCX0RvUGluZyhVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQnggLCB1aW50OF90IGNoX251bSkNCnsNCiAgdWludDhfdCAgbnVtX3BhY2tldHMgPSAxOw0KICB1aW50MzJfdCB0bXByZWcgPSAwOw0KDQogIFVTQnhfSEMoY2hfbnVtKS0+SENUU0laID0gKChudW1fcGFja2V0cyA8PCAxOSkgJiBVU0JfT1RHX0hDVFNJWl9QS1RDTlQpIHxcDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFVTQl9PVEdfSENUU0laX0RPUElORzsNCiAgDQogIC8qIFNldCBob3N0IGNoYW5uZWwgZW5hYmxlICovDQogIHRtcHJlZyA9IFVTQnhfSEMoY2hfbnVtKS0+SENDSEFSOw0KICB0bXByZWcgJj0gflVTQl9PVEdfSENDSEFSX0NIRElTOw0KICB0bXByZWcgfD0gVVNCX09UR19IQ0NIQVJfQ0hFTkE7DQogIFVTQnhfSEMoY2hfbnVtKS0+SENDSEFSID0gdG1wcmVnOw0KICANCiAgcmV0dXJuIEhBTF9PSzsgIA0KfQ0KDQovKioNCiAgKiBAYnJpZWYgIFN0b3AgSG9zdCBDb3JlDQogICogQHBhcmFtICBVU0J4IDogU2VsZWN0ZWQgZGV2aWNlDQogICogQHJldHZhbCBIQUwgc3RhdGUNCiAgKi8NCkhBTF9TdGF0dXNUeXBlRGVmIFVTQl9TdG9wSG9zdChVU0JfT1RHX0dsb2JhbFR5cGVEZWYgKlVTQngpDQp7DQogIHVpbnQ4X3QgaTsNCiAgdWludDMyX3QgY291bnQgPSAwOw0KICB1aW50MzJfdCB2YWx1ZTsNCiAgDQogIFVTQl9EaXNhYmxlR2xvYmFsSW50KFVTQngpOw0KICANCiAgICAvKiBGbHVzaCBGSUZPICovDQogIFVTQl9GbHVzaFR4RmlmbyhVU0J4LCAweDEwKTsNCiAgVVNCX0ZsdXNoUnhGaWZvKFVTQngpOw0KICANCiAgLyogRmx1c2ggb3V0IGFueSBsZWZ0b3ZlciBxdWV1ZWQgcmVxdWVzdHMuICovDQogIGZvciAoaSA9IDA7IGkgPD0gMTU7IGkrKykNCiAgeyAgIA0KDQogICAgdmFsdWUgPSBVU0J4X0hDKGkpLT5IQ0NIQVIgOw0KICAgIHZhbHVlIHw9ICBVU0JfT1RHX0hDQ0hBUl9DSERJUzsNCiAgICB2YWx1ZSAmPSB+VVNCX09UR19IQ0NIQVJfQ0hFTkE7ICANCiAgICB2YWx1ZSAmPSB+VVNCX09UR19IQ0NIQVJfRVBESVI7DQogICAgVVNCeF9IQyhpKS0+SENDSEFSID0gdmFsdWU7DQogIH0NCiAgDQogIC8qIEhhbHQgYWxsIGNoYW5uZWxzIHRvIHB1dCB0aGVtIGludG8gYSBrbm93biBzdGF0ZS4gKi8gIA0KICBmb3IgKGkgPSAwOyBpIDw9IDE1OyBpKyspDQogIHsNCiAgICB2YWx1ZSA9IFVTQnhfSEMoaSktPkhDQ0hBUiA7DQogICAgDQogICAgdmFsdWUgfD0gVVNCX09UR19IQ0NIQVJfQ0hESVM7DQogICAgdmFsdWUgfD0gVVNCX09UR19IQ0NIQVJfQ0hFTkE7ICANCiAgICB2YWx1ZSAmPSB+VVNCX09UR19IQ0NIQVJfRVBESVI7DQogICAgDQogICAgVVNCeF9IQyhpKS0+SENDSEFSID0gdmFsdWU7DQogICAgZG8gDQogICAgew0KICAgICAgaWYgKCsrY291bnQgPiAxMDAwKSANCiAgICAgIHsNCiAgICAgICAgYnJlYWs7DQogICAgICB9DQogICAgfSANCiAgICB3aGlsZSAoKFVTQnhfSEMoaSktPkhDQ0hBUiAmIFVTQl9PVEdfSENDSEFSX0NIRU5BKSA9PSBVU0JfT1RHX0hDQ0hBUl9DSEVOQSk7DQogIH0NCg0KICAvKiBDbGVhciBhbnkgcGVuZGluZyBIb3N0IGludGVycnVwdHMgKi8NCiAgVVNCeF9IT1NULT5IQUlOVCA9IDB4RkZGRkZGRkY7DQogIFVTQngtPkdJTlRTVFMgPSAweEZGRkZGRkZGOw0KICBVU0JfRW5hYmxlR2xvYmFsSW50KFVTQngpOw0KICByZXR1cm4gSEFMX09LOyAgDQp9DQovKioNCiAgKiBAfQ0KICAqLw0KDQojZW5kaWYgLyogZGVmaW5lZCAoSEFMX1BDRF9NT0RVTEVfRU5BQkxFRCkgfHwgZGVmaW5lZCAoSEFMX0hDRF9NT0RVTEVfRU5BQkxFRCkgKi8NCg0KLyoqDQogICogQH0NCiAgKi8NCg0KLyoqKioqKioqKioqKioqKioqKioqKioqKiAoQykgQ09QWVJJR0hUIFNUTWljcm9lbGVjdHJvbmljcyAqKioqKkVORCBPRiBGSUxFKioqKi8NCg==