Exemplo n.º 1
0
const bool ConsoleUI::StartProgress(LPCTSTR pszText, HANDLE hevtCancel)
{
	AutoCS		autoLock(m_csProgress);		// Automatic critical section object
	DWORD		dwThreadId;					// Launched progress thread id code
	
	if(!LockConsole()) return false;		// Attempt to lock the console handles

	if(!m_hevtStop) { UnlockConsole(); return false; }	// Test STOP event object
	m_hevtCancel = hevtCancel;							// Store CANCEL event object
	
	// Display the standard PLEASE WAIT separator bar, and the progress message
	
	if(Separator(CONSOLE_HEADER_PROGRESS)) BlankLines();
	if(WriteText(pszText)) BlankLines();

	// Attempt to launch the progress worker thread that actually does all of 
	// the real work for us
	
	m_hThread = SVCTL::CreateThread(NULL, 0, ProgressThreadProc, this, 0, &dwThreadId);
	if(!m_hThread) { UnlockConsole(); return false; }

	// NOTE : The call to UnlockConsole() happens in the StopProgress() function

	return true;
}
Exemplo n.º 2
0
void ConsoleUI::DeActivate(void)
{
	CONSOLE_SCREEN_BUFFER_INFO	conInfo;	// Console screen buffer information

	if(!LockConsole(true)) return;						// Wait for the console lock
	if(m_hin == m_hout) { UnlockConsole(); return; }	// Console is not active

	// Revoke the console control handler, and destroy the CTRL+C event object

	SetConsoleCtrlHandler(ConsoleControlHandler, FALSE);
	if(s_hevtCtrlC) CloseHandle(s_hevtCtrlC); 
	s_hevtCtrlC = NULL;

	// Restore the original console window caption if it had been altered

	if(!m_strSavedTitle.IsNull()) SetConsoleTitle(m_strSavedTitle);
	m_strSavedTitle.Clear();

	// Restore the original console screen buffer width if it had been altered

	if(m_uSavedWidth) {

		GetConsoleScreenBufferInfo(m_hout, &conInfo);
		conInfo.dwSize.X = m_uSavedWidth;
		SetConsoleScreenBufferSize(m_hout, conInfo.dwSize);
		m_uSavedWidth = 0;
	}
	
	m_hin = m_hout = INVALID_HANDLE_VALUE;		// Reset the STDIN/STDOUT handles
	UnlockConsole();							// Release the console lock
}
Exemplo n.º 3
0
DWORD ConsoleUI::Activate(LPCTSTR pszTitle)
{
	CONSOLE_SCREEN_BUFFER_INFO	conInfo;			// Console screen buffer info
	Buffer<TCHAR>				strConTitle;		// Console title string buffer
	
	// Attempt to lock the console handles.  The only way this can fail is if
	// the underlying kernel object(s) were not properly created
	
	if(!LockConsole(true)) return ERROR_INVALID_HANDLE;
	
	// Check to see if the input/output handles have already been initialized

	if(m_hin != m_hout) { UnlockConsole(); return ERROR_ALREADY_INITIALIZED; }
	
	// Retrieve the STDIN/STDOUT handles for this process.  If they are both set
	// to INVALID_HANDLE_VALUE, this process is not attached to a console
	
	m_hin = GetStdHandle(STD_INPUT_HANDLE);
	m_hout = GetStdHandle(STD_OUTPUT_HANDLE);
	
	if(m_hin == m_hout) { UnlockConsole(); return ERROR_INVALID_HANDLE; }

	// There are some assumptions made about the width of the console,
	// so ensure that the screen buffer is at least CONSOLE_MIN_WIDTH wide 
	
	if(GetConsoleScreenBufferInfo(m_hout, &conInfo)) {

		if(conInfo.dwSize.X < CONSOLE_MIN_WIDTH) {

			m_uSavedWidth = conInfo.dwSize.X;
			conInfo.dwSize.X = CONSOLE_MIN_WIDTH;
			SetConsoleScreenBufferSize(m_hout, conInfo.dwSize);
		}
	}

	// Change the console window title to reflect the application name

	if((pszTitle) && (strConTitle.Allocate(1025))) {

		if(GetConsoleTitle(strConTitle, 1024) > 0) {

			m_strSavedTitle = strConTitle;		// Save the original title
			SetConsoleTitle(pszTitle);			// Set the new title
		}
	}

	// Attempt to create the CTRL+C handler event object, and register the control
	// handler function to be used for this process

	s_hevtCtrlC = CreateEvent(NULL, FALSE, FALSE, NULL);
	SetConsoleCtrlHandler(ConsoleControlHandler, TRUE);

	BlankLines();							// Start out with a blank line
	UnlockConsole();						// Release the console lock

	return ERROR_SUCCESS;
}
Exemplo n.º 4
0
VOID
FreeCon(
    IN HANDLE ConsoleHandle
)

