LyoKICogTU1TIHByb3RvY29sIG92ZXIgVENQCiAqIENvcHlyaWdodCAoYykgMjAwNiwyMDA3IFJ5YW4gTWFydGVsbAogKiBDb3B5cmlnaHQgKGMpIDIwMDcgQmr2cm4gQXhlbHNzb24KICogQ29weXJpZ2h0IChjKSAyMDEwIFpoZW50YW4gRmVuZyA8c3B5ZmVuZyBhdCBnbWFpbCBkb3QgY29tPgogKgogKiBUaGlzIGZpbGUgaXMgcGFydCBvZiBGRm1wZWcuCiAqCiAqIEZGbXBlZyBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIEZGbXBlZyBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCBGRm1wZWc7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTEgRnJhbmtsaW4gU3RyZWV0LCBGaWZ0aCBGbG9vciwgQm9zdG9uLCBNQSAwMjExMC0xMzAxIFVTQQogKi8KCi8qIFJlZmVyZW5jZXMKICogTU1TIHByb3RvY29sIHNwZWNpZmljYXRpb246CiAqICBbMV1odHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvY2MyMzQ3MTEoUFJPVC4xMCkuYXNweAogKiBBU0Ygc3BlY2lmaWNhdGlvbi4gUmV2aXNpb24gMDEuMjAuMDMuCiAqICBbMl1odHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvYmI2NDMzMjMuYXNweAogKi8KCiNpbmNsdWRlICJhdmZvcm1hdC5oIgojaW5jbHVkZSAibW1zLmgiCiNpbmNsdWRlICJpbnRlcm5hbC5oIgojaW5jbHVkZSAiYXZpb19pbnRlcm5hbC5oIgojaW5jbHVkZSAibGliYXZ1dGlsL2ludHJlYWR3cml0ZS5oIgojaW5jbHVkZSAibGliYXZjb2RlYy9ieXRlc3RyZWFtLmgiCiNpbmNsdWRlICJuZXR3b3JrLmgiCiNpbmNsdWRlICJ1cmwuaCIKCiNkZWZpbmUgTE9DQUxfQUREUkVTUyAweGMwYTgwMDgxICAgIC8vIEZJWE1FIGdldCBhbmQgdXNlIGNvcnJlY3QgbG9jYWwgaXAgYWRkcmVzcy4KI2RlZmluZSBMT0NBTF9QT1JUICAgIDEwMzcgICAgICAgICAgLy8gYXMgYWJvdmUuCi8qKiBDbGllbnQgdG8gc2VydmVyIHBhY2tldCB0eXBlcy4gKi8KdHlwZWRlZiBlbnVtIHsKICAgIENTX1BLVF9JTklUSUFMICAgICAgICAgICAgICAgICAgPSAweDAxLAogICAgQ1NfUEtUX1BST1RPQ09MX1NFTEVDVCAgICAgICAgICA9IDB4MDIsCiAgICBDU19QS1RfTUVESUFfRklMRV9SRVFVRVNUICAgICAgID0gMHgwNSwKICAgIENTX1BLVF9TVEFSVF9GUk9NX1BLVF9JRCAgICAgICAgPSAweDA3LAogICAgQ1NfUEtUX1NUUkVBTV9QQVVTRSAgICAgICAgICAgICA9IDB4MDksCiAgICBDU19QS1RfU1RSRUFNX0NMT1NFICAgICAgICAgICAgID0gMHgwZCwKICAgIENTX1BLVF9NRURJQV9IRUFERVJfUkVRVUVTVCAgICAgPSAweDE1LAogICAgQ1NfUEtUX1RJTUlOR19EQVRBX1JFUVVFU1QgICAgICA9IDB4MTgsCiAgICBDU19QS1RfVVNFUl9QQVNTV09SRCAgICAgICAgICAgID0gMHgxYSwKICAgIENTX1BLVF9LRUVQQUxJVkUgICAgICAgICAgICAgICAgPSAweDFiLAogICAgQ1NfUEtUX1NUUkVBTV9JRF9SRVFVRVNUICAgICAgICA9IDB4MzMsCn0gTU1TQ1NQYWNrZXRUeXBlOwoKLyoqIFNlcnZlciB0byBjbGllbnQgcGFja2V0IHR5cGVzLiAqLwp0eXBlZGVmIGVudW0gewogICAgLyoqIENvbnRyb2wgcGFja2V0cy4gKi8KICAgIC8qQHsqLwogICAgU0NfUEtUX0NMSUVOVF9BQ0NFUFRFRCAgICAgICAgICA9IDB4MDEsCiAgICBTQ19QS1RfUFJPVE9DT0xfQUNDRVBURUQgICAgICAgID0gMHgwMiwKICAgIFNDX1BLVF9QUk9UT0NPTF9GQUlMRUQgICAgICAgICAgPSAweDAzLAogICAgU0NfUEtUX01FRElBX1BLVF9GT0xMT1dTICAgICAgICA9IDB4MDUsCiAgICBTQ19QS1RfTUVESUFfRklMRV9ERVRBSUxTICAgICAgID0gMHgwNiwKICAgIFNDX1BLVF9IRUFERVJfUkVRVUVTVF9BQ0NFUFRFRCAgPSAweDExLAogICAgU0NfUEtUX1RJTUlOR19URVNUX1JFUExZICAgICAgICA9IDB4MTUsCiAgICBTQ19QS1RfUEFTU1dPUkRfUkVRVUlSRUQgICAgICAgID0gMHgxYSwKICAgIFNDX1BLVF9LRUVQQUxJVkUgICAgICAgICAgICAgICAgPSAweDFiLAogICAgU0NfUEtUX1NUUkVBTV9TVE9QUEVEICAgICAgICAgICA9IDB4MWUsCiAgICBTQ19QS1RfU1RSRUFNX0NIQU5HSU5HICAgICAgICAgID0gMHgyMCwKICAgIFNDX1BLVF9TVFJFQU1fSURfQUNDRVBURUQgICAgICAgPSAweDIxLAogICAgLypAfSovCgogICAgLyoqIFBzZXVkbyBwYWNrZXRzLiAqLwogICAgLypAeyovCiAgICBTQ19QS1RfQ0FOQ0VMICAgICAgICAgICAgICAgICAgID0gLTEsCiAgICBTQ19QS1RfTk9fREFUQSAgICAgICAgICAgICAgICAgID0gLTIsCiAgICAvKkB9Ki8KCiAgICAvKiogRGF0YSBwYWNrZXRzLiAqLwogICAgLypAeyovCiAgICBTQ19QS1RfQVNGX0hFQURFUiAgICAgICAgICAgICAgID0gMHgwMTAwMDAsLy8gbWFrZSBpdCBiaWdnZXIgdGhhbiAweEZGIGluIGNhc2Ugb2YKICAgIFNDX1BLVF9BU0ZfTUVESUEgICAgICAgICAgICAgICAgPSAweDAxMDAwMSwvLyByZWNlaXZpbmcgZmFsc2UgZGF0YSBwYWNrZXRzLgogICAgLypAfSovCn0gTU1TU0NQYWNrZXRUeXBlOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgTU1TQ29udGV4dCAgbW1zOwogICAgaW50IG91dGdvaW5nX3BhY2tldF9zZXE7ICAgICAgICAgICAgIC8vLzwgT3V0Z29pbmcgcGFja2V0IHNlcXVlbmNlIG51bWJlci4KICAgIGNoYXIgcGF0aFsyNTZdOyAgICAgICAgICAgICAgICAgICAgICAvLy88IFBhdGggb2YgdGhlIHJlc291cmNlIGJlaW5nIGFza2VkIGZvci4KICAgIGNoYXIgaG9zdFsxMjhdOyAgICAgICAgICAgICAgICAgICAgICAvLy88IEhvc3Qgb2YgdGhlIHJlc291cmNlcy4KICAgIGludCBpbmNvbWluZ19wYWNrZXRfc2VxOyAgICAgICAgICAgICAvLy88IEluY29taW5nIHBhY2tldCBzZXF1ZW5jZSBudW1iZXIuCiAgICBpbnQgaW5jb21pbmdfZmxhZ3M7ICAgICAgICAgICAgICAgICAgLy8vPCBJbmNvbWluZyBwYWNrZXQgZmxhZ3MuCiAgICBpbnQgcGFja2V0X2lkOyAgICAgICAgICAgICAgICAgICAgICAgLy8vPCBJZGVudGlmaWVyIGZvciBwYWNrZXRzIGluIHRoZSBjdXJyZW50IHN0cmVhbS4KICAgIHVuc2lnbmVkIGludCBoZWFkZXJfcGFja2V0X2lkOyAgICAgICAvLy88IGRlZmF1bHQgaXMgMi4KfSBNTVNUQ29udGV4dDsKCi8qKiBDcmVhdGUgTU1TVCBjb21tYW5kIHBhY2tldCBoZWFkZXIgKi8Kc3RhdGljIHZvaWQgc3RhcnRfY29tbWFuZF9wYWNrZXQoTU1TVENvbnRleHQgKm1tc3QsIE1NU0NTUGFja2V0VHlwZSBwYWNrZXRfdHlwZSkKewogICAgTU1TQ29udGV4dCAqbW1zICAgID0gJm1tc3QtPm1tczsKICAgIG1tcy0+d3JpdGVfb3V0X3B0ciA9IG1tcy0+b3V0X2J1ZmZlcjsKCiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIDEpOyAvLyBzdGFydCBzZXF1ZW5jZQogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCAweGIwMGJmYWNlKTsKICAgIGJ5dGVzdHJlYW1fcHV0X2xlMzIoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMCk7IC8vIExlbmd0aCBzdGFydHMgZnJvbSBhZnRlciB0aGUgcHJvdG9jb2wgdHlwZSBieXRlcwogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCBNS1RBRygnTScsJ00nLCdTJywnICcpKTsKICAgIGJ5dGVzdHJlYW1fcHV0X2xlMzIoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMCk7CiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIG1tc3QtPm91dGdvaW5nX3BhY2tldF9zZXErKyk7CiAgICBieXRlc3RyZWFtX3B1dF9sZTY0KCZtbXMtPndyaXRlX291dF9wdHIsIDApOyAvLyB0aW1lc3RhbXAKICAgIGJ5dGVzdHJlYW1fcHV0X2xlMzIoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMCk7CiAgICBieXRlc3RyZWFtX3B1dF9sZTE2KCZtbXMtPndyaXRlX291dF9wdHIsIHBhY2tldF90eXBlKTsKICAgIGJ5dGVzdHJlYW1fcHV0X2xlMTYoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMyk7IC8vIGRpcmVjdGlvbiB0byBzZXJ2ZXIKfQoKLyoqIEFkZCBwcmVmaXhlcyB0byBNTVNUIGNvbW1hbmQgcGFja2V0LiAqLwpzdGF0aWMgdm9pZCBpbnNlcnRfY29tbWFuZF9wcmVmaXhlcyhNTVNDb250ZXh0ICptbXMsCiAgICAgICAgdWludDMyX3QgcHJlZml4MSwgdWludDMyX3QgcHJlZml4MikKewogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCBwcmVmaXgxKTsgLy8gZmlyc3QgcHJlZml4CiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIHByZWZpeDIpOyAvLyBzZWNvbmQgcHJlZml4Cn0KCi8qKiBTZW5kIGEgcHJlcGFyZWQgTU1TVCBjb21tYW5kIHBhY2tldC4gKi8Kc3RhdGljIGludCBzZW5kX2NvbW1hbmRfcGFja2V0KE1NU1RDb250ZXh0ICptbXN0KQp7CiAgICBNTVNDb250ZXh0ICptbXMgID0gJm1tc3QtPm1tczsKICAgIGludCBsZW49IG1tcy0+d3JpdGVfb3V0X3B0ciAtIG1tcy0+b3V0X2J1ZmZlcjsKICAgIGludCBleGFjdF9sZW5ndGggPSBGRkFMSUdOKGxlbiwgOCk7CiAgICBpbnQgZmlyc3RfbGVuZ3RoPSBleGFjdF9sZW5ndGggLSAxNjsKICAgIGludCBsZW44PSBmaXJzdF9sZW5ndGgvODsKICAgIGludCB3cml0ZV9yZXN1bHQ7CgogICAgLy8gdXBkYXRlIHBhY2tldCBsZW5ndGggZmllbGRzLgogICAgQVZfV0wzMihtbXMtPm91dF9idWZmZXIgKyA4LCBmaXJzdF9sZW5ndGgpOwogICAgQVZfV0wzMihtbXMtPm91dF9idWZmZXIgKyAxNiwgbGVuOCk7CiAgICBBVl9XTDMyKG1tcy0+b3V0X2J1ZmZlciArIDMyLCBsZW44LTIpOwogICAgbWVtc2V0KG1tcy0+d3JpdGVfb3V0X3B0ciwgMCwgZXhhY3RfbGVuZ3RoIC0gbGVuKTsKCiAgICAvLyB3cml0ZSBpdCBvdXQuCiAgICB3cml0ZV9yZXN1bHQ9IGZmdXJsX3dyaXRlKG1tcy0+bW1zX2hkLCBtbXMtPm91dF9idWZmZXIsIGV4YWN0X2xlbmd0aCk7CiAgICBpZih3cml0ZV9yZXN1bHQgIT0gZXhhY3RfbGVuZ3RoKSB7CiAgICAgICAgYXZfbG9nKE5VTEwsIEFWX0xPR19FUlJPUiwKICAgICAgICAgICAgICAgIkZhaWxlZCB0byB3cml0ZSBkYXRhIG9mIGxlbmd0aCAlZDogJWQgKCVzKVxuIiwKICAgICAgICAgICAgICAgZXhhY3RfbGVuZ3RoLCB3cml0ZV9yZXN1bHQsCiAgICAgICAgICAgICAgIHdyaXRlX3Jlc3VsdCA8IDAgPyBzdHJlcnJvcihBVlVORVJST1Iod3JpdGVfcmVzdWx0KSkgOgogICAgICAgICAgICAgICAgICAgIlRoZSBzZXJ2ZXIgY2xvc2VkIHRoZSBjb25uZWN0aW9uIik7CiAgICAgICAgcmV0dXJuIEFWRVJST1IoRUlPKTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgbW1zX3B1dF91dGYxNihNTVNDb250ZXh0ICptbXMsIGNvbnN0IHVpbnQ4X3QgKnNyYykKewogICAgQVZJT0NvbnRleHQgYmljOwogICAgaW50IHNpemUgPSBtbXMtPndyaXRlX291dF9wdHIgLSBtbXMtPm91dF9idWZmZXI7CiAgICBpbnQgbGVuOwogICAgZmZpb19pbml0X2NvbnRleHQoJmJpYywgbW1zLT53cml0ZV9vdXRfcHRyLAogICAgICAgICAgICBzaXplb2YobW1zLT5vdXRfYnVmZmVyKSAtIHNpemUsIDEsIE5VTEwsIE5VTEwsIE5VTEwsIE5VTEwpOwoKICAgIGxlbiA9IGF2aW9fcHV0X3N0cjE2bGUoJmJpYywgc3JjKTsKICAgIG1tcy0+d3JpdGVfb3V0X3B0ciArPSBsZW47Cn0KCnN0YXRpYyBpbnQgc2VuZF90aW1lX3Rlc3RfZGF0YShNTVNUQ29udGV4dCAqbW1zdCkKewogICAgc3RhcnRfY29tbWFuZF9wYWNrZXQobW1zdCwgQ1NfUEtUX1RJTUlOR19EQVRBX1JFUVVFU1QpOwogICAgaW5zZXJ0X2NvbW1hbmRfcHJlZml4ZXMoJm1tc3QtPm1tcywgMHgwMGYwZjBmMCwgMHgwMDA0MDAwYik7CiAgICByZXR1cm4gc2VuZF9jb21tYW5kX3BhY2tldChtbXN0KTsKfQoKc3RhdGljIGludCBzZW5kX3Byb3RvY29sX3NlbGVjdChNTVNUQ29udGV4dCAqbW1zdCkKewogICAgY2hhciBkYXRhX3N0cmluZ1syNTZdOwogICAgTU1TQ29udGV4dCAqbW1zID0gJm1tc3QtPm1tczsKCiAgICBzdGFydF9jb21tYW5kX3BhY2tldChtbXN0LCBDU19QS1RfUFJPVE9DT0xfU0VMRUNUKTsKICAgIGluc2VydF9jb21tYW5kX3ByZWZpeGVzKG1tcywgMCwgMHhmZmZmZmZmZik7CiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIDApOyAgICAgICAgICAvLyBtYXhGdW5uZWxCeXRlcwogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCAweDAwOTg5NjgwKTsgLy8gbWF4Yml0UmF0ZQogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCAyKTsgICAgICAgICAgLy8gZnVubmVsTW9kZQogICAgc25wcmludGYoZGF0YV9zdHJpbmcsIHNpemVvZihkYXRhX3N0cmluZyksICJcXFxcJWQuJWQuJWQuJWRcXCVzXFwlZCIsCiAgICAgICAgICAgIChMT0NBTF9BRERSRVNTPj4yNCkmMHhmZiwKICAgICAgICAgICAgKExPQ0FMX0FERFJFU1M+PjE2KSYweGZmLAogICAgICAgICAgICAoTE9DQUxfQUREUkVTUz4+OCkmMHhmZiwKICAgICAgICAgICAgTE9DQUxfQUREUkVTUyYweGZmLAogICAgICAgICAgICAiVENQIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gb3IgVURQCiAgICAgICAgICAgIExPQ0FMX1BPUlQpOwoKICAgIG1tc19wdXRfdXRmMTYobW1zLCBkYXRhX3N0cmluZyk7CiAgICByZXR1cm4gc2VuZF9jb21tYW5kX3BhY2tldChtbXN0KTsKfQoKc3RhdGljIGludCBzZW5kX21lZGlhX2ZpbGVfcmVxdWVzdChNTVNUQ29udGV4dCAqbW1zdCkKewogICAgTU1TQ29udGV4dCAqbW1zID0gJm1tc3QtPm1tczsKICAgIHN0YXJ0X2NvbW1hbmRfcGFja2V0KG1tc3QsIENTX1BLVF9NRURJQV9GSUxFX1JFUVVFU1QpOwogICAgaW5zZXJ0X2NvbW1hbmRfcHJlZml4ZXMobW1zLCAxLCAweGZmZmZmZmZmKTsKICAgIGJ5dGVzdHJlYW1fcHV0X2xlMzIoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMCk7CiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIDApOwogICAgbW1zX3B1dF91dGYxNihtbXMsIG1tc3QtPnBhdGggKyAxKTsgLy8gKzEgZm9yIHNraXAgIi8iCgogICAgcmV0dXJuIHNlbmRfY29tbWFuZF9wYWNrZXQobW1zdCk7Cn0KCnN0YXRpYyB2b2lkIGhhbmRsZV9wYWNrZXRfc3RyZWFtX2NoYW5naW5nX3R5cGUoTU1TVENvbnRleHQgKm1tc3QpCnsKICAgIE1NU0NvbnRleHQgKm1tcyA9ICZtbXN0LT5tbXM7CiAgICBhdl9kbG9nKE5VTEwsICJTdHJlYW0gY2hhbmdpbmchXG4iKTsKCiAgICAvLyA0MCBpcyB0aGUgcGFja2V0IGhlYWRlciBzaXplLCA3IGlzIHRoZSBwcmVmaXggc2l6ZS4KICAgIG1tc3QtPmhlYWRlcl9wYWNrZXRfaWQ9IEFWX1JMMzIobW1zLT5pbl9idWZmZXIgKyA0MCArIDcpOwogICAgYXZfZGxvZyhOVUxMLCAiQ2hhbmdlZCBoZWFkZXIgcHJlZml4IHRvIDB4JXgiLCBtbXN0LT5oZWFkZXJfcGFja2V0X2lkKTsKfQoKc3RhdGljIGludCBzZW5kX2tlZXBhbGl2ZV9wYWNrZXQoTU1TVENvbnRleHQgKm1tc3QpCnsKICAgIC8vIHJlc3BvbmQgdG8gYSBrZWVwYWxpdmUgd2l0aCBhIGtlZXBhbGl2ZS4uLgogICAgc3RhcnRfY29tbWFuZF9wYWNrZXQobW1zdCwgQ1NfUEtUX0tFRVBBTElWRSk7CiAgICBpbnNlcnRfY29tbWFuZF9wcmVmaXhlcygmbW1zdC0+bW1zLCAxLCAweDEwMEZGRkYpOwogICAgcmV0dXJuIHNlbmRfY29tbWFuZF9wYWNrZXQobW1zdCk7Cn0KCi8qKiBQYWQgbWVkaWEgcGFja2V0cyBzbWFsbGVyIHRoYW4gbWF4X3BhY2tldF9zaXplIGFuZC9vciBhZGp1c3QgcmVhZCBwb3NpdGlvbgogICogYWZ0ZXIgYSBzZWVrLiAqLwpzdGF0aWMgdm9pZCBwYWRfbWVkaWFfcGFja2V0KE1NU0NvbnRleHQgKm1tcykKewogICAgaWYobW1zLT5yZW1haW5pbmdfaW5fbGVuPG1tcy0+YXNmX3BhY2tldF9sZW4pIHsKICAgICAgICBpbnQgcGFkZGluZ19zaXplID0gbW1zLT5hc2ZfcGFja2V0X2xlbiAtIG1tcy0+cmVtYWluaW5nX2luX2xlbjsKICAgICAgICBtZW1zZXQobW1zLT5pbl9idWZmZXIgKyBtbXMtPnJlbWFpbmluZ19pbl9sZW4sIDAsIHBhZGRpbmdfc2l6ZSk7CiAgICAgICAgbW1zLT5yZW1haW5pbmdfaW5fbGVuICs9IHBhZGRpbmdfc2l6ZTsKICAgIH0KfQoKLyoqIFJlYWQgaW5jb21pbmcgTU1TVCBtZWRpYSwgaGVhZGVyIG9yIGNvbW1hbmQgcGFja2V0LiAqLwpzdGF0aWMgTU1TU0NQYWNrZXRUeXBlIGdldF90Y3Bfc2VydmVyX3Jlc3BvbnNlKE1NU1RDb250ZXh0ICptbXN0KQp7CiAgICBpbnQgcmVhZF9yZXN1bHQ7CiAgICBNTVNTQ1BhY2tldFR5cGUgcGFja2V0X3R5cGU9IC0xOwogICAgTU1TQ29udGV4dCAqbW1zID0gJm1tc3QtPm1tczsKICAgIGZvcig7OykgewogICAgICAgIHJlYWRfcmVzdWx0ID0gZmZ1cmxfcmVhZF9jb21wbGV0ZShtbXMtPm1tc19oZCwgbW1zLT5pbl9idWZmZXIsIDgpOwogICAgICAgIGlmIChyZWFkX3Jlc3VsdCAhPSA4KSB7CiAgICAgICAgICAgIGlmKHJlYWRfcmVzdWx0IDwgMCkgewogICAgICAgICAgICAgICAgYXZfbG9nKE5VTEwsIEFWX0xPR19FUlJPUiwKICAgICAgICAgICAgICAgICAgICAgICAiRXJyb3IgcmVhZGluZyBwYWNrZXQgaGVhZGVyOiAlZCAoJXMpXG4iLAogICAgICAgICAgICAgICAgICAgICAgIHJlYWRfcmVzdWx0LCBzdHJlcnJvcihBVlVORVJST1IocmVhZF9yZXN1bHQpKSk7CiAgICAgICAgICAgICAgICBwYWNrZXRfdHlwZSA9IFNDX1BLVF9DQU5DRUw7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBhdl9sb2coTlVMTCwgQVZfTE9HX0VSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICJUaGUgc2VydmVyIGNsb3NlZCB0aGUgY29ubmVjdGlvblxuIik7CiAgICAgICAgICAgICAgICBwYWNrZXRfdHlwZSA9IFNDX1BLVF9OT19EQVRBOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiBwYWNrZXRfdHlwZTsKICAgICAgICB9CgogICAgICAgIC8vIGhhbmRsZSBjb21tYW5kIHBhY2tldC4KICAgICAgICBpZihBVl9STDMyKG1tcy0+aW5fYnVmZmVyICsgNCk9PTB4YjAwYmZhY2UpIHsKICAgICAgICAgICAgaW50IGxlbmd0aF9yZW1haW5pbmcsIGhyOwoKICAgICAgICAgICAgbW1zdC0+aW5jb21pbmdfZmxhZ3M9IG1tcy0+aW5fYnVmZmVyWzNdOwogICAgICAgICAgICByZWFkX3Jlc3VsdD0gZmZ1cmxfcmVhZF9jb21wbGV0ZShtbXMtPm1tc19oZCwgbW1zLT5pbl9idWZmZXIrOCwgNCk7CiAgICAgICAgICAgIGlmKHJlYWRfcmVzdWx0ICE9IDQpIHsKICAgICAgICAgICAgICAgIGF2X2xvZyhOVUxMLCBBVl9MT0dfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgIlJlYWRpbmcgY29tbWFuZCBwYWNrZXQgbGVuZ3RoIGZhaWxlZDogJWQgKCVzKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICByZWFkX3Jlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICByZWFkX3Jlc3VsdCA8IDAgPyBzdHJlcnJvcihBVlVORVJST1IocmVhZF9yZXN1bHQpKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaGUgc2VydmVyIGNsb3NlZCB0aGUgY29ubmVjdGlvbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlYWRfcmVzdWx0IDwgMCA/IHJlYWRfcmVzdWx0IDogQVZFUlJPUihFSU8pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBsZW5ndGhfcmVtYWluaW5nPSBBVl9STDMyKG1tcy0+aW5fYnVmZmVyKzgpICsgNDsKICAgICAgICAgICAgYXZfZGxvZyhOVUxMLCAiTGVuZ3RoIHJlbWFpbmluZyBpcyAlZFxuIiwgbGVuZ3RoX3JlbWFpbmluZyk7CiAgICAgICAgICAgIC8vIHJlYWQgdGhlIHJlc3Qgb2YgdGhlIHBhY2tldC4KICAgICAgICAgICAgaWYgKGxlbmd0aF9yZW1haW5pbmcgPCAwCiAgICAgICAgICAgICAgICB8fCBsZW5ndGhfcmVtYWluaW5nID4gc2l6ZW9mKG1tcy0+aW5fYnVmZmVyKSAtIDEyKSB7CiAgICAgICAgICAgICAgICBhdl9sb2coTlVMTCwgQVZfTE9HX0VSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICJJbmNvbWluZyBwYWNrZXQgbGVuZ3RoICVkIGV4Y2VlZHMgYnVmc2l6ZSAlenVcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgbGVuZ3RoX3JlbWFpbmluZywgc2l6ZW9mKG1tcy0+aW5fYnVmZmVyKSAtIDEyKTsKICAgICAgICAgICAgICAgIHJldHVybiBBVkVSUk9SX0lOVkFMSUREQVRBOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHJlYWRfcmVzdWx0ID0gZmZ1cmxfcmVhZF9jb21wbGV0ZShtbXMtPm1tc19oZCwgbW1zLT5pbl9idWZmZXIgKyAxMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGhfcmVtYWluaW5nKSA7CiAgICAgICAgICAgIGlmIChyZWFkX3Jlc3VsdCAhPSBsZW5ndGhfcmVtYWluaW5nKSB7CiAgICAgICAgICAgICAgICBhdl9sb2coTlVMTCwgQVZfTE9HX0VSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICJSZWFkaW5nIHBrdCBkYXRhIChsZW5ndGg9JWQpIGZhaWxlZDogJWQgKCVzKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGhfcmVtYWluaW5nLCByZWFkX3Jlc3VsdCwKICAgICAgICAgICAgICAgICAgICAgICByZWFkX3Jlc3VsdCA8IDAgPyBzdHJlcnJvcihBVlVORVJST1IocmVhZF9yZXN1bHQpKSA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICJUaGUgc2VydmVyIGNsb3NlZCB0aGUgY29ubmVjdGlvbiIpOwogICAgICAgICAgICAgICAgcmV0dXJuIHJlYWRfcmVzdWx0IDwgMCA/IHJlYWRfcmVzdWx0IDogQVZFUlJPUihFSU8pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHBhY2tldF90eXBlPSBBVl9STDE2KG1tcy0+aW5fYnVmZmVyKzM2KTsKICAgICAgICAgICAgaWYgKHJlYWRfcmVzdWx0ID49IDQ0ICYmIChociA9IEFWX1JMMzIobW1zLT5pbl9idWZmZXIgKyA0MCkpKSB7CiAgICAgICAgICAgICAgICBhdl9sb2coTlVMTCwgQVZfTE9HX0VSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICJTZXJ2ZXIgc2VudCBhIG1lc3NhZ2Ugd2l0aCBwYWNrZXQgdHlwZSAweCV4IGFuZCBlcnJvciBzdGF0dXMgY29kZSAweCUwOHhcbiIsIHBhY2tldF90eXBlLCBocik7CiAgICAgICAgICAgICAgICByZXR1cm4gQVZFUlJPUihFSU5WQUwpOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgaW50IGxlbmd0aF9yZW1haW5pbmc7CiAgICAgICAgICAgIGludCBwYWNrZXRfaWRfdHlwZTsKICAgICAgICAgICAgaW50IHRtcDsKCiAgICAgICAgICAgIC8vIG5vdGUgd2UgY2FjaGUgdGhlIGZpcnN0IDggYnl0ZXMsCiAgICAgICAgICAgIC8vIHRoZW4gZmlsbCB1cCB0aGUgYnVmZmVyIHdpdGggdGhlIG90aGVycwogICAgICAgICAgICB0bXAgICAgICAgICAgICAgICAgICAgICAgID0gQVZfUkwxNihtbXMtPmluX2J1ZmZlciArIDYpOwogICAgICAgICAgICBsZW5ndGhfcmVtYWluaW5nICAgICAgICAgID0gKHRtcCAtIDgpICYgMHhmZmZmOwogICAgICAgICAgICBtbXN0LT5pbmNvbWluZ19wYWNrZXRfc2VxID0gQVZfUkwzMihtbXMtPmluX2J1ZmZlcik7CiAgICAgICAgICAgIHBhY2tldF9pZF90eXBlICAgICAgICAgICAgPSBtbXMtPmluX2J1ZmZlcls0XTsKICAgICAgICAgICAgbW1zdC0+aW5jb21pbmdfZmxhZ3MgICAgICA9IG1tcy0+aW5fYnVmZmVyWzVdOwoKICAgICAgICAgICAgaWYgKGxlbmd0aF9yZW1haW5pbmcgPCAwCiAgICAgICAgICAgICAgICB8fCBsZW5ndGhfcmVtYWluaW5nID4gc2l6ZW9mKG1tcy0+aW5fYnVmZmVyKSAtIDgpIHsKICAgICAgICAgICAgICAgIGF2X2xvZyhOVUxMLCBBVl9MT0dfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgIkRhdGEgbGVuZ3RoICVkIGlzIGludmFsaWQgb3IgdG9vIGxhcmdlIChtYXg9JXp1KVxuIiwKICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGhfcmVtYWluaW5nLCBzaXplb2YobW1zLT5pbl9idWZmZXIpKTsKICAgICAgICAgICAgICAgIHJldHVybiBBVkVSUk9SX0lOVkFMSUREQVRBOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1tcy0+cmVtYWluaW5nX2luX2xlbiAgICA9IGxlbmd0aF9yZW1haW5pbmc7CiAgICAgICAgICAgIG1tcy0+cmVhZF9pbl9wdHIgICAgICAgICA9IG1tcy0+aW5fYnVmZmVyOwogICAgICAgICAgICByZWFkX3Jlc3VsdD0gZmZ1cmxfcmVhZF9jb21wbGV0ZShtbXMtPm1tc19oZCwgbW1zLT5pbl9idWZmZXIsIGxlbmd0aF9yZW1haW5pbmcpOwogICAgICAgICAgICBpZihyZWFkX3Jlc3VsdCAhPSBsZW5ndGhfcmVtYWluaW5nKSB7CiAgICAgICAgICAgICAgICBhdl9sb2coTlVMTCwgQVZfTE9HX0VSUk9SLAogICAgICAgICAgICAgICAgICAgICAgICJGYWlsZWQgdG8gcmVhZCBwYWNrZXQgZGF0YSBvZiBzaXplICVkOiAlZCAoJXMpXG4iLAogICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aF9yZW1haW5pbmcsIHJlYWRfcmVzdWx0LAogICAgICAgICAgICAgICAgICAgICAgIHJlYWRfcmVzdWx0IDwgMCA/IHN0cmVycm9yKEFWVU5FUlJPUihyZWFkX3Jlc3VsdCkpIDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRoZSBzZXJ2ZXIgY2xvc2VkIHRoZSBjb25uZWN0aW9uIik7CiAgICAgICAgICAgICAgICByZXR1cm4gcmVhZF9yZXN1bHQgPCAwID8gcmVhZF9yZXN1bHQgOiBBVkVSUk9SKEVJTyk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8vIGlmIHdlIHN1Y2Nlc3NmdWxseSByZWFkIGV2ZXJ5dGhpbmcuCiAgICAgICAgICAgIGlmKHBhY2tldF9pZF90eXBlID09IG1tc3QtPmhlYWRlcl9wYWNrZXRfaWQpIHsKICAgICAgICAgICAgICAgIHBhY2tldF90eXBlID0gU0NfUEtUX0FTRl9IRUFERVI7CiAgICAgICAgICAgICAgICAvLyBTdG9yZSB0aGUgYXNmIGhlYWRlcgogICAgICAgICAgICAgICAgaWYoIW1tcy0+aGVhZGVyX3BhcnNlZCkgewogICAgICAgICAgICAgICAgICAgIHZvaWQgKnAgPSBhdl9yZWFsbG9jKG1tcy0+YXNmX2hlYWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1tcy0+YXNmX2hlYWRlcl9zaXplICsgbW1zLT5yZW1haW5pbmdfaW5fbGVuKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIXApIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXZfZnJlZXAoJm1tcy0+YXNmX2hlYWRlcik7CiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBBVkVSUk9SKEVOT01FTSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIG1tcy0+YXNmX2hlYWRlciA9IHA7CiAgICAgICAgICAgICAgICAgICAgbWVtY3B5KG1tcy0+YXNmX2hlYWRlciArIG1tcy0+YXNmX2hlYWRlcl9zaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgICBtbXMtPnJlYWRfaW5fcHRyLCBtbXMtPnJlbWFpbmluZ19pbl9sZW4pOwogICAgICAgICAgICAgICAgICAgIG1tcy0+YXNmX2hlYWRlcl9zaXplICs9IG1tcy0+cmVtYWluaW5nX2luX2xlbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8vIDB4MDQgbWVhbnMgYXNmIGhlYWRlciBpcyBzZW50IGluIG11bHRpcGxlIHBhY2tldHMuCiAgICAgICAgICAgICAgICBpZiAobW1zdC0+aW5jb21pbmdfZmxhZ3MgPT0gMHgwNCkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfSBlbHNlIGlmKHBhY2tldF9pZF90eXBlID09IG1tc3QtPnBhY2tldF9pZCkgewogICAgICAgICAgICAgICAgcGFja2V0X3R5cGUgPSBTQ19QS1RfQVNGX01FRElBOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXZfZGxvZyhOVUxMLCAicGFja2V0IGlkIHR5cGUgJWQgaXMgb2xkLiIsIHBhY2tldF9pZF90eXBlKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvLyBwcmVwcm9jZXNzIHNvbWUgcGFja2V0IHR5cGUKICAgICAgICBpZihwYWNrZXRfdHlwZSA9PSBTQ19QS1RfS0VFUEFMSVZFKSB7CiAgICAgICAgICAgIHNlbmRfa2VlcGFsaXZlX3BhY2tldChtbXN0KTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfSBlbHNlIGlmKHBhY2tldF90eXBlID09IFNDX1BLVF9TVFJFQU1fQ0hBTkdJTkcpIHsKICAgICAgICAgICAgaGFuZGxlX3BhY2tldF9zdHJlYW1fY2hhbmdpbmdfdHlwZShtbXN0KTsKICAgICAgICB9IGVsc2UgaWYocGFja2V0X3R5cGUgPT0gU0NfUEtUX0FTRl9NRURJQSkgewogICAgICAgICAgICBwYWRfbWVkaWFfcGFja2V0KG1tcyk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBwYWNrZXRfdHlwZTsKICAgIH0KfQoKc3RhdGljIGludCBtbXNfc2FmZV9zZW5kX3JlY3YoTU1TVENvbnRleHQgKm1tc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCAoKnNlbmRfZnVuKShNTVNUQ29udGV4dCAqbW1zdCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IE1NU1NDUGFja2V0VHlwZSBleHBlY3RfdHlwZSkKewogICAgTU1TU0NQYWNrZXRUeXBlIHR5cGU7CiAgICBpZihzZW5kX2Z1bikgewogICAgICAgIGludCByZXQgPSBzZW5kX2Z1bihtbXN0KTsKICAgICAgICBpZiAocmV0IDwgMCkgewogICAgICAgICAgICBhdl9kbG9nKE5VTEwsICJTZW5kIFBhY2tldCBlcnJvciBiZWZvcmUgZXhwZWN0aW5nIHJlY3YgcGFja2V0ICVkXG4iLCBleHBlY3RfdHlwZSk7CiAgICAgICAgICAgIHJldHVybiByZXQ7CiAgICAgICAgfQogICAgfQoKICAgIGlmICgodHlwZSA9IGdldF90Y3Bfc2VydmVyX3Jlc3BvbnNlKG1tc3QpKSAhPSBleHBlY3RfdHlwZSkgewogICAgICAgIGF2X2xvZyhOVUxMLCBBVl9MT0dfRVJST1IsCiAgICAgICAgICAgICAgICJDb3JydXB0IHN0cmVhbSAodW5leHBlY3RlZCBwYWNrZXQgdHlwZSAweCV4LCBleHBlY3RlZCAweCV4KVxuIiwKICAgICAgICAgICAgICAgdHlwZSwgZXhwZWN0X3R5cGUpOwogICAgICAgIHJldHVybiBBVkVSUk9SX0lOVkFMSUREQVRBOwogICAgfSBlbHNlIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KfQoKc3RhdGljIGludCBzZW5kX21lZGlhX2hlYWRlcl9yZXF1ZXN0KE1NU1RDb250ZXh0ICptbXN0KQp7CiAgICBNTVNDb250ZXh0ICptbXMgPSAmbW1zdC0+bW1zOwogICAgc3RhcnRfY29tbWFuZF9wYWNrZXQobW1zdCwgQ1NfUEtUX01FRElBX0hFQURFUl9SRVFVRVNUKTsKICAgIGluc2VydF9jb21tYW5kX3ByZWZpeGVzKG1tcywgMSwgMCk7CiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIDApOwogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCAweDAwODAwMDAwKTsKICAgIGJ5dGVzdHJlYW1fcHV0X2xlMzIoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMHhmZmZmZmZmZik7CiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIDApOwogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCAwKTsKICAgIGJ5dGVzdHJlYW1fcHV0X2xlMzIoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMCk7CgogICAgLy8gdGhlIG1lZGlhIHByZXJvbGwgdmFsdWUgaW4gbWlsbGlzZWNvbmRzPwogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCAwKTsKICAgIGJ5dGVzdHJlYW1fcHV0X2xlMzIoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMHg0MEFDMjAwMCk7CiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIDIpOwogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCAwKTsKCiAgICByZXR1cm4gc2VuZF9jb21tYW5kX3BhY2tldChtbXN0KTsKfQoKLyoqIFNlbmQgdGhlIGluaXRpYWwgaGFuZHNoYWtlLiAqLwpzdGF0aWMgaW50IHNlbmRfc3RhcnR1cF9wYWNrZXQoTU1TVENvbnRleHQgKm1tc3QpCnsKICAgIGNoYXIgZGF0YV9zdHJpbmdbMjU2XTsKICAgIE1NU0NvbnRleHQgKm1tcyA9ICZtbXN0LT5tbXM7CiAgICAvLyBTdWJzY3JpYmVyTmFtZSBpcyBkZWZpbmVkIGluIE1TIHNwZWNpZmljYXRpb24gbGlua2VkIGJlbG93LgogICAgLy8gVGhlIGd1aWQgdmFsdWUgY2FuIGJlIGFueSB2YWxpZCB2YWx1ZS4KICAgIC8vIGh0dHA6Ly9kb3dubG9hZC5taWNyb3NvZnQuY29tLwogICAgLy8gZG93bmxvYWQvOS81L0UvOTVFRjY2QUYtOTAyNi00QkIwLUE0MUQtQTRGODE4MDJEOTJDLyU1Qk1TLVdNU1AlNUQucGRmCiAgICBzbnByaW50ZihkYXRhX3N0cmluZywgc2l6ZW9mKGRhdGFfc3RyaW5nKSwKICAgICAgICAgICAgIk5TUGxheWVyLzcuMC4wLjE5NTY7IHslc307IEhvc3Q6ICVzIiwKICAgICAgICAgICAgIjdFNjY3RjVELUE2NjEtNDk1RS1BNTEyLUY1NTY4NkREQTE3OCIsIG1tc3QtPmhvc3QpOwoKICAgIHN0YXJ0X2NvbW1hbmRfcGFja2V0KG1tc3QsIENTX1BLVF9JTklUSUFMKTsKICAgIGluc2VydF9jb21tYW5kX3ByZWZpeGVzKG1tcywgMCwgMHgwMDA0MDAwYik7CiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIDB4MDAwMzAwMWMpOwogICAgbW1zX3B1dF91dGYxNihtbXMsIGRhdGFfc3RyaW5nKTsKICAgIHJldHVybiBzZW5kX2NvbW1hbmRfcGFja2V0KG1tc3QpOwp9CgovKiogU2VuZCBNTVNUIHN0cmVhbSBzZWxlY3Rpb24gY29tbWFuZCBiYXNlZCBvbiB0aGUgQVZTdHJlYW0tPmRpc2NhcmQgdmFsdWVzLiAqLwpzdGF0aWMgaW50IHNlbmRfc3RyZWFtX3NlbGVjdGlvbl9yZXF1ZXN0KE1NU1RDb250ZXh0ICptbXN0KQp7CiAgICBpbnQgaTsKICAgIE1NU0NvbnRleHQgKm1tcyA9ICZtbXN0LT5tbXM7CiAgICAvLyAgc2VuZCB0aGUgc3RyZWFtcyB3ZSB3YW50IGJhY2suLi4KICAgIHN0YXJ0X2NvbW1hbmRfcGFja2V0KG1tc3QsIENTX1BLVF9TVFJFQU1fSURfUkVRVUVTVCk7CiAgICBieXRlc3RyZWFtX3B1dF9sZTMyKCZtbXMtPndyaXRlX291dF9wdHIsIG1tcy0+c3RyZWFtX251bSk7ICAgICAgICAgLy8gc3RyZWFtIG51bXMKICAgIGZvcihpPSAwOyBpPG1tcy0+c3RyZWFtX251bTsgaSsrKSB7CiAgICAgICAgYnl0ZXN0cmVhbV9wdXRfbGUxNigmbW1zLT53cml0ZV9vdXRfcHRyLCAweGZmZmYpOyAgICAgICAgICAgICAgLy8gZmxhZ3MKICAgICAgICBieXRlc3RyZWFtX3B1dF9sZTE2KCZtbXMtPndyaXRlX291dF9wdHIsIG1tcy0+c3RyZWFtc1tpXS5pZCk7ICAvLyBzdHJlYW0gaWQKICAgICAgICBieXRlc3RyZWFtX3B1dF9sZTE2KCZtbXMtPndyaXRlX291dF9wdHIsIDApOyAgICAgICAgICAgICAgICAgICAvLyBzZWxlY3Rpb24KICAgIH0KICAgIHJldHVybiBzZW5kX2NvbW1hbmRfcGFja2V0KG1tc3QpOwp9CgpzdGF0aWMgaW50IHNlbmRfY2xvc2VfcGFja2V0KE1NU1RDb250ZXh0ICptbXN0KQp7CiAgICBzdGFydF9jb21tYW5kX3BhY2tldChtbXN0LCBDU19QS1RfU1RSRUFNX0NMT1NFKTsKICAgIGluc2VydF9jb21tYW5kX3ByZWZpeGVzKCZtbXN0LT5tbXMsIDEsIDEpOwoKICAgIHJldHVybiBzZW5kX2NvbW1hbmRfcGFja2V0KG1tc3QpOwp9CgovKiogQ2xvc2UgdGhlIE1NU0gvTU1TVCBjb25uZWN0aW9uICovCnN0YXRpYyBpbnQgbW1zX2Nsb3NlKFVSTENvbnRleHQgKmgpCnsKICAgIE1NU1RDb250ZXh0ICptbXN0ID0gKE1NU1RDb250ZXh0ICopaC0+cHJpdl9kYXRhOwogICAgTU1TQ29udGV4dCAqbW1zICAgPSAmbW1zdC0+bW1zOwogICAgaWYobW1zLT5tbXNfaGQpIHsKICAgICAgICBzZW5kX2Nsb3NlX3BhY2tldChtbXN0KTsKICAgICAgICBmZnVybF9jbG9zZShtbXMtPm1tc19oZCk7CiAgICB9CgogICAgLyogZnJlZSBhbGwgc2VwYXJhdGVseSBhbGxvY2F0ZWQgcG9pbnRlcnMgaW4gbW1zICovCiAgICBhdl9mcmVlKG1tcy0+c3RyZWFtcyk7CiAgICBhdl9mcmVlKG1tcy0+YXNmX2hlYWRlcik7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgc2VuZF9tZWRpYV9wYWNrZXRfcmVxdWVzdChNTVNUQ29udGV4dCAqbW1zdCkKewogICAgTU1TQ29udGV4dCAqbW1zID0gJm1tc3QtPm1tczsKICAgIHN0YXJ0X2NvbW1hbmRfcGFja2V0KG1tc3QsIENTX1BLVF9TVEFSVF9GUk9NX1BLVF9JRCk7CiAgICBpbnNlcnRfY29tbWFuZF9wcmVmaXhlcyhtbXMsIDEsIDB4MDAwMUZGRkYpOwogICAgYnl0ZXN0cmVhbV9wdXRfbGU2NCgmbW1zLT53cml0ZV9vdXRfcHRyLCAwKTsgICAgICAgICAgLy8gc2VlayB0aW1lc3RhbXAKICAgIGJ5dGVzdHJlYW1fcHV0X2xlMzIoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMHhmZmZmZmZmZik7IC8vIHVua25vd24KICAgIGJ5dGVzdHJlYW1fcHV0X2xlMzIoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMHhmZmZmZmZmZik7IC8vIHBhY2tldCBvZmZzZXQKICAgIGJ5dGVzdHJlYW1fcHV0X2J5dGUoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMHhmZik7ICAgICAgIC8vIG1heCBzdHJlYW0gdGltZSBsaW1pdAogICAgYnl0ZXN0cmVhbV9wdXRfYnl0ZSgmbW1zLT53cml0ZV9vdXRfcHRyLCAweGZmKTsgICAgICAgLy8gbWF4IHN0cmVhbSB0aW1lIGxpbWl0CiAgICBieXRlc3RyZWFtX3B1dF9ieXRlKCZtbXMtPndyaXRlX291dF9wdHIsIDB4ZmYpOyAgICAgICAvLyBtYXggc3RyZWFtIHRpbWUgbGltaXQKICAgIGJ5dGVzdHJlYW1fcHV0X2J5dGUoJm1tcy0+d3JpdGVfb3V0X3B0ciwgMHgwMCk7ICAgICAgIC8vIHN0cmVhbSB0aW1lIGxpbWl0IGZsYWcKCiAgICBtbXN0LT5wYWNrZXRfaWQrKzsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmV3IHBhY2tldF9pZAogICAgYnl0ZXN0cmVhbV9wdXRfbGUzMigmbW1zLT53cml0ZV9vdXRfcHRyLCBtbXN0LT5wYWNrZXRfaWQpOwogICAgcmV0dXJuIHNlbmRfY29tbWFuZF9wYWNrZXQobW1zdCk7Cn0KCgpzdGF0aWMgdm9pZCBjbGVhcl9zdHJlYW1fYnVmZmVycyhNTVNDb250ZXh0ICptbXMpCnsKICAgIG1tcy0+cmVtYWluaW5nX2luX2xlbiA9IDA7CiAgICBtbXMtPnJlYWRfaW5fcHRyICAgICAgPSBtbXMtPmluX2J1ZmZlcjsKfQoKc3RhdGljIGludCBtbXNfb3BlbihVUkxDb250ZXh0ICpoLCBjb25zdCBjaGFyICp1cmksIGludCBmbGFncykKewogICAgTU1TVENvbnRleHQgKm1tc3QgPSBoLT5wcml2X2RhdGE7CiAgICBNTVNDb250ZXh0ICptbXM7CiAgICBpbnQgcG9ydCwgZXJyOwogICAgY2hhciB0Y3BuYW1lWzI1Nl07CgogICAgaC0+aXNfc3RyZWFtZWQgPSAxOwogICAgbW1zID0gJm1tc3QtPm1tczsKCiAgICAvLyBvbmx5IGZvciBNTVMgb3ZlciBUQ1AsIHNvIHNldCBwcm90byA9IE5VTEwKICAgIGF2X3VybF9zcGxpdChOVUxMLCAwLCBOVUxMLCAwLAogICAgICAgICAgICBtbXN0LT5ob3N0LCBzaXplb2YobW1zdC0+aG9zdCksICZwb3J0LCBtbXN0LT5wYXRoLAogICAgICAgICAgICBzaXplb2YobW1zdC0+cGF0aCksIHVyaSk7CgogICAgaWYocG9ydDwwKQogICAgICAgIHBvcnQgPSAxNzU1OyAvLyBkZWZhdXQgbW1zIHByb3RvY29sIHBvcnQKCiAgICAvLyBlc3RhYmxpc2ggdGNwIGNvbm5lY3Rpb24uCiAgICBmZl91cmxfam9pbih0Y3BuYW1lLCBzaXplb2YodGNwbmFtZSksICJ0Y3AiLCBOVUxMLCBtbXN0LT5ob3N0LCBwb3J0LCBOVUxMKTsKICAgIGVyciA9IGZmdXJsX29wZW4oJm1tcy0+bW1zX2hkLCB0Y3BuYW1lLCBBVklPX0ZMQUdfUkVBRF9XUklURSwKICAgICAgICAgICAgICAgICAgICAgJmgtPmludGVycnVwdF9jYWxsYmFjaywgTlVMTCk7CiAgICBpZiAoZXJyKQogICAgICAgIGdvdG8gZmFpbDsKCiAgICBtbXN0LT5wYWNrZXRfaWQgICAgICAgID0gMzsgICAgICAgICAgLy8gZGVmYXVsdCwgaW5pdGlhbCB2YWx1ZS4KICAgIG1tc3QtPmhlYWRlcl9wYWNrZXRfaWQgPSAyOyAgICAgICAgICAvLyBkZWZhdWx0LCBpbml0aWFsIHZhbHVlLgogICAgZXJyID0gbW1zX3NhZmVfc2VuZF9yZWN2KG1tc3QsIHNlbmRfc3RhcnR1cF9wYWNrZXQsIFNDX1BLVF9DTElFTlRfQUNDRVBURUQpOwogICAgaWYgKGVycikKICAgICAgICBnb3RvIGZhaWw7CiAgICBlcnIgPSBtbXNfc2FmZV9zZW5kX3JlY3YobW1zdCwgc2VuZF90aW1lX3Rlc3RfZGF0YSwgU0NfUEtUX1RJTUlOR19URVNUX1JFUExZKTsKICAgIGlmIChlcnIpCiAgICAgICAgZ290byBmYWlsOwogICAgZXJyID0gbW1zX3NhZmVfc2VuZF9yZWN2KG1tc3QsIHNlbmRfcHJvdG9jb2xfc2VsZWN0LCBTQ19QS1RfUFJPVE9DT0xfQUNDRVBURUQpOwogICAgaWYgKGVycikKICAgICAgICBnb3RvIGZhaWw7CiAgICBlcnIgPSBtbXNfc2FmZV9zZW5kX3JlY3YobW1zdCwgc2VuZF9tZWRpYV9maWxlX3JlcXVlc3QsIFNDX1BLVF9NRURJQV9GSUxFX0RFVEFJTFMpOwogICAgaWYgKGVycikKICAgICAgICBnb3RvIGZhaWw7CiAgICBlcnIgPSBtbXNfc2FmZV9zZW5kX3JlY3YobW1zdCwgc2VuZF9tZWRpYV9oZWFkZXJfcmVxdWVzdCwgU0NfUEtUX0hFQURFUl9SRVFVRVNUX0FDQ0VQVEVEKTsKICAgIGlmIChlcnIpCiAgICAgICAgZ290byBmYWlsOwogICAgZXJyID0gbW1zX3NhZmVfc2VuZF9yZWN2KG1tc3QsIE5VTEwsIFNDX1BLVF9BU0ZfSEVBREVSKTsKICAgIGlmIChlcnIpCiAgICAgICAgZ290byBmYWlsOwogICAgaWYoKG1tc3QtPmluY29taW5nX2ZsYWdzICE9IDBYMDgpICYmIChtbXN0LT5pbmNvbWluZ19mbGFncyAhPSAwWDBDKSkgewogICAgICAgIGF2X2xvZyhOVUxMLCBBVl9MT0dfRVJST1IsCiAgICAgICAgICAgICAgICJUaGUgc2VydmVyIGRvZXMgbm90IHN1cHBvcnQgTU1TVCAodHJ5IE1NU0ggb3IgUlRTUClcbiIpOwogICAgICAgIGVyciA9IEFWRVJST1IoRUlOVkFMKTsKICAgICAgICBnb3RvIGZhaWw7CiAgICB9CiAgICBlcnIgPSBmZl9tbXNfYXNmX2hlYWRlcl9wYXJzZXIobW1zKTsKICAgIGlmIChlcnIpIHsKICAgICAgICBhdl9kbG9nKE5VTEwsICJhc2YgaGVhZGVyIHBhcnNlZCBmYWlsZWQhXG4iKTsKICAgICAgICBnb3RvIGZhaWw7CiAgICB9CiAgICBtbXMtPmhlYWRlcl9wYXJzZWQgPSAxOwoKICAgIGlmICghbW1zLT5hc2ZfcGFja2V0X2xlbiB8fCAhbW1zLT5zdHJlYW1fbnVtKQogICAgICAgIGdvdG8gZmFpbDsKCiAgICBjbGVhcl9zdHJlYW1fYnVmZmVycyhtbXMpOwogICAgZXJyID0gbW1zX3NhZmVfc2VuZF9yZWN2KG1tc3QsIHNlbmRfc3RyZWFtX3NlbGVjdGlvbl9yZXF1ZXN0LCBTQ19QS1RfU1RSRUFNX0lEX0FDQ0VQVEVEKTsKICAgIGlmIChlcnIpCiAgICAgICAgZ290byBmYWlsOwogICAgLy8gc2VuZCBtZWRpYSBwYWNrZXQgcmVxdWVzdAogICAgZXJyID0gbW1zX3NhZmVfc2VuZF9yZWN2KG1tc3QsIHNlbmRfbWVkaWFfcGFja2V0X3JlcXVlc3QsIFNDX1BLVF9NRURJQV9QS1RfRk9MTE9XUyk7CiAgICBpZiAoZXJyKSB7CiAgICAgICAgZ290byBmYWlsOwogICAgfQogICAgYXZfZGxvZyhOVUxMLCAiTGVhdmluZyBvcGVuIChzdWNjZXNzKVxuIik7CiAgICByZXR1cm4gMDsKZmFpbDoKICAgIG1tc19jbG9zZShoKTsKICAgIGF2X2Rsb2coTlVMTCwgIkxlYXZpbmcgb3BlbiAoZmFpbHVyZTogJWQpXG4iLCBlcnIpOwogICAgcmV0dXJuIGVycjsKfQoKLyoqIFJlYWQgQVNGIGRhdGEgdGhyb3VnaCB0aGUgcHJvdG9jb2wuICovCnN0YXRpYyBpbnQgbW1zX3JlYWQoVVJMQ29udGV4dCAqaCwgdWludDhfdCAqYnVmLCBpbnQgc2l6ZSkKewogICAgLyogVE9ETzogc2VlIHRjcC5jOnRjcF9yZWFkKCkgYWJvdXQgYSBwb3NzaWJsZSB0aW1lb3V0IHNjaGVtZSAqLwogICAgTU1TVENvbnRleHQgKm1tc3QgPSBoLT5wcml2X2RhdGE7CiAgICBNTVNDb250ZXh0ICptbXMgICA9ICZtbXN0LT5tbXM7CiAgICBpbnQgcmVzdWx0ID0gMDsKCiAgICBkbyB7CiAgICAgICAgaWYobW1zLT5hc2ZfaGVhZGVyX3JlYWRfc2l6ZSA8IG1tcy0+YXNmX2hlYWRlcl9zaXplKSB7CiAgICAgICAgICAgIC8qIFJlYWQgZnJvbSBBU0YgaGVhZGVyIGJ1ZmZlciAqLwogICAgICAgICAgICByZXN1bHQgPSBmZl9tbXNfcmVhZF9oZWFkZXIobW1zLCBidWYsIHNpemUpOwogICAgICAgIH0gZWxzZSBpZihtbXMtPnJlbWFpbmluZ19pbl9sZW4pIHsKICAgICAgICAgICAgLyogUmVhZCByZW1haW5pbmcgcGFja2V0IGRhdGEgdG8gYnVmZmVyLgogICAgICAgICAgICAgKiB0aGUgcmVzdWx0IGNhbiBub3QgYmUgemVybyBiZWNhdXNlIHJlbWFpbmluZ19pbl9sZW4gaXMgcG9zaXRpdmUuKi8KICAgICAgICAgICAgcmVzdWx0ID0gZmZfbW1zX3JlYWRfZGF0YShtbXMsIGJ1Ziwgc2l6ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyogUmVhZCBmcm9tIG5ldHdvcmsgKi8KICAgICAgICAgICAgaW50IGVyciA9IG1tc19zYWZlX3NlbmRfcmVjdihtbXN0LCBOVUxMLCBTQ19QS1RfQVNGX01FRElBKTsKICAgICAgICAgICAgaWYgKGVyciA9PSAwKSB7CiAgICAgICAgICAgICAgICBpZihtbXMtPnJlbWFpbmluZ19pbl9sZW4+bW1zLT5hc2ZfcGFja2V0X2xlbikgewogICAgICAgICAgICAgICAgICAgIGF2X2xvZyhOVUxMLCBBVl9MT0dfRVJST1IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICJJbmNvbWluZyBwa3RsZW4gJWQgaXMgbGFyZ2VyIHRoYW4gQVNGIHBrdHNpemUgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1tcy0+cmVtYWluaW5nX2luX2xlbiwgbW1zLT5hc2ZfcGFja2V0X2xlbik7CiAgICAgICAgICAgICAgICAgICAgcmVzdWx0PSBBVkVSUk9SKEVJTyk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIC8vIGNvcHkgdGhlIGRhdGEgdG8gdGhlIHBhY2tldCBidWZmZXIuCiAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gZmZfbW1zX3JlYWRfZGF0YShtbXMsIGJ1Ziwgc2l6ZSk7CiAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGF2X2Rsb2coTlVMTCwgIlJlYWQgQVNGIG1lZGlhIHBhY2tldCBzaXplIGlzIHplcm8hXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXZfZGxvZyhOVUxMLCAicmVhZCBwYWNrZXQgZXJyb3IhXG4iKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSB3aGlsZSghcmVzdWx0KTsgLy8gb25seSByZXR1cm4gb25lIHBhY2tldC4KICAgIHJldHVybiByZXN1bHQ7Cn0KClVSTFByb3RvY29sIGZmX21tc3RfcHJvdG9jb2wgPSB7CiAgICAubmFtZSAgICAgICAgICAgPSAibW1zdCIsCiAgICAudXJsX29wZW4gICAgICAgPSBtbXNfb3BlbiwKICAgIC51cmxfcmVhZCAgICAgICA9IG1tc19yZWFkLAogICAgLnVybF9jbG9zZSAgICAgID0gbW1zX2Nsb3NlLAogICAgLnByaXZfZGF0YV9zaXplID0gc2l6ZW9mKE1NU1RDb250ZXh0KSwKICAgIC5mbGFncyAgICAgICAgICA9IFVSTF9QUk9UT0NPTF9GTEFHX05FVFdPUkssCn07Cg==