BOOL SystemHandleInformation::GetNameByType( HANDLE h, WORD type, MyString& str, DWORD processId )
{
	ULONG size = 0x2000;
	UCHAR* lpBuffer = NULL;
	BOOL ret = FALSE;

	HANDLE handle;
	HANDLE hRemoteProcess = NULL;
	BOOL remote = processId != GetCurrentProcessId();
	DWORD dwId = 0;
	
	if ( !NtDllStatus )
		return FALSE;

	if ( remote )
	{
		hRemoteProcess = OpenProcess( processId );
		
		if ( hRemoteProcess == NULL )
			return FALSE;

		handle = DuplicateHandle( hRemoteProcess, h );
	}
	else
		handle = h;

	// let's be happy, handle is in our process space, so query the infos :)
	switch( type )
	{
	case OB_TYPE_PROCESS:
		GetProcessId( handle, dwId );
		
		//str.Format( "PID: 0x%X", dwId );
		str.formatstr( "PID: 0x%X", dwId );
			
		ret = TRUE;
		goto cleanup;
		break;

	case OB_TYPE_THREAD:
		GetThreadId( handle, dwId );

		str.formatstr( "TID: 0x%X" , dwId );
				
		ret = TRUE;
		goto cleanup;
		break;

	case OB_TYPE_FILE:
		ret = GetFileName( handle, str );

		// access denied :(
		if ( ret && str == "" )
			goto cleanup;
		break;

	};

	INtDll::NtQueryObject ( handle, 1, NULL, 0, &size );

	// let's try to use the default
	if ( size == 0 )
		size = 0x2000;

	lpBuffer = new UCHAR[size];

	if ( INtDll::NtQueryObject( handle, 1, lpBuffer, size, NULL ) == 0 )
	{
		SystemInfoUtils::Unicode2MyString( (UNICODE_STRING*)lpBuffer, str );
		ret = TRUE;
	}
	
cleanup:

	if ( remote )
	{
		if ( hRemoteProcess != NULL )
			CloseHandle( hRemoteProcess );

		if ( handle != NULL )
			CloseHandle( handle );
	}

	if ( lpBuffer != NULL )
		delete [] lpBuffer;
	
	return ret;
}
Exemple #2
0
EASYHOOK_NT_EXPORT RhInjectLibrary(
		ULONG InTargetPID,
		ULONG InWakeUpTID,
		ULONG InInjectionOptions,
		WCHAR* InLibraryPath_x86,
		WCHAR* InLibraryPath_x64,
		PVOID InPassThruBuffer,
        ULONG InPassThruSize)
{
/*
Description:

    Injects a library into the target process. This is a very stable operation.
    The problem so far is, that only the NET layer will support injection
    through WOW64 boundaries and into other terminal sessions. It is quite
    complex to realize with unmanaged code and that's why it is not supported!

    If you really need this feature I highly recommend to at least look at C++.NET
    because using the managed injection can speed up your development progress
    about orders of magnitudes. I know by experience that writing the required
    multi-process injection code in any unmanaged language is a rather daunting task!

Parameters:

    - InTargetPID

        The process in which the library should be injected.
    
    - InWakeUpTID

        If the target process was created suspended (RhCreateAndInject), then
        this parameter should be set to the main thread ID of the target.
        You may later resume the process from within the injected library
        by calling RhWakeUpProcess(). If the process is already running, you
        should specify zero.

    - InInjectionOptions

        All flags can be combined.

        EASYHOOK_INJECT_DEFAULT: 
            
            No special behavior. The given libraries are expected to be unmanaged DLLs.
            Further they should export an entry point named 
            "NativeInjectionEntryPoint" (in case of 64-bit) and
            "_NativeInjectionEntryPoint@4" (in case of 32-bit). The expected entry point 
            signature is REMOTE_ENTRY_POINT.

        EASYHOOK_INJECT_MANAGED: 
        
            The given user library is a NET assembly. Further they should export a class
            named "EasyHook.InjectionLoader" with a static method named "Main". The
            signature of this method is expected to be "int (String)". Please refer
            to the managed injection loader of EasyHook for more information about
            writing such managed entry points.

        EASYHOOK_INJECT_STEALTH:

            Uses the experimental stealth thread creation. If it fails
            you may try it with default settings. 

		EASYHOOK_INJECT_HEART_BEAT:
			
			Is only used internally to workaround the managed process creation bug.
			For curiosity, NET seems to hijack our remote thread if a managed process
			is created suspended. It doesn't do anything with the suspended main thread,


    - InLibraryPath_x86

        A relative or absolute path to the 32-bit version of the user library being injected.
        If you don't want to inject into 32-Bit processes, you may set this parameter to NULL.

    - InLibraryPath_x64

        A relative or absolute path to the 64-bit version of the user library being injected.
        If you don't want to inject into 64-Bit processes, you may set this parameter to NULL.

    - InPassThruBuffer

        An optional buffer containg data to be passed to the injection entry point. Such data
        is available in both, the managed and unmanaged user library entry points.
        Set to NULL if no used.

    - InPassThruSize

        Specifies the size in bytes of the pass thru data. If "InPassThruBuffer" is NULL, this
        parameter shall also be zero.

Returns:

    

*/
	HANDLE					hProc = NULL;
	HANDLE					hRemoteThread = NULL;
	HANDLE					hSignal = NULL;
	UCHAR*					RemoteInjectCode = NULL;
	LPREMOTE_INFO			Info = NULL;
    LPREMOTE_INFO           RemoteInfo = NULL;
	ULONG					RemoteInfoSize = 0;
	BYTE*					Offset = 0;
    ULONG                   CodeSize;
    BOOL                    Is64BitTarget;
    NTSTATUS				NtStatus;
    LONGLONG                Diff;
    HANDLE                  Handles[2];

    ULONG                   UserLibrarySize;
    ULONG                   PATHSize;
    ULONG                   EasyHookPathSize;
    ULONG                   EasyHookEntrySize;
    ULONG                   Code;

    SIZE_T                  BytesWritten;
    WCHAR                   UserLibrary[MAX_PATH+1];
    WCHAR					PATH[MAX_PATH + 1];
    WCHAR					EasyHookPath[MAX_PATH + 1];
#ifdef _M_X64
	CHAR*					EasyHookEntry = "HookCompleteInjection";
#else
	CHAR*					EasyHookEntry = "_HookCompleteInjection@4";
#endif

    // validate parameters
    if(InPassThruSize > MAX_PASSTHRU_SIZE)
        THROW(STATUS_INVALID_PARAMETER_7, L"The given pass thru buffer is too large.");

    if(InPassThruBuffer != NULL)
    {
        if(!IsValidPointer(InPassThruBuffer, InPassThruSize))
            THROW(STATUS_INVALID_PARAMETER_6, L"The given pass thru buffer is invalid.");
    }
    else if(InPassThruSize != 0)
        THROW(STATUS_INVALID_PARAMETER_7, L"If no pass thru buffer is specified, the pass thru length also has to be zero.");

	if(InTargetPID == GetCurrentProcessId())
		THROW(STATUS_NOT_SUPPORTED, L"For stability reasons it is not supported to inject into the calling process.");

	// open target process
	if((hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, InTargetPID)) == NULL)
	{
		if(GetLastError() == ERROR_ACCESS_DENIED)
		    THROW(STATUS_ACCESS_DENIED, L"Unable to open target process. Consider using a system service.")
		else
			THROW(STATUS_NOT_FOUND, L"The given target process does not exist!");
	}

	/*
		Check bitness...

		After this we can assume hooking a target that is running in the same
		WOW64 level.
	*/
#ifdef _M_X64
	FORCE(RhIsX64Process(InTargetPID, &Is64BitTarget));
      
    if(!Is64BitTarget)
        THROW(STATUS_WOW_ASSERTION, L"It is not supported to directly hook through the WOW64 barrier.");

    if(!GetFullPathNameW(InLibraryPath_x64, MAX_PATH, UserLibrary, NULL))
        THROW(STATUS_INVALID_PARAMETER_5, L"Unable to get full path to the given 64-bit library.");
#else
	FORCE(RhIsX64Process(InTargetPID, &Is64BitTarget));
      
    if(Is64BitTarget)
        THROW(STATUS_WOW_ASSERTION, L"It is not supported to directly hook through the WOW64 barrier.");

	if(!GetFullPathNameW(InLibraryPath_x86, MAX_PATH, UserLibrary, NULL))
        THROW(STATUS_INVALID_PARAMETER_4, L"Unable to get full path to the given 32-bit library.");
#endif

	/*
		Validate library path...
	*/
	if(!RtlFileExists(UserLibrary))
    {
    #ifdef _M_X64
        THROW(STATUS_INVALID_PARAMETER_5, L"The given 64-Bit library does not exist!");
    #else
        THROW(STATUS_INVALID_PARAMETER_4, L"The given 32-Bit library does not exist!");
    #endif
    }

	// import strings...
    RtlGetWorkingDirectory(PATH, MAX_PATH - 1);
    RtlGetCurrentModulePath(EasyHookPath, MAX_PATH);

	// allocate remote information block
    EasyHookPathSize = (RtlUnicodeLength(EasyHookPath) + 1) * 2;
    EasyHookEntrySize = (RtlAnsiLength(EasyHookEntry) + 1);
    PATHSize = (RtlUnicodeLength(PATH) + 1 + 1) * 2;
    UserLibrarySize = (RtlUnicodeLength(UserLibrary) + 1 + 1) * 2;

    PATH[PATHSize / 2 - 2] = ';';
    PATH[PATHSize / 2 - 1] = 0;

	RemoteInfoSize = EasyHookPathSize + EasyHookEntrySize + PATHSize + InPassThruSize + UserLibrarySize;

	RemoteInfoSize += sizeof(REMOTE_INFO);

	if((Info = (LPREMOTE_INFO)RtlAllocateMemory(TRUE, RemoteInfoSize)) == NULL)
		THROW(STATUS_NO_MEMORY, L"Unable to allocate memory in current process.");

	Info->LoadLibraryW = (PVOID)GetProcAddress(hKernel32, "LoadLibraryW");
	Info->FreeLibrary = (PVOID)GetProcAddress(hKernel32, "FreeLibrary");
	Info->GetProcAddress = (PVOID)GetProcAddress(hKernel32, "GetProcAddress");
	Info->VirtualFree = (PVOID)GetProcAddress(hKernel32, "VirtualFree");
	Info->VirtualProtect = (PVOID)GetProcAddress(hKernel32, "VirtualProtect");
	Info->ExitThread = (PVOID)GetProcAddress(hKernel32, "ExitThread");
	Info->GetLastError = (PVOID)GetProcAddress(hKernel32, "GetLastError");

    Info->WakeUpThreadID = InWakeUpTID;
    Info->IsManaged = InInjectionOptions & EASYHOOK_INJECT_MANAGED;

	// allocate memory in target process
	CodeSize = GetInjectionSize();

	if((RemoteInjectCode = (BYTE*)VirtualAllocEx(hProc, NULL, CodeSize + RemoteInfoSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) == NULL)
        THROW(STATUS_NO_MEMORY, L"Unable to allocate memory in target process.");

	// save strings
	Offset = (BYTE*)(Info + 1);

	Info->EasyHookEntry = (char*)Offset;
	Info->EasyHookPath = (wchar_t*)(Offset += EasyHookEntrySize);
	Info->PATH = (wchar_t*)(Offset += EasyHookPathSize);
	Info->UserData = (BYTE*)(Offset += PATHSize);
    Info->UserLibrary = (WCHAR*)(Offset += InPassThruSize);

	Info->Size = RemoteInfoSize;
	Info->HostProcess = GetCurrentProcessId();
	Info->UserDataSize = 0;

	Offset += UserLibrarySize;

	if((ULONG)(Offset - ((BYTE*)Info)) > Info->Size)
        THROW(STATUS_BUFFER_OVERFLOW, L"A buffer overflow in internal memory was detected.");

	RtlCopyMemory(Info->EasyHookPath, EasyHookPath, EasyHookPathSize);
	RtlCopyMemory(Info->PATH, PATH, PATHSize);
	RtlCopyMemory(Info->EasyHookEntry, EasyHookEntry, EasyHookEntrySize);
    RtlCopyMemory(Info->UserLibrary, UserLibrary, UserLibrarySize);


	if(InPassThruBuffer != NULL)
	{
		RtlCopyMemory(Info->UserData, InPassThruBuffer, InPassThruSize);

		Info->UserDataSize = InPassThruSize;
	}

	// copy code into target process
	if(!WriteProcessMemory(hProc, RemoteInjectCode, GetInjectionPtr(), CodeSize, &BytesWritten) || (BytesWritten != CodeSize))
		THROW(STATUS_INTERNAL_ERROR, L"Unable to write into target process memory.");

	// create and export signal event>
	if((hSignal = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL)
        THROW(STATUS_INSUFFICIENT_RESOURCES, L"Unable to create event.");

	// Possible resource leck: the remote handles cannt be closed here if an error occurs
	if(!DuplicateHandle(GetCurrentProcess(), hSignal, hProc, &Info->hRemoteSignal, EVENT_ALL_ACCESS, FALSE, 0))
		THROW(STATUS_INTERNAL_ERROR, L"Failed to duplicate remote event.");

	// relocate remote information
	RemoteInfo = (LPREMOTE_INFO)(RemoteInjectCode + CodeSize);
	Diff = ((BYTE*)RemoteInfo - (BYTE*)Info);

	Info->EasyHookEntry = (char*)(((BYTE*)Info->EasyHookEntry) + Diff);
	Info->EasyHookPath = (wchar_t*)(((BYTE*)Info->EasyHookPath) + Diff);
	Info->PATH = (wchar_t*)(((BYTE*)Info->PATH) + Diff);
    Info->UserLibrary = (wchar_t*)(((BYTE*)Info->UserLibrary) + Diff);

	if(Info->UserData != NULL)
		Info->UserData = (BYTE*)(((BYTE*)Info->UserData) + Diff);

	Info->RemoteEntryPoint = RemoteInjectCode;

	if(!WriteProcessMemory(hProc, RemoteInfo, Info, RemoteInfoSize, &BytesWritten) || (BytesWritten != RemoteInfoSize))
		THROW(STATUS_INTERNAL_ERROR, L"Unable to write into target process memory.");

	if((InInjectionOptions & EASYHOOK_INJECT_STEALTH) != 0)
	{
		FORCE(RhCreateStealthRemoteThread(InTargetPID, (LPTHREAD_START_ROUTINE)RemoteInjectCode, RemoteInfo, &hRemoteThread));
	}
	else
	{
		if(!RTL_SUCCESS(NtCreateThreadEx(hProc, (LPTHREAD_START_ROUTINE)RemoteInjectCode, RemoteInfo, FALSE, &hRemoteThread)))
		{
			// create remote thread and wait for injection completion
			if((hRemoteThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)RemoteInjectCode, RemoteInfo, 0, NULL)) == NULL)
				THROW(STATUS_ACCESS_DENIED, L"Unable to create remote thread.");
		}
	}

	/*
	 * The assembler codes are designed to let us derive extensive error information...
	*/
    Handles[1] = hSignal;
	Handles[0] = hRemoteThread;

	Code = WaitForMultipleObjects(2, Handles, FALSE, INFINITE);

	if(Code == WAIT_OBJECT_0)
	{
		// parse error code
		GetExitCodeThread(hRemoteThread, &Code);

		SetLastError(Code & 0x0FFFFFFF);

		switch(Code & 0xF0000000)
		{
		case 0x10000000: THROW(STATUS_INTERNAL_ERROR, L"Unable to find internal entry point.");
		case 0x20000000: THROW(STATUS_INTERNAL_ERROR, L"Unable to make stack executable.");
		case 0x30000000: THROW(STATUS_INTERNAL_ERROR, L"Unable to release injected library.");
		case 0x40000000: THROW(STATUS_INTERNAL_ERROR, L"Unable to find EasyHook library in target process context.");
		case 0xF0000000: // error in C++ injection completion
			{
				switch(Code & 0xFF)
				{
#ifdef _M_X64
                case 20: THROW(STATUS_INVALID_PARAMETER_5, L"Unable to load the given 64-bit library into target process.");
                case 21: THROW(STATUS_INVALID_PARAMETER_5, L"Unable to find the required native entry point in the given 64-bit library.");
                case 12: THROW(STATUS_INVALID_PARAMETER_5, L"Unable to find the required managed entry point in the given 64-bit library.");
#else
                case 20: THROW(STATUS_INVALID_PARAMETER_4, L"Unable to load the given 32-bit library into target process.");
                case 21: THROW(STATUS_INVALID_PARAMETER_4, L"Unable to find the required native entry point in the given 32-bit library.");
                case 12: THROW(STATUS_INVALID_PARAMETER_4, L"Unable to find the required managed entry point in the given 32-bit library.");
#endif
                
                case 13: THROW(STATUS_DLL_INIT_FAILED, L"The user defined managed entry point failed in the target process. Make sure that EasyHook is registered in the GAC. Refer to event logs for more information.");
				case 1: THROW(STATUS_INTERNAL_ERROR, L"Unable to allocate memory in target process.");
				case 2: THROW(STATUS_INTERNAL_ERROR, L"Unable to adjust target's PATH variable.");
                case 10: THROW(STATUS_INTERNAL_ERROR, L"Unable to load 'mscoree.dll' into target process.");
				case 11: THROW(STATUS_INTERNAL_ERROR, L"Unable to bind NET Runtime to target process.");
				case 22: THROW(STATUS_INTERNAL_ERROR, L"Unable to signal remote event.");
				default: THROW(STATUS_INTERNAL_ERROR, L"Unknown error in injected C++ completion routine.");
				}
			}break;
		case 0:
			THROW(STATUS_INTERNAL_ERROR, L"C++ completion routine has returned success but didn't raise the remote event.");
		default:
			THROW(STATUS_INTERNAL_ERROR, L"Unknown error in injected assembler code.");
		}
	}
	else if(Code != WAIT_OBJECT_0 + 1)
		THROW(STATUS_INTERNAL_ERROR, L"Unable to wait for injection completion due to timeout. ");

    RETURN;