/*++

Routine Description:

    This routine frees a console and its associated
    data - input buffer and screen buffer.

Arguments:

    ConsoleHandle - Handle of console to free.

Return Value:

Note:

    The console handle table lock must be held when calling this routine.

--*/

{
    PCONSOLE_INFORMATION Console;
    NTSTATUS Status;
    HANDLE hWait;
    HWND hWnd;
    LARGE_INTEGER li;

    Status = DereferenceConsoleHandle(ConsoleHandle,
                                      &Console
                                     );
    ASSERT (NT_SUCCESS(Status));
    Console->Flags |= CONSOLE_TERMINATING;
    NtSetEvent(Console->TerminationEvent,NULL);
    hWnd = Console->hWnd;
    UnlockConsole(Console);

    //
    // Use an event to synchronize the window destruction with
    // the termination of the thread
    //

    if (hWnd != NULL) {
        Status = NtCreateEvent(&hWait, EVENT_ALL_ACCESS,
                               NULL, SynchronizationEvent, FALSE);
        ASSERT(NT_SUCCESS(Status));
        if (GetWindowThreadProcessId(hWnd, NULL) ==
                (DWORD)NtCurrentTeb()->ClientId.UniqueThread) {
            DestroyWindowsWindow(Console,hWait);
        } else {
            PostMessage(hWnd, CM_DESTROY_WINDOW, (DWORD)hWait, 0);
            li.QuadPart = (LONGLONG)-10000 * 10000;
            NtWaitForSingleObject(hWait, FALSE, &li);
        }
        NtClose(hWait);
    }
}
Exemplo n.º 5
0
NTSTATUS
ApiPreamble(
    IN HANDLE ConsoleHandle,
    OUT PCONSOLE_INFORMATION *Console
)
{
    NTSTATUS Status;
#ifdef _X86_
    //Do not lock the console if we are in the special case:
    //(1). we are in the middle of handshaking with ntvdm doing
    //     full-screen to windowed mode transition
    //(2). the calling process is THE ntvdm process(this implies that the
    //     the console has vdm registered.
    //(3). the console handle is the same one.
    // if (1), (2) and (3) are true then the console is already locked
    // (locked by the windowproc while processing the WM_FULLSCREEN
    // message)

    RtlEnterCriticalSection(&ConsoleVDMCriticalSection);
    if (ConsoleVDMOnSwitching != NULL &&
            ConsoleVDMOnSwitching->ConsoleHandle == ConsoleHandle &&
            ConsoleVDMOnSwitching->VDMProcessId == CONSOLE_CLIENTPROCESSID())
    {
        *Console = ConsoleVDMOnSwitching;
        return STATUS_SUCCESS;
    }
    RtlLeaveCriticalSection(&ConsoleVDMCriticalSection);
#endif

    LockConsoleHandleTable();
    Status = DereferenceConsoleHandle(ConsoleHandle,
                                      Console
                                     );
    if (!NT_SUCCESS(Status)) {
        UnlockConsoleHandleTable();
        return((ULONG) Status);
    }
    LockConsole(*Console);
    UnlockConsoleHandleTable();

    //
    // Make sure the console has been initialized and the window is valid
    //

    if ((*Console)->hWnd == NULL || ((*Console)->Flags & CONSOLE_TERMINATING)) {
        KdPrint(("CONSRV: bogus window for console %lx\n", *Console));
        UnlockConsole(*Console);
        return STATUS_INVALID_HANDLE;
    }

    return Status;
}
Exemplo n.º 6
0
const INT_PTR ConsoleUI::Message(UINT uType, LPCTSTR pszText)
{
	INT_PTR			nResult;				// Result from function call

	// Attempt to lock the console, and default the response code if we cannot

	if(!LockConsole()) return DefaultUserResponse(uType, false);

	// Display the icon header and the message text in the console window
	
	if(InsertHeader(uType)) BlankLines();
	if(WriteText(pszText)) BlankLines();	

	nResult = PromptUser(uType);			// Prompt the user for their response
	BlankLines();							// Skip a line for neatness

	UnlockConsole();						// Release the console handle lock
	return nResult;							// Return the user's response
}
Exemplo n.º 7
0
ULONG
SrvVerifyConsoleIoHandle(
    IN OUT PCSR_API_MSG m,
    IN OUT PCSR_REPLY_STATUS ReplyStatus
)

