Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin-developers AT sources DOT redhat DOT com Message-ID: <001301c0916b$aed385c0$0201a8c0@sos> From: "Sergey Okhapkin" To: Subject: Remember me?-) Date: Wed, 7 Feb 2001 20:08:42 -0500 X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.00.2919.6700 X-MimeOLE: Produced By Microsoft MimeOLE V5.00.2919.6700 Hi! Here is an example of NT-specific fork() implementation. It seems to me interesting, isn't it? #include "ntdll.h" #include namespace NT { extern "C" { NTSTATUS NTAPI CsrClientCallServer( IN PVOID Message, IN PVOID, IN ULONG Opcode, IN ULONG Size ); } } VOID InheritAll() { ULONG n = 0x1000; PULONG p = new ULONG[n]; while (NT::ZwQuerySystemInformation(NT::SystemHandleInformation, p, n * sizeof *p, 0) == STATUS_INFO_LENGTH_MISMATCH) delete [] p, p = new ULONG[n *= 2]; NT::PSYSTEM_HANDLE_INFORMATION h = NT::PSYSTEM_HANDLE_INFORMATION(p + 1); ULONG pid = GetCurrentProcessId(); for (ULONG i = 0; i < *p; i++) if (h[i].ProcessId == pid) SetHandleInformation(HANDLE(h[i].Handle), HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT); delete [] p; } VOID InformCsrss(HANDLE hProcess, HANDLE hThread, ULONG pid, ULONG tid) { struct CSRSS_MESSAGE { ULONG Unknown1; ULONG Opcode; ULONG Status; ULONG Unknown2; }; struct { NT::PORT_MESSAGE PortMessage; CSRSS_MESSAGE CsrssMessage; PROCESS_INFORMATION ProcessInformation; NT::CLIENT_ID Debugger; ULONG CreationFlags; ULONG VdmInfo[2]; } csrmsg = {{0}, {0}, {hProcess, hThread, pid, tid}, {0}, 0, {0}}; NT::CsrClientCallServer(&csrmsg, 0, 0x10000, 0x24); } __declspec(naked) int child() { typedef BOOL (WINAPI *CsrpConnectToServer)(PWSTR); CsrpConnectToServer(0x77F8F65D)(L"\\Windows"); __asm mov eax, 0 __asm mov esp, ebp __asm pop ebp __asm ret } #pragma optimize("y", off) // disable frame pointer omission int fork() { HANDLE hProcess, hThread; InheritAll(); NT::OBJECT_ATTRIBUTES oa = {sizeof oa}; NT::ZwCreateProcess(&hProcess, PROCESS_ALL_ACCESS, &oa, NtCurrentProcess(), TRUE, 0, 0, 0); NT::CONTEXT context = {CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS | CONTEXT_FLOATING_POINT}; NT::ZwGetContextThread(NtCurrentThread(), &context); context.Eip = ULONG(child); MEMORY_BASIC_INFORMATION mbi; NT::ZwQueryVirtualMemory(NtCurrentProcess(), PVOID(context.Esp), NT::MemoryBasicInformation, &mbi, sizeof mbi, 0); NT::USER_STACK stack = {0, 0, PCHAR(mbi.BaseAddress) + mbi.RegionSize, mbi.BaseAddress, mbi.AllocationBase}; NT::CLIENT_ID cid; NT::ZwCreateThread(&hThread, THREAD_ALL_ACCESS, &oa, hProcess, &cid, &context, &stack, TRUE); NT::THREAD_BASIC_INFORMATION tbi; NT::ZwQueryInformationThread(NtCurrentThread(), NT::ThreadBasicInformation, &tbi, sizeof tbi, 0); NT::PNT_TIB tib = tbi.TebBaseAddress; NT::ZwQueryInformationThread(hThread, NT::ThreadBasicInformation, &tbi, sizeof tbi, 0); NT::ZwWriteVirtualMemory(hProcess, tbi.TebBaseAddress, &tib->ExceptionList, sizeof tib->ExceptionList, 0); InformCsrss(hProcess, hThread, ULONG(cid.UniqueProcess), ULONG(cid.UniqueThread)); NT::ZwResumeThread(hThread, 0); NT::ZwClose(hThread); NT::ZwClose(hProcess); return int(cid.UniqueProcess); } #pragma optimize("", on) int main() { int n = fork(); Sleep(n * 10); Beep(100, 100); printf("%d\n", n); return 0; } Sergey Okhapkin, http://www.lexa.ru/sos Somerset, NJ