THROW_OUTRO:
FINALLY_OUTRO:
    {
		// release resources
		if(hProc != NULL)
			CloseHandle(hProc);

		if(Info != NULL)
			RtlFreeMemory(Info);

		if(hRemoteThread != NULL)
			CloseHandle(hRemoteThread);

		if(hSignal != NULL)
			CloseHandle(hSignal);

        return NtStatus;
	}
}
//  Called from MyApp() immediately upon entry to MyApp::OnInit()
void OCPNPlatform::Initialize_1( void )
{
    
#ifdef OCPN_USE_CRASHRPT
#ifndef _DEBUG
    // Install Windows crash reporting
    
    CR_INSTALL_INFO info;
    memset(&info, 0, sizeof(CR_INSTALL_INFO));
    info.cb = sizeof(CR_INSTALL_INFO);
    info.pszAppName = _T("OpenCPN");
    
    wxString version_crash = str_version_major + _T(".") + str_version_minor + _T(".") + str_version_patch;
    info.pszAppVersion = version_crash.c_str();
    
    int type = MiniDumpWithDataSegs;  // Include the data sections from all loaded modules.
    // This results in the inclusion of global variables
    
    type |=  MiniDumpNormal;// | MiniDumpWithPrivateReadWriteMemory | MiniDumpWithIndirectlyReferencedMemory;
    info.uMiniDumpType = (MINIDUMP_TYPE)type;
    
    // Install all available exception handlers....
    info.dwFlags = CR_INST_ALL_POSSIBLE_HANDLERS;
    
    //  Except memory allocation failures
    info.dwFlags &= ~CR_INST_NEW_OPERATOR_ERROR_HANDLER;
    
    //  Allow user to attach files
    info.dwFlags |= CR_INST_ALLOW_ATTACH_MORE_FILES;
    
    //  Allow user to add more info
    info.dwFlags |= CR_INST_SHOW_ADDITIONAL_INFO_FIELDS;
    
    
    // URL for sending error reports over HTTP.
    if(g_bEmailCrashReport){
        info.pszEmailTo = _T("*****@*****.**");
        info.pszSmtpProxy = _T("mail.bigdumboat.com:587");
        info.pszUrl = _T("http://bigdumboat.com/crashrpt/ocpn_crashrpt.php");
        info.uPriorities[CR_HTTP] = 1;  // First try send report over HTTP
    }
    else{
        info.dwFlags |= CR_INST_DONT_SEND_REPORT;
        info.uPriorities[CR_HTTP] = CR_NEGATIVE_PRIORITY;       // don't send at all
    }
    
    info.uPriorities[CR_SMTP] = CR_NEGATIVE_PRIORITY;  // Second try send report over SMTP
    info.uPriorities[CR_SMAPI] = CR_NEGATIVE_PRIORITY; //1; // Third try send report over Simple MAPI
    
    wxStandardPaths& crash_std_path = g_Platform->GetStdPaths();
    
    wxString crash_rpt_save_locn = crash_std_path.GetConfigDir();
    if( g_bportable ) {
        wxFileName exec_path_crash( crash_std_path.GetExecutablePath() );
        crash_rpt_save_locn = exec_path_crash.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR );
    }
    
    wxString locn = crash_rpt_save_locn + _T("\\CrashReports");
    
    if(!wxDirExists( locn ) )
        wxMkdir( locn );
    
    if(wxDirExists( locn ) ){
        wxCharBuffer buf = locn.ToUTF8();
        wchar_t wlocn[256];
        if(buf && (locn.Length() < sizeof(wlocn)) ){
            MultiByteToWideChar( 0, 0, buf.data(), -1, wlocn, sizeof(wlocn)-1);
            info.pszErrorReportSaveDir = (LPCWSTR)wlocn;
        }
    }
    
    // Provide privacy policy URL
    wxFileName exec_path_crash( crash_std_path.GetExecutablePath() );
    wxString policy_file =  exec_path_crash.GetPath( wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR );
    policy_file += _T("PrivacyPolicy.txt");
    policy_file.Prepend(_T("file:"));
    
    info.pszPrivacyPolicyURL = policy_file.c_str();;
    
    int nResult = crInstall(&info);
    if(nResult!=0) {
        TCHAR buff[256];
        crGetLastErrorMsg(buff, 256);
        MessageBox(NULL, buff, _T("crInstall error, Crash Reporting disabled."), MB_OK);
    }
    
    // Establish the crash callback function
    crSetCrashCallback( CrashCallback, NULL );
    
    // Take screenshot of the app window at the moment of crash
    crAddScreenshot2(CR_AS_PROCESS_WINDOWS|CR_AS_USE_JPEG_FORMAT, 95);
    
    //  Mark some files to add to the crash report
    wxString home_data_crash = crash_std_path.GetConfigDir();
    if( g_bportable ) {
        wxFileName f( crash_std_path.GetExecutablePath() );
        home_data_crash = f.GetPath();
    }
    appendOSDirSlash( &home_data_crash );
    
    wxString config_crash = _T("opencpn.ini");
    config_crash.Prepend( home_data_crash );
    crAddFile2( config_crash.c_str(), NULL, NULL, CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE );
    
    wxString log_crash = _T("opencpn.log");
    log_crash.Prepend( home_data_crash );
    crAddFile2( log_crash.c_str(), NULL, NULL, CR_AF_MISSING_FILE_OK | CR_AF_ALLOW_DELETE );
    
#endif
#endif

    
#ifdef LINUX_CRASHRPT
#if wxUSE_ON_FATAL_EXCEPTION
    // fatal exceptions handling
    wxHandleFatalExceptions (true);
#endif
#endif

#ifdef __WXMSW__
    //  Invoke my own handler for failures of malloc/new
    _set_new_handler( MyNewHandler );
    //  configure malloc to call the New failure handler on failure
    _set_new_mode(1);
#endif    
    
    //    On MSW, force the entire process to run on one CPU core only
    //    This resolves some difficulty with wxThread syncronization
#if 0
#ifdef __WXMSW__
    //Gets the current process handle
    HANDLE hProc = GetCurrentProcess();
    DWORD procMask;
    DWORD sysMask;
    HANDLE hDup;
    DuplicateHandle( hProc, hProc, hProc, &hDup, 0, FALSE, DUPLICATE_SAME_ACCESS );
    
    //Gets the current process affinity mask
    GetProcessAffinityMask( hDup, &procMask, &sysMask );
    
    // Take a simple approach, and assume up to 4 processors
    DWORD newMask;
    if( ( procMask & 1 ) == 1 ) newMask = 1;
    else
        if( ( procMask & 2 ) == 2 ) newMask = 2;
        else
            if( ( procMask & 4 ) == 4 ) newMask = 4;
            else
                if( ( procMask & 8 ) == 8 ) newMask = 8;
                
                //Set te affinity mask for the process
                BOOL res = SetProcessAffinityMask( hDup, (DWORD_PTR) newMask );
            
            if( res == 0 ) {
                //Error setting affinity mask!!
            }
#endif
#endif
            
#ifdef __WXMSW__
            
            //    Handle any Floating Point Exceptions which may leak thru from other
            //    processes.  The exception filter is in cutil.c
            //    Seems to only happen for W98
            
            wxPlatformInfo Platform;
            if( Platform.GetOperatingSystemId() == wxOS_WINDOWS_9X ) SetUnhandledExceptionFilter (&MyUnhandledExceptionFilter);
#endif
            
#ifdef __WXMSW__
            //     _CrtSetBreakAlloc(25503);
#endif
            

#ifndef __WXMSW__
            //      Setup Linux SIGNAL handling, for external program control
            
            //      Build the sigaction structure
            sa_all.sa_handler = catch_signals;// point to my handler
            sigemptyset(&sa_all.sa_mask);// make the blocking set
            // empty, so that all
            // other signals will be
            // unblocked during my handler
            sa_all.sa_flags = 0;
            
            sigaction(SIGUSR1, NULL, &sa_all_old);// save existing action for this signal
            
            //      Register my request for some signals
            sigaction(SIGUSR1, &sa_all, NULL);
            
            sigaction(SIGUSR1, NULL, &sa_all_old);// inspect existing action for this signal
            
            sigaction(SIGTERM, &sa_all, NULL);
            sigaction(SIGTERM, NULL, &sa_all_old);