/*++

Routine Description:

    This routine verifies that a console io handle is valid.

Arguments:

    ApiMessageData - Points to parameter structure.

Return Value:

--*/

{
    PCONSOLE_VERIFYIOHANDLE_MSG a = (PCONSOLE_VERIFYIOHANDLE_MSG)&m->u.ApiMessageData;
    PCONSOLE_INFORMATION Console;
    NTSTATUS Status;
    PHANDLE_DATA HandleData;
    PCONSOLE_PER_PROCESS_DATA ProcessData;

    UNREFERENCED_PARAMETER(ReplyStatus);

    Status = ApiPreamble(a->ConsoleHandle,
                         &Console
                        );
    if (NT_SUCCESS(Status)) {
        ProcessData = CONSOLE_PERPROCESSDATA();
        Status = DereferenceIoHandleNoCheck(ProcessData,
                                            HANDLE_TO_INDEX(a->Handle),
                                            &HandleData
                                           );
        UnlockConsole(Console);
    }
    a->Valid = (NT_SUCCESS(Status));
    return STATUS_SUCCESS;
}
Exemplo n.º 8
0
const INT_PTR ConsoleUI::List(UINT uType, LPCTSTR pszHeader, LPCTSTR *rgszItems,
							  DWORD cItems, LPCTSTR pszFooter)
{
	String			strItem;				// Item text string object
	DWORD			dwIndex;				// Loop index variable
	INT_PTR			nResult;				// Result from function call

	// Attempt to lock the console, and default the response code if we cannot

	if(!LockConsole()) return DefaultUserResponse(uType, false);

	// Display the optional faux icon header string, and the list box header text
	
	if(InsertHeader(uType)) BlankLines();
	if(pszHeader) { if(WriteText(pszHeader)) BlankLines(); }

	// Loop through the array of list items to display them in the console
	
	if(rgszItems) {
		
		for(dwIndex = 0; dwIndex < cItems; dwIndex++) {

			strItem = CONSOLE_BULLET;		// Start with the bullet
			strItem += CONSOLE_SPACE;		// Add in a space
			strItem += rgszItems[dwIndex];	// Finish with the text itself

			WriteText(strItem, CONSOLE_LIST_LMARGIN);
		}

		BlankLines();						// Finish up with a blank line
	}

	// Display the optional list box footer text before prompting the user
	
	if(pszFooter) { if(WriteText(pszFooter)) BlankLines(); }
		
	nResult = PromptUser(uType);			// Prompt the user for their response
	BlankLines();							// Skip a line for neatness

	UnlockConsole();						// Release the console handle lock
	return nResult;							// Return the user's response
}
Exemplo n.º 9
0
void ConsoleUI::StopProgress(void)
{
	AutoCS		autoLock(m_csProgress);		// Automatic critical section

	// If the progress worker thread was successfully started, it needs to be
	// shut down, and the progress related variables need to be reset
	
	if(m_hThread) {

		// Signal the STOP event object, and wait for the thread to terminate
		
		SetEvent(m_hevtStop);
		WaitForSingleObject(m_hThread, INFINITE);

		m_hThread = NULL;				// Reset the thread object handle
		m_hevtCancel = NULL;			// Reset the event object handle

		BlankLines();					// Append a blank line to the output
		UnlockConsole();				// Unlock the lock acquired in StartProgress()
	}	
}
Exemplo n.º 10
0
VOID
PropertiesDlgShow(
    IN PCONSOLE_INFORMATION Console
    )

/*++

    Displays the properties dialog and updates the window state,
    if necessary.

--*/

