X-Recipient: archive-cygwin AT delorie DOT com X-SWARE-Spam-Status: No, hits=0.0 required=5.0 tests=AWL,BAYES_50,RCVD_IN_DNSWL_NONE,TW_CP X-Spam-Check-By: sourceware.org X-USANET-Received: from gateout02.mbox.net [127.0.0.1] by gateout02.mbox.net via mtad (C8.MAIN.3.65C) with ESMTP id 323oikamr7024Mo2; Sat, 11 Sep 2010 00:12:43 -0000 X-USANET-Source: 165.212.120.254 IN aeolus AT electric-cloud DOT com s1hub3.EXCHPROD.USA.NET X-USANET-MsgId: XID192oikamr5574Xo2 From: John Carey To: "cygwin AT cygwin DOT com" Date: Sat, 11 Sep 2010 00:12:42 +0000 Subject: RE: 1.7.5: Occasional failure of CreatePipe or signal handing due to thread-unsafe code in cwdstuff::set Message-ID: <3C031C390CBF1E4A8CE1F74DE7ECAF3A158EDA704C@MBX8.EXCHPROD.USA.NET> References: <3C031C390CBF1E4A8CE1F74DE7ECAF3A140684F0AA AT MBX8 DOT EXCHPROD DOT USA DOT NET> <20100811084926 DOT GC26152 AT calimero DOT vinschen DOT de> <3C031C390CBF1E4A8CE1F74DE7ECAF3A140684F0B0 AT MBX8 DOT EXCHPROD DOT USA DOT NET> <20100812081151 DOT GT14202 AT calimero DOT vinschen DOT de> <3C031C390CBF1E4A8CE1F74DE7ECAF3A158EDA702A AT MBX8 DOT EXCHPROD DOT USA DOT NET> <20100903073740 DOT GA1749 AT calimero DOT vinschen DOT de> <3C031C390CBF1E4A8CE1F74DE7ECAF3A158EDA702D AT MBX8 DOT EXCHPROD DOT USA DOT NET>,<20100904092626 DOT GE16534 AT calimero DOT vinschen DOT de> In-Reply-To: <20100904092626.GE16534@calimero.vinschen.de> Content-Type: multipart/mixed; boundary="_002_3C031C390CBF1E4A8CE1F74DE7ECAF3A158EDA704CMBX8EXCHPRODU_" MIME-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com --_002_3C031C390CBF1E4A8CE1F74DE7ECAF3A158EDA704CMBX8EXCHPRODU_ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable On Sep 04 02:26 Corinna Vinschen wrote: > On Sep 3 16:18, John Carey wrote: > > On Sep 03 12:37 Corinna Vinschen wrote: > > > On Sep 2 23:32, John Carey wrote: > > > > In Aug 17 10:15, Corinna Vinschen wrote: > > > > > I just released 1.7.6-1. > > > > ... > > > > > What changed since Cygwin 1.7.5: > > > > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D > > > > > > > > > > - Cygwin handles the current working directory entirely on its ow= n. The > > > > > Win32 current working directory is set to an invalid path to be= out of > > > > > the way. This affects calls to the Win32 file API (CreateFile,= etc.). > > > > > See http://cygwin.com/htdocs/cygwin-ug-net/using.html#pathnames= -win32-api > > > > > > > > Thank you very much for the fix! > > > > > > > > I've been running tests against Cygwin 1.7.6, and then 1.7.7, > > > > and those sporadic, non-deterministic failures in CreatePipe > > > > did stop after the 1.7.6 upgrade, and are still gone in 1.7.7. > > > > I think it's been long enough to conclude that it is not just > > > > the non-determinism--it really is fixed, as expected. > > > > > > > > I understand that this issue opened a can of worms; > > > > thanks again for your efforts to overcome those difficulties. > > > > > > I still don't like the final workaround, which is, to set the Win32 C= WD > > > to the Cygwin CWD. It would be nice if we could revert that change to > > > the pre-1.7.6 behaviour in a Vista-friendly way. If you ever find out > > > how to make sure that the new handle in the PEB's user parameter block > > > is used even on Vista and later, pray tell me. > > > > Thus far the only ideas I have come up with are somewhat > > shaky and go well beyond the documented Win32 API. > > (If only there was the equivalent of dup2(), but for Win32 > > handles!!!) > > ACK. > > > Just how much undocumented behavior is > > tolerable, do you think? > > Up to XP/2K3, we can simply set the handle in the user parameter block > and be done with it, just as in 1.7.5, but without the Vista workaround. > > The problem only starts with Vista. I have no objections to use > undocumented features, if they work. If there's any way to replace the > cwd handle with our own *and* keep the Win32 API happy, I'll take it. I think I've found a way to open the directory handle for backup intent on Vista and later versions. Essentially, I emulate the new things that SetCurrentDirectory() is doing, but in order to get the necessary addresses, I have to do some very ugly hacks. The proof-of-concept code follows (and is also attached). It includes an analysis of what is going on--to the extent that I know what is going on, of course. Please let me know what you think. - - - - - - BEGIN INCLUSION - - - - - - - // Compile with Cygwin G++, and include a '-I' argument that // specifies the "winsup" directory of the Cygwin source tree. // // Run with two arguments: // // 1. An absolute Windows path to a directory (can use forward slashes). // // 2. The relative name of a file within that directory. // // The purpose of this source code is to discuss Win32 CWD // issues and to compile into a proof-of-concept program. // Please read the interleaved comments. #include #include #include #include #include #include #include #include #include #include using namespace std; /**************************************** Primary research was on Windows 7 x64, but there appears to be at least superficial similarity on Windows 2008 (x32 and x64) and Windows Vista (x32 and x64). Let "Params" be an alias for *NtCurrentTeb ()->Peb->ProcessParameters. Let "HeapHandle" be an alias for *(PVOID*)((char*)NtCurrentTeb ()->Peb + 0x= 18) (which is the second 32-bit word after ProcessParameters.) Let "DismountCount" be an alias for the user space mapping of KUSER_SHARED_DATA::DismountCount: namely, *(ULONG*)0x7ffe02dc. See: http://www.nirsoft.net/kernel_struct/vista/KUSER_SHARED_DATA.html In the implementation of SetCurrentDirectory (), Params.CurrentDirectoryName.MaximumLength is read but NOT modified. Its value determines the sizes of various buffers, including the new buffer that will hold the new current directory pathname. The constant value we have observed for Params.CurrentDirectoryName.MaximumLength is 520, which is sizeof(wchar_t [MAX_PATH]). In addition to the PEB, there is an allocated memory block describing the current directory. Its lifetime is controlled by thread-safe reference counting. Call its type "VistaCwd"; more details follow. The PEB does NOT seem to point to any VistaCwd instances. Instead, there is a global pointer outside of the PEB, which we call "Cwd", and it is protected by a critical section, which we call "CwdCS", which is also outside of the PEB. Apparently these globals are in the ntdll.dll data space, but their symbols are not exported. Later we will discuss how to compute their addresses. NOTE: The SetCurrentDirectory () implementation appears to update the Win32 CWD *without* locking the PEB as such. It locks CwdCS instead. Structure: ****************************************/ struct VistaCwd { // Use bus-locked increment/decrement to adjust this reference count. // When the reference count drops to zero, destroy and deallocate. volatile LONG ReferenceCount; // The open handle to the current directory. HANDLE DirectoryHandle; // A snapshot of the global DismountCount, updated at various // times during the lifetime of this struct. It appears that // reads of and writes to this member are locked by CwdCS, // except for initialization (see below). // // What is this member for? Following things in a debugger, // it seems likely that whenever the current VistaCwd is used, // its current value of OldDismountCount is compared against the // current (or perhaps slightly stale?) value of DismountCount, // and if it does not match then some extra action is taken. // Such extra action seems to include checking if the volume // is mounted. // // Presumably the global DismountCount increases monotonically. // Reads of the global DismountCount appear to be unlocked. // If a stale value is stored in OldDismountCount, then it // may be harmless in the sense that it just fails to prevent // unnecessary computation later. But a stale read during // a comparison with OldDismountCount could prevent the extra // actions, which could be more serious. At a guess, that // problem is prevented by the following code structure, // observed in at least one place that uses the CWD setting: // the value of OldDismountCount is read under a CwdCS lock, // and only *after* that lock is released is the global // DismountCount read. The lock-unlock probably flushes // writes to the global DismountCount. ULONG OldDismountCount; // The path of the current directory. Always ends in a backslash; // one is appended if the given path did not already end in one. // // The "MaximumLength" and "Buffer" members always specify the size // and starting address of the "Buffer" sibling member (see below). UNICODE_STRING Path; // The actual size of this member, and therefore of the struct as // a whole, is computed dynamically so that this member has the // same size as the previous value of // // Params.CurrentDirectoryName.MaximumLength // // But since SetCurrentDirectory () never seems to modify that // PEB datum, in practice the dimension is always MAX_PATH. wchar_t Buffer[MAX_PATH]; }; /**************************************** Allocation: Before modifying the PEB data, the implementation of SetCurrentDirectory () allocates a new instance of VistaCwd, as follows: RtlAllocateHeap (HeapHandle, 0, offsetof (VistaCwd, Buffer) + Params.CurrentDirectoryName.MaximumLeng= th); Initialization: The SetCurrentDirectory () implementation then initializes that instance as follows: // Read DismountCount before calling NtOpenFile(). // If the relative order matters at all, then it is // probably following the general principle that // a stale value copied from DismountCount to the // OldDismountCount member (see below) just causes // extra work but is otherwise harmless, whereas // a too-recent value might prevent necessary work. ULONG DismountCountBeforeNtOpenFile =3D DismountCount; ReferenceCount =3D 1; DirectoryHandle =3D NtOpenFile (...); // NOTE: There is no locking around this initialization. // But the SetCurrentDirectory () implementation locks CwdCS // while updating Cwd to point to new instances of VistaCwd, // and presumably that suffices to flush this initialization // to other CPUs. Other threads would not see the new VistaCwd // instance before that point. As mentioned before, copying of // a stale value of the global DismountCount is probably harmless, // in that it would merely trigger an unnecessary update. OldDismountCount =3D DismountCountBeforeNtOpenFile; // The length of the path in bytes, not counting the terminator. Path.Length =3D ...; // As mentioned before, in practice this is sizeof(wchar_t [MAX_PATH]). Path.MaximumLength =3D Params.CurrentDirectoryName.MaximumLength; Path.Buffer =3D Buffer; // The wide path for the directory; if necessary a backslash is // appended so that the final character (before the terminator) // is always a backslash. memcpy (Buffer, ...); Buffer[Path.Length / sizeof(wchar_t)] =3D L'\0'; Usage: After creating the new VistaCwd instance; call it newCwd, the SetCurrentDirectory () implementation modifies the PEB and Cwd under a lock on CwdCS, as follows: Params.CurrentDirectoryHandle =3D newCwd.DirectoryHandle; Params.CurrentDirectoryName.Buffer =3D newCwd.Path.Buffer; Params.CurrentDirectoryName.Length =3D newCwd.Path.Length; VistaCwd *oldCwd =3D Cwd; Cwd =3D newCwd; Note that as mentioned before, Params.CurrentDirectoryName.MaximumLength is NOT modified. Cleanup: After the SetCurrentDirectory () implementation releases its lock on CwdCS, it performs a bus-locked decrement on oldCwd->ReferenceCount (unless oldCwd =3D=3D NULL). If the result is zero, it then destroys and deallocates the old VistaCwd instance as follows: NtClose (oldCwd->DirectoryHandle); RtlFreeHeap (HeapHandle, 0, oldCwd); Addresses of Cwd and CwdCS: In order to imitate the way in which SetCurrentDirectory () updates the Win32 CWD data, we must learn the addresses of Cwd and CwdCS. The following program performs code analysis to discover those. It then changes the Win32 CWD directly and tests the result with a relative CreateFile (). It is intended as a quick-and-dirty stand-alone proof-of-concept program; final code to be included in cygwin1.dll would differ greatly. ****************************************/ typedef unsigned char code_t; unsigned peek32 (const unsigned char *p) { return p[0] + (p[1] << 8) + (p[2] << 16) + (p[3] << 24); } void badCode () { cerr << "Code looks different than expected; bailing out." << endl; exit (1); } ostream& winError (ostream& os, DWORD code =3D GetLastError()) { LPSTR msg =3D 0; if (FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&msg, 1, NULL)) { os << "error " << code << ": " << msg; LocalFree (msg); } else { os << "???"; } return os; } #define DDKAPI __stdcall typedef CONST char *PCSZ; typedef NTSTATUS DDKAPI (* NtClose_t)( /*IN*/ HANDLE Handle); typedef NTSTATUS DDKAPI (* NtOpenFile_t) ( /*OUT*/ PHANDLE FileHandle, /*IN*/ ACCESS_MASK DesiredAccess, /*IN*/ POBJECT_ATTRIBUTES ObjectAttributes, /*OUT*/ PIO_STATUS_BLOCK IoStatusBlock, /*IN*/ ULONG ShareAccess, /*IN*/ ULONG OpenOptions); typedef PVOID NTAPI (* RtlAllocateHeap_t) ( /*IN*/ HANDLE HeapHandle, /*IN*/ ULONG Flags, /*IN*/ ULONG Size ); typedef BOOLEAN NTAPI (* RtlFreeHeap_t) ( /*IN*/ HANDLE HeapHandle, /*IN*/ ULONG Flags, /*IN*/ PVOID P ); typedef VOID DDKAPI (* RtlInitString_t) ( /*IN OUT*/ PSTRING DestinationString, /*IN*/ PCSZ SourceString); typedef NTSTATUS DDKAPI (* RtlAnsiStringToUnicodeString_t) ( /*IN OUT*/ PUNICODE_STRING DestinationString, /*IN*/ PANSI_STRING SourceString, /*IN*/ BOOLEAN AllocateDestinationString); typedef VOID DDKAPI (* RtlFreeUnicodeString_t) ( /*IN*/ PUNICODE_STRING UnicodeString); typedef NTSTATUS DDKAPI (* RtlUnicodeStringToAnsiString_t)( /*IN OUT*/ PANSI_STRING DestinationString, /*IN*/ PUNICODE_STRING SourceString, /*IN*/ BOOLEAN AllocateDestinationString); typedef VOID DDKAPI (* RtlFreeAnsiString_t)( /*IN*/ PANSI_STRING AnsiString); #define NTFUNC_DECL(F) F ## _t _ ## F struct NtFuncs { NTFUNC_DECL(NtClose); NTFUNC_DECL(NtOpenFile); NTFUNC_DECL(RtlAllocateHeap); NTFUNC_DECL(RtlFreeHeap); NTFUNC_DECL(RtlInitString); NTFUNC_DECL(RtlAnsiStringToUnicodeString); NTFUNC_DECL(RtlFreeUnicodeString); NTFUNC_DECL(RtlUnicodeStringToAnsiString); NTFUNC_DECL(RtlFreeAnsiString); NtFuncs(HMODULE module); }; #define NTFUNC_BIND(M, F) _ ## F =3D (F ## _t) GetProcAddress(M, # F) NtFuncs::NtFuncs(HMODULE module) { NTFUNC_BIND(module, NtClose); NTFUNC_BIND(module, NtOpenFile); NTFUNC_BIND(module, RtlAllocateHeap); NTFUNC_BIND(module, RtlFreeHeap); NTFUNC_BIND(module, RtlInitString); NTFUNC_BIND(module, RtlAnsiStringToUnicodeString); NTFUNC_BIND(module, RtlFreeUnicodeString); NTFUNC_BIND(module, RtlUnicodeStringToAnsiString); NTFUNC_BIND(module, RtlFreeAnsiString); } void modifiedSetCurrentDirectory ( const NtFuncs& nt, CRITICAL_SECTION *CwdCS, VistaCwd **Cwd, UNICODE_STRING& upath) { // The real SetCurrentDirectory () implementation calls // a non-exported function that appears to expand relative // paths to absolute paths and convert / to \. It might // also do other things. // // There appear to be no locks on the PEB or Cwd that // persist between this conversion and the actual Win32 // CWD change, so presumably the following race is possible: // // 1. Thread A calls SetCurrentDirectory("C:\\a\\b"). // // 2. Thread A creates Thread B. // // 3. Thread A starts calling SetCurrentDirectory("..") // and gets through relative-to-absolute conversion, // yielding "C:\\a" as the desired CWD. // // 4. Thread B calls SetCurrentDirectory("C:\\d\\e"). // // 5. Thread A acquires CwdCS and sets Cwd to a new // VistaCwd instance that specifies "C:\\a". // // Holding a lock between (3) and (5) would force // (4) to come either before (3) or after (5), but // there would still be a race: if (4) comes first, // then the final CWD is "C:\\d", whereas if (4) // comes last, then the final CWD is "C:\\d\\e". // Probably that is why no lock is held: it would // increase contention but not eliminate races. // // On the other hand, it appears that at least some // other versions of Windows that do not use the // VistaCwd mechanism, such as Windows Server 2003 R2 x64, // might actually acquire a lock before relative-to-absolute // path conversion. Perhaps Microsoft rethought the races // when they changed to the newer mechanism? // // Anyway, the output of relative-to-absolute conversion // is run through another, non-exported path conversion // function that prefixes \??\ and presumably does // other normalizations appropriate to such paths. // However, that special form is used only as an argument // to NtOpenFile()--it does NOT get put into the new // VistaCwd instance. Instead, the VistaCwd instance // gets a separate copy of the output of the // relative-to-absolute conversion, and in this copy only, // a backslash is appended if the absolute path did not // already end in a backslash. // // In this implementation we do not bother to perform // the relative-to-absolute path conversion; instead // we just warn if the path is not absolute. // But we do convert / to \. replace (upath.Buffer, upath.Buffer + upath.Length / sizeof(wchar_t), L'/', L'\\'); if (upath.Length < 3 || upath.Buffer[1] !=3D L':' || upath.Buffer[2] !=3D= L'\\'){ cerr << "Relative paths not implemented." << endl; exit (1); } // Prefix \??\ to the path before passing it to NtOpenFile(). if (upath.Length > (MAX_PATH - 5) * sizeof(wchar_t)) { cerr << "Path too long." << endl; exit(1); } wchar_t ntupath_buf[MAX_PATH]; UNICODE_STRING ntupath; ntupath.Length =3D upath.Length + 4 * sizeof(wchar_t); ntupath.MaximumLength =3D sizeof ntupath_buf; ntupath.Buffer =3D ntupath_buf; memcpy(ntupath_buf, L"\\??\\", 4 * sizeof(wchar_t)); memcpy(ntupath_buf + 4, upath.Buffer, upath.Length); ntupath_buf[4 + (upath.Length / sizeof(wchar_t))] =3D L'\0'; RTL_USER_PROCESS_PARAMETERS& Params =3D *NtCurrentTeb ()->Peb->ProcessParameters; PVOID HeapHandle =3D *(PVOID*)((char*)NtCurrentTeb ()->Peb + 0x18); volatile ULONG& DismountCount =3D *(volatile ULONG*)0x7ffe02dc; // Do this before the NtOpenFile, just in case that order matters. ULONG DismountCountBeforeNtOpenFile =3D DismountCount; HANDLE h; NTSTATUS status; IO_STATUS_BLOCK io; OBJECT_ATTRIBUTES attr; InitializeObjectAttributes (&attr, &ntupath, OBJ_CASE_INSENSITIVE | OBJ_INHERIT, NULL, NULL); status =3D nt._NtOpenFile (&h, SYNCHRONIZE | FILE_TRAVERSE, &attr, &io, FILE_SHARE_VALID_FLAGS, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT); if (!NT_SUCCESS (status)) { ANSI_STRING narrow; nt._RtlUnicodeStringToAnsiString(&narrow, &ntupath, TRUE); cerr << "Failed to open directory '"; cerr.write(narrow.Buffer, narrow.Length); cerr << "': NTSTATUS " << showbase << hex << status << endl; nt._RtlFreeAnsiString(&narrow); exit(1); } // As mentioned before, in practice this is sizeof (wchar_t [MAX_PATH]). USHORT MaximumLength =3D Params.CurrentDirectoryName.MaximumLength; VistaCwd *newCwd =3D (VistaCwd *) nt._RtlAllocateHeap (HeapHandle, 0, offsetof (VistaCwd, Buffer) + MaximumLength); newCwd->ReferenceCount =3D 1; newCwd->DirectoryHandle =3D h; newCwd->OldDismountCount =3D DismountCountBeforeNtOpenFile; newCwd->Path.Length =3D upath.Length; newCwd->Path.MaximumLength =3D MaximumLength; newCwd->Path.Buffer =3D newCwd->Buffer; memcpy (newCwd->Buffer, upath.Buffer, upath.Length); newCwd->Buffer[upath.Length / sizeof(wchar_t)] =3D L'\0'; // In new VistaCwd instance, ensure that the final path character is L'\\= ': if (newCwd->Buffer[(upath.Length / sizeof(wchar_t)) - 1] !=3D L'\\') { if (upath.Length > newCwd->Path.MaximumLength - (2 * sizeof(wchar_t))) { cerr << "Path too long." << endl; exit(1); } newCwd->Buffer[upath.Length / sizeof(wchar_t)] =3D L'\\'; newCwd->Buffer[(upath.Length / sizeof(wchar_t)) + 1] =3D L'\0'; upath.Length +=3D sizeof(wchar_t); } // NOTE: We never acquire the PEB lock, only the Vista++ CWD lock: EnterCriticalSection(CwdCS); Params.CurrentDirectoryHandle =3D newCwd->DirectoryHandle; Params.CurrentDirectoryName.Buffer =3D newCwd->Path.Buffer; Params.CurrentDirectoryName.Length =3D newCwd->Path.Length; VistaCwd *oldCwd =3D *Cwd; *Cwd =3D newCwd; LeaveCriticalSection(CwdCS); if (InterlockedDecrement(&oldCwd->ReferenceCount) =3D=3D 0) { nt._NtClose (oldCwd->DirectoryHandle); nt._RtlFreeHeap (HeapHandle, 0, oldCwd); } } int main (int argc, char **argv) { HMODULE module =3D GetModuleHandle ("ntdll.dll"); // Reading the CWD is simpler than writing the CWD, // which makes it easier to find the addresses we need, // and might also tend to make code changes less frequent. const code_t *get_dir =3D (const code_t*) GetProcAddress (module, "RtlGetCurrentDirectory_U"); const code_t *ent_crit =3D (const code_t*) GetProcAddress (module, "RtlEnterCriticalSection"); // Find first relative call instruction. const code_t *rcall =3D (const code_t *) memchr (get_dir, 0xE8, 32); if (! rcall) { badCode (); } // Compute the address, use_cwd, of the function being called. // This function actually fetches the current VistaCwd instance // and performs actions conditioned upon the freshness of its // OldDismountCount member. ptrdiff_t offset =3D peek32 (rcall + 1); const code_t *use_cwd =3D rcall + 5 + offset; // Find the first "push edi" instruction... const code_t *movedi =3D (const code_t *) memchr (use_cwd, 0x57, 32); ++movedi; // ...which should be followed by "mov edi, crit-sect-addr" then "push ed= i". // (Ideally we should not depend upon %EDI being the register, // but this is a proof of concept, and even with more flexibility // we are still depending heavily upon code structure here.) if (movedi[0] !=3D 0xBF || movedi[5] !=3D 0x57) { badCode (); } // Get the address of the critical section for the CWD. CRITICAL_SECTION *CwdCS =3D (CRITICAL_SECTION *) peek32 (movedi + 1); // To check we are seeing the right code, we check our expectation that // the next instruction is a relative call into RtlEnterCriticalSection. rcall =3D movedi + 6; if (rcall[0] !=3D 0xe8) { badCode (); } offset =3D peek32 (rcall + 1); if (rcall + 5 + offset !=3D ent_crit) { badCode (); } // After locking the critical section, the code should read the // global CWD block pointer that is guarded by that critical section. const code_t *movesi =3D rcall + 5; if (movesi[0] !=3D 0x8b) { badCode (); } VistaCwd **Cwd =3D (VistaCwd **) peek32 (movesi + 2); cout << showbase << hex << (size_t)CwdCS << " <=3D=3D critical section" << endl; cout << showbase << hex << (size_t)Cwd << " <=3D=3D Vista++ CWD struct pointer" << endl; if (argc >=3D 2) { NtFuncs nt(module); STRING npath; nt._RtlInitString (&npath, argv[1]); UNICODE_STRING upath; nt._RtlAnsiStringToUnicodeString (&upath, &npath, TRUE); modifiedSetCurrentDirectory (nt, CwdCS, Cwd, upath); nt._RtlFreeUnicodeString (&upath); cout << "Changed directory." << endl; } if (argc >=3D 3) { HANDLE h =3D CreateFile (argv[2], GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (h =3D=3D INVALID_HANDLE_VALUE) { winError(cerr << "Failed to open file: ") << endl; return 1; } cout << "Successfully opened file." << endl; if (! CloseHandle (h)) { winError(cerr << "Failed to close file: ") << endl; return 1; } } return 0; } --_002_3C031C390CBF1E4A8CE1F74DE7ECAF3A158EDA704CMBX8EXCHPRODU_ Content-Type: text/x-c++src; name="vistachdir.cc" Content-Description: vistachdir.cc Content-Disposition: attachment; filename="vistachdir.cc"; size=20349; creation-date="Sat, 11 Sep 2010 00:12:29 GMT"; modification-date="Sat, 11 Sep 2010 00:12:29 GMT" Content-Transfer-Encoding: base64 Ly8gQ29tcGlsZSB3aXRoIEN5Z3dpbiBHKyssIGFuZCBpbmNsdWRlIGEgJy1J JyBhcmd1bWVudCB0aGF0Ci8vIHNwZWNpZmllcyB0aGUgIndpbnN1cCIgZGly ZWN0b3J5IG9mIHRoZSBDeWd3aW4gc291cmNlIHRyZWUuCi8vCi8vIFJ1biB3 aXRoIHR3byBhcmd1bWVudHM6Ci8vCi8vICAgMS4gQW4gYWJzb2x1dGUgV2lu ZG93cyBwYXRoIHRvIGEgZGlyZWN0b3J5IChjYW4gdXNlIGZvcndhcmQgc2xh c2hlcykuCi8vCi8vICAgMi4gVGhlIHJlbGF0aXZlIG5hbWUgb2YgYSBmaWxl IHdpdGhpbiB0aGF0IGRpcmVjdG9yeS4KLy8KLy8gVGhlIHB1cnBvc2Ugb2Yg dGhpcyBzb3VyY2UgY29kZSBpcyB0byBkaXNjdXNzIFdpbjMyIENXRAovLyBp c3N1ZXMgYW5kIHRvIGNvbXBpbGUgaW50byBhIHByb29mLW9mLWNvbmNlcHQg cHJvZ3JhbS4KLy8gUGxlYXNlIHJlYWQgdGhlIGludGVybGVhdmVkIGNvbW1l bnRzLgoKI2luY2x1ZGUgPHczMmFwaS9pbmNsdWRlL3dpbmRvd3MuaD4KI2lu Y2x1ZGUgPHczMmFwaS9pbmNsdWRlL250ZGVmLmg+CiNpbmNsdWRlIDx3MzJh cGkvaW5jbHVkZS93aW5udC5oPgojaW5jbHVkZSA8Y3lnd2luL250ZGxsLmg+ CiNpbmNsdWRlIDxhbGdvcml0aG0+CiNpbmNsdWRlIDxjc3RkbGliPgojaW5j bHVkZSA8Y3N0cmluZz4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8 bG9jYWxlPgojaW5jbHVkZSA8c3RyaW5nPgoKdXNpbmcgbmFtZXNwYWNlIHN0 ZDsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq CgpQcmltYXJ5IHJlc2VhcmNoIHdhcyBvbiBXaW5kb3dzIDcgeDY0LCBidXQg dGhlcmUgYXBwZWFycyB0byBiZQphdCBsZWFzdCBzdXBlcmZpY2lhbCBzaW1p bGFyaXR5IG9uIFdpbmRvd3MgMjAwOCAoeDMyIGFuZCB4NjQpCmFuZCBXaW5k b3dzIFZpc3RhICh4MzIgYW5kIHg2NCkuCgpMZXQgIlBhcmFtcyIgYmUgYW4g YWxpYXMgZm9yICpOdEN1cnJlbnRUZWIgKCktPlBlYi0+UHJvY2Vzc1BhcmFt ZXRlcnMuCgpMZXQgIkhlYXBIYW5kbGUiIGJlIGFuIGFsaWFzIGZvciAqKFBW T0lEKikoKGNoYXIqKU50Q3VycmVudFRlYiAoKS0+UGViICsgMHgxOCkKKHdo aWNoIGlzIHRoZSBzZWNvbmQgMzItYml0IHdvcmQgYWZ0ZXIgUHJvY2Vzc1Bh cmFtZXRlcnMuKQoKTGV0ICJEaXNtb3VudENvdW50IiBiZSBhbiBhbGlhcyBm b3IgdGhlIHVzZXIgc3BhY2UgbWFwcGluZyBvZgpLVVNFUl9TSEFSRURfREFU QTo6RGlzbW91bnRDb3VudDogbmFtZWx5LCAqKFVMT05HKikweDdmZmUwMmRj LgpTZWU6IGh0dHA6Ly93d3cubmlyc29mdC5uZXQva2VybmVsX3N0cnVjdC92 aXN0YS9LVVNFUl9TSEFSRURfREFUQS5odG1sCgpJbiB0aGUgaW1wbGVtZW50 YXRpb24gb2YgU2V0Q3VycmVudERpcmVjdG9yeSAoKSwKUGFyYW1zLkN1cnJl bnREaXJlY3RvcnlOYW1lLk1heGltdW1MZW5ndGggaXMgcmVhZCBidXQgTk9U IG1vZGlmaWVkLgpJdHMgdmFsdWUgZGV0ZXJtaW5lcyB0aGUgc2l6ZXMgb2Yg dmFyaW91cyBidWZmZXJzLCBpbmNsdWRpbmcgdGhlCm5ldyBidWZmZXIgdGhh dCB3aWxsIGhvbGQgdGhlIG5ldyBjdXJyZW50IGRpcmVjdG9yeSBwYXRobmFt ZS4KClRoZSBjb25zdGFudCB2YWx1ZSB3ZSBoYXZlIG9ic2VydmVkIGZvcgpQ YXJhbXMuQ3VycmVudERpcmVjdG9yeU5hbWUuTWF4aW11bUxlbmd0aAppcyA1 MjAsIHdoaWNoIGlzIHNpemVvZih3Y2hhcl90IFtNQVhfUEFUSF0pLgoKSW4g YWRkaXRpb24gdG8gdGhlIFBFQiwgdGhlcmUgaXMgYW4gYWxsb2NhdGVkIG1l bW9yeSBibG9jayBkZXNjcmliaW5nCnRoZSBjdXJyZW50IGRpcmVjdG9yeS4g IEl0cyBsaWZldGltZSBpcyBjb250cm9sbGVkIGJ5IHRocmVhZC1zYWZlCnJl ZmVyZW5jZSBjb3VudGluZy4gIENhbGwgaXRzIHR5cGUgIlZpc3RhQ3dkIjsg bW9yZSBkZXRhaWxzIGZvbGxvdy4KClRoZSBQRUIgZG9lcyBOT1Qgc2VlbSB0 byBwb2ludCB0byBhbnkgVmlzdGFDd2QgaW5zdGFuY2VzLiAgSW5zdGVhZCwK dGhlcmUgaXMgYSBnbG9iYWwgcG9pbnRlciBvdXRzaWRlIG9mIHRoZSBQRUIs IHdoaWNoIHdlIGNhbGwgIkN3ZCIsCmFuZCBpdCBpcyBwcm90ZWN0ZWQgYnkg YSBjcml0aWNhbCBzZWN0aW9uLCB3aGljaCB3ZSBjYWxsICJDd2RDUyIsCndo aWNoIGlzIGFsc28gb3V0c2lkZSBvZiB0aGUgUEVCLiAgQXBwYXJlbnRseSB0 aGVzZSBnbG9iYWxzIGFyZQppbiB0aGUgbnRkbGwuZGxsIGRhdGEgc3BhY2Us IGJ1dCB0aGVpciBzeW1ib2xzIGFyZSBub3QgZXhwb3J0ZWQuCkxhdGVyIHdl IHdpbGwgZGlzY3VzcyBob3cgdG8gY29tcHV0ZSB0aGVpciBhZGRyZXNzZXMu CgpOT1RFOiBUaGUgU2V0Q3VycmVudERpcmVjdG9yeSAoKSBpbXBsZW1lbnRh dGlvbiBhcHBlYXJzIHRvIHVwZGF0ZSB0aGUKV2luMzIgQ1dEICp3aXRob3V0 KiBsb2NraW5nIHRoZSBQRUIgYXMgc3VjaC4gIEl0IGxvY2tzIEN3ZENTIGlu c3RlYWQuCgpTdHJ1Y3R1cmU6CgoqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqLwoKICBzdHJ1Y3QgVmlzdGFDd2QgewogICAgLy8g VXNlIGJ1cy1sb2NrZWQgaW5jcmVtZW50L2RlY3JlbWVudCB0byBhZGp1c3Qg dGhpcyByZWZlcmVuY2UgY291bnQuCiAgICAvLyBXaGVuIHRoZSByZWZlcmVu Y2UgY291bnQgZHJvcHMgdG8gemVybywgZGVzdHJveSBhbmQgZGVhbGxvY2F0 ZS4KCiAgICB2b2xhdGlsZSBMT05HIFJlZmVyZW5jZUNvdW50OwoKICAgIC8v IFRoZSBvcGVuIGhhbmRsZSB0byB0aGUgY3VycmVudCBkaXJlY3RvcnkuCgog ICAgSEFORExFIERpcmVjdG9yeUhhbmRsZTsKCiAgICAvLyBBIHNuYXBzaG90 IG9mIHRoZSBnbG9iYWwgRGlzbW91bnRDb3VudCwgdXBkYXRlZCBhdCB2YXJp b3VzCiAgICAvLyB0aW1lcyBkdXJpbmcgdGhlIGxpZmV0aW1lIG9mIHRoaXMg c3RydWN0LiAgSXQgYXBwZWFycyB0aGF0CiAgICAvLyByZWFkcyBvZiBhbmQg d3JpdGVzIHRvIHRoaXMgbWVtYmVyIGFyZSBsb2NrZWQgYnkgQ3dkQ1MsCiAg ICAvLyBleGNlcHQgZm9yIGluaXRpYWxpemF0aW9uIChzZWUgYmVsb3cpLgog ICAgLy8KICAgIC8vIFdoYXQgaXMgdGhpcyBtZW1iZXIgZm9yPyAgRm9sbG93 aW5nIHRoaW5ncyBpbiBhIGRlYnVnZ2VyLAogICAgLy8gaXQgc2VlbXMgbGlr ZWx5IHRoYXQgd2hlbmV2ZXIgdGhlIGN1cnJlbnQgVmlzdGFDd2QgaXMgdXNl ZCwKICAgIC8vIGl0cyBjdXJyZW50IHZhbHVlIG9mIE9sZERpc21vdW50Q291 bnQgaXMgY29tcGFyZWQgYWdhaW5zdCB0aGUKICAgIC8vIGN1cnJlbnQgKG9y IHBlcmhhcHMgc2xpZ2h0bHkgc3RhbGU/KSB2YWx1ZSBvZiBEaXNtb3VudENv dW50LAogICAgLy8gYW5kIGlmIGl0IGRvZXMgbm90IG1hdGNoIHRoZW4gc29t ZSBleHRyYSBhY3Rpb24gaXMgdGFrZW4uCiAgICAvLyBTdWNoIGV4dHJhIGFj dGlvbiBzZWVtcyB0byBpbmNsdWRlIGNoZWNraW5nIGlmIHRoZSB2b2x1bWUK ICAgIC8vIGlzIG1vdW50ZWQuCiAgICAvLwogICAgLy8gUHJlc3VtYWJseSB0 aGUgZ2xvYmFsIERpc21vdW50Q291bnQgaW5jcmVhc2VzIG1vbm90b25pY2Fs bHkuCiAgICAvLyBSZWFkcyBvZiB0aGUgZ2xvYmFsIERpc21vdW50Q291bnQg YXBwZWFyIHRvIGJlIHVubG9ja2VkLgogICAgLy8gSWYgYSBzdGFsZSB2YWx1 ZSBpcyBzdG9yZWQgaW4gT2xkRGlzbW91bnRDb3VudCwgdGhlbiBpdAogICAg Ly8gbWF5IGJlIGhhcm1sZXNzIGluIHRoZSBzZW5zZSB0aGF0IGl0IGp1c3Qg ZmFpbHMgdG8gcHJldmVudAogICAgLy8gdW5uZWNlc3NhcnkgY29tcHV0YXRp b24gbGF0ZXIuICBCdXQgYSBzdGFsZSByZWFkIGR1cmluZwogICAgLy8gYSBj b21wYXJpc29uIHdpdGggT2xkRGlzbW91bnRDb3VudCBjb3VsZCBwcmV2ZW50 IHRoZSBleHRyYQogICAgLy8gYWN0aW9ucywgd2hpY2ggY291bGQgYmUgbW9y ZSBzZXJpb3VzLiAgQXQgYSBndWVzcywgdGhhdAogICAgLy8gcHJvYmxlbSBp cyBwcmV2ZW50ZWQgYnkgdGhlIGZvbGxvd2luZyBjb2RlIHN0cnVjdHVyZSwK ICAgIC8vIG9ic2VydmVkIGluIGF0IGxlYXN0IG9uZSBwbGFjZSB0aGF0IHVz ZXMgdGhlIENXRCBzZXR0aW5nOgogICAgLy8gdGhlIHZhbHVlIG9mIE9sZERp c21vdW50Q291bnQgaXMgcmVhZCB1bmRlciBhIEN3ZENTIGxvY2ssCiAgICAv LyBhbmQgb25seSAqYWZ0ZXIqIHRoYXQgbG9jayBpcyByZWxlYXNlZCBpcyB0 aGUgZ2xvYmFsCiAgICAvLyBEaXNtb3VudENvdW50IHJlYWQuICBUaGUgbG9j ay11bmxvY2sgcHJvYmFibHkgZmx1c2hlcwogICAgLy8gd3JpdGVzIHRvIHRo ZSBnbG9iYWwgRGlzbW91bnRDb3VudC4KCiAgICBVTE9ORyBPbGREaXNtb3Vu dENvdW50OwoKICAgIC8vIFRoZSBwYXRoIG9mIHRoZSBjdXJyZW50IGRpcmVj dG9yeS4gIEFsd2F5cyBlbmRzIGluIGEgYmFja3NsYXNoOwogICAgLy8gb25l IGlzIGFwcGVuZGVkIGlmIHRoZSBnaXZlbiBwYXRoIGRpZCBub3QgYWxyZWFk eSBlbmQgaW4gb25lLgogICAgLy8KICAgIC8vIFRoZSAiTWF4aW11bUxlbmd0 aCIgYW5kICJCdWZmZXIiIG1lbWJlcnMgYWx3YXlzIHNwZWNpZnkgdGhlIHNp emUKICAgIC8vIGFuZCBzdGFydGluZyBhZGRyZXNzIG9mIHRoZSAiQnVmZmVy IiBzaWJsaW5nIG1lbWJlciAoc2VlIGJlbG93KS4KCiAgICBVTklDT0RFX1NU UklORyBQYXRoOwoKICAgIC8vIFRoZSBhY3R1YWwgc2l6ZSBvZiB0aGlzIG1l bWJlciwgYW5kIHRoZXJlZm9yZSBvZiB0aGUgc3RydWN0IGFzCiAgICAvLyBh IHdob2xlLCBpcyBjb21wdXRlZCBkeW5hbWljYWxseSBzbyB0aGF0IHRoaXMg bWVtYmVyIGhhcyB0aGUKICAgIC8vIHNhbWUgc2l6ZSBhcyB0aGUgcHJldmlv dXMgdmFsdWUgb2YKICAgIC8vCiAgICAvLyAgIFBhcmFtcy5DdXJyZW50RGly ZWN0b3J5TmFtZS5NYXhpbXVtTGVuZ3RoCiAgICAvLwogICAgLy8gQnV0IHNp bmNlIFNldEN1cnJlbnREaXJlY3RvcnkgKCkgbmV2ZXIgc2VlbXMgdG8gbW9k aWZ5IHRoYXQKICAgIC8vIFBFQiBkYXR1bSwgaW4gcHJhY3RpY2UgdGhlIGRp bWVuc2lvbiBpcyBhbHdheXMgTUFYX1BBVEguCgogICAgd2NoYXJfdCBCdWZm ZXJbTUFYX1BBVEhdOwogIH07CgovKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKioqKioqKioqKgoKQWxsb2NhdGlvbjoKCkJlZm9yZSBtb2RpZnlp bmcgdGhlIFBFQiBkYXRhLCB0aGUgaW1wbGVtZW50YXRpb24Kb2YgU2V0Q3Vy cmVudERpcmVjdG9yeSAoKSBhbGxvY2F0ZXMgYSBuZXcgaW5zdGFuY2UKb2Yg VmlzdGFDd2QsIGFzIGZvbGxvd3M6CgogICAgUnRsQWxsb2NhdGVIZWFwIChI ZWFwSGFuZGxlLCAwLAogICAgICBvZmZzZXRvZiAoVmlzdGFDd2QsIEJ1ZmZl cikgKyBQYXJhbXMuQ3VycmVudERpcmVjdG9yeU5hbWUuTWF4aW11bUxlbmd0 aCk7CgpJbml0aWFsaXphdGlvbjoKClRoZSBTZXRDdXJyZW50RGlyZWN0b3J5 ICgpIGltcGxlbWVudGF0aW9uCnRoZW4gaW5pdGlhbGl6ZXMgdGhhdCBpbnN0 YW5jZSBhcyBmb2xsb3dzOgoKICAvLyBSZWFkIERpc21vdW50Q291bnQgYmVm b3JlIGNhbGxpbmcgTnRPcGVuRmlsZSgpLgogIC8vIElmIHRoZSByZWxhdGl2 ZSBvcmRlciBtYXR0ZXJzIGF0IGFsbCwgdGhlbiBpdCBpcwogIC8vIHByb2Jh Ymx5IGZvbGxvd2luZyB0aGUgZ2VuZXJhbCBwcmluY2lwbGUgdGhhdAogIC8v IGEgc3RhbGUgdmFsdWUgY29waWVkIGZyb20gRGlzbW91bnRDb3VudCB0byB0 aGUKICAvLyBPbGREaXNtb3VudENvdW50IG1lbWJlciAoc2VlIGJlbG93KSBq dXN0IGNhdXNlcwogIC8vIGV4dHJhIHdvcmsgYnV0IGlzIG90aGVyd2lzZSBo YXJtbGVzcywgd2hlcmVhcwogIC8vIGEgdG9vLXJlY2VudCB2YWx1ZSBtaWdo dCBwcmV2ZW50IG5lY2Vzc2FyeSB3b3JrLgoKICBVTE9ORyBEaXNtb3VudENv dW50QmVmb3JlTnRPcGVuRmlsZSA9IERpc21vdW50Q291bnQ7CgogIFJlZmVy ZW5jZUNvdW50ID0gMTsKCiAgRGlyZWN0b3J5SGFuZGxlID0gTnRPcGVuRmls ZSAoLi4uKTsKCiAgLy8gTk9URTogVGhlcmUgaXMgbm8gbG9ja2luZyBhcm91 bmQgdGhpcyBpbml0aWFsaXphdGlvbi4KICAvLyBCdXQgdGhlIFNldEN1cnJl bnREaXJlY3RvcnkgKCkgaW1wbGVtZW50YXRpb24gbG9ja3MgQ3dkQ1MKICAv LyB3aGlsZSB1cGRhdGluZyBDd2QgdG8gcG9pbnQgdG8gbmV3IGluc3RhbmNl cyBvZiBWaXN0YUN3ZCwKICAvLyBhbmQgcHJlc3VtYWJseSB0aGF0IHN1ZmZp Y2VzIHRvIGZsdXNoIHRoaXMgaW5pdGlhbGl6YXRpb24KICAvLyB0byBvdGhl ciBDUFVzLiAgT3RoZXIgdGhyZWFkcyB3b3VsZCBub3Qgc2VlIHRoZSBuZXcg VmlzdGFDd2QKICAvLyBpbnN0YW5jZSBiZWZvcmUgdGhhdCBwb2ludC4gIEFz IG1lbnRpb25lZCBiZWZvcmUsIGNvcHlpbmcgb2YKICAvLyBhIHN0YWxlIHZh bHVlIG9mIHRoZSBnbG9iYWwgRGlzbW91bnRDb3VudCBpcyBwcm9iYWJseSBo YXJtbGVzcywKICAvLyBpbiB0aGF0IGl0IHdvdWxkIG1lcmVseSB0cmlnZ2Vy IGFuIHVubmVjZXNzYXJ5IHVwZGF0ZS4KCiAgT2xkRGlzbW91bnRDb3VudCA9 IERpc21vdW50Q291bnRCZWZvcmVOdE9wZW5GaWxlOwoKICAvLyBUaGUgbGVu Z3RoIG9mIHRoZSBwYXRoIGluIGJ5dGVzLCBub3QgY291bnRpbmcgdGhlIHRl cm1pbmF0b3IuCgogIFBhdGguTGVuZ3RoID0gLi4uOwoKICAvLyBBcyBtZW50 aW9uZWQgYmVmb3JlLCBpbiBwcmFjdGljZSB0aGlzIGlzIHNpemVvZih3Y2hh cl90IFtNQVhfUEFUSF0pLgoKICBQYXRoLk1heGltdW1MZW5ndGggPSBQYXJh bXMuQ3VycmVudERpcmVjdG9yeU5hbWUuTWF4aW11bUxlbmd0aDsKCiAgUGF0 aC5CdWZmZXIgPSBCdWZmZXI7CgogIC8vIFRoZSB3aWRlIHBhdGggZm9yIHRo ZSBkaXJlY3Rvcnk7IGlmIG5lY2Vzc2FyeSBhIGJhY2tzbGFzaCBpcwogIC8v IGFwcGVuZGVkIHNvIHRoYXQgdGhlIGZpbmFsIGNoYXJhY3RlciAoYmVmb3Jl IHRoZSB0ZXJtaW5hdG9yKQogIC8vIGlzIGFsd2F5cyBhIGJhY2tzbGFzaC4K CiAgbWVtY3B5IChCdWZmZXIsIC4uLik7CiAgQnVmZmVyW1BhdGguTGVuZ3Ro IC8gc2l6ZW9mKHdjaGFyX3QpXSA9IEwnXDAnOwoKVXNhZ2U6CgpBZnRlciBj cmVhdGluZyB0aGUgbmV3IFZpc3RhQ3dkIGluc3RhbmNlOyBjYWxsIGl0IG5l d0N3ZCwgdGhlClNldEN1cnJlbnREaXJlY3RvcnkgKCkgaW1wbGVtZW50YXRp b24gbW9kaWZpZXMgdGhlIFBFQiBhbmQgQ3dkCnVuZGVyIGEgbG9jayBvbiBD d2RDUywgYXMgZm9sbG93czoKCiAgUGFyYW1zLkN1cnJlbnREaXJlY3RvcnlI YW5kbGUgPSBuZXdDd2QuRGlyZWN0b3J5SGFuZGxlOwoKICBQYXJhbXMuQ3Vy cmVudERpcmVjdG9yeU5hbWUuQnVmZmVyID0gbmV3Q3dkLlBhdGguQnVmZmVy OwoKICBQYXJhbXMuQ3VycmVudERpcmVjdG9yeU5hbWUuTGVuZ3RoID0gbmV3 Q3dkLlBhdGguTGVuZ3RoOwoKICBWaXN0YUN3ZCAqb2xkQ3dkID0gQ3dkOwoK ICBDd2QgPSBuZXdDd2Q7CgpOb3RlIHRoYXQgYXMgbWVudGlvbmVkIGJlZm9y ZSwKUGFyYW1zLkN1cnJlbnREaXJlY3RvcnlOYW1lLk1heGltdW1MZW5ndGgK aXMgTk9UIG1vZGlmaWVkLgoKQ2xlYW51cDoKCkFmdGVyIHRoZSBTZXRDdXJy ZW50RGlyZWN0b3J5ICgpIGltcGxlbWVudGF0aW9uIHJlbGVhc2VzCml0cyBs b2NrIG9uIEN3ZENTLCBpdCBwZXJmb3JtcyBhIGJ1cy1sb2NrZWQgZGVjcmVt ZW50IG9uCm9sZEN3ZC0+UmVmZXJlbmNlQ291bnQgKHVubGVzcyBvbGRDd2Qg PT0gTlVMTCkuICBJZiB0aGUKcmVzdWx0IGlzIHplcm8sIGl0IHRoZW4gZGVz dHJveXMgYW5kIGRlYWxsb2NhdGVzIHRoZQpvbGQgVmlzdGFDd2QgaW5zdGFu Y2UgYXMgZm9sbG93czoKCiAgTnRDbG9zZSAob2xkQ3dkLT5EaXJlY3RvcnlI YW5kbGUpOwoKICBSdGxGcmVlSGVhcCAoSGVhcEhhbmRsZSwgMCwgb2xkQ3dk KTsKCkFkZHJlc3NlcyBvZiBDd2QgYW5kIEN3ZENTOgoKSW4gb3JkZXIgdG8g aW1pdGF0ZSB0aGUgd2F5IGluIHdoaWNoIFNldEN1cnJlbnREaXJlY3Rvcnkg KCkgdXBkYXRlcwp0aGUgV2luMzIgQ1dEIGRhdGEsIHdlIG11c3QgbGVhcm4g dGhlIGFkZHJlc3NlcyBvZiBDd2QgYW5kIEN3ZENTLgoKVGhlIGZvbGxvd2lu ZyBwcm9ncmFtIHBlcmZvcm1zIGNvZGUgYW5hbHlzaXMgdG8gZGlzY292ZXIg dGhvc2UuCkl0IHRoZW4gY2hhbmdlcyB0aGUgV2luMzIgQ1dEIGRpcmVjdGx5 IGFuZCB0ZXN0cyB0aGUgcmVzdWx0CndpdGggYSByZWxhdGl2ZSBDcmVhdGVG aWxlICgpLiAgSXQgaXMgaW50ZW5kZWQgYXMKYSBxdWljay1hbmQtZGlydHkg c3RhbmQtYWxvbmUgcHJvb2Ytb2YtY29uY2VwdCBwcm9ncmFtOwpmaW5hbCBj b2RlIHRvIGJlIGluY2x1ZGVkIGluIGN5Z3dpbjEuZGxsIHdvdWxkIGRpZmZl ciBncmVhdGx5LgoKKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq KioqKioqKi8KCnR5cGVkZWYgdW5zaWduZWQgY2hhciBjb2RlX3Q7Cgp1bnNp Z25lZCBwZWVrMzIgKGNvbnN0IHVuc2lnbmVkIGNoYXIgKnApCnsKICByZXR1 cm4gcFswXSArIChwWzFdIDw8IDgpICsgKHBbMl0gPDwgMTYpICsgKHBbM10g PDwgMjQpOwp9Cgp2b2lkIGJhZENvZGUgKCkKewogIGNlcnIgPDwgIkNvZGUg bG9va3MgZGlmZmVyZW50IHRoYW4gZXhwZWN0ZWQ7IGJhaWxpbmcgb3V0LiIg PDwgZW5kbDsKICBleGl0ICgxKTsKfQoKb3N0cmVhbSYgd2luRXJyb3IgKG9z dHJlYW0mIG9zLCBEV09SRCBjb2RlID0gR2V0TGFzdEVycm9yKCkpCnsKICBM UFNUUiBtc2cgPSAwOwogIGlmIChGb3JtYXRNZXNzYWdlQSAoRk9STUFUX01F U1NBR0VfRlJPTV9TWVNURU0KICAgICAgICAgICAgICAgICAgICAgIHwgRk9S TUFUX01FU1NBR0VfQUxMT0NBVEVfQlVGRkVSLAogICAgICAgICAgICAgICAg ICAgICAgMCwKICAgICAgICAgICAgICAgICAgICAgIGNvZGUsCiAgICAgICAg ICAgICAgICAgICAgICBNQUtFTEFOR0lEKExBTkdfTkVVVFJBTCwgU1VCTEFO R19ERUZBVUxUKSwKICAgICAgICAgICAgICAgICAgICAgIChMUFNUUikmbXNn LAogICAgICAgICAgICAgICAgICAgICAgMSwKICAgICAgICAgICAgICAgICAg ICAgIE5VTEwpKSB7CiAgICBvcyA8PCAiZXJyb3IgIiA8PCBjb2RlIDw8ICI6 ICIgPDwgbXNnOwogICAgTG9jYWxGcmVlIChtc2cpOwogIH0gZWxzZSB7CiAg ICBvcyA8PCAiPz8/IjsKICB9CiAgcmV0dXJuIG9zOwp9CgojZGVmaW5lIERE S0FQSSBfX3N0ZGNhbGwKCnR5cGVkZWYgQ09OU1QgY2hhciAqUENTWjsKCnR5 cGVkZWYKTlRTVEFUVVMKRERLQVBJCigqIE50Q2xvc2VfdCkoCiAgLypJTiov IEhBTkRMRSAgSGFuZGxlKTsKCnR5cGVkZWYKTlRTVEFUVVMKRERLQVBJCigq IE50T3BlbkZpbGVfdCkgKAogIC8qT1VUKi8gUEhBTkRMRSAgRmlsZUhhbmRs ZSwKICAvKklOKi8gQUNDRVNTX01BU0sgIERlc2lyZWRBY2Nlc3MsCiAgLypJ TiovIFBPQkpFQ1RfQVRUUklCVVRFUyAgT2JqZWN0QXR0cmlidXRlcywKICAv Kk9VVCovIFBJT19TVEFUVVNfQkxPQ0sgIElvU3RhdHVzQmxvY2ssCiAgLypJ TiovIFVMT05HICBTaGFyZUFjY2VzcywKICAvKklOKi8gVUxPTkcgIE9wZW5P cHRpb25zKTsKCnR5cGVkZWYKUFZPSUQKTlRBUEkKKCogUnRsQWxsb2NhdGVI ZWFwX3QpICgKICAvKklOKi8gSEFORExFICBIZWFwSGFuZGxlLAogIC8qSU4q LyBVTE9ORyAgIEZsYWdzLAogIC8qSU4qLyBVTE9ORyAgIFNpemUKKTsKCnR5 cGVkZWYKQk9PTEVBTgpOVEFQSQooKiBSdGxGcmVlSGVhcF90KSAoCiAgLypJ TiovIEhBTkRMRSAgSGVhcEhhbmRsZSwKICAvKklOKi8gVUxPTkcgICBGbGFn cywKICAvKklOKi8gUFZPSUQgICBQCik7Cgp0eXBlZGVmClZPSUQKRERLQVBJ CigqIFJ0bEluaXRTdHJpbmdfdCkgKAogIC8qSU4gT1VUKi8gUFNUUklORyAg RGVzdGluYXRpb25TdHJpbmcsCiAgLypJTiovIFBDU1ogIFNvdXJjZVN0cmlu Zyk7Cgp0eXBlZGVmCk5UU1RBVFVTCkRES0FQSQooKiBSdGxBbnNpU3RyaW5n VG9Vbmljb2RlU3RyaW5nX3QpICgKICAvKklOIE9VVCovIFBVTklDT0RFX1NU UklORyAgRGVzdGluYXRpb25TdHJpbmcsCiAgLypJTiovIFBBTlNJX1NUUklO RyAgU291cmNlU3RyaW5nLAogIC8qSU4qLyBCT09MRUFOICBBbGxvY2F0ZURl c3RpbmF0aW9uU3RyaW5nKTsKCnR5cGVkZWYKVk9JRApEREtBUEkKKCogUnRs RnJlZVVuaWNvZGVTdHJpbmdfdCkgKAogIC8qSU4qLyBQVU5JQ09ERV9TVFJJ TkcgIFVuaWNvZGVTdHJpbmcpOwoKdHlwZWRlZgpOVFNUQVRVUwpEREtBUEkK KCogUnRsVW5pY29kZVN0cmluZ1RvQW5zaVN0cmluZ190KSgKICAvKklOIE9V VCovIFBBTlNJX1NUUklORyAgRGVzdGluYXRpb25TdHJpbmcsCiAgLypJTiov IFBVTklDT0RFX1NUUklORyAgU291cmNlU3RyaW5nLAogIC8qSU4qLyBCT09M RUFOICBBbGxvY2F0ZURlc3RpbmF0aW9uU3RyaW5nKTsKCnR5cGVkZWYKVk9J RApEREtBUEkKKCogUnRsRnJlZUFuc2lTdHJpbmdfdCkoCiAgLypJTiovIFBB TlNJX1NUUklORyAgQW5zaVN0cmluZyk7CgojZGVmaW5lIE5URlVOQ19ERUNM KEYpIEYgIyMgX3QgXyAjIyBGCgpzdHJ1Y3QgTnRGdW5jcwp7CiAgTlRGVU5D X0RFQ0woTnRDbG9zZSk7CiAgTlRGVU5DX0RFQ0woTnRPcGVuRmlsZSk7CiAg TlRGVU5DX0RFQ0woUnRsQWxsb2NhdGVIZWFwKTsKICBOVEZVTkNfREVDTChS dGxGcmVlSGVhcCk7CiAgTlRGVU5DX0RFQ0woUnRsSW5pdFN0cmluZyk7CiAg TlRGVU5DX0RFQ0woUnRsQW5zaVN0cmluZ1RvVW5pY29kZVN0cmluZyk7CiAg TlRGVU5DX0RFQ0woUnRsRnJlZVVuaWNvZGVTdHJpbmcpOwogIE5URlVOQ19E RUNMKFJ0bFVuaWNvZGVTdHJpbmdUb0Fuc2lTdHJpbmcpOwogIE5URlVOQ19E RUNMKFJ0bEZyZWVBbnNpU3RyaW5nKTsKCiAgTnRGdW5jcyhITU9EVUxFIG1v ZHVsZSk7Cn07CgojZGVmaW5lIE5URlVOQ19CSU5EKE0sIEYpIF8gIyMgRiA9 IChGICMjIF90KSBHZXRQcm9jQWRkcmVzcyhNLCAjIEYpCgpOdEZ1bmNzOjpO dEZ1bmNzKEhNT0RVTEUgbW9kdWxlKQp7CiAgTlRGVU5DX0JJTkQobW9kdWxl LCBOdENsb3NlKTsKICBOVEZVTkNfQklORChtb2R1bGUsIE50T3BlbkZpbGUp OwogIE5URlVOQ19CSU5EKG1vZHVsZSwgUnRsQWxsb2NhdGVIZWFwKTsKICBO VEZVTkNfQklORChtb2R1bGUsIFJ0bEZyZWVIZWFwKTsKICBOVEZVTkNfQklO RChtb2R1bGUsIFJ0bEluaXRTdHJpbmcpOwogIE5URlVOQ19CSU5EKG1vZHVs ZSwgUnRsQW5zaVN0cmluZ1RvVW5pY29kZVN0cmluZyk7CiAgTlRGVU5DX0JJ TkQobW9kdWxlLCBSdGxGcmVlVW5pY29kZVN0cmluZyk7CiAgTlRGVU5DX0JJ TkQobW9kdWxlLCBSdGxVbmljb2RlU3RyaW5nVG9BbnNpU3RyaW5nKTsKICBO VEZVTkNfQklORChtb2R1bGUsIFJ0bEZyZWVBbnNpU3RyaW5nKTsKfQoKdm9p ZCBtb2RpZmllZFNldEN1cnJlbnREaXJlY3RvcnkgKAogICAgY29uc3QgTnRG dW5jcyYgbnQsCiAgICBDUklUSUNBTF9TRUNUSU9OICpDd2RDUywKICAgIFZp c3RhQ3dkICoqQ3dkLAogICAgVU5JQ09ERV9TVFJJTkcmIHVwYXRoKQp7CiAg Ly8gVGhlIHJlYWwgU2V0Q3VycmVudERpcmVjdG9yeSAoKSBpbXBsZW1lbnRh dGlvbiBjYWxscwogIC8vIGEgbm9uLWV4cG9ydGVkIGZ1bmN0aW9uIHRoYXQg YXBwZWFycyB0byBleHBhbmQgcmVsYXRpdmUKICAvLyBwYXRocyB0byBhYnNv bHV0ZSBwYXRocyBhbmQgY29udmVydCAvIHRvIFwuICBJdCBtaWdodAogIC8v IGFsc28gZG8gb3RoZXIgdGhpbmdzLgogIC8vCiAgLy8gVGhlcmUgYXBwZWFy IHRvIGJlIG5vIGxvY2tzIG9uIHRoZSBQRUIgb3IgQ3dkIHRoYXQKICAvLyBw ZXJzaXN0IGJldHdlZW4gdGhpcyBjb252ZXJzaW9uIGFuZCB0aGUgYWN0dWFs IFdpbjMyCiAgLy8gQ1dEIGNoYW5nZSwgc28gcHJlc3VtYWJseSB0aGUgZm9s bG93aW5nIHJhY2UgaXMgcG9zc2libGU6CiAgLy8KICAvLyAgIDEuIFRocmVh ZCBBIGNhbGxzIFNldEN1cnJlbnREaXJlY3RvcnkoIkM6XFxhXFxiIikuCiAg Ly8KICAvLyAgIDIuIFRocmVhZCBBIGNyZWF0ZXMgVGhyZWFkIEIuCiAgLy8K ICAvLyAgIDMuIFRocmVhZCBBIHN0YXJ0cyBjYWxsaW5nIFNldEN1cnJlbnRE aXJlY3RvcnkoIi4uIikKICAvLyAgICAgIGFuZCBnZXRzIHRocm91Z2ggcmVs YXRpdmUtdG8tYWJzb2x1dGUgY29udmVyc2lvbiwKICAvLyAgICAgIHlpZWxk aW5nICJDOlxcYSIgYXMgdGhlIGRlc2lyZWQgQ1dELgogIC8vCiAgLy8gICA0 LiBUaHJlYWQgQiBjYWxscyBTZXRDdXJyZW50RGlyZWN0b3J5KCJDOlxcZFxc ZSIpLgogIC8vCiAgLy8gICA1LiBUaHJlYWQgQSBhY3F1aXJlcyBDd2RDUyBh bmQgc2V0cyBDd2QgdG8gYSBuZXcKICAvLyAgICAgIFZpc3RhQ3dkIGluc3Rh bmNlIHRoYXQgc3BlY2lmaWVzICJDOlxcYSIuCiAgLy8KICAvLyBIb2xkaW5n IGEgbG9jayBiZXR3ZWVuICgzKSBhbmQgKDUpIHdvdWxkIGZvcmNlCiAgLy8g KDQpIHRvIGNvbWUgZWl0aGVyIGJlZm9yZSAoMykgb3IgYWZ0ZXIgKDUpLCBi dXQKICAvLyB0aGVyZSB3b3VsZCBzdGlsbCBiZSBhIHJhY2U6IGlmICg0KSBj b21lcyBmaXJzdCwKICAvLyB0aGVuIHRoZSBmaW5hbCBDV0QgaXMgIkM6XFxk Iiwgd2hlcmVhcyBpZiAoNCkKICAvLyBjb21lcyBsYXN0LCB0aGVuIHRoZSBm aW5hbCBDV0QgaXMgIkM6XFxkXFxlIi4KICAvLyBQcm9iYWJseSB0aGF0IGlz IHdoeSBubyBsb2NrIGlzIGhlbGQ6IGl0IHdvdWxkCiAgLy8gaW5jcmVhc2Ug Y29udGVudGlvbiBidXQgbm90IGVsaW1pbmF0ZSByYWNlcy4KICAvLwogIC8v IE9uIHRoZSBvdGhlciBoYW5kLCBpdCBhcHBlYXJzIHRoYXQgYXQgbGVhc3Qg c29tZQogIC8vIG90aGVyIHZlcnNpb25zIG9mIFdpbmRvd3MgdGhhdCBkbyBu b3QgdXNlIHRoZQogIC8vIFZpc3RhQ3dkIG1lY2hhbmlzbSwgc3VjaCBhcyBX aW5kb3dzIFNlcnZlciAyMDAzIFIyIHg2NCwKICAvLyBtaWdodCBhY3R1YWxs eSBhY3F1aXJlIGEgbG9jayBiZWZvcmUgcmVsYXRpdmUtdG8tYWJzb2x1dGUK ICAvLyBwYXRoIGNvbnZlcnNpb24uICBQZXJoYXBzIE1pY3Jvc29mdCByZXRo b3VnaHQgdGhlIHJhY2VzCiAgLy8gd2hlbiB0aGV5IGNoYW5nZWQgdG8gdGhl IG5ld2VyIG1lY2hhbmlzbT8KICAvLwogIC8vIEFueXdheSwgdGhlIG91dHB1 dCBvZiByZWxhdGl2ZS10by1hYnNvbHV0ZSBjb252ZXJzaW9uCiAgLy8gaXMg cnVuIHRocm91Z2ggYW5vdGhlciwgbm9uLWV4cG9ydGVkIHBhdGggY29udmVy c2lvbgogIC8vIGZ1bmN0aW9uIHRoYXQgcHJlZml4ZXMgXD8/XCBhbmQgcHJl c3VtYWJseSBkb2VzCiAgLy8gb3RoZXIgbm9ybWFsaXphdGlvbnMgYXBwcm9w cmlhdGUgdG8gc3VjaCBwYXRocy4KICAvLyBIb3dldmVyLCB0aGF0IHNwZWNp YWwgZm9ybSBpcyB1c2VkIG9ubHkgYXMgYW4gYXJndW1lbnQKICAvLyB0byBO dE9wZW5GaWxlKCktLWl0IGRvZXMgTk9UIGdldCBwdXQgaW50byB0aGUgbmV3 CiAgLy8gVmlzdGFDd2QgaW5zdGFuY2UuICBJbnN0ZWFkLCB0aGUgVmlzdGFD d2QgaW5zdGFuY2UKICAvLyBnZXRzIGEgc2VwYXJhdGUgY29weSBvZiB0aGUg b3V0cHV0IG9mIHRoZQogIC8vIHJlbGF0aXZlLXRvLWFic29sdXRlIGNvbnZl cnNpb24sIGFuZCBpbiB0aGlzIGNvcHkgb25seSwKICAvLyBhIGJhY2tzbGFz aCBpcyBhcHBlbmRlZCBpZiB0aGUgYWJzb2x1dGUgcGF0aCBkaWQgbm90CiAg Ly8gYWxyZWFkeSBlbmQgaW4gYSBiYWNrc2xhc2guCiAgLy8KICAvLyBJbiB0 aGlzIGltcGxlbWVudGF0aW9uIHdlIGRvIG5vdCBib3RoZXIgdG8gcGVyZm9y bQogIC8vIHRoZSByZWxhdGl2ZS10by1hYnNvbHV0ZSBwYXRoIGNvbnZlcnNp b247IGluc3RlYWQKICAvLyB3ZSBqdXN0IHdhcm4gaWYgdGhlIHBhdGggaXMg bm90IGFic29sdXRlLgogIC8vIEJ1dCB3ZSBkbyBjb252ZXJ0IC8gdG8gXC4K CiAgcmVwbGFjZSAodXBhdGguQnVmZmVyLCB1cGF0aC5CdWZmZXIgKyB1cGF0 aC5MZW5ndGggLyBzaXplb2Yod2NoYXJfdCksCiAgICAgICAgICAgTCcvJywg TCdcXCcpOwogIGlmICh1cGF0aC5MZW5ndGggPCAzIHx8IHVwYXRoLkJ1ZmZl clsxXSAhPSBMJzonIHx8IHVwYXRoLkJ1ZmZlclsyXSAhPSBMJ1xcJyl7CiAg ICBjZXJyIDw8ICJSZWxhdGl2ZSBwYXRocyBub3QgaW1wbGVtZW50ZWQuIiA8 PCBlbmRsOwogICAgZXhpdCAoMSk7CiAgfQoKICAvLyBQcmVmaXggXD8/XCB0 byB0aGUgcGF0aCBiZWZvcmUgcGFzc2luZyBpdCB0byBOdE9wZW5GaWxlKCku CiAgaWYgKHVwYXRoLkxlbmd0aCA+IChNQVhfUEFUSCAtIDUpICogc2l6ZW9m KHdjaGFyX3QpKSB7CiAgICBjZXJyIDw8ICJQYXRoIHRvbyBsb25nLiIgPDwg ZW5kbDsKICAgIGV4aXQoMSk7CiAgfQogIHdjaGFyX3QgbnR1cGF0aF9idWZb TUFYX1BBVEhdOwogIFVOSUNPREVfU1RSSU5HIG50dXBhdGg7CiAgbnR1cGF0 aC5MZW5ndGggPSB1cGF0aC5MZW5ndGggKyA0ICogc2l6ZW9mKHdjaGFyX3Qp OwogIG50dXBhdGguTWF4aW11bUxlbmd0aCA9IHNpemVvZiBudHVwYXRoX2J1 ZjsKICBudHVwYXRoLkJ1ZmZlciA9IG50dXBhdGhfYnVmOwogIG1lbWNweShu dHVwYXRoX2J1ZiwgTCJcXD8/XFwiLCA0ICogc2l6ZW9mKHdjaGFyX3QpKTsK ICBtZW1jcHkobnR1cGF0aF9idWYgKyA0LCB1cGF0aC5CdWZmZXIsIHVwYXRo Lkxlbmd0aCk7CiAgbnR1cGF0aF9idWZbNCArICh1cGF0aC5MZW5ndGggLyBz aXplb2Yod2NoYXJfdCkpXSA9IEwnXDAnOwoKICBSVExfVVNFUl9QUk9DRVNT X1BBUkFNRVRFUlMmIFBhcmFtcwogICAgPSAqTnRDdXJyZW50VGViICgpLT5Q ZWItPlByb2Nlc3NQYXJhbWV0ZXJzOwoKICBQVk9JRCBIZWFwSGFuZGxlID0g KihQVk9JRCopKChjaGFyKilOdEN1cnJlbnRUZWIgKCktPlBlYiArIDB4MTgp OwoKICB2b2xhdGlsZSBVTE9ORyYgRGlzbW91bnRDb3VudCA9ICoodm9sYXRp bGUgVUxPTkcqKTB4N2ZmZTAyZGM7CgogIC8vIERvIHRoaXMgYmVmb3JlIHRo ZSBOdE9wZW5GaWxlLCBqdXN0IGluIGNhc2UgdGhhdCBvcmRlciBtYXR0ZXJz LgoKICBVTE9ORyBEaXNtb3VudENvdW50QmVmb3JlTnRPcGVuRmlsZSA9IERp c21vdW50Q291bnQ7CgogIEhBTkRMRSBoOwogIE5UU1RBVFVTIHN0YXR1czsK ICBJT19TVEFUVVNfQkxPQ0sgaW87CiAgT0JKRUNUX0FUVFJJQlVURVMgYXR0 cjsKCiAgSW5pdGlhbGl6ZU9iamVjdEF0dHJpYnV0ZXMgKCZhdHRyLCAmbnR1 cGF0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0JKX0NBU0Vf SU5TRU5TSVRJVkUgfCBPQkpfSU5IRVJJVCwKICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgTlVMTCwgTlVMTCk7CiAgc3RhdHVzID0gbnQuX050T3Bl bkZpbGUgKCZoLCBTWU5DSFJPTklaRSB8IEZJTEVfVFJBVkVSU0UsICZhdHRy LCAmaW8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfU0hBUkVf VkFMSURfRkxBR1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVf RElSRUNUT1JZX0ZJTEUKICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBG SUxFX1NZTkNIUk9OT1VTX0lPX05PTkFMRVJUCiAgICAgICAgICAgICAgICAg ICAgICAgICAgIHwgRklMRV9PUEVOX0ZPUl9CQUNLVVBfSU5URU5UKTsKICBp ZiAoIU5UX1NVQ0NFU1MgKHN0YXR1cykpCiAgewogICAgQU5TSV9TVFJJTkcg bmFycm93OwogICAgbnQuX1J0bFVuaWNvZGVTdHJpbmdUb0Fuc2lTdHJpbmco Jm5hcnJvdywgJm50dXBhdGgsIFRSVUUpOwoKICAgIGNlcnIgPDwgIkZhaWxl ZCB0byBvcGVuIGRpcmVjdG9yeSAnIjsKICAgIGNlcnIud3JpdGUobmFycm93 LkJ1ZmZlciwgbmFycm93Lkxlbmd0aCk7CiAgICBjZXJyIDw8ICInOiBOVFNU QVRVUyAiIDw8IHNob3diYXNlIDw8IGhleCA8PCBzdGF0dXMgPDwgZW5kbDsK CiAgICBudC5fUnRsRnJlZUFuc2lTdHJpbmcoJm5hcnJvdyk7CgogICAgZXhp dCgxKTsKICB9CgogIC8vIEFzIG1lbnRpb25lZCBiZWZvcmUsIGluIHByYWN0 aWNlIHRoaXMgaXMgc2l6ZW9mICh3Y2hhcl90IFtNQVhfUEFUSF0pLgoKICBV U0hPUlQgTWF4aW11bUxlbmd0aCA9IFBhcmFtcy5DdXJyZW50RGlyZWN0b3J5 TmFtZS5NYXhpbXVtTGVuZ3RoOwoKICBWaXN0YUN3ZCAqbmV3Q3dkID0gKFZp c3RhQ3dkICopIG50Ll9SdGxBbGxvY2F0ZUhlYXAgKEhlYXBIYW5kbGUsIDAs CiAgICAgIG9mZnNldG9mIChWaXN0YUN3ZCwgQnVmZmVyKSArIE1heGltdW1M ZW5ndGgpOwoKICBuZXdDd2QtPlJlZmVyZW5jZUNvdW50ID0gMTsKCiAgbmV3 Q3dkLT5EaXJlY3RvcnlIYW5kbGUgPSBoOwoKICBuZXdDd2QtPk9sZERpc21v dW50Q291bnQgPSBEaXNtb3VudENvdW50QmVmb3JlTnRPcGVuRmlsZTsKCiAg bmV3Q3dkLT5QYXRoLkxlbmd0aCA9IHVwYXRoLkxlbmd0aDsKCiAgbmV3Q3dk LT5QYXRoLk1heGltdW1MZW5ndGggPSBNYXhpbXVtTGVuZ3RoOwoKICBuZXdD d2QtPlBhdGguQnVmZmVyID0gbmV3Q3dkLT5CdWZmZXI7CgogIG1lbWNweSAo bmV3Q3dkLT5CdWZmZXIsIHVwYXRoLkJ1ZmZlciwgdXBhdGguTGVuZ3RoKTsK ICBuZXdDd2QtPkJ1ZmZlclt1cGF0aC5MZW5ndGggLyBzaXplb2Yod2NoYXJf dCldID0gTCdcMCc7CgogIC8vIEluIG5ldyBWaXN0YUN3ZCBpbnN0YW5jZSwg ZW5zdXJlIHRoYXQgdGhlIGZpbmFsIHBhdGggY2hhcmFjdGVyIGlzIEwnXFwn OgoKICBpZiAobmV3Q3dkLT5CdWZmZXJbKHVwYXRoLkxlbmd0aCAvIHNpemVv Zih3Y2hhcl90KSkgLSAxXSAhPSBMJ1xcJykgewogICAgaWYgKHVwYXRoLkxl bmd0aCA+IG5ld0N3ZC0+UGF0aC5NYXhpbXVtTGVuZ3RoIC0gKDIgKiBzaXpl b2Yod2NoYXJfdCkpKSB7CiAgICAgIGNlcnIgPDwgIlBhdGggdG9vIGxvbmcu IiA8PCBlbmRsOwogICAgICBleGl0KDEpOwogICAgfQogICAgbmV3Q3dkLT5C dWZmZXJbdXBhdGguTGVuZ3RoIC8gc2l6ZW9mKHdjaGFyX3QpXSA9IEwnXFwn OwogICAgbmV3Q3dkLT5CdWZmZXJbKHVwYXRoLkxlbmd0aCAvIHNpemVvZih3 Y2hhcl90KSkgKyAxXSA9IEwnXDAnOwogICAgdXBhdGguTGVuZ3RoICs9IHNp emVvZih3Y2hhcl90KTsKICB9CgogIC8vIE5PVEU6IFdlIG5ldmVyIGFjcXVp cmUgdGhlIFBFQiBsb2NrLCBvbmx5IHRoZSBWaXN0YSsrIENXRCBsb2NrOgoK ICBFbnRlckNyaXRpY2FsU2VjdGlvbihDd2RDUyk7CgogIFBhcmFtcy5DdXJy ZW50RGlyZWN0b3J5SGFuZGxlID0gbmV3Q3dkLT5EaXJlY3RvcnlIYW5kbGU7 CgogIFBhcmFtcy5DdXJyZW50RGlyZWN0b3J5TmFtZS5CdWZmZXIgPSBuZXdD d2QtPlBhdGguQnVmZmVyOwoKICBQYXJhbXMuQ3VycmVudERpcmVjdG9yeU5h bWUuTGVuZ3RoID0gbmV3Q3dkLT5QYXRoLkxlbmd0aDsKCiAgVmlzdGFDd2Qg Km9sZEN3ZCA9ICpDd2Q7CgogICpDd2QgPSBuZXdDd2Q7CgogIExlYXZlQ3Jp dGljYWxTZWN0aW9uKEN3ZENTKTsKCiAgaWYgKEludGVybG9ja2VkRGVjcmVt ZW50KCZvbGRDd2QtPlJlZmVyZW5jZUNvdW50KSA9PSAwKSB7CiAgICBudC5f TnRDbG9zZSAob2xkQ3dkLT5EaXJlY3RvcnlIYW5kbGUpOwoKICAgIG50Ll9S dGxGcmVlSGVhcCAoSGVhcEhhbmRsZSwgMCwgb2xkQ3dkKTsKICB9Cn0KCmlu dCBtYWluIChpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKICBITU9EVUxFIG1v ZHVsZSA9IEdldE1vZHVsZUhhbmRsZSAoIm50ZGxsLmRsbCIpOwoKICAvLyBS ZWFkaW5nIHRoZSBDV0QgaXMgc2ltcGxlciB0aGFuIHdyaXRpbmcgdGhlIENX RCwKICAvLyB3aGljaCBtYWtlcyBpdCBlYXNpZXIgdG8gZmluZCB0aGUgYWRk cmVzc2VzIHdlIG5lZWQsCiAgLy8gYW5kIG1pZ2h0IGFsc28gdGVuZCB0byBt YWtlIGNvZGUgY2hhbmdlcyBsZXNzIGZyZXF1ZW50LgogIGNvbnN0IGNvZGVf dCAqZ2V0X2RpciA9IChjb25zdCBjb2RlX3QqKSBHZXRQcm9jQWRkcmVzcwog ICAgKG1vZHVsZSwgIlJ0bEdldEN1cnJlbnREaXJlY3RvcnlfVSIpOwoKICBj b25zdCBjb2RlX3QgKmVudF9jcml0ID0gKGNvbnN0IGNvZGVfdCopIEdldFBy b2NBZGRyZXNzCiAgICAobW9kdWxlLCAiUnRsRW50ZXJDcml0aWNhbFNlY3Rp b24iKTsKCiAgLy8gRmluZCBmaXJzdCByZWxhdGl2ZSBjYWxsIGluc3RydWN0 aW9uLgogIGNvbnN0IGNvZGVfdCAqcmNhbGwgPSAoY29uc3QgY29kZV90ICop IG1lbWNociAoZ2V0X2RpciwgMHhFOCwgMzIpOwogIGlmICghIHJjYWxsKSB7 CiAgICBiYWRDb2RlICgpOwogIH0KCiAgLy8gQ29tcHV0ZSB0aGUgYWRkcmVz cywgdXNlX2N3ZCwgb2YgdGhlIGZ1bmN0aW9uIGJlaW5nIGNhbGxlZC4KICAv LyBUaGlzIGZ1bmN0aW9uIGFjdHVhbGx5IGZldGNoZXMgdGhlIGN1cnJlbnQg VmlzdGFDd2QgaW5zdGFuY2UKICAvLyBhbmQgcGVyZm9ybXMgYWN0aW9ucyBj b25kaXRpb25lZCB1cG9uIHRoZSBmcmVzaG5lc3Mgb2YgaXRzCiAgLy8gT2xk RGlzbW91bnRDb3VudCBtZW1iZXIuCiAgcHRyZGlmZl90IG9mZnNldCA9IHBl ZWszMiAocmNhbGwgKyAxKTsKICBjb25zdCBjb2RlX3QgKnVzZV9jd2QgPSBy Y2FsbCArIDUgKyBvZmZzZXQ7CgogIC8vIEZpbmQgdGhlIGZpcnN0ICJwdXNo IGVkaSIgaW5zdHJ1Y3Rpb24uLi4KICBjb25zdCBjb2RlX3QgKm1vdmVkaSA9 IChjb25zdCBjb2RlX3QgKikgbWVtY2hyICh1c2VfY3dkLCAweDU3LCAzMik7 CiAgKyttb3ZlZGk7CiAgLy8gLi4ud2hpY2ggc2hvdWxkIGJlIGZvbGxvd2Vk IGJ5ICJtb3YgZWRpLCBjcml0LXNlY3QtYWRkciIgdGhlbiAicHVzaCBlZGki LgogIC8vIChJZGVhbGx5IHdlIHNob3VsZCBub3QgZGVwZW5kIHVwb24gJUVE SSBiZWluZyB0aGUgcmVnaXN0ZXIsCiAgLy8gYnV0IHRoaXMgaXMgYSBwcm9v ZiBvZiBjb25jZXB0LCBhbmQgZXZlbiB3aXRoIG1vcmUgZmxleGliaWxpdHkK ICAvLyB3ZSBhcmUgc3RpbGwgZGVwZW5kaW5nIGhlYXZpbHkgdXBvbiBjb2Rl IHN0cnVjdHVyZSBoZXJlLikKICBpZiAobW92ZWRpWzBdICE9IDB4QkYgfHwg bW92ZWRpWzVdICE9IDB4NTcpIHsKICAgIGJhZENvZGUgKCk7CiAgfQogIC8v IEdldCB0aGUgYWRkcmVzcyBvZiB0aGUgY3JpdGljYWwgc2VjdGlvbiBmb3Ig dGhlIENXRC4KICBDUklUSUNBTF9TRUNUSU9OICpDd2RDUyA9IChDUklUSUNB TF9TRUNUSU9OICopIHBlZWszMiAobW92ZWRpICsgMSk7CgogIC8vIFRvIGNo ZWNrIHdlIGFyZSBzZWVpbmcgdGhlIHJpZ2h0IGNvZGUsIHdlIGNoZWNrIG91 ciBleHBlY3RhdGlvbiB0aGF0CiAgLy8gdGhlIG5leHQgaW5zdHJ1Y3Rpb24g aXMgYSByZWxhdGl2ZSBjYWxsIGludG8gUnRsRW50ZXJDcml0aWNhbFNlY3Rp b24uCiAgcmNhbGwgPSBtb3ZlZGkgKyA2OwogIGlmIChyY2FsbFswXSAhPSAw eGU4KSB7CiAgICBiYWRDb2RlICgpOwogIH0KICBvZmZzZXQgPSBwZWVrMzIg KHJjYWxsICsgMSk7CiAgaWYgKHJjYWxsICsgNSArIG9mZnNldCAhPSBlbnRf Y3JpdCkgewogICAgYmFkQ29kZSAoKTsKICB9CgogIC8vIEFmdGVyIGxvY2tp bmcgdGhlIGNyaXRpY2FsIHNlY3Rpb24sIHRoZSBjb2RlIHNob3VsZCByZWFk IHRoZQogIC8vIGdsb2JhbCBDV0QgYmxvY2sgcG9pbnRlciB0aGF0IGlzIGd1 YXJkZWQgYnkgdGhhdCBjcml0aWNhbCBzZWN0aW9uLgogIGNvbnN0IGNvZGVf dCAqbW92ZXNpID0gcmNhbGwgKyA1OwogIGlmIChtb3Zlc2lbMF0gIT0gMHg4 YikgewogICAgYmFkQ29kZSAoKTsKICB9CiAgVmlzdGFDd2QgKipDd2QgPSAo VmlzdGFDd2QgKiopIHBlZWszMiAobW92ZXNpICsgMik7CgogIGNvdXQgPDwg c2hvd2Jhc2UgPDwgaGV4IDw8IChzaXplX3QpQ3dkQ1MKICAgICAgIDw8ICIg IDw9PSBjcml0aWNhbCBzZWN0aW9uIiA8PCBlbmRsOwogIGNvdXQgPDwgc2hv d2Jhc2UgPDwgaGV4IDw8IChzaXplX3QpQ3dkCiAgICAgICA8PCAiICA8PT0g VmlzdGErKyBDV0Qgc3RydWN0IHBvaW50ZXIiIDw8IGVuZGw7CgogIGlmIChh cmdjID49IDIpIHsKICAgIE50RnVuY3MgbnQobW9kdWxlKTsKCiAgICBTVFJJ TkcgbnBhdGg7CiAgICBudC5fUnRsSW5pdFN0cmluZyAoJm5wYXRoLCBhcmd2 WzFdKTsKCiAgICBVTklDT0RFX1NUUklORyB1cGF0aDsKICAgIG50Ll9SdGxB bnNpU3RyaW5nVG9Vbmljb2RlU3RyaW5nICgmdXBhdGgsICZucGF0aCwgVFJV RSk7CgogICAgbW9kaWZpZWRTZXRDdXJyZW50RGlyZWN0b3J5IChudCwgQ3dk Q1MsIEN3ZCwgdXBhdGgpOwoKICAgIG50Ll9SdGxGcmVlVW5pY29kZVN0cmlu ZyAoJnVwYXRoKTsKCiAgICBjb3V0IDw8ICJDaGFuZ2VkIGRpcmVjdG9yeS4i IDw8IGVuZGw7CiAgfQoKICBpZiAoYXJnYyA+PSAzKSB7CiAgICBIQU5ETEUg aCA9IENyZWF0ZUZpbGUgKGFyZ3ZbMl0sIEdFTkVSSUNfUkVBRCwgMCwgTlVM TCwgT1BFTl9FWElTVElORywKICAgICAgICAgICAgICAgICAgICAgICAgICAg RklMRV9BVFRSSUJVVEVfTk9STUFMLCBOVUxMKTsKICAgIGlmIChoID09IElO VkFMSURfSEFORExFX1ZBTFVFKSB7CiAgICAgIHdpbkVycm9yKGNlcnIgPDwg IkZhaWxlZCB0byBvcGVuIGZpbGU6ICIpIDw8IGVuZGw7CiAgICAgIHJldHVy biAxOwogICAgfQoKICAgIGNvdXQgPDwgIlN1Y2Nlc3NmdWxseSBvcGVuZWQg ZmlsZS4iIDw8IGVuZGw7CiAgICBpZiAoISBDbG9zZUhhbmRsZSAoaCkpIHsK ICAgICAgd2luRXJyb3IoY2VyciA8PCAiRmFpbGVkIHRvIGNsb3NlIGZpbGU6 ICIpIDw8IGVuZGw7CiAgICAgIHJldHVybiAxOwogICAgfQogIH0KCiAgcmV0 dXJuIDA7Cn0K --_002_3C031C390CBF1E4A8CE1F74DE7ECAF3A158EDA704CMBX8EXCHPRODU_ Content-Type: text/plain; charset=us-ascii -- Problem reports: http://cygwin.com/problems.html FAQ: http://cygwin.com/faq/ Documentation: http://cygwin.com/docs.html Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple --_002_3C031C390CBF1E4A8CE1F74DE7ECAF3A158EDA704CMBX8EXCHPRODU_--