#endif
            
}
int __cdecl _dup2 (
        int fh1,
        int fh2
        )
{
        ULONG dosretval;                /* o.s. return code */
        long new_osfhandle;

        /* validate file handles */
        if ( ((unsigned)fh1 >= (unsigned)_nhandle) ||
             !(_osfile(fh1) & FOPEN) ||
             ((unsigned)fh2 >= _NHANDLE_) )
        {
                /* handle out of range */
                errno = EBADF;
                _doserrno = 0;  /* not an OS error */
                return -1;
        }

        /*
         * Make sure there is an ioinfo struct corresponding to fh2.
         */
        if ( (fh2 >= _nhandle) && (extend_ioinfo_arrays(fh2) != 0) ) {
                errno = ENOMEM;
                return -1;
        }


#ifdef _MT
        /* get the two file handle locks; in order to prevent deadlock,
           get the lowest handle lock first. */
        if ( fh1 < fh2 ) {
                _lock_fh(fh1);
                _lock_fh(fh2);
        }
        else if ( fh1 > fh2 ) {
                _lock_fh(fh2);
                _lock_fh(fh1);
        }

        /*
         * Re-test and take care of case of unopened source handle. This is
         * necessary only in the multi-thread case where the file have been
         * closed by another thread before the lock was asserted, but after
         * the initial test above.
         */
        if ( !(_osfile(fh1) & FOPEN) ) {
                /*
                 * Source handle isn't open, release locks and bail out with
                 * an error. Note that the DuplicateHandle API will not
                 * detect this error since it implies that _osfhnd(fh1) ==
                 * INVALID_HANDLE_VALUE, and this is a legal HANDLE value
                 * (it's the HANDLE for the current process).
                 */
                _unlock_fh(fh1);
                _unlock_fh(fh2);
                errno = EBADF;
                _doserrno = 0;  /* not an OS error */
                return -1;
        }
#endif  /* _MT */

        /*
         * Take of the case of equal handles.
         */
        if ( fh1 == fh2 ) {
                /*
                 * Since fh1 is known to be open, return 0 indicating success.
                 * This is in conformance with the POSIX specification for
                 * dup2.
                 */
                _unlock_fh(fh1);
                _unlock_fh(fh2);
                return 0;
        }

        /*
         * if fh2 is open, close it.
         */
        if ( _osfile(fh2) & FOPEN )
                /*
                 * close the handle. ignore the possibility of an error - an
                 * error simply means that an OS handle value may remain bound
                 * for the duration of the process.  Use _close_lk as we
                 * already own lock
                 */
                (void) _close_lk(fh2);


        /* Duplicate source file onto target file */

        if ( !(DuplicateHandle(GetCurrentProcess(),
                               (HANDLE)_get_osfhandle(fh1),
                               GetCurrentProcess(),
                               (PHANDLE)&new_osfhandle,
                               0L,
                               TRUE,
                               DUPLICATE_SAME_ACCESS)) )
        {

                dosretval = GetLastError();
        }
        else {
                _set_osfhnd(fh2, new_osfhandle);
                dosretval = 0;
        }

        if (dosretval) {
                _dosmaperr(dosretval);
                _unlock_fh(fh1);
                _unlock_fh(fh2);
                return -1;
        }

        /* copy the _osfile information, with the FNOINHERIT bit cleared */
        _osfile(fh2) = _osfile(fh1) & ~FNOINHERIT;

        /* unlock file handles */
        _unlock_fh(fh1);
        _unlock_fh(fh2);

        return 0;
}
Exemple #5
0
void WCMD_batch (WCHAR *file, WCHAR *command, int called, WCHAR *startLabel, HANDLE pgmHandle) {

  HANDLE h = INVALID_HANDLE_VALUE;
  BATCH_CONTEXT *prev_context;

  if (startLabel == NULL) {
    h = CreateFileW (file, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
                     NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (h == INVALID_HANDLE_VALUE) {
      SetLastError (ERROR_FILE_NOT_FOUND);
      WCMD_print_error ();
      return;
    }
  } else {
    DuplicateHandle(GetCurrentProcess(), pgmHandle,
                    GetCurrentProcess(), &h,
                    0, FALSE, DUPLICATE_SAME_ACCESS);
  }

/*
 *	Create a context structure for this batch file.
 */

  prev_context = context;
  context = LocalAlloc (LMEM_FIXED, sizeof (BATCH_CONTEXT));
  context -> h = h;
  context->batchfileW = WCMD_strdupW(file);
  context -> command = command;
  memset(context -> shift_count, 0x00, sizeof(context -> shift_count));
  context -> prev_context = prev_context;
  context -> skip_rest = FALSE;

  /* If processing a call :label, 'goto' the label in question */
  if (startLabel) {
    strcpyW(param1, startLabel);
    WCMD_goto(NULL);
  }

/*
 * 	Work through the file line by line. Specific batch commands are processed here,
 * 	the rest are handled by the main command processor.
 */

  while (context -> skip_rest == FALSE) {
      CMD_LIST *toExecute = NULL;         /* Commands left to be executed */
      if (WCMD_ReadAndParseLine(NULL, &toExecute, h) == NULL)
        break;
      WCMD_process_commands(toExecute, FALSE, NULL, NULL);
      WCMD_free_commands(toExecute);
      toExecute = NULL;
  }
  CloseHandle (h);

/*
 *	If invoked by a CALL, we return to the context of our caller. Otherwise return
 *	to the caller's caller.
 */

  HeapFree(GetProcessHeap(), 0, context->batchfileW);
  LocalFree (context);
  if ((prev_context != NULL) && (!called)) {
    prev_context -> skip_rest = TRUE;
    context = prev_context;
  }
  context = prev_context;
}
void FastTrackGiftDll::CheckPerformanceCounters()
{
	UINT i;

    // Collect the pdh query data
	if(PdhCollectQueryData(m_pdh))
	{
//		MessageBox(NULL,"Error collecting pdh query data","Error",MB_OK);
//		MessageBox(NULL,m_keynames[1].c_str(),"On this network adaptor",MB_OK);
		//return;
	}

	// Check the processor usage counter
	PDH_FMT_COUNTERVALUE value;
    PDH_STATUS error;

	error=PdhGetFormattedCounterValue(m_pdh_counters[0],PDH_FMT_LONG,0,&value);
	if(error)
	{
//		MessageBox(NULL,"Error formatting pdh counter data","Error",MB_OK);
//		MessageBox(NULL,m_keynames[1].c_str(),"On this network adaptor",MB_OK);
//		m_dlg.SetWindowText("Error formatting pdh coutner data");
		return;
	}

	m_proc_percent_usage=value.longValue;

	// If less than 90 % kick off another mod if there is less than min count of them
	if(/*(m_proc_percent_usage<90) & */(m_connection_manager.ReturnModCount()<(UINT)m_min_module_count))
	{
		m_connection_manager.AddModule();

		char log[1024];
		sprintf(log,"Module Added : (Current Count : %u) : (Proc % Usage : %u%%) : (Min Mod Count : %u)",
			m_connection_manager.ReturnModCount(),m_proc_percent_usage,m_min_module_count);
		m_dlg.Log(log);
	}
		

	// Check the bandwidth counter
	error=PdhGetFormattedCounterValue(m_pdh_counters[1],PDH_FMT_LONG,0,&value);
	if(error)
	{
//		MessageBox(NULL,"Error formatting bandwidth counter data","Error",MB_OK);
//		MessageBox(NULL,m_keynames[1].c_str(),"On this network adaptor",MB_OK);
//		m_dlg.SetWindowText("Error formatting pdh coutner data");
		return;
	}

	m_bandwidth_in_bytes=value.longValue;

	// Check the current bandwidth in bits per second
	error=PdhGetFormattedCounterValue(m_pdh_counters[2],PDH_FMT_LONG,0,&value);
	if(error)
	{
//		MessageBox(NULL,"Error formatting bandwidth in bits per second data","Error",MB_OK);
//		MessageBox(NULL,m_keynames[1].c_str(),"On this network adaptor",MB_OK);
		return;
	}

	m_current_bandwdith_in_bits_per_second=value.longValue;	// this should be 100 Mbps
	
	double bps=m_bandwidth_in_bytes*8;

	// Measure the processes mem usage
	HANDLE hHandle;
	DuplicateHandle(GetCurrentProcess(),GetCurrentProcess(),GetCurrentProcess(),&hHandle,0,FALSE,DUPLICATE_SAME_ACCESS);
	
	PROCESS_MEMORY_COUNTERS pmc;
	pmc.cb=sizeof(PROCESS_MEMORY_COUNTERS);
	GetProcessMemoryInfo(hHandle,&pmc,sizeof(PROCESS_MEMORY_COUNTERS));

	CloseHandle(hHandle);

	m_mem_usage=(UINT)pmc.WorkingSetSize;	// in bytes

	// Put commas in the mem measurement value
	char mem_buf[1024];
	string mem;
	_itoa(m_mem_usage/1024,mem_buf,10);
	strrev(mem_buf);
	for(i=0;i<strlen(mem_buf);i++)
	{
		if((i>0) && (i%3==0))
		{
			mem+=",";
		}
		
		mem+=mem_buf[i];
	}
	strcpy(mem_buf,mem.c_str());
	strrev(mem_buf);
	
	// Display the status
	char buf[1024];
	sprintf(buf,"[ %u %% ] - [ %.2f KB/sec - %.2f %% ] - [ %s KB ]",m_proc_percent_usage,((double)m_bandwidth_in_bytes)/1024,
		(100*bps)/m_current_bandwdith_in_bits_per_second,mem_buf);
	m_dlg.GetDlgItem(IDC_Computer_Status_Static)->SetWindowText(buf);

	
	//Get DB queues sizes
	UINT qh_size;
	m_db_manager.ReportDBStatus(qh_size);
	sprintf(buf, "%u", qh_size);
	m_dlg.GetDlgItem(IDC_QH_SIZE_STATIC)->SetWindowText(buf);

	//if less than m_auto_resume_threshold cpu, resuming searching, if more than m_auto_pause_threshold cpu, pause searching
	if((m_proc_percent_usage <= m_auto_resume_threshold) && (qh_size < 10000))
	{
		m_dlg.AutoPause(false);
		m_supply_manager.AutoPauseSearching(false);
	}
	else if((m_proc_percent_usage >= m_auto_pause_threshold) || (qh_size >= 10000) )
	{
		m_dlg.AutoPause(true);
		m_supply_manager.AutoPauseSearching(true);
	}
}
Exemple #7
0
int CLAMAPI Scan_ScanObjectByHandle(CClamAVScanner *pScanner, HANDLE object, int *pScanStatus, PCLAM_SCAN_INFO_LIST *pInfoList) {
    instance *inst;
    HANDLE duphdl, self;
    char *virname = NULL;
    int fd, res;
    unsigned int i;
    struct scan_ctx sctx;
    DWORD perf;

    logg("*in Scan_ScanObjectByHandle(pScanner = %p, HANDLE = %p, pScanStatus = %p, pInfoList = %p)\n", pScanner, object, pScanStatus, pInfoList);

    if(!pScanner)
	FAIL(CL_ENULLARG, "NULL pScanner");
    if(!pScanStatus)
	FAIL(CL_ENULLARG, "NULL pScanStatus on instance %p", pScanner);

    self = GetCurrentProcess();
    if(!DuplicateHandle(self, object, self, &duphdl, GENERIC_READ, FALSE, 0))
	FAIL(CL_EDUP, "Duplicate handle failed for instance %p", pScanner);

    if((fd = _open_osfhandle((intptr_t)duphdl, _O_RDONLY)) == -1) {
	CloseHandle(duphdl);
	FAIL(CL_EOPEN, "Open handle failed for instance %p", pScanner);
    }

    if(lock_instances()) {
	close(fd);
	FAIL(CL_ELOCK, "failed to lock instances for instance %p", pScanner);
    }
    inst = (instance *)pScanner;
    for(i=0; i<ninsts_total; i++) {
	if(instances[i].inst == inst)
	    break;
    }
    if(i == ninsts_total) {
	unlock_instances();
	close(fd);
	FAIL(CL_EARG, "invalid instance %p", inst);
    }
    instances[i].refcnt++;
    ResetEvent(reload_event);
    unlock_instances();

    sctx.entryfd = fd;
    sctx.inst = inst;
    sctx.cb_times = 0;
    sctx.copy_times = 0;
    logg("*Scan_ScanObjectByHandle (instance %p) invoking cl_scandesc with clamav context %p\n", inst, &sctx);
    perf = GetTickCount();
    res = cl_scandesc_callback(fd, &virname, NULL, engine, inst->scanopts, &sctx);

    if(!inst->filetype) do {
	CLAM_SCAN_INFO si;
	CLAM_ACTION act;
	DWORD cbperf;
	wchar_t wvirname[MAX_VIRNAME_LEN] = L"Clam.";
	LONG lo = 0, hi = 0, hi2 = 0;

	si.cbSize = sizeof(si);
	si.flags = 0;
	si.scanPhase = SCAN_PHASE_FINAL;
	si.errorCode = CLAMAPI_SUCCESS;
	if(res == CL_VIRUS) {
	    if(MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, virname, -1, &wvirname[5], MAX_VIRNAME_LEN - 5))
		si.pThreatName = wvirname;
	    else
		si.pThreatName = L"Clam.UNOFFICIAL";
	} else
	    si.pThreatName = NULL;
	logg("*in final_cb with clamav context %p, instance %p, fd %d, result %d, virusname %S)\n", &sctx, inst, fd, res, si.pThreatName);
	si.pThreatType = threat_type(virname);
	si.object = INVALID_HANDLE_VALUE;
	si.objectId = INVALID_HANDLE_VALUE;
	si.pInnerObjectPath = NULL;
	lo = SetFilePointer(duphdl, 0, &hi, FILE_CURRENT);
	SetFilePointer(duphdl, 0, &hi2, FILE_BEGIN);
	logg("*final_cb (clamav context %p, instance %p) invoking callback %p with context %p\n", &sctx, inst, inst->scancb, inst->scancb_ctx);
	cbperf = GetTickCount();
	inst->scancb(&si, &act, inst->scancb_ctx);
	cbperf = GetTickCount() - cbperf;
	sctx.cb_times += cbperf;
	logg("*final_cb (clamav context %p, instance %p) callback completed with %u (result ignored) in %u ms\n", &sctx, inst, act, cbperf);
	SetFilePointer(duphdl, lo, &hi, FILE_BEGIN);
    } while(0);

    perf = GetTickCount() - perf;
    close(fd);
    logg("*Scan_ScanObjectByHandle (instance %p): cl_scandesc returned %d in %u ms (%d ms own, %d ms copy)\n", inst, res, perf, perf - sctx.cb_times - sctx.copy_times, sctx.copy_times);

    if(lock_instances())
	FAIL(CL_ELOCK, "failed to lock instances for instance %p", pScanner);
    instances[i].refcnt--;
    if(!instances[i].refcnt)
	SetEvent(reload_event);
    unlock_instances();

    if(res == CL_VIRUS) {
	logg("Scan_ScanObjectByHandle (instance %p): file is INFECTED with %s\n", inst, virname);
	if(pInfoList) {
	    CLAM_SCAN_INFO_LIST *infolist = (CLAM_SCAN_INFO_LIST *)calloc(1, sizeof(CLAM_SCAN_INFO_LIST) + sizeof(CLAM_SCAN_INFO) + MAX_VIRNAME_LEN * 2);
	    PCLAM_SCAN_INFO scaninfo;
	    wchar_t *wvirname;
	    if(!infolist)
		FAIL(CL_EMEM, "ScanByHandle (instance %p): OOM while allocating result list", inst);
	    scaninfo = (PCLAM_SCAN_INFO)(infolist + 1);
	    infolist->cbCount = 1;
	    scaninfo->cbSize = sizeof(*scaninfo);
	    scaninfo->scanPhase = SCAN_PHASE_FINAL;
	    scaninfo->errorCode = CLAMAPI_SUCCESS;
	    scaninfo->pThreatType = threat_type(virname);
	    scaninfo->object = INVALID_HANDLE_VALUE;
	    scaninfo->objectId = INVALID_HANDLE_VALUE;
	    wvirname = (wchar_t *)(scaninfo + 1);
	    scaninfo->pThreatName = wvirname;
	    memcpy(wvirname, L"Clam.", 10);
	    if(!MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, virname, -1, &wvirname[5], MAX_VIRNAME_LEN-5))
		scaninfo->pThreatName = L"Clam.UNOFFICIAL";
	    *pInfoList = infolist;
	    logg("*Scan_ScanObjectByHandle (instance %p): created result list %p\n", inst, infolist);
	}
	*pScanStatus = CLAM_INFECTED;
    } else if(res == CL_CLEAN) {
	logg("*Scan_ScanObjectByHandle (instance %p): file is CLEAN\n", inst);
        if(pInfoList) *pInfoList = NULL;
	*pScanStatus = CLAM_CLEAN;
    } else {
	FAIL(res, "Scan failed for instance %p: %s", inst, cl_strerror(res));
    }
    WIN();
}
Exemple #8
0
bool Q3Process::start( QStringList *env )
{
#if defined(QT_Q3PROCESS_DEBUG)
    qDebug( "Q3Process::start()" );
#endif
    reset();

    if ( _arguments.isEmpty() )
	return false;

    // Open the pipes.  Make non-inheritable copies of input write and output
    // read handles to avoid non-closable handles (this is done by the
    // DuplicateHandle() call).
    SECURITY_ATTRIBUTES secAtt = { sizeof( SECURITY_ATTRIBUTES ), NULL, TRUE };
#ifndef Q_OS_WINCE
    // I guess there is no stdin stdout and stderr on Q_OS_WINCE to dup
    // CreatePipe and DupilcateHandle aren't available for Q_OS_WINCE
    HANDLE tmpStdin, tmpStdout, tmpStderr;
    if ( comms & Stdin ) {
	if ( !CreatePipe( &d->pipeStdin[0], &tmpStdin, &secAtt, 0 ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !DuplicateHandle( GetCurrentProcess(), tmpStdin, GetCurrentProcess(), &d->pipeStdin[1], 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !CloseHandle( tmpStdin ) ) {
	    d->closeHandles();
	    return false;
	}
    }
    if ( comms & Stdout ) {
	if ( !CreatePipe( &tmpStdout, &d->pipeStdout[1], &secAtt, 0 ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !DuplicateHandle( GetCurrentProcess(), tmpStdout, GetCurrentProcess(), &d->pipeStdout[0], 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !CloseHandle( tmpStdout ) ) {
	    d->closeHandles();
	    return false;
	}
    }
    if ( comms & Stderr ) {
	if ( !CreatePipe( &tmpStderr, &d->pipeStderr[1], &secAtt, 0 ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !DuplicateHandle( GetCurrentProcess(), tmpStderr, GetCurrentProcess(), &d->pipeStderr[0], 0, FALSE, DUPLICATE_SAME_ACCESS ) ) {
	    d->closeHandles();
	    return false;
	}
	if ( !CloseHandle( tmpStderr ) ) {
	    d->closeHandles();
	    return false;
	}
    }
    if ( comms & DupStderr ) {
	CloseHandle( d->pipeStderr[1] );
	d->pipeStderr[1] = d->pipeStdout[1];
    }
#endif

    // construct the arguments for CreateProcess()
    QString args;
    QString appName;
    QStringList::Iterator it = _arguments.begin();
    args = *it;
    ++it;
    if ( args.endsWith( QLatin1String(".bat") ) && args.contains( QLatin1Char(' ') ) ) {
	// CreateProcess() seems to have a strange semantics (see also
	// http://www.experts-exchange.com/Programming/Programming_Platforms/Win_Prog/Q_11138647.html):
	// If you start a batch file with spaces in the filename, the first
	// argument to CreateProcess() must be the name of the batchfile
	// without quotes, but the second argument must start with the same
	// argument with quotes included. But if the same approach is used for
	// .exe files, it doesn't work.
	appName = args;
	args = QLatin1Char('"') + args + QLatin1Char('"');
    }
    for ( ; it != _arguments.end(); ++it ) {
	QString tmp = *it;
	// escape a single " because the arguments will be parsed
	tmp.replace( QLatin1Char('\"'), QLatin1String("\\\"") );
	if ( tmp.isEmpty() || tmp.contains( QLatin1Char(' ') ) || tmp.contains( QLatin1Char('\t') ) ) {
	    // The argument must not end with a \ since this would be interpreted
	    // as escaping the quote -- rather put the \ behind the quote: e.g.
	    // rather use "foo"\ than "foo\"
	    QString endQuote( QLatin1String("\"") );
	    int i = tmp.length();
	    while ( i>0 && tmp.at( i-1 ) == QLatin1Char('\\') ) {
		--i;
		endQuote += QLatin1Char('\\');
	    }
        args += QLatin1String(" \"") + tmp.left( i ) + endQuote;
	} else {
	    args += QLatin1Char(' ') + tmp;
	}
    }
#if defined(QT_Q3PROCESS_DEBUG)
    qDebug( "Q3Process::start(): args [%s]", args.latin1() );
#endif

    // CreateProcess()
    bool success;
    d->newPid();

    STARTUPINFOW startupInfo = {
        sizeof( STARTUPINFO ), 0, 0, 0,
        (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT, (ulong)CW_USEDEFAULT,
        0, 0, 0,
        STARTF_USESTDHANDLES,
        0, 0, 0,
        d->pipeStdin[0], d->pipeStdout[1], d->pipeStderr[1]
    };
    wchar_t *applicationName;
    if ( appName.isNull() )
        applicationName = 0;
    else
        applicationName = _wcsdup( (wchar_t*)appName.utf16() );
    wchar_t *commandLine = _wcsdup( (wchar_t*)args.utf16() );
    QByteArray envlist;
    if ( env != 0 ) {
        int pos = 0;
        // add PATH if necessary (for DLL loading)
        QByteArray path = qgetenv( "PATH" );
        if ( env->grep( QRegExp(QLatin1String("^PATH="),FALSE) ).empty() && !path.isNull() ) {
            QString tmp = QString::fromLatin1("PATH=%1").arg(QLatin1String(path.constData()));
            uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1);
            envlist.resize( envlist.size() + tmpSize );
            memcpy( envlist.data() + pos, tmp.utf16(), tmpSize );
            pos += tmpSize;
        }
        // add the user environment
        for ( QStringList::Iterator it = env->begin(); it != env->end(); it++ ) {
            QString tmp = *it;
            uint tmpSize = sizeof(wchar_t) * (tmp.length() + 1);
            envlist.resize( envlist.size() + tmpSize );
            memcpy( envlist.data() + pos, tmp.utf16(), tmpSize );
            pos += tmpSize;
        }
        // add the 2 terminating 0 (actually 4, just to be on the safe side)
        envlist.resize( envlist.size()+4 );
        envlist[pos++] = 0;
        envlist[pos++] = 0;
        envlist[pos++] = 0;
        envlist[pos++] = 0;
    }
    success = CreateProcess( applicationName, commandLine,
                            0, 0, TRUE, ( comms == 0 ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW )
#ifndef Q_OS_WINCE
                            | CREATE_UNICODE_ENVIRONMENT
#endif
                            , env == 0 ? 0 : envlist.data(),
                            (wchar_t*)QDir::toNativeSeparators(workingDir.absPath()).utf16(),
                            &startupInfo, d->pid );

    free( applicationName );
    free( commandLine );

    if  ( !success ) {
	d->deletePid();
	return false;
    }

#ifndef Q_OS_WINCE
    if ( comms & Stdin )
	CloseHandle( d->pipeStdin[0] );
    if ( comms & Stdout )
        CloseHandle( d->pipeStdout[1] );
    if ( (comms & Stderr) && !(comms & DupStderr) )
	CloseHandle( d->pipeStderr[1] );
#endif

    if ( ioRedirection || notifyOnExit ) {
	d->lookup->start( 100 );
    }

    // cleanup and return
    return true;
}
Exemple #9
0
/*
 * This may be called from DllMain, and hence operates under unusual
 * constraints.  In particular, it must be lock-free if GC_win32_dll_threads
 * is set.  Always called from the thread being added.
 * If GC_win32_dll_threads is not set, we already hold the allocation lock,
 * except possibly during single-threaded start-up code.
 */
static GC_thread GC_register_my_thread_inner(struct GC_stack_base *sb,
					     DWORD thread_id)
{
  GC_vthread me;

  /* The following should be a noop according to the win32	*/
  /* documentation.  There is empirical evidence that it	*/
  /* isn't.		- HB					*/
# if defined(MPROTECT_VDB)
#   if defined(GWW_VDB)
      if (GC_incremental && !GC_gww_dirty_init())
	SetUnhandledExceptionFilter(GC_write_fault_handler);
#   else
      if (GC_incremental) SetUnhandledExceptionFilter(GC_write_fault_handler);
#   endif
# endif

  if (GC_win32_dll_threads) {
    int i;
    /* It appears to be unsafe to acquire a lock here, since this	*/
    /* code is apparently not preeemptible on some systems.		*/
    /* (This is based on complaints, not on Microsoft's official	*/
    /* documentation, which says this should perform "only simple	*/
    /* initialization tasks".)						*/
    /* Hence we make do with nonblocking synchronization.		*/
    /* It has been claimed that DllMain is really only executed with	*/
    /* a particular system lock held, and thus careful use of locking	*/
    /* around code that doesn't call back into the system libraries	*/
    /* might be OK.  But this hasn't been tested across all win32	*/
    /* variants.							*/
                /* cast away volatile qualifier */
    for (i = 0; InterlockedExchange((IE_t)&dll_thread_table[i].in_use,1) != 0;
	 i++) {
      /* Compare-and-swap would make this cleaner, but that's not 	*/
      /* supported before Windows 98 and NT 4.0.  In Windows 2000,	*/
      /* InterlockedExchange is supposed to be replaced by		*/
      /* InterlockedExchangePointer, but that's not really what I	*/
      /* want here.							*/
      /* FIXME: We should eventually declare Win95 dead and use AO_	*/
      /* primitives here.						*/
      if (i == MAX_THREADS - 1)
        ABORT("too many threads");
    }
    /* Update GC_max_thread_index if necessary.  The following is safe,	*/
    /* and unlike CompareExchange-based solutions seems to work on all	*/
    /* Windows95 and later platforms.					*/
    /* Unfortunately, GC_max_thread_index may be temporarily out of 	*/
    /* bounds, so readers have to compensate.				*/
    while (i > GC_max_thread_index) {
      InterlockedIncrement((IE_t)&GC_max_thread_index);
    }
    if (GC_max_thread_index >= MAX_THREADS) {
      /* We overshot due to simultaneous increments.	*/
      /* Setting it to MAX_THREADS-1 is always safe.	*/
      GC_max_thread_index = MAX_THREADS - 1;
    }
    me = dll_thread_table + i;
  } else /* Not using DllMain */ {
    GC_ASSERT(I_HOLD_LOCK());
    GC_in_thread_creation = TRUE; /* OK to collect from unknown thread. */
    me = GC_new_thread(thread_id);
    GC_in_thread_creation = FALSE;
  }
# ifdef GC_PTHREADS
    /* me can be NULL -> segfault */
    me -> pthread_id = pthread_self();
# endif

  if (!DuplicateHandle(GetCurrentProcess(),
                 	GetCurrentThread(),
		        GetCurrentProcess(),
		        (HANDLE*)&(me -> handle),
		        0,
		        0,
		        DUPLICATE_SAME_ACCESS)) {
	DWORD last_error = GetLastError();
	GC_err_printf("Last error code: %d\n", last_error);
	ABORT("DuplicateHandle failed");
  }
  me -> stack_base = sb -> mem_base;
  /* Up until this point, GC_push_all_stacks considers this thread	*/
  /* invalid.								*/
  /* Up until this point, this entry is viewed as reserved but invalid	*/
  /* by GC_delete_thread.						*/
  me -> id = thread_id;
# if defined(THREAD_LOCAL_ALLOC)
      GC_init_thread_local((GC_tlfs)(&(me->tlfs)));
# endif
  if (me -> stack_base == NULL) 
      ABORT("Bad stack base in GC_register_my_thread_inner");
  if (GC_win32_dll_threads) {
    if (GC_please_stop) {
      AO_store(&GC_attached_thread, TRUE);
      AO_nop_full();  // Later updates must become visible after this.
    }
    /* We'd like to wait here, but can't, since waiting in DllMain 	*/
    /* provokes deadlocks.						*/
    /* Thus we force marking to be restarted instead.			*/
  } else {
    GC_ASSERT(!GC_please_stop);
  	/* Otherwise both we and the thread stopping code would be	*/
  	/* holding the allocation lock.					*/
  }
  return (GC_thread)(me);
}
Exemple #10
0
DWORD main(int argc, char *argv[]) 
{ 
   SECURITY_ATTRIBUTES saAttr; 
   BOOL fSuccess; 
 
// Set the bInheritHandle flag so pipe handles are inherited. 
 
   saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 
   saAttr.bInheritHandle = TRUE; 
   saAttr.lpSecurityDescriptor = NULL; 
 
   // The steps for redirecting child process's STDOUT: 
   //     1. Save current STDOUT, to be restored later. 
   //     2. Create anonymous pipe to be STDOUT for child process. 
   //     3. Set STDOUT of the parent process to be write handle to 
   //        the pipe, so it is inherited by the child process. 
   //     4. Create a noninheritable duplicate of the read handle and
   //        close the inheritable read handle. 
 
// Save the handle to the current STDOUT. 
 
   hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); 
 
// Create a pipe for the child process's STDOUT. 
 
   if (! CreatePipe(&hChildStdoutRd, &hChildStdoutWr, &saAttr, 0)) 
      ErrorExit("Stdout pipe creation failed\n"); 
 
// Set a write handle to the pipe to be STDOUT. 
 
   if (! SetStdHandle(STD_OUTPUT_HANDLE, hChildStdoutWr)) 
      ErrorExit("Redirecting STDOUT failed"); 
 
// Create noninheritable read handle and close the inheritable read 
// handle. 

    fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdoutRd,
        GetCurrentProcess(), &hChildStdoutRdDup , 0,
        FALSE,
        DUPLICATE_SAME_ACCESS);
    if( !fSuccess )
        ErrorExit("DuplicateHandle failed");
    CloseHandle(hChildStdoutRd);

   // The steps for redirecting child process's STDIN: 
   //     1.  Save current STDIN, to be restored later. 
   //     2.  Create anonymous pipe to be STDIN for child process. 
   //     3.  Set STDIN of the parent to be the read handle to the 
   //         pipe, so it is inherited by the child process. 
   //     4.  Create a noninheritable duplicate of the write handle, 
   //         and close the inheritable write handle. 
 
// Save the handle to the current STDIN. 
 
   hSaveStdin = GetStdHandle(STD_INPUT_HANDLE); 
 
// Create a pipe for the child process's STDIN. 
 
   if (! CreatePipe(&hChildStdinRd, &hChildStdinWr, &saAttr, 0)) 
      ErrorExit("Stdin pipe creation failed\n"); 
 
// Set a read handle to the pipe to be STDIN. 
 
   if (! SetStdHandle(STD_INPUT_HANDLE, hChildStdinRd)) 
      ErrorExit("Redirecting Stdin failed"); 
 
// Duplicate the write handle to the pipe so it is not inherited. 
 
   fSuccess = DuplicateHandle(GetCurrentProcess(), hChildStdinWr, 
      GetCurrentProcess(), &hChildStdinWrDup, 0, 
      FALSE,                  // not inherited 
      DUPLICATE_SAME_ACCESS); 
   if (! fSuccess) 
      ErrorExit("DuplicateHandle failed"); 
 
   CloseHandle(hChildStdinWr); 
 
// Now create the child process. 
 
   if (! CreateChildProcess()) 
      ErrorExit("Create process failed"); 
 
// After process creation, restore the saved STDIN and STDOUT. 
 
   if (! SetStdHandle(STD_INPUT_HANDLE, hSaveStdin)) 
      ErrorExit("Re-redirecting Stdin failed\n"); 
 
   if (! SetStdHandle(STD_OUTPUT_HANDLE, hSaveStdout)) 
      ErrorExit("Re-redirecting Stdout failed\n"); 
 
// Get a handle to the parent's input file. 
 
   if (argc > 1) 
      hInputFile = CreateFile(argv[1], GENERIC_READ, 0, NULL, 
         OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL); 
   else 
      hInputFile = hSaveStdin; 
 
   if (hInputFile == INVALID_HANDLE_VALUE) 
      ErrorExit("no input file\n"); 
 
// Write to pipe that is the standard input for a child process. 
 
   WriteToPipe(); 
 
// Read from pipe that is the standard output for child process. 
 
   ReadFromPipe(); 
 
   return 0; 
} 
Exemple #11
0
UINT WINAPI CWriteMain::TeeThread(LPVOID param)
{
	CWriteMain* sys = (CWriteMain*)param;
	wstring cmd = sys->teeCmd;
	Replace(cmd, L"$FilePath$", sys->savePath);
	vector<WCHAR> cmdBuff(cmd.c_str(), cmd.c_str() + cmd.size() + 1);

	WCHAR szCurrentDir[_MAX_PATH];
	DWORD ret = GetModuleFileName(NULL, szCurrentDir, _MAX_PATH);
	if( ret && ret < _MAX_PATH ){
		//カレントは実行ファイルのあるフォルダ
		WCHAR szDrive[_MAX_DRIVE];
		WCHAR szDir[_MAX_DIR];
		_wsplitpath_s(szCurrentDir, szDrive, _MAX_DRIVE, szDir, _MAX_DIR, NULL, 0, NULL, 0);
		_wmakepath_s(szCurrentDir, szDrive, szDir, NULL, NULL);

		//標準入力にパイプしたプロセスを起動する
		HANDLE tempPipe;
		HANDLE writePipe;
		if( CreatePipe(&tempPipe, &writePipe, NULL, 0) ){
			HANDLE readPipe;
			BOOL bRet = DuplicateHandle(GetCurrentProcess(), tempPipe, GetCurrentProcess(), &readPipe, 0, TRUE, DUPLICATE_SAME_ACCESS);
			CloseHandle(tempPipe);
			if( bRet ){
				SECURITY_ATTRIBUTES sa;
				sa.nLength = sizeof(sa);
				sa.lpSecurityDescriptor = NULL;
				sa.bInheritHandle = TRUE;
				STARTUPINFO si = {};
				si.cb = sizeof(si);
				si.dwFlags = STARTF_USESTDHANDLES;
				si.hStdInput = readPipe;
				//標準(エラー)出力はnulデバイスに捨てる
				si.hStdOutput = CreateFile(L"nul", GENERIC_WRITE, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
				si.hStdError = CreateFile(L"nul", GENERIC_WRITE, 0, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
				PROCESS_INFORMATION pi;
				bRet = CreateProcess(NULL, &cmdBuff.front(), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, szCurrentDir, &si, &pi);
				CloseHandle(readPipe);
				if( si.hStdOutput != INVALID_HANDLE_VALUE ){
					CloseHandle(si.hStdOutput);
				}
				if( si.hStdError != INVALID_HANDLE_VALUE ){
					CloseHandle(si.hStdError);
				}
				if( bRet ){
					CloseHandle(pi.hThread);
					CloseHandle(pi.hProcess);
					while( sys->teeThreadStopFlag == FALSE ){
						__int64 readablePos;
						{
							CBlockLock lock(&sys->wroteLock);
							readablePos = sys->wrotePos - sys->teeDelay;
						}
						LARGE_INTEGER liPos = {};
						DWORD read;
						if( SetFilePointerEx(sys->teeFile, liPos, &liPos, FILE_CURRENT) &&
						    readablePos - liPos.QuadPart >= (__int64)sys->teeBuff.size() &&
						    ReadFile(sys->teeFile, &sys->teeBuff.front(), (DWORD)sys->teeBuff.size(), &read, NULL) && read > 0 ){
							DWORD write;
							if( WriteFile(writePipe, &sys->teeBuff.front(), read, &write, NULL) == FALSE ){
								break;
							}
						}else{
							Sleep(100);
						}
					}
					//プロセスは回収しない(標準入力が閉じられた後にどうするかはプロセスの判断に任せる)
				}
			}
			CloseHandle(writePipe);
		}
	}
	return 0;
}
Exemple #12
0
string exec_command( const string& str )
{
  // Construct this before any resources are claimed
  string result; 

  const char *argv[4]; // No ownership of memory

  // Respect the SHELL environment variable,
  // and drop back to using CMD.EXE
  argv[0] = getenv("SHELL");
  if ( !argv[0] || !*argv[0] ) {
    // TODO: On Windows NT 4, 2K and XP this is correct;
    // on Windows 95, 98 and ME, this should be COMMAND.COM,
    // though that'll probably be unusably slow.
    argv[0] = "CMD.EXE";
    argv[1] = "/C";
  } else {
    //
    argv[1] = "-c";
  }
  argv[2] = str.c_str();
  argv[3] = NULL;

  // -------
  // From now on we have to be careful about exceptions
  // as we have pipes and child processes hanging around
  //
  HANDLE hErr;
  if (DuplicateHandle(GetCurrentProcess(),
                      GetStdHandle(STD_ERROR_HANDLE),
                      GetCurrentProcess(),
                      &hErr,
                      0,
                      TRUE,
                      DUPLICATE_SAME_ACCESS) == FALSE)
    THROW_SYSTEM_ERROR( "DuplicateHandle" );
  

  // Two ends of the pipe:
  HANDLE hChildOutRd, hChildOutWr;
  {
    SECURITY_ATTRIBUTES saAttr;
    saAttr.nLength = sizeof (SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&hChildOutRd, &hChildOutWr, &saAttr, 0)) {
      CloseHandle(hErr);
      THROW_SYSTEM_ERROR( "CreatePipe" );
    }
  }

  PROCESS_INFORMATION procInfo;

  {
    string command_line( make_command_line( argv[0], argv ) );

    STARTUPINFO startInfo;
    GetStartupInfo(&startInfo);
    startInfo.dwFlags = STARTF_USESTDHANDLES;
    startInfo.lpReserved = 0;
    startInfo.cbReserved2 = 0;
    startInfo.lpReserved2 = 0;
    startInfo.lpTitle = 0;
    startInfo.hStdInput = NULL;
    startInfo.hStdOutput = hChildOutWr;
    startInfo.hStdError = hErr;

    if (CreateProcess(0,
                      // Const correctness -- we've heard of it
                      const_cast< char* >( command_line.c_str() ),
                      NULL,
                      0, // default security attributes for thread
                      TRUE, // inherit handles (e.g. helper pipes)
                      0,
                      NULL,
                      0, // default starting directory
                      &startInfo,
                      &procInfo) == FALSE) {
      CloseHandle(hErr);
      CloseHandle(hChildOutRd);
      CloseHandle(hChildOutWr);
      THROW_SYSTEM_ERROR( "CreateProcess" );
    }

    // Close the thread handle -- we'll just watch the process
    CloseHandle(procInfo.hThread);
  }

  CloseHandle( hErr );
  CloseHandle( hChildOutWr );

  try {
    while (true) {
      const size_t buflen(4096);
      char buffer[buflen];

      // TODO:  Unicode conversions???

      DWORD i;
      ReadFile( hChildOutRd, buffer, buflen, &i, NULL);
      if (i <= 0) break; // TODO: Do something more sensible
      result.append( buffer, i ); // Might throw
    }
  } 
  catch( ... ) {
    CloseHandle( hChildOutRd );

    DWORD rv = WaitForMultipleObjects( 1, &procInfo.hProcess, 
				       FALSE, INFINITE );
    if ( rv == WAIT_FAILED ) abort();

    throw;
  }

  CloseHandle( hChildOutRd );

  DWORD rv = WaitForMultipleObjects( 1, &procInfo.hProcess, FALSE, INFINITE );
  if ( rv == WAIT_FAILED )
    THROW_SYSTEM_ERROR( "WaitForMultipleObjects" );  
  return result;
}
Exemple #13
0
/*
 * Create both an fd and an OVERLAPPED from an open Windows handle, so that
 * it can be used with our polling function
 * The handle MUST support overlapped transfers (usually requires CreateFile
 * with FILE_FLAG_OVERLAPPED)
 * Return a pollable file descriptor struct, or INVALID_WINFD on error
 *
 * Note that the fd returned by this function is a per-transfer fd, rather
 * than a per-session fd and cannot be used for anything else but our
 * custom functions (the fd itself points to the NUL: device)
 * if you plan to do R/W on the same handle, you MUST create 2 fds: one for
 * read and one for write. Using a single R/W fd is unsupported and will
 * produce unexpected results
 */
struct winfd usbi_create_fd(HANDLE handle, int access_mode, struct usbi_transfer *itransfer, cancel_transfer *cancel_fn)
{
	int i;
	struct winfd wfd = INVALID_WINFD;
	OVERLAPPED* overlapped = NULL;

	CHECK_INIT_POLLING;

	if ((handle == 0) || (handle == INVALID_HANDLE_VALUE)) {
		return INVALID_WINFD;
	}

	wfd.itransfer = itransfer;
	wfd.cancel_fn = cancel_fn;

	if ((access_mode != RW_READ) && (access_mode != RW_WRITE)) {
		usbi_warn(NULL, "only one of RW_READ or RW_WRITE are supported.\n"
			"If you want to poll for R/W simultaneously, create multiple fds from the same handle.");
		return INVALID_WINFD;
	}
	if (access_mode == RW_READ) {
		wfd.rw = RW_READ;
	} else {
		wfd.rw = RW_WRITE;
	}

	overlapped = create_overlapped();
	if(overlapped == NULL) {
		return INVALID_WINFD;
	}

	for (i=0; i<MAX_FDS; i++) {
		if (poll_fd[i].fd < 0) {
			EnterCriticalSection(&_poll_fd[i].mutex);
			// fd might have been removed before we got to critical
			if (poll_fd[i].fd >= 0) {
				LeaveCriticalSection(&_poll_fd[i].mutex);
				continue;
			}
			// Use index as the unique fd number
			wfd.fd = i;
			// Attempt to emulate some of the CancelIoEx behaviour on platforms
			// that don't have it
			if (Use_Duplicate_Handles) {
				_poll_fd[i].thread_id = GetCurrentThreadId();
				if (!DuplicateHandle(GetCurrentProcess(), handle, GetCurrentProcess(),
					&wfd.handle, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
					usbi_dbg("could not duplicate handle for CancelIo - using original one");
					wfd.handle = handle;
					// Make sure we won't close the original handle on fd deletion then
					_poll_fd[i].original_handle = INVALID_HANDLE_VALUE;
				} else {
					_poll_fd[i].original_handle = handle;
				}
			} else {
				wfd.handle = handle;
			}
			wfd.overlapped = overlapped;
			memcpy(&poll_fd[i], &wfd, sizeof(struct winfd));
			LeaveCriticalSection(&_poll_fd[i].mutex);
			return wfd;
		}
	}
	free_overlapped(overlapped);
	return INVALID_WINFD;
}
BOOL SystemHandleInformation::GetFileName( HANDLE h, MyString& str, DWORD processId )
{
	BOOL ret= FALSE;
	HANDLE hThread = NULL;
	GetFileNameThreadParam tp;
	HANDLE handle;
	HANDLE hRemoteProcess = NULL;
	BOOL remote = processId != GetCurrentProcessId();
	
	if ( !NtDllStatus )
		return FALSE;

	if ( remote )
	{
		// Open process
		hRemoteProcess = OpenProcess( processId );
		
		if ( hRemoteProcess == NULL )
			return FALSE;

		// Duplicate handle
		handle = DuplicateHandle( hRemoteProcess, h );
	}
	else
		handle = h;

	tp.hFile = handle;
	tp.pName = &str;
	tp.rc = 0;

	// tj:2012 is it really necessary to create a thread to call NtQueryInformationFile??"
	// Let's start the thread to get the file name
	hThread = (HANDLE)_beginthread( GetFileNameThread, 0, &tp );

	if ( hThread == NULL )
	{
		ret = FALSE;
		goto cleanup;
	}

	// Wait for finishing the thread
	if ( WaitForSingleObject( hThread, 100 ) == WAIT_TIMEOUT )
	{	
		// Access denied
		// Terminate the thread
		#pragma warning(suppress: 6258) // Using TerminateThread does not allow proper thread clean up
		TerminateThread( hThread, 0 );

		str = "";

		ret = TRUE;
	}
	else
		ret = ( tp.rc == 0 );

cleanup:

	if ( remote )
	{
		if ( hRemoteProcess != NULL )
			CloseHandle( hRemoteProcess );

		if ( handle != NULL )
			CloseHandle( handle );
	}
		
	return ret;
}
// Given a PID attempt to find or create a DbgTransportSession instance to manage a connection to a runtime in
// that process. Returns E_UNEXPECTED if the process can't be found. Also returns a handle that can be waited
// on for process termination.
HRESULT DbgTransportTarget::GetTransportForProcess(DWORD                   dwPID,
                                                   DbgTransportSession   **ppTransport,
                                                   HANDLE                 *phProcessHandle)
{
    RSLockHolder lock(&m_sLock);
    HRESULT hr = S_OK;

    ProcessEntry *entry = LocateProcessByPID(dwPID);

    if (entry == NULL)
    {

       NewHolder<ProcessEntry> newEntry = new(nothrow) ProcessEntry();
       if (newEntry == NULL)
           return E_OUTOFMEMORY;

       NewHolder<DbgTransportSession> transport = new(nothrow) DbgTransportSession();
       if (transport == NULL)
       {
           return E_OUTOFMEMORY;
       }


       HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID);
       if (hProcess == NULL)
       {
           transport->Shutdown();
           return HRESULT_FROM_GetLastError();
       }

       // Initialize it (this immediately starts the remote connection process).
       hr = transport->Init(dwPID, hProcess);
       if (FAILED(hr))
       {
           transport->Shutdown();
           CloseHandle(hProcess);
           return hr;
       }

       entry = newEntry;
       newEntry.SuppressRelease();   
       entry->m_dwPID = dwPID;
       entry->m_hProcess = hProcess;
       entry->m_transport = transport;
       transport.SuppressRelease();
       entry->m_cProcessRef = 0;

       // Adding new entry to the list.
       entry->m_pNext = m_pProcessList;
       m_pProcessList = entry;
    }

    entry->m_cProcessRef++;
    _ASSERTE(entry->m_cProcessRef > 0);
    _ASSERTE(entry->m_transport != NULL);
    _ASSERTE(entry->m_hProcess > 0);
    
    *ppTransport = entry->m_transport;
    if (!DuplicateHandle(GetCurrentProcess(), 
                         entry->m_hProcess,
                         GetCurrentProcess(), 
                         phProcessHandle,
                         0,      // ignored since we are going to pass DUPLICATE_SAME_ACCESS
                         FALSE, 
                         DUPLICATE_SAME_ACCESS))
    {
        return HRESULT_FROM_GetLastError();
    }

    return hr;
}
Exemple #16
0
/*
 * The runtime library's popen() on win32 does not work when being
 * called from a service when running on windows <= 2000, because
 * there is no stdin/stdout/stderr.
 *
 * Executing a command in a pipe and reading the first line from it
 * is all we need.
 */
static char *
pipe_read_line(char *cmd, char *line, int maxsize)
{
#ifndef WIN32
	FILE	   *pgver;

	/* flush output buffers in case popen does not... */
	fflush(stdout);
	fflush(stderr);

	if ((pgver = popen(cmd, "r")) == NULL)
		return NULL;

	if (fgets(line, maxsize, pgver) == NULL)
	{
		perror("fgets failure");
		pclose(pgver);			/* no error checking */
		return NULL;
	}

	if (pclose_check(pgver))
		return NULL;

	return line;
#else							/* WIN32 */

	SECURITY_ATTRIBUTES sattr;
	HANDLE		childstdoutrd,
				childstdoutwr,
				childstdoutrddup;
	PROCESS_INFORMATION pi;
	STARTUPINFO si;
	char	   *retval = NULL;

	sattr.nLength = sizeof(SECURITY_ATTRIBUTES);
	sattr.bInheritHandle = TRUE;
	sattr.lpSecurityDescriptor = NULL;

	if (!CreatePipe(&childstdoutrd, &childstdoutwr, &sattr, 0))
		return NULL;

	if (!DuplicateHandle(GetCurrentProcess(),
						 childstdoutrd,
						 GetCurrentProcess(),
						 &childstdoutrddup,
						 0,
						 FALSE,
						 DUPLICATE_SAME_ACCESS))
	{
		CloseHandle(childstdoutrd);
		CloseHandle(childstdoutwr);
		return NULL;
	}

	CloseHandle(childstdoutrd);

	ZeroMemory(&pi, sizeof(pi));
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwFlags = STARTF_USESTDHANDLES;
	si.hStdError = childstdoutwr;
	si.hStdOutput = childstdoutwr;
	si.hStdInput = INVALID_HANDLE_VALUE;

	if (CreateProcess(NULL,
					  cmd,
					  NULL,
					  NULL,
					  TRUE,
					  0,
					  NULL,
					  NULL,
					  &si,
					  &pi))
	{
		/* Successfully started the process */
		char	   *lineptr;

		ZeroMemory(line, maxsize);

		/* Try to read at least one line from the pipe */
		/* This may require more than one wait/read attempt */
		for (lineptr = line; lineptr < line + maxsize - 1;)
		{
			DWORD		bytesread = 0;

			/* Let's see if we can read */
			if (WaitForSingleObject(childstdoutrddup, 10000) != WAIT_OBJECT_0)
				break;			/* Timeout, but perhaps we got a line already */

			if (!ReadFile(childstdoutrddup, lineptr, maxsize - (lineptr - line),
						  &bytesread, NULL))
				break;			/* Error, but perhaps we got a line already */

			lineptr += strlen(lineptr);

			if (!bytesread)
				break;			/* EOF */

			if (strchr(line, '\n'))
				break;			/* One or more lines read */
		}

		if (lineptr != line)
		{
			/* OK, we read some data */
			int			len;

			/* If we got more than one line, cut off after the first \n */
			lineptr = strchr(line, '\n');
			if (lineptr)
				*(lineptr + 1) = '\0';

			len = strlen(line);

			/*
			 * If EOL is \r\n, convert to just \n. Because stdout is a
			 * text-mode stream, the \n output by the child process is
			 * received as \r\n, so we convert it to \n.  The server main.c
			 * sets setvbuf(stdout, NULL, _IONBF, 0) which has the effect of
			 * disabling \n to \r\n expansion for stdout.
			 */
			if (len >= 2 && line[len - 2] == '\r' && line[len - 1] == '\n')
			{
				line[len - 2] = '\n';
				line[len - 1] = '\0';
				len--;
			}

			/*
			 * We emulate fgets() behaviour. So if there is no newline at the
			 * end, we add one...
			 */
			if (len == 0 || line[len - 1] != '\n')
				strcat(line, "\n");

			retval = line;
		}

		CloseHandle(pi.hProcess);
		CloseHandle(pi.hThread);
	}

	CloseHandle(childstdoutwr);
	CloseHandle(childstdoutrddup);

	return retval;
#endif   /* WIN32 */
}
//-----------------------------------------------------------------------------
// name: cb2()
// desc: ...
//-----------------------------------------------------------------------------
//int Digitalio::cb2( char * buffer, int buffer_size, void * user_data )
int Digitalio::cb2( void *output_buffer, void *input_buffer,
                    unsigned int buffer_size,
                    double streamTime,
                    RtAudioStreamStatus status,
                    void *user_data )
{
    DWORD__ len = buffer_size * sizeof(SAMPLE) * m_num_channels_out;
    Chuck_VM * vm_ref = (Chuck_VM *)user_data;
    
    // priority boost
    if( !m_go && Chuck_VM::our_priority != 0x7fffffff )
    {
#if !defined(__PLATFORM_WIN32__) || defined(__WINDOWS_PTHREAD__)
        g_tid_synthesis = pthread_self();
#else
        // must duplicate for handle to be usable by other threads
        g_tid_synthesis = NULL;
        DuplicateHandle(
            GetCurrentProcess(),
            GetCurrentThread(),
            GetCurrentProcess(),
            &g_tid_synthesis,
            0,
            FALSE,
            DUPLICATE_SAME_ACCESS
        );

        // TODO: close the duplicate handle?
#endif
        Chuck_VM::set_priority( Chuck_VM::our_priority, NULL );
        memset( output_buffer, 0, len );
        m_go = TRUE;

        // start watchdog
        if( g_do_watchdog )
        {
            // timestamp
            g_watchdog_time = get_current_time( TRUE );
            // start watchdog
            watchdog_start();
        }

        // let it go the first time
        return 0;
    }

    // copy input to local buffer
    if( m_num_channels_in )
    {
        memcpy( m_buffer_in, input_buffer, len );
        // copy to extern
        if( m_extern_in ) memcpy( m_extern_in, input_buffer, len );
    }

    // check xrun
    if( m_xrun < 6 )
    {
        // timestamp
        if( g_do_watchdog ) g_watchdog_time = get_current_time( TRUE );
        // get samples from output
        vm_ref->run( buffer_size, m_buffer_in, m_buffer_out );
        // ...
        if( m_xrun ) m_xrun--;
    }
    else
    {
        // reset
        m_xrun /= 2;
    }

    // copy local buffer to be rendered
    if( !m_end ) memcpy( output_buffer, m_buffer_out, len );
    // set all elements of local buffer to silence
    else memset( output_buffer, 0, len );

    // copy to extern
    if( m_extern_out ) memcpy( m_extern_out, output_buffer, len );


    return 0;
}
/*static*/
IProcess* WinProcessImpl::Execute(wxEvtHandler *parent, const wxString& cmd, wxString &errMsg, IProcessCreateFlags flags, const wxString &workingDir, IProcessCallback* cb)
{
    SECURITY_ATTRIBUTES saAttr;
    BOOL                fSuccess;

    MyDirGuard dg;

    wxString wd(workingDir);
    if (workingDir.IsEmpty()) {
        wd = wxGetCwd();
    }
    wxSetWorkingDirectory( wd );

    // Set the bInheritHandle flag so pipe handles are inherited.
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    WinProcessImpl *prc = new WinProcessImpl(parent);
    prc->LinkCallback( cb );
    prc->m_flags = flags;

    // The steps for redirecting child process's STDOUT:
    //     1. Save current STDOUT, to be restored later.
    //     2. Create anonymous pipe to be STDOUT for child process.
    //     3. Set STDOUT of the parent process to be write handle to
    //        the pipe, so it is inherited by the child process.
    //     4. Create a noninheritable duplicate of the read handle and
    //        close the inheritable read handle.

    // Save the handle to the current STDOUT.
    prc->hSaveStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    // Create a pipe for the child process's STDOUT.
    if ( !CreatePipe( &prc->hChildStdoutRd, &prc->hChildStdoutWr, &saAttr, 0) ) {
        delete prc;
        return NULL;
    }

    // Set a write handle to the pipe to be STDOUT.
    if ( !SetStdHandle(STD_OUTPUT_HANDLE, prc->hChildStdoutWr) ) {
        delete prc;
        return NULL;
    }

    // Create noninheritable read handle and close the inheritable read handle.
    fSuccess = DuplicateHandle( GetCurrentProcess(), prc->hChildStdoutRd,
                                GetCurrentProcess(),  &prc->hChildStdoutRdDup ,
                                0,  FALSE,
                                DUPLICATE_SAME_ACCESS );
    if ( !fSuccess ) {
        delete prc;
        return NULL;
    }
    CloseHandle( prc->hChildStdoutRd );

    // The steps for redirecting child process's STDERR:
    //     1. Save current STDERR, to be restored later.
    //     2. Create anonymous pipe to be STDERR for child process.
    //     3. Set STDERR of the parent process to be write handle to
    //        the pipe, so it is inherited by the child process.
    //     4. Create a noninheritable duplicate of the read handle and
    //        close the inheritable read handle.

    // Save the handle to the current STDERR.
    prc->hSaveStderr = GetStdHandle(STD_ERROR_HANDLE);

    // Create a pipe for the child process's STDERR.
    if ( !CreatePipe( &prc->hChildStderrRd, &prc->hChildStderrWr, &saAttr, 0) ) {
        delete prc;
        return NULL;
    }

    // Set a write handle to the pipe to be STDERR.
    if ( !SetStdHandle(STD_ERROR_HANDLE, prc->hChildStderrWr) ) {
        delete prc;
        return NULL;
    }

    // Create noninheritable read handle and close the inheritable read handle.
    fSuccess = DuplicateHandle( GetCurrentProcess(), prc->hChildStderrRd,
                                GetCurrentProcess(),  &prc->hChildStderrRdDup ,
                                0,  FALSE,
                                DUPLICATE_SAME_ACCESS );
    if ( !fSuccess ) {
        delete prc;
        return NULL;
    }
    CloseHandle( prc->hChildStderrRd );

    // The steps for redirecting child process's STDIN:
    //     1.  Save current STDIN, to be restored later.
    //     2.  Create anonymous pipe to be STDIN for child process.
    //     3.  Set STDIN of the parent to be the read handle to the
    //         pipe, so it is inherited by the child process.
    //     4.  Create a noninheritable duplicate of the write handle,
    //         and close the inheritable write handle.

    // Save the handle to the current STDIN.
    prc->hSaveStdin = GetStdHandle(STD_INPUT_HANDLE);

    // Create a pipe for the child process's STDIN.
    if ( !CreatePipe(&prc->hChildStdinRd, &prc->hChildStdinWr, &saAttr, 0) ) {
        delete prc;
        return NULL;
    }
    // Set a read handle to the pipe to be STDIN.
    if ( !SetStdHandle(STD_INPUT_HANDLE, prc->hChildStdinRd) ) {
        delete prc;
        return NULL;
    }
    // Duplicate the write handle to the pipe so it is not inherited.
    fSuccess = DuplicateHandle(GetCurrentProcess(), prc->hChildStdinWr,
                               GetCurrentProcess(), &prc->hChildStdinWrDup,
                               0, FALSE,                  // not inherited
                               DUPLICATE_SAME_ACCESS );
    if ( !fSuccess ) {
        delete prc;
        return NULL;
    }
    CloseHandle(prc->hChildStdinWr);

    // Execute the child process
    STARTUPINFO siStartInfo;

    // Set up members of STARTUPINFO structure.
    ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
    siStartInfo.cb = sizeof(STARTUPINFO);

    siStartInfo.dwFlags    = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; ;
    siStartInfo.hStdInput  = prc->hChildStdinRd;
    siStartInfo.hStdOutput = prc->hChildStdoutWr;
    siStartInfo.hStdError  = prc->hChildStderrWr;

    // Set the window to hide
    siStartInfo.wShowWindow = flags & IProcessCreateConsole ? SW_SHOW : SW_HIDE;
    DWORD creationFlags     = flags & IProcessCreateConsole ? CREATE_NEW_CONSOLE : CREATE_NO_WINDOW;

    if(flags & IProcessCreateWithHiddenConsole) {
        siStartInfo.wShowWindow = SW_HIDE;
        creationFlags           = CREATE_NEW_CONSOLE|CREATE_NEW_PROCESS_GROUP;
    }

    BOOL ret = CreateProcess( NULL,
                              cmd.wchar_str(),   // shell line execution command
                              NULL,              // process security attributes
                              NULL,              // primary thread security attributes
                              TRUE,              // handles are inherited
                              creationFlags,     // creation flags
                              NULL,              // use parent's environment
                              NULL,              // CD to tmp dir
                              &siStartInfo,      // STARTUPINFO pointer
                              &prc->piProcInfo); // receives PROCESS_INFORMATION
    if ( ret ) {
        prc->dwProcessId = prc->piProcInfo.dwProcessId;
    } else {
        int err = GetLastError();
        wxUnusedVar(err);
        delete prc;
        return NULL;
    }

    // After process creation, restore the saved STDIN and STDOUT.
    if ( !SetStdHandle(STD_INPUT_HANDLE, prc->hSaveStdin) ) {

        delete prc;
        return NULL;
    }
    if ( !SetStdHandle(STD_OUTPUT_HANDLE, prc->hSaveStdout) ) {

        delete prc;
        return NULL;
    }
    if ( !SetStdHandle(STD_OUTPUT_HANDLE, prc->hSaveStderr) ) {

        delete prc;
        return NULL;
    }
    
    if ( prc->m_flags & IProcessCreateConsole || prc->m_flags & IProcessCreateWithHiddenConsole ) {
        ConsoleAttacher ca(prc->GetPid());
        if ( ca.isAttached ) {
            freopen("CONOUT$","wb", stdout);  // reopen stout handle as console window output
            freopen("CONOUT$","wb", stderr);  // reopen stderr handle as console window output
        }
    }
    
    prc->SetPid( prc->dwProcessId );
    prc->StartReaderThread();
    return prc;
}
Exemple #19
0
int __cdecl main(int argc, char **argv)
{
    HANDLE  hFile;
    HANDLE  hDupFile;
    char    buf[256];
    char    teststr[]    = "A uNiQuE tEsT sTrInG";
    char    lpFileName[] = "testfile.txt";
    DWORD   dwBytesWritten;
    DWORD   dwBytesRead;
    BOOL    bRetVal;

    /*Initalize the PAL*/
    if ((PAL_Initialize(argc,argv)) != 0)
    {
        return (FAIL);
    }

    /*Create a file handle with CreateFile*/
    hFile = CreateFile(lpFileName,
                GENERIC_WRITE|GENERIC_READ,
                FILE_SHARE_WRITE|FILE_SHARE_READ,
                NULL, 
                OPEN_ALWAYS,
                FILE_ATTRIBUTE_NORMAL, 
                NULL);
    if (hFile == INVALID_HANDLE_VALUE)
    {
        Fail("ERROR: %u :unable to create file \"%s\".\n",
            GetLastError(),
            lpFileName);
    }

    /*Write test string to the file.*/    
    bRetVal = WriteFile(hFile,      // handle to file
                teststr,            // data buffer
                strlen(teststr),    // number of bytes to write
                &dwBytesWritten,    // number of bytes written
                NULL);              // overlapped buffer

    if (bRetVal == FALSE)
    {
        Trace("ERROR: %u : unable to write to file handle "
                "hFile=0x%lx\n",
                GetLastError(),
                hFile);
        CloseHandle(hFile);
        Fail("");
    }

    /*Create a duplicate handle with DuplicateHandle.*/
    if (!(DuplicateHandle(
            GetCurrentProcess(), 
            hFile,
            GetCurrentProcess(), 
            &hDupFile,
            GENERIC_READ|GENERIC_WRITE,
            FALSE, 
            DUPLICATE_SAME_ACCESS)))
    {
        Trace("ERROR: %u : Fail to create the duplicate handle"
             " to hFile=0x%lx\n",
             GetLastError(),
             hFile);
        CloseHandle(hFile);
        Fail("");
    }

    memset(buf, 0, 256);

    /*Read from the Duplicated handle.*/
    bRetVal = ReadFile(hDupFile,
                       buf,
                       256,
                       &dwBytesRead,
                       NULL);
    if (bRetVal == FALSE)
    {
        Trace("ERROR: %u :unable to read from file handle "
                "hFile=0x%lx\n",
                GetLastError(),
                hFile);
        CloseHandle(hFile);
        CloseHandle(hDupFile);
        Fail("");
    }

    /*Compare what was written to what was read.*/
    if (memcmp(teststr, buf, dwBytesRead) != 0)
    {
        Trace("ERROR: expected %s, got %s\n", teststr, buf);
        CloseHandle(hFile);
        CloseHandle(hDupFile);
        Fail("");
    }

    /*Close the handles*/
    CloseHandle(hFile);
    CloseHandle(hDupFile);

    /*Failure test: Create DuplicateHandle to a closed handle*/
    if ((DuplicateHandle(
            GetCurrentProcess(), 
            hFile,
            GetCurrentProcess(), 
            &hDupFile,
            GENERIC_READ|GENERIC_WRITE,
            FALSE, 
            DUPLICATE_SAME_ACCESS)))
    {
        Fail("ERROR: %u :Created a duplicate handle to"
             " a closed handle hFile=0x%lx\n",
             GetLastError(),
             hFile);
    }

    /*Failure test: Create DuplicateHandle to a NULL handle*/
    hFile = NULL;
    if ((DuplicateHandle(
            GetCurrentProcess(),
            hFile,
            GetCurrentProcess(),
            &hDupFile,
            GENERIC_READ|GENERIC_WRITE,
            FALSE, 
            DUPLICATE_SAME_ACCESS)))
    {
        Fail("ERROR: %u :Created a duplicate handle to "
             " a NULL handle hFile=0x%lx\n", 
             GetLastError(),
             hFile);
    }

    PAL_Terminate();
    return (PASS);
}
Exemple #20
0
int run_child(int fd, char *args[] )
{
    PROCESS_INFORMATION	pi;
    STARTUPINFO	si;
    HANDLE	hsockDup;
    int	ret = 0;
    int	i;
    char	*p;
    char	temp[10];
    char commandline[256];

    commandline[0] = '\0';

    hsockDup = (HANDLE)-1;



    /* replace the old socket with the dup */
    i = 0;
    while ( args[i] != NULL )
    {
        p = strstr(args[i], "%d");
        if ( p )
        {
            if ( hsockDup == (HANDLE)-1 )
            {
                /* Duplicate the socket OrigSock to create an inheritable copy.*/
                if (!DuplicateHandle(GetCurrentProcess(), (HANDLE)fd,
                                     GetCurrentProcess(), (HANDLE*)&hsockDup, GENERIC_WRITE, FALSE, 0))
                {
                    return(0);
                }
            }

            sprintf( temp, args[i], (int)hsockDup );
            strcat(commandline, temp );
            strcat(commandline, " " );
        }
        else
        {
            strcat(commandline, args[i] );
            strcat(commandline, " " );
        }

        i++;
    }



    /* we dont really use this because its a detached process */
    ZeroMemory( &si, sizeof(STARTUPINFO ) );
    /* but the struct size must be correct */
    si.cb = sizeof(STARTUPINFO );

    if ( CreateProcess(NULL, commandline, NULL, NULL, TRUE,
                       DETACHED_PROCESS,
                       NULL, NULL, &si, &pi) )
    {
        if ( hsockDup != (HANDLE)-1 )
        {
            CLOSEHANDLE	ch;
            DWORD	dwThreadID;

            ch.hsockDup = hsockDup;
            ch.hProcess = pi.hProcess;
            CreateThread(NULL, 0, CloseDupHandleThread, &ch, 0, &dwThreadID);
        }

        /* return the pid of the new process */
        ret = (int)pi.dwProcessId;

    }

    return(ret);

}
Exemple #21
0
/*
 *--------------------------------------------------------------
 *
 * OS_LibInit --
 *
 *	Set up the OS library for use.
 *
 * Results:
 *	Returns 0 if success, -1 if not.
 *
 * Side effects:
 *	Sockets initialized, pseudo file descriptors setup, etc.
 *
 *--------------------------------------------------------------
 */
int OS_LibInit(int stdioFds[3])
{
    WORD  wVersion;
    WSADATA wsaData;
    int err;
    int fakeFd;
    char *cLenPtr = NULL;
    char *val = NULL;
        
    if(libInitialized)
        return 0;

    InitializeCriticalSection(&fdTableCritical);   
        
    /*
     * Initialize windows sockets library.
     */
    wVersion = MAKEWORD(2,0);
    err = WSAStartup( wVersion, &wsaData );
    if (err) {
        fprintf(stderr, "Error starting Windows Sockets.  Error: %d",
		WSAGetLastError());
	exit(111);
    }

    /*
     * Create the I/O completion port to be used for our I/O queue.
     */
    if (hIoCompPort == INVALID_HANDLE_VALUE) {
	hIoCompPort = CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL,
					      0, 1);
	if(hIoCompPort == INVALID_HANDLE_VALUE) {
	    printf("<H2>OS_LibInit Failed CreateIoCompletionPort!  ERROR: %d</H2>\r\n\r\n",
	       GetLastError());
	    return -1;
	}
    }

    /*
     * If a shutdown event is in the env, save it (I don't see any to 
     * remove it from the environment out from under the application).
     * Spawn a thread to wait on the shutdown request.
     */
    val = getenv(SHUTDOWN_EVENT_NAME);
    if (val != NULL) 
    {
        HANDLE shutdownEvent = strToHandle(val);

        if (_beginthread(ShutdownRequestThread, 0, shutdownEvent) == -1)
        {
            return -1;
        }
    }

    if (acceptMutex == INVALID_HANDLE_VALUE)
    {
        /* If an accept mutex is in the env, use it */
        val = getenv(MUTEX_VARNAME);
        if (val != NULL) 
        {
            acceptMutex = strToHandle(val);
        }
    }

    /*
     * Determine if this library is being used to listen for FastCGI
     * connections.  This is communicated by STDIN containing a
     * valid handle to a listener object.  In this case, both the
     * "stdout" and "stderr" handles will be INVALID (ie. closed) by
     * the starting process.
     *
     * The trick is determining if this is a pipe or a socket...
     *
     * XXX: Add the async accept test to determine socket or handle to a
     *      pipe!!!
     */
    if((GetStdHandle(STD_OUTPUT_HANDLE) == INVALID_HANDLE_VALUE) &&
       (GetStdHandle(STD_ERROR_HANDLE)  == INVALID_HANDLE_VALUE) &&
       (GetStdHandle(STD_INPUT_HANDLE)  != INVALID_HANDLE_VALUE) ) 
    {
        DWORD pipeMode = PIPE_READMODE_BYTE | PIPE_WAIT;
        HANDLE oldStdIn = GetStdHandle(STD_INPUT_HANDLE);

        // Move the handle to a "low" number
        if (! DuplicateHandle(GetCurrentProcess(), oldStdIn,
                              GetCurrentProcess(), &hListen,
                              0, TRUE, DUPLICATE_SAME_ACCESS))
        {
            return -1;
        }

        if (! SetStdHandle(STD_INPUT_HANDLE, hListen))
        {
            return -1;
        }

        CloseHandle(oldStdIn);

	/*
	 * Set the pipe handle state so that it operates in wait mode.
	 *
	 * NOTE: The listenFd is not mapped to a pseudo file descriptor
	 *       as all work done on it is contained to the OS library.
	 *
	 * XXX: Initial assumption is that SetNamedPipeHandleState will
	 *      fail if this is an IP socket...
	 */
        if (SetNamedPipeHandleState(hListen, &pipeMode, NULL, NULL)) 
        {
            listenType = FD_PIPE_SYNC;
        } 
        else 
        {
            listenType = FD_SOCKET_SYNC;
        }
    }

    /*
     * If there are no stdioFds passed in, we're done.
     */
    if(stdioFds == NULL) {
        libInitialized = 1;
        return 0;
    }

    /*
     * Setup standard input asynchronous I/O.  There is actually a separate
     * thread spawned for this purpose.  The reason for this is that some
     * web servers use anonymous pipes for the connection between itself
     * and a CGI application.  Anonymous pipes can't perform asynchronous
     * I/O or use I/O completion ports.  Therefore in order to present a
     * consistent I/O dispatch model to an application we emulate I/O
     * completion port behavior by having the standard input thread posting
     * messages to the hIoCompPort which look like a complete overlapped
     * I/O structure.  This keeps the event dispatching simple from the
     * application perspective.
     */
    stdioHandles[STDIN_FILENO] = GetStdHandle(STD_INPUT_HANDLE);

    if(!SetHandleInformation(stdioHandles[STDIN_FILENO],
			     HANDLE_FLAG_INHERIT, 0)) {
/*
 * XXX: Causes error when run from command line.  Check KB
        err = GetLastError();
        DebugBreak();
	exit(99);
 */
    }

    ASSERT(INT_MIN <= (intptr_t)stdioHandles[STDIN_FILENO] && 
           (intptr_t)stdioHandles[STDIN_FILENO] <= INT_MAX);
    if ((fakeFd = Win32NewDescriptor(FD_PIPE_SYNC,
                                     (int)(intptr_t)stdioHandles[STDIN_FILENO],
				     STDIN_FILENO)) == -1) {
        return -1;
    } else {
        /*
	 * Set stdin equal to our pseudo FD and create the I/O completion
	 * port to be used for async I/O.
	 */
	stdioFds[STDIN_FILENO] = fakeFd;
    }

    /*
     * Create the I/O completion port to be used for communicating with
     * the thread doing I/O on standard in.  This port will carry read
     * and possibly thread termination requests to the StdinThread.
     */
    if (hStdinCompPort == INVALID_HANDLE_VALUE) {
	hStdinCompPort = CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL,
					      0, 1);
	if(hStdinCompPort == INVALID_HANDLE_VALUE) {
	    printf("<H2>OS_LibInit Failed CreateIoCompletionPort: STDIN!  ERROR: %d</H2>\r\n\r\n",
	       GetLastError());
	    return -1;
	}
    }

    /*
     * Create the thread that will read stdin if the CONTENT_LENGTH
     * is non-zero.
     */
    if((cLenPtr = getenv("CONTENT_LENGTH")) != NULL &&
       atoi(cLenPtr) > 0) {
        hStdinThread = (HANDLE) _beginthread(StdinThread, 0, NULL);
        if (hStdinThread == (HANDLE)(LONG_PTR) -1) {
	    printf("<H2>OS_LibInit Failed to create STDIN thread!  ERROR: %d</H2>\r\n\r\n",
		   GetLastError());
	    return -1;
        }
    }

    /*
     * STDOUT will be used synchronously.
     *
     * XXX: May want to convert this so that it could be used for OVERLAPPED
     *      I/O later.  If so, model it after the Stdin I/O as stdout is
     *      also incapable of async I/O on some servers.
     */
    stdioHandles[STDOUT_FILENO] = GetStdHandle(STD_OUTPUT_HANDLE);
    if(!SetHandleInformation(stdioHandles[STDOUT_FILENO],
			     HANDLE_FLAG_INHERIT, FALSE)) {
        DebugBreak();
	exit(99);
    }

    ASSERT(INT_MIN <= (intptr_t)stdioHandles[STDOUT_FILENO] &&
           (intptr_t)stdioHandles[STDOUT_FILENO] <= INT_MAX);
    if ((fakeFd = Win32NewDescriptor(FD_PIPE_SYNC,
                                     (int)(intptr_t)stdioHandles[STDOUT_FILENO],
				     STDOUT_FILENO)) == -1) {
        return -1;
    } else {
        /*
	 * Set stdout equal to our pseudo FD
	 */
	stdioFds[STDOUT_FILENO] = fakeFd;
    }

    stdioHandles[STDERR_FILENO] = GetStdHandle(STD_ERROR_HANDLE);
    if(!SetHandleInformation(stdioHandles[STDERR_FILENO],
			     HANDLE_FLAG_INHERIT, FALSE)) {
        DebugBreak();
	exit(99);
    }
    ASSERT(INT_MIN <= (intptr_t)stdioHandles[STDERR_FILENO] &&
           (intptr_t)stdioHandles[STDERR_FILENO] <= INT_MAX);
    if ((fakeFd = Win32NewDescriptor(FD_PIPE_SYNC,
                                     (int)(intptr_t)stdioHandles[STDERR_FILENO],
				     STDERR_FILENO)) == -1) {
        return -1;
    } else {
        /*
	 * Set stderr equal to our pseudo FD
	 */
	stdioFds[STDERR_FILENO] = fakeFd;
    }

    return 0;
}
Exemple #22
0
bool Subprocess::Start(const string& command) {
  char pipe_name_out[32], pipe_name_err[32];
  _snprintf(pipe_name_out, _TRUNCATE, "\\\\.\\pipe\\ninja_%p_out", ::GetModuleHandle(NULL));
  _snprintf(pipe_name_err, _TRUNCATE, "\\\\.\\pipe\\ninja_%p_err", ::GetModuleHandle(NULL));
  
  assert(stdout_.state_ == 0);
  assert(stderr_.state_ == 0);

  if (INVALID_HANDLE_VALUE == (stdout_.fd_ = ::CreateNamedPipeA(pipe_name_out, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, 4096, 4096, INFINITE, NULL)))
    Win32Fatal("CreateNamedPipe failed: %s");
  if (INVALID_HANDLE_VALUE == (stderr_.fd_ = ::CreateNamedPipeA(pipe_name_err, PIPE_ACCESS_INBOUND | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE, PIPE_UNLIMITED_INSTANCES, 4096, 4096, INFINITE, NULL)))
    Win32Fatal("CreateNamedPipe failed: %s");

  // assign read channels to io completion ports
  if (!CreateIoCompletionPort(stdout_.fd_, g_ioport, (char*)this - (char*)0, 0))
    Win32Fatal("failed to bind pipe to io completion port: %s");
  if (!CreateIoCompletionPort(stderr_.fd_, g_ioport, (char*)this - (char*)0, 0))
    Win32Fatal("failed to bind pipe to io completion port: %s");

  memset(&stdout_.overlapped_, 0, sizeof(stdout_.overlapped_));
  if (!ConnectNamedPipe(stdout_.fd_, &stdout_.overlapped_) && GetLastError() != ERROR_IO_PENDING)
    Win32Fatal("ConnectNamedPipe failed: %s");
  memset(&stderr_.overlapped_, 0, sizeof(stderr_.overlapped_));
  if (!ConnectNamedPipe(stderr_.fd_, &stderr_.overlapped_) && GetLastError() != ERROR_IO_PENDING)
    Win32Fatal("ConnectNamedPipe failed: %s");


  // get the client pipes
  HANDLE output_write_handle = CreateFile(pipe_name_out, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
  HANDLE output_write_child;
  if (!DuplicateHandle(GetCurrentProcess(),output_write_handle, GetCurrentProcess(),&output_write_child, 0, TRUE, DUPLICATE_SAME_ACCESS))
    Win32Fatal("DuplicateHandle: %s");
  CloseHandle(output_write_handle);

  HANDLE error_wirte_handle = CreateFile(pipe_name_err, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
  HANDLE error_write_child;
  if (!DuplicateHandle(GetCurrentProcess(), error_wirte_handle, GetCurrentProcess(), &error_write_child, 0, TRUE, DUPLICATE_SAME_ACCESS))
    Win32Fatal("DuplicateHandle: %s");
  CloseHandle(error_wirte_handle);
 
  //accept connection
  while (stdout_.state_ != 1 || stderr_.state_ != 1)
    procset_->DoWork();

  PROCESS_INFORMATION pi;
  STARTUPINFOA si;

  // Set up the start up info struct.
  ZeroMemory(&si,sizeof(STARTUPINFO));
  si.cb = sizeof(STARTUPINFO);
  si.dwFlags = STARTF_USESTDHANDLES;
  si.hStdOutput = output_write_child;
  si.hStdInput  = NULL;
  si.hStdError  = error_write_child;
 
  char path[MAX_PATH]; BOOL ok = FALSE;

  const int kCmd32LiteralLen = 17; const char* kCmd32LiteralStr = "\\System32\\cmd.exe";
  const int kCmd32MiddleLen = 6; const char* kCmd32MiddleStr = "\" /c \"";
  GetSystemWindowsDirectoryA(path, sizeof(path) - kCmd32LiteralLen - 1);
  strcat_s(path, sizeof(path), kCmd32LiteralStr);
  size_t win_dir_len = strlen(path);
  char* mem = (char*) malloc(command.size() + win_dir_len + 3 + kCmd32MiddleLen);
  if (!mem)
    Fatal("out of memory: %s", strerror(errno));

  mem[0] = '"';
  memcpy(mem+1, path, win_dir_len);
  memcpy(mem+1+win_dir_len, kCmd32MiddleStr, kCmd32MiddleLen);
  memcpy(mem+1+win_dir_len+kCmd32MiddleLen, command.c_str(), command.size()+1);

  //extract executable name
  char *e,* s = mem+1+win_dir_len+kCmd32MiddleLen;
  while (isspace(*s))
    ++s;
  
  if (*s == '"') {
    while (isspace(*s))
      ++s;
    e = s;
    while (*e && *e != '"')
      ++e;
  } else {
    e = s;
    while (*e && !isspace(*e) && *e != '&' && *e != '|' && *e != '>' && *e != '<')
      ++e;
  }

  // replace '/' with '\' in the executable name
  for (char* i = s; i != e; ++i) {
    if (*i == '/')
      *i = '\\';
  }

#if 0 // old code to manually resolve the executable path name (optimization to avoid launching cmd.exe) - does not really work with relative paths"
  {
    e = s + __min(e-s,MAX_PATH-1);
    memcpy(path, s, e-s);
    path[e-s]='\0';

    // extract the executable and a path 
    char* dirsep = strrchr(path, '\\');
    char* look_up_dirs[] = {NULL, NULL};
    if (dirsep) {
      look_up_dirs[0] = (char*) malloc(dirsep-path);
      memcpy(look_up_dirs[0], path, dirsep-path);
      look_up_dirs[0][dirsep-path] = '\0';
      memmove(path, dirsep+1, strlen(dirsep+1)+1);
    }
 
    DWORD err = ERROR_NOT_ENOUGH_MEMORY;

    if (PathFindOnPathA(path, (PZPCSTR) look_up_dirs)) {
      ok = CreateProcessA(path, mem, NULL,NULL,TRUE, 0, NULL,NULL,&si,&pi);
    }

    free(mem);
  }

  if (!ok)
#endif


  {
    mem[1+win_dir_len+kCmd32MiddleLen+command.size()] = '"';
    mem[1+win_dir_len+kCmd32MiddleLen+command.size()+1] = '\0';
    ok = CreateProcessA(path, mem, NULL,NULL,TRUE, 0, NULL,NULL,&si,&pi);
    free(mem);
  }

  
  if (!ok) {
    char* msg_buf;
    FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*) &msg_buf, 0, NULL);
    fprintf(stderr, "Failed to launch command \"%s\": %s", command.c_str(), msg_buf);
    LocalFree(msg_buf);
  }

  

  // close pipe channels we do not need
  if (error_write_child)
    CloseHandle(error_write_child);
  if (output_write_child)
    CloseHandle(output_write_child);
  
  if (ok) {
    CloseHandle(pi.hThread);

    pid_ = pi.hProcess; // Set global child process handle to cause threads to exit.

    return true;
  }

  // in order to close stdout_.fd_ and stderr_.fd_ we should get the NumBytesRead=0 because error_write_child and output_write_child have been just closed
  // and the DoWork will do the rest of the clean up in this case.
  while (stdout_.state_ != 0 || stderr_.state_ != 0)
    procset_->DoWork();

  return false;
}
Exemple #23
0
static void NotifyCurrentThread()
{
	// (we leave it to the OS to clean these up at process exit - threads are not created often)
	WARN_IF_FALSE(DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS));
}
Exemple #24
0
RTDECL(int)  RTPipeFromNative(PRTPIPE phPipe, RTHCINTPTR hNativePipe, uint32_t fFlags)
{
    AssertPtrReturn(phPipe, VERR_INVALID_POINTER);
    AssertReturn(!(fFlags & ~RTPIPE_N_VALID_MASK), VERR_INVALID_PARAMETER);
    AssertReturn(!!(fFlags & RTPIPE_N_READ) != !!(fFlags & RTPIPE_N_WRITE), VERR_INVALID_PARAMETER);

    /*
     * Get and validate the pipe handle info.
     */
    HANDLE hNative = (HANDLE)hNativePipe;
    AssertReturn(GetFileType(hNative) == FILE_TYPE_PIPE, VERR_INVALID_HANDLE);

    DWORD cMaxInstances;
    DWORD fInfo;
    if (!GetNamedPipeInfo(hNative, &fInfo, NULL, NULL, &cMaxInstances))
        return RTErrConvertFromWin32(GetLastError());
    AssertReturn(!(fInfo & PIPE_TYPE_MESSAGE), VERR_INVALID_HANDLE);
    AssertReturn(cMaxInstances == 1, VERR_INVALID_HANDLE);

    DWORD cInstances;
    DWORD fState;
    if (!GetNamedPipeHandleState(hNative, &fState, &cInstances, NULL, NULL, NULL, 0))
        return RTErrConvertFromWin32(GetLastError());
    AssertReturn(!(fState & PIPE_NOWAIT), VERR_INVALID_HANDLE);
    AssertReturn(!(fState & PIPE_READMODE_MESSAGE), VERR_INVALID_HANDLE);
    AssertReturn(cInstances <= 1, VERR_INVALID_HANDLE);

    /*
     * Looks kind of OK, create a handle so we can try rtPipeQueryInfo on it
     * and see if we need to duplicate it to make that call work.
     */
    RTPIPEINTERNAL *pThis = (RTPIPEINTERNAL *)RTMemAllocZ(sizeof(RTPIPEINTERNAL));
    if (!pThis)
        return VERR_NO_MEMORY;
    int rc = RTCritSectInit(&pThis->CritSect);
    if (RT_SUCCESS(rc))
    {
        pThis->Overlapped.hEvent = CreateEvent(NULL, TRUE /*fManualReset*/,
                                               TRUE /*fInitialState*/, NULL /*pName*/);
        if (pThis->Overlapped.hEvent != NULL)
        {
            pThis->u32Magic        = RTPIPE_MAGIC;
            pThis->hPipe           = hNative;
            pThis->fRead           = !!(fFlags & RTPIPE_N_READ);
            //pThis->fIOPending      = false;
            //pThis->fZeroByteRead   = false;
            //pThis->fBrokenPipe     = false;
            //pThisR->fPromisedWritable= false;
            //pThis->cUsers          = 0;
            //pThis->pbBounceBuf     = NULL;
            //pThis->cbBounceBufUsed = 0;
            //pThis->cbBounceBufAlloc= 0;
            pThis->hPollSet        = NIL_RTPOLLSET;

            HANDLE  hNative2 = INVALID_HANDLE_VALUE;
            FILE_PIPE_LOCAL_INFORMATION Info;
            if (rtPipeQueryInfo(pThis, &Info))
                rc = VINF_SUCCESS;
            else
            {
                if (DuplicateHandle(GetCurrentProcess() /*hSrcProcess*/, hNative /*hSrcHandle*/,
                                    GetCurrentProcess() /*hDstProcess*/, &hNative2 /*phDstHandle*/,
                                    pThis->fRead ? GENERIC_READ : GENERIC_WRITE | FILE_READ_ATTRIBUTES /*dwDesiredAccess*/,
                                    !!(fFlags & RTPIPE_N_INHERIT) /*fInheritHandle*/,
                                    0 /*dwOptions*/))
                {
                    pThis->hPipe = hNative2;
                    if (rtPipeQueryInfo(pThis, &Info))
                        rc = VINF_SUCCESS;
                    else
                    {
                        rc = VERR_ACCESS_DENIED;
                        CloseHandle(hNative2);
                    }
                }
                else
                    hNative2 = INVALID_HANDLE_VALUE;
            }
            if (RT_SUCCESS(rc))
            {
                /*
                 * Verify the pipe state and correct the inheritability.
                 */
                AssertStmt(   Info.NamedPipeState == FILE_PIPE_CONNECTED_STATE
                           || Info.NamedPipeState == FILE_PIPE_CLOSING_STATE
                           || Info.NamedPipeState == FILE_PIPE_DISCONNECTED_STATE,
                           VERR_INVALID_HANDLE);
                AssertStmt(   Info.NamedPipeConfiguration
                           == (   Info.NamedPipeEnd == FILE_PIPE_SERVER_END
                               ? (pThis->fRead ? FILE_PIPE_INBOUND  : FILE_PIPE_OUTBOUND)
                               : (pThis->fRead ? FILE_PIPE_OUTBOUND : FILE_PIPE_INBOUND) ),
                           VERR_INVALID_HANDLE);
                if (   RT_SUCCESS(rc)
                    && hNative2 == INVALID_HANDLE_VALUE
                    && !SetHandleInformation(hNative,
                                             HANDLE_FLAG_INHERIT /*dwMask*/,
                                             fFlags & RTPIPE_N_INHERIT ? HANDLE_FLAG_INHERIT : 0))
                {
                    rc = RTErrConvertFromWin32(GetLastError());
                    AssertMsgFailed(("%Rrc\n", rc));
                }
                if (RT_SUCCESS(rc))
                {
                    /*
                     * Ok, we're good!
                     */
                    if (hNative2 != INVALID_HANDLE_VALUE)
                        CloseHandle(hNative);
                    *phPipe = pThis;
                    return VINF_SUCCESS;
                }
            }

            /* Bail out. */
            if (hNative2 != INVALID_HANDLE_VALUE)
                CloseHandle(hNative2);
            CloseHandle(pThis->Overlapped.hEvent);
        }
        RTCritSectDelete(&pThis->CritSect);
    }
    RTMemFree(pThis);
    return rc;
}
Exemple #25
0
/*
 * StatDialog - show task status
 */
BOOL __export FAR PASCAL StatDialog( HWND hwnd, UINT msg, UINT wparam,
                                    DWORD lparam )
{
    WORD        cmd;
    FARPROC     fp;

    fp = fp;
    lparam = lparam;
    switch( msg ) {
    case WM_INITDIALOG:
        InitStatDialog( hwnd );
        oldIntData = IntData;
        return( TRUE );
        break;
    case WM_VSCROLL:
        ScrollAsmDisplay( hwnd, wparam, &currAddr, &firstAddr,
                        STAT_DISASM_1, STAT_DISASM_8, STAT_SCROLL );
        break;
    case WM_USER:
        /* an owned window is being destroyed make sure
         * Windows doesn't take the focus away from us*/
        SetFocus( hwnd );
        break;
    case WM_CLOSE:
        PostMessage( hwnd, WM_COMMAND, STAT_CANCEL, 0L );
        return( TRUE );
    case WM_COMMAND:
        cmd = LOWORD( wparam );
        switch( cmd ) {
#ifndef __NT__
        case STAT_SEG_MAP:
            fp = MakeProcInstance( SegMapDlgProc, Instance );
            JDialogBox( Instance, "SEG_MAP_DLG", hwnd, fp );
            FreeProcInstance( fp );
            break;
        case STAT_STACK_TRACE:
            StartStackTraceDialog( hwnd );
            break;
#else
        case STAT_SEG_MAP:
            {
                HANDLE                  hdl;
                DuplicateHandle(
                            GetCurrentProcess(),
                            processHdl,
                            GetCurrentProcess(),
                            &hdl,
                            0,
                            FALSE,
                            DUPLICATE_SAME_ACCESS );
                WalkMemory( hwnd, hdl, processID );
            }
            break;
#endif
        case STAT_SYMBOLS:
            if( StatShowSymbols ) {
                StatShowSymbols = FALSE;
            } else {
                StatShowSymbols = TRUE;
            }
            CheckDlgButton( hwnd, STAT_SYMBOLS, ( StatShowSymbols ) ? BST_CHECKED : BST_UNCHECKED );
            DisplayAsmLines( hwnd, &currAddr, &firstAddr, STAT_DISASM_1,
                        STAT_DISASM_8, STAT_SCROLL );
            break;
        case STAT_APPLY:
            GetStatRegisters( hwnd );
            InitStatDialog( hwnd );
            return( TRUE );
        case IDCANCEL:
            IntData = oldIntData;
            EndDialog( hwnd, 0 );
            return( TRUE );
        case IDOK:
            GetStatRegisters( hwnd );
            EndDialog( hwnd, 0 );
            return( TRUE );
        }
    }
    return( FALSE );

} /* StatDialog */
Exemple #26
0
/*
  Execute a command as a "user". The command is run as cmd.exe /c <command>
  The command is executed from the user's HOME (as determined by the user profile)
  Input, Output & Err streams are redirected. 
*/
void *win_execute_command(wchar_t *shell, wchar_t *command, wchar_t *user, wchar_t *password, wchar_t *domain, wchar_t *root, int pty_mode) {
    SECURITY_ATTRIBUTES sa;
    STARTUPINFOW si;
    HANDLE out_rd_tmp, in_wr_tmp, out_wr, in_rd, in_wr, err_wr;
    exec_ctx *ctx;
    HANDLE ttok, ntok;
	int ret;

    ZeroMemory(&sa, sizeof(sa));
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;

    ctx = malloc(sizeof(*ctx));
    ZeroMemory(ctx, sizeof(*ctx));
    ctx->pty_mode = pty_mode;
 
    /* setup the parent child plumbing */
    if (!CreatePipe(&in_rd, &in_wr_tmp, &sa, 0)) {
        printf("Couldn't set up in pipe to child %s", get_error_msg(GetLastError()));
        free(ctx);
        return NULL;
    }

    if (!CreatePipe(&out_rd_tmp, &out_wr, &sa, 0)) {
        printf("Couldn't set up stdout pipe to child %s", get_error_msg(GetLastError()));
		free(ctx);
        return NULL;
    }

    if (!DuplicateHandle(GetCurrentProcess(), out_wr, GetCurrentProcess(), &err_wr, 0, TRUE, DUPLICATE_SAME_ACCESS)) {
		printf("Couldn't set up stderr pipe to child %s", get_error_msg(GetLastError()));
		free(ctx);
		return NULL;
    }

    if (!DuplicateHandle(GetCurrentProcess(), out_rd_tmp, GetCurrentProcess(), &ctx->out_rd, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
		return NULL;
    }
    if (!DuplicateHandle(GetCurrentProcess(), in_wr_tmp, GetCurrentProcess(), &in_wr, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
		return NULL;
    }
    CloseHandle(out_rd_tmp);
    CloseHandle(in_wr_tmp);

    ZeroMemory(&si, sizeof(si));
    si.cb = sizeof(si);
    si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput = in_rd;
    si.hStdOutput = out_wr; 
    si.hStdError = err_wr;
/*
    if (!CreateProcessWithLogonW(user, domain, password, LOGON_WITH_PROFILE, shell, command, 0, NULL, root, &si, &ctx->pi)) {
	*/
	ret = LogonUserW(user, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &ttok);
	if (!ret) {
		CloseHandle(ttok);
		INFO(GetLastError(), "Login failed for user");
		return NULL;
	}
	ret = DuplicateTokenEx(ttok, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &ntok);
	if (!ret) {
		CloseHandle(ttok);
		INFO(GetLastError(), "Can't impersonate user");
		return NULL;
	}
	CloseHandle(ttok);
	if (!CreateProcessAsUserW(ntok, shell, command, NULL, NULL, TRUE, 0, NULL, root, &si, &ctx->pi)) {
		int ecode = GetLastError();
		INFO(GetLastError(), "CreateProcess failed");
        free(ctx);
		CloseHandle(ntok);
        return NULL;
    }
	CloseHandle(ntok);
    CloseHandle(out_wr);
    CloseHandle(err_wr);
    CloseHandle(in_rd);
    return ctx;
}
Exemple #27
0
BOOL CGravador::RodaConsole(DWORD * pdwExitCode, CString strRun)
{
	HANDLE hOutputReadTmp;
	HANDLE hOutputWrite;
	SECURITY_ATTRIBUTES sa;

	strReturn.Empty();

	// Set up the security attributes struct.
	sa.nLength = sizeof(SECURITY_ATTRIBUTES);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;


	// Create the child output pipe.
	if (!CreatePipe(&hOutputReadTmp, &hOutputWrite, &sa, 0))
		DisplayError(_T("CreatePipe"));


	// Create new output read handle and the input write handles. Set
	// the Properties to FALSE. Otherwise, the child inherits the
	// properties and, as a result, non-closeable handles to the pipes
	// are created.
	if (!DuplicateHandle(	GetCurrentProcess(),
							hOutputReadTmp,
							GetCurrentProcess(),
							&hOutputRead, // Address of new handle.
							0,
							FALSE, // Make it uninheritable.
							DUPLICATE_SAME_ACCESS))
		DisplayError(_T("DuplicateHandle"));


	// Close inheritable copies of the handles you do not want to be
	// inherited.
	if (!CloseHandle(hOutputReadTmp))
		DisplayError(_T("CloseHandle"));

	pWDlg->BeginWaitCursor();

	CHandleThread * pHandleThread;
	pHandleThread = new CHandleThread();
	pHandleThread->IniciaThread((void *) this, ReadAndHandleOutput);

	PrepAndLaunchRedirectedChild(hOutputWrite, NULL, NULL, strRun); // o child neste caso será o osql.exe


	// Close pipe handles (do not continue to modify the parent).
	// You need to make sure that no handles to the write end of the
	// output pipe are maintained in this process or else the pipe will
	// not close when the child process exits and the ReadFile will hang.
	if (!CloseHandle(hOutputWrite))
		DisplayError(_T("CloseHandle"));


	// Read the child's output.
	// ReadAndHandleOutput(hOutputRead);

	// Redirection is complete

	// espera finalização do osql.exe
	DWORD dwRet;
	dwRet = WaitForSingleObject(hChildProcess, INFINITE);

	pHandleThread->FinalizaThread(10000);
	delete pHandleThread;

	if (dwRet == WAIT_FAILED)
		DisplayError(_T("WaitForSingleObject"));

	pWDlg->EndWaitCursor();

	if (!CloseHandle(hOutputRead))
		DisplayError(_T("CloseHandle"));

	BOOL bResult;
	bResult = GetExitCodeProcess(hChildProcess, pdwExitCode);
	if (!CloseHandle(hChildProcess))
		DisplayError(_T("CloseHandle"));

	return bResult;
}
void PioletPoisoner::CheckPerformanceCounters()
{
    UINT i;

    // Collect the pdh query data
    if(PdhCollectQueryData(m_pdh))
    {
        MessageBox(NULL,"Error collecting pdh query data","Error",MB_OK);
        return;
    }

    // Check the processor usage counter
    PDH_FMT_COUNTERVALUE value;
    PDH_STATUS error;

    error=PdhGetFormattedCounterValue(m_pdh_counters[0],PDH_FMT_LONG,0,&value);
    if(error)
    {
//		MessageBox("Error formatting pdh counter data");
//		m_dlg.SetWindowText("Error formatting pdh coutner data");
        return;
    }

    m_proc_percent_usage=value.longValue;

    /*
    	// If less than 50 % kick off another mod if there is less than min count of them
    	if((m_proc_percent_usage<50) & (m_connection_manager.ReturnModCount()<(UINT)m_min_module_count))	// was 60
    	{
    		m_connection_manager.AddModule();

    		char log[1024];
    		sprintf(log,"Module Added : (Current Count : %u) : (Proc % Usage : %u%%) : (Min Mod Count : %u)\n",
    			m_connection_manager.ReturnModCount(),m_proc_percent_usage,m_min_module_count);
    		m_log_window_manager.Log(log,0x00888888);
    	}
    */
    // Check the bandwidth counter
    error=PdhGetFormattedCounterValue(m_pdh_counters[1],PDH_FMT_LONG,0,&value);
    if(error)
    {
//		MessageBox("Error formatting pdh counter data");
//		m_dlg.SetWindowText("Error formatting pdh coutner data");
        return;
    }

    m_bandwidth_in_bytes=value.longValue;

    // Check the current bandwidth in bits per second
    error=PdhGetFormattedCounterValue(m_pdh_counters[2],PDH_FMT_LONG,0,&value);
    if(error)
    {
        return;
    }

    m_current_bandwdith_in_bits_per_second=value.longValue;	// this should be 100 Mbps

    double bps=m_bandwidth_in_bytes*8;

    // Measure the processes mem usage
    HANDLE hHandle;
    DuplicateHandle(GetCurrentProcess(),GetCurrentProcess(),GetCurrentProcess(),&hHandle,0,FALSE,DUPLICATE_SAME_ACCESS);

    PROCESS_MEMORY_COUNTERS pmc;
    pmc.cb=sizeof(PROCESS_MEMORY_COUNTERS);
    GetProcessMemoryInfo(hHandle,&pmc,sizeof(PROCESS_MEMORY_COUNTERS));

    CloseHandle(hHandle);

    m_mem_usage=(UINT)pmc.WorkingSetSize;	// in bytes

    // Put commas in the mem measurement value
    char mem_buf[100];
    string mem;
    _itoa(m_mem_usage/1024,mem_buf,10);
    strrev(mem_buf);
    for(i=0; i<strlen(mem_buf); i++)
    {
        if((i>0) && (i%3==0))
        {
            mem+=",";
        }

        mem+=mem_buf[i];
    }
    strcpy(mem_buf,mem.c_str());
    strrev(mem_buf);

    // Display the status
    char buf[1024];
    sprintf(buf,"[ %u %% ] - [ %.2f KB/sec - %.2f %% ] - [ %s KB ]",m_proc_percent_usage,((double)m_bandwidth_in_bytes)/1024,
            (100*bps)/m_current_bandwdith_in_bits_per_second,mem_buf);
    m_dlg.GetDlgItem(IDC_Computer_Status_Static)->SetWindowText(buf);

//	sprintf(buf, "Poison Entries Size: %u", v_poison_entries.size());
//	m_dlg.GetDlgItem(IDC_POISON_ENTRIES_SIZE_STATIC)->SetWindowText(buf);

}
Exemple #29
0
int
CheckForLinkerFeature(
    const char *option)
{
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    SECURITY_ATTRIBUTES sa;
    DWORD threadID;
    char msg[300];
    BOOL ok;
    HANDLE hProcess, h, pipeThreads[2];
    char cmdline[100];

    hProcess = GetCurrentProcess();

    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
    ZeroMemory(&si, sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags   = STARTF_USESTDHANDLES;
    si.hStdInput = INVALID_HANDLE_VALUE;

    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /*
     * Create a non-inheritible pipe.
     */

    CreatePipe(&Out.pipe, &h, &sa, 0);

    /*
     * Dupe the write side, make it inheritible, and close the original.
     */

    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Same as above, but for the error side.
     */

    CreatePipe(&Err.pipe, &h, &sa, 0);
    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);

    /*
     * Base command line.
     */

    lstrcpy(cmdline, "link.exe -nologo ");

    /*
     * Append our option for testing.
     */

    lstrcat(cmdline, option);

    ok = CreateProcess(
	    NULL,	    /* Module name. */
	    cmdline,	    /* Command line. */
	    NULL,	    /* Process handle not inheritable. */
	    NULL,	    /* Thread handle not inheritable. */
	    TRUE,	    /* yes, inherit handles. */
	    DETACHED_PROCESS, /* No console for you. */
	    NULL,	    /* Use parent's environment block. */
	    NULL,	    /* Use parent's starting directory. */
	    &si,	    /* Pointer to STARTUPINFO structure. */
	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */

    if (!ok) {
	DWORD err = GetLastError();
	int chars = snprintf(msg, sizeof(msg) - 1,
		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);

	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
		(300-chars), 0);
	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
	return 2;
    }

    /*
     * Close our references to the write handles that have now been inherited.
     */

    CloseHandle(si.hStdOutput);
    CloseHandle(si.hStdError);

    WaitForInputIdle(pi.hProcess, 5000);
    CloseHandle(pi.hThread);

    /*
     * Start the pipe reader threads.
     */

    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);

    /*
     * Block waiting for the process to end.
     */

    WaitForSingleObject(pi.hProcess, INFINITE);
    CloseHandle(pi.hProcess);

    /*
     * Wait for our pipe to get done reading, should it be a little slow.
     */

    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
    CloseHandle(pipeThreads[0]);
    CloseHandle(pipeThreads[1]);

    /*
     * Look for the commandline warning code in the stderr stream.
     */

    return !(strstr(Out.buffer, "LNK1117") != NULL ||
	    strstr(Err.buffer, "LNK1117") != NULL ||
	    strstr(Out.buffer, "LNK4044") != NULL ||
	    strstr(Err.buffer, "LNK4044") != NULL);
}
Exemple #30
0
bool CSubprocess::CreateProcess(LPCTSTR pszCmdline)
{
  
  STARTUPINFO   si;                    // For CreateProcess call
  HANDLE        hrPipe,hwPipe,hwPipe2,m_hrPipeTemp,m_hwPipeTemp;
  // Create the anonymous pipe
  
  SECURITY_ATTRIBUTES saPipe;          // Security for anonymous pipe
  saPipe.nLength = sizeof(SECURITY_ATTRIBUTES);
  saPipe.lpSecurityDescriptor = NULL;
  saPipe.bInheritHandle = true;
  
  ::CreatePipe(&m_hrPipeTemp,&hwPipe,&saPipe,10240);
  
  // In most cases you can get away with using the same anonymous
  // pipe write handle for both the child's standard output and
  // standard error, but this may cause problems if the child app
  // explicitly closes one of its standard output or error handles. If
  // that happens, the anonymous pipe will close, since the child's
  // standard output and error handles are really the same handle. The
  // child won't be able to write to the other write handle since the
  // pipe is now gone, and parent reads from the pipe will return
  // ERROR_BROKEN_PIPE and child output will be lost. To solve this
  // problem, simply duplicate the write end of the pipe to create
  // another distinct, separate handle to the write end of the pipe.
  // One pipe write handle will serve as standard out, the other as
  // standard error. Now *both* write handles must be closed before the
  // write end of the pipe actually closes.
  
  ::DuplicateHandle(::GetCurrentProcess(),			// Source process
    hwPipe,		        // Handle to duplicate
    ::GetCurrentProcess(),   // Destination process
    &hwPipe2,	            // New handle, used as stderr by child 
    0,                     // New access flags - ignored since DUPLICATE_SAME_ACCESS
    true,                  // It's inheritable
    DUPLICATE_SAME_ACCESS);
  
  ::CreatePipe(&hrPipe,&m_hwPipeTemp,&saPipe,10240);
  

  // Create new output read handle and the input write handles, setting
  // the Properties to FALSE. Otherwise, the child inherits the
  // properties and, as a result, non-closeable handles to the pipes
  // are created.
  DuplicateHandle(GetCurrentProcess(),m_hrPipeTemp,
                       GetCurrentProcess(),
                       &m_hrPipe, // Address of new handle.
                       0,FALSE, // Make it uninheritable.
                       DUPLICATE_SAME_ACCESS);

  DuplicateHandle(GetCurrentProcess(),m_hwPipeTemp,
                       GetCurrentProcess(),
                       &m_hwPipe, // Address of new handle.
                       0,FALSE, // Make it uninheritable.
                       DUPLICATE_SAME_ACCESS);

  // Close inheritable copies of the handles we do not want to be inherited:
  CloseHandle(m_hrPipeTemp);
  CloseHandle(m_hwPipeTemp);


  memset(&si, 0, sizeof(si));
  si.cb = sizeof(si);
  
  si.hStdOutput = hwPipe;
  si.hStdError =  hwPipe2;
  si.hStdInput =  hrPipe;
  si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  si.wShowWindow = SW_SHOW;
  
  LPCTSTR pszDir;
  if(m_strDir.empty()){
    pszDir=NULL; // current directory
  } else {
    pszDir=m_strDir;
  }
  
  PROCESS_INFORMATION pi;
  String strCmd(pszCmdline);

  String strOrigpath;
  if(!m_strPath.empty()){
	  int nSize=GetEnvironmentVariable(_T("PATH"), NULL, 0);
	  if(nSize>0){
      GetEnvironmentVariable(_T("PATH"),strOrigpath.GetBuffer(nSize),nSize);
      strOrigpath.ReleaseBuffer();
      SetEnvironmentVariable(_T("PATH"),m_strPath);
    }
  }

  bool rc=(TRUE==::CreateProcess(NULL,strCmd.GetBuffer(),NULL,NULL,true,DETACHED_PROCESS|CREATE_NEW_PROCESS_GROUP,NULL,pszDir,&si,&pi));

  if(!m_strPath.empty()){
    SetEnvironmentVariable(_T("PATH"),strOrigpath);
  }

  m_nErr=GetLastError();

  strCmd.ReleaseBuffer();
  
  if(rc){
    m_idProcess=pi.dwProcessId;
    m_hProcess=pi.hProcess;
    if(m_bVerbose){
      Output(String::SFormat(_T("*** Process %d created \"%s\"\n"),m_idProcess,pszCmdline));
    }
    TRACE(String::SFormat(_T("Process %d created \"%s\"\n"),m_idProcess,pszCmdline));
    m_nExitCode=STILL_ACTIVE;
    CloseHandle(pi.hThread);
  } else {
    m_idProcess=0;
    if(m_bVerbose){
      Output(String::SFormat(_T("*** Failed to create process \"%s\" %s\n"),pszCmdline,(LPCTSTR)ErrorString()));
    }
    TRACE(String::SFormat(_T("Failed to create process \"%s\" %s\n"),pszCmdline,(LPCTSTR)ErrorString()));
    m_nExitCode=GetLastError();
    CloseHandle(m_hrPipe);m_hrPipe=INVALID_HANDLE_VALUE;
    CloseHandle(m_hwPipe);m_hwPipe=INVALID_HANDLE_VALUE;
  }
  
  CloseHandle(hrPipe);
  CloseHandle(hwPipe);
  CloseHandle(hwPipe2);
  
  return rc;
  
}