{
    HANDLE hSection = NULL;
    HANDLE hClientSection = NULL;
    HANDLE hThread;
    ULONG ulViewSize;
    LARGE_INTEGER li;
    NTSTATUS Status;
    PCONSOLE_STATE_INFO pStateInfo;
    PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
    PSCREEN_INFORMATION ScreenInfo;
    LPTHREAD_START_ROUTINE MyPropRoutine;

    /*
     * Create a shared memory block.
     */
    li.QuadPart = sizeof(CONSOLE_STATE_INFO) + Console->OriginalTitleLength;
    Status = NtCreateSection(&hSection,
                             SECTION_ALL_ACCESS,
                             NULL,
                             &li,
                             PAGE_READWRITE,
                             SEC_COMMIT,
                             NULL);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x creating file mapping\n", Status));
        return;
    }

    /*
     * Get a pointer to the shared memory block.
     */
    pStateInfo = NULL;
    ulViewSize = 0;
    Status = NtMapViewOfSection(hSection,
                                NtCurrentProcess(),
                                &pStateInfo,
                                0,
                                0,
                                NULL,
                                &ulViewSize,
                                ViewUnmap,
                                0,
                                PAGE_READWRITE);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x mapping view of file\n", Status));
        NtClose(hSection);
        return;
    }

    /*
     * Fill in the shared memory block with the current values.
     */
    ScreenInfo = Console->CurrentScreenBuffer;
    pStateInfo->Length = li.LowPart;
    pStateInfo->ScreenBufferSize = ScreenInfo->ScreenBufferSize;
    pStateInfo->WindowSize.X = CONSOLE_WINDOW_SIZE_X(ScreenInfo);
    pStateInfo->WindowSize.Y = CONSOLE_WINDOW_SIZE_Y(ScreenInfo);
    pStateInfo->WindowPosX = Console->WindowRect.left;
    pStateInfo->WindowPosY = Console->WindowRect.top;
    if (ScreenInfo->Flags & CONSOLE_TEXTMODE_BUFFER) {
        pStateInfo->FontSize = SCR_FONTSIZE(ScreenInfo);
        pStateInfo->FontFamily = SCR_FAMILY(ScreenInfo);
        pStateInfo->FontWeight = SCR_FONTWEIGHT(ScreenInfo);
        wcscpy(pStateInfo->FaceName, SCR_FACENAME(ScreenInfo));
        pStateInfo->CursorSize = ScreenInfo->BufferInfo.TextInfo.CursorSize;
    }
    pStateInfo->FullScreen = Console->FullScreenFlags & CONSOLE_FULLSCREEN;
    pStateInfo->QuickEdit = Console->Flags & CONSOLE_QUICK_EDIT_MODE;
    pStateInfo->AutoPosition = Console->Flags & CONSOLE_AUTO_POSITION;
    pStateInfo->InsertMode = Console->InsertMode;
    pStateInfo->ScreenAttributes = ScreenInfo->Attributes;
    pStateInfo->PopupAttributes = ScreenInfo->PopupAttributes;
    pStateInfo->HistoryBufferSize = Console->CommandHistorySize;
    pStateInfo->NumberOfHistoryBuffers = Console->MaxCommandHistories;
    pStateInfo->HistoryNoDup = Console->Flags & CONSOLE_HISTORY_NODUP;
    RtlCopyMemory(pStateInfo->ColorTable,
                  Console->ColorTable,
                  sizeof(Console->ColorTable));
    pStateInfo->hWnd = Console->hWnd;
    wcscpy(pStateInfo->ConsoleTitle, Console->OriginalTitle);
    NtUnmapViewOfSection(NtCurrentProcess(), pStateInfo);

    /*
     * Map the shared memory block handle into the client side process's
     * address space.
     */
    ProcessHandleRecord = CONTAINING_RECORD(Console->ProcessHandleList.Blink,
                                            CONSOLE_PROCESS_HANDLE,
                                            ListLink);
    Status = NtDuplicateObject(NtCurrentProcess(),
                               hSection,
                               ProcessHandleRecord->ProcessHandle,
                               &hClientSection,
                               0,
                               0,
                               DUPLICATE_SAME_ACCESS);
    if (!NT_SUCCESS(Status)) {
        KdPrint(("CONSRV: error %x mapping handle to client\n", Status));
        NtClose(hSection);
        return;
    }

    /*
     * Get a pointer to the client-side properties routine.
     */
    if (ProcessHandleRecord->PropRoutine) {
        MyPropRoutine = ProcessHandleRecord->PropRoutine;
    } else {
        MyPropRoutine = PropRoutine;
    }

    /*
     * Call back into the client process to spawn the properties dialog.
     */
    UnlockConsole(Console);
    hThread = InternalCreateCallbackThread(ProcessHandleRecord->ProcessHandle,
                                           (DWORD)MyPropRoutine,
                                           (DWORD)hClientSection);
    if (!hThread) {
        KdPrint(("CONSRV: CreateRemoteThread failed %d\n", GetLastError()));
    }
    LockConsole(Console);

    /*
     * Close any open handles and free allocated memory.
     */
    if (hThread)
        NtClose(hThread);
    if (hSection)
        NtClose(hSection);

    return;
}
Exemplo n.º 11
0
NTSTATUS
ConsoleAddProcessRoutine(
    IN PCSR_PROCESS ParentProcess,
    IN PCSR_PROCESS Process
)
{
    PCONSOLE_PER_PROCESS_DATA ProcessData, ParentProcessData;
    PCONSOLE_INFORMATION Console;
    PCONSOLE_PROCESS_HANDLE ProcessHandleRecord;
    NTSTATUS Status = STATUS_SUCCESS;

    ProcessData = CONSOLE_FROMPROCESSPERPROCESSDATA(Process);
    ProcessData->HandleTablePtr = ProcessData->HandleTable;
    ProcessData->HandleTableSize = CONSOLE_INITIAL_IO_HANDLES;
    CONSOLE_SETCONSOLEAPPFROMPROCESSDATA(ProcessData,FALSE);

    if (ParentProcess) {

        ProcessData->RootProcess = FALSE;
        ParentProcessData = CONSOLE_FROMPROCESSPERPROCESSDATA(ParentProcess);

        //
        // If both the parent and new processes are console apps,
        // inherit handles from the parent process.
        //

        if (ParentProcessData->ConsoleHandle != NULL &&
                (Process->Flags & CSR_PROCESS_CONSOLEAPP)) {
            LockConsoleHandleTable();
            if (!(NT_SUCCESS(DereferenceConsoleHandle(ParentProcessData->ConsoleHandle,
                             &Console)))) {
                ProcessData->ConsoleHandle = NULL;
                UnlockConsoleHandleTable();
                return STATUS_PROCESS_IS_TERMINATING;
            }

            //
            // Don't add the process if the console is being shutdown.
            //

            LockConsole(Console);
            if (Console->Flags & CONSOLE_SHUTTING_DOWN) {
                Status = STATUS_PROCESS_IS_TERMINATING;
                ProcessHandleRecord = NULL;
            } else {
                ProcessHandleRecord = HeapAlloc(pConHeap,MAKE_TAG( HANDLE_TAG ),sizeof(CONSOLE_PROCESS_HANDLE));
                if (ProcessHandleRecord == NULL) {
                    Status = STATUS_NO_MEMORY;
                } else {

                    //
                    // duplicate parent's handle table
                    //

                    ASSERT(ProcessData->Foo == 0xF00);
                    Status = InheritIoHandleTable(ProcessData, ParentProcess);
                    if (NT_SUCCESS(Status)) {
                        ProcessHandleRecord->Process = Process;
                        ProcessHandleRecord->CtrlRoutine = NULL;
                        ProcessHandleRecord->PropRoutine = NULL;
                        AddProcessToList(Console,ProcessHandleRecord,Process->ProcessHandle);

                        //
                        // increment console reference count
                        //

                        Console->RefCount++;
                    } else {
                        HeapFree(pConHeap, 0, ProcessHandleRecord);
                    }
                }
            }
            if (!NT_SUCCESS(Status)) {
                ProcessData->ConsoleHandle = NULL;
            }
            UnlockConsole(Console);
            UnlockConsoleHandleTable();
        } else
            ProcessData->ConsoleHandle = NULL;
    } else {
        ProcessData->ConsoleHandle = NULL;
    }
    return Status;
}