⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stioinit.c

📁 不错的东西 请查看 WINCE OS
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
/***
* stioinit.c - Init that is ONLY pulled in if CORSTIOA or CORESTIOW 
*       components are selected
*
*
*Purpose:
*       Init code for all the STDIO functionality in CE
*
*******************************************************************************/

#include <cruntime.h>
#include <crtmisc.h>
#include <internal.h>
#include <malloc.h>
#include <mtdll.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <crttchar.h>
#include <dbgint.h>
#include <msdos.h>
#include <coredll.h>
#include <console.h>

extern FARPROC pfnTermStdio;

// This data should NOT be pulled in in the STR-only version
// Other Locks
CRITICAL_SECTION csIobScanLock;   // used to lock entire __piob array

// This is the basic structure of the STDIO/buffered IO portion
// of the library. The FILE handle apps get are actualy FILEX ptrs
// This array grows dynamically in increments of NSTREAM_INCREMENT
FILEX** __piob; // pointer to an array of ptrs to FILEX*
int _nstream;   // Current length of the __piob array.

// Console globals. Initialized on access to the console handles stdin/out/err
// (if they havn't been redirected). Access to these is protected by the 
// csStdioInitLock both at Init and later in OpenStdConsole & LowioTerm
HANDLE hConsoleDevice;
int    iConsoleNumber;
HANDLE hCOMPort = INVALID_HANDLE_VALUE;
HMODULE hCoreDll = NULL;

tGetCommState fGetCommState = NULL;
tSetCommState fSetCommState = NULL;
tSetCommTimeouts fSetCommTimeouts = NULL;
tGetCommTimeouts fGetCommTimeouts = NULL;

// Value of regkey we read to decide whether to redirect console to COMx: or debugout
int iConsoleRedir;
DWORD dwCOMSpeed;

// functions decalred in this file
void __cdecl ConsoleRedirInit(void);
int __cdecl TermStdio(void);
BOOL __cdecl InitPiob(void);
void __cdecl TermPiob(void);
void __cdecl MarkConsoleForDereg(void);
BOOL __cdecl LowioInit(void);
void __cdecl LowioTerm(void);
int __cdecl _real_filbuf2(FILEX *str, int fWide);
int __cdecl _real_flsbuf2(int ch,FILEX *str, int fWide);

int __cdecl _InitStdioLib(void)
{
    // already inside csStdioInitLock
    DEBUGMSG (DBGSTDIO, (TEXT("Stdio: STDIO is being INITED\r\n")));
    
    // Init the rest of the locks
    InitializeCriticalSection(&csIobScanLock);
    
    if(!LowioInit())
        return FALSE;
        
    // setup __piob array & init stdin/out/err FILEX structs. Must be last
    if(!InitPiob())
        return FALSE;

    // Init for the str-only library
    _pfnfilbuf2 = _real_filbuf2;
    _pfnflsbuf2 = _real_flsbuf2;

    // setup cleanup function pointer
    pfnTermStdio = TermStdio;
    return TRUE;
}

/*
 * Cleanup
 */

int __cdecl TermStdio(void)
{
    EnterCriticalSection(&csStdioInitLock);
    if(!fStdioInited) goto done;

    // we can't do a real deregister due to possibel deadlock
    // so we've added this IOCTL hack. Do this before TermPiob
    MarkConsoleForDereg();
    
    TermPiob();  // flush & close all stream & free __piob. Must be called *before* LowioTerm
    LowioTerm(); // DeRegister our console device if any
    
    DeleteCriticalSection(&csIobScanLock);
    fStdioInited = FALSE;

done:
    LeaveCriticalSection(&csStdioInitLock);
    return 0;
}

/***
* InitPiob 
*   Create and initialize the __piob array.
*******************************************************************************/

BOOL __cdecl InitPiob(void)
{
    int i;

    // We are inside the csInitStdioLock critsec
    _nstream = INITIAL_NSTREAM;
    if(!(__piob = (FILEX**)_malloc_crt(_nstream * sizeof(FILEX*))))
    {
        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
        return FALSE;
    }
    memset(__piob, 0, (_nstream * sizeof(FILEX*)));

    // Initialize the stdin/out/err handles
    for ( i = 0 ; i < 3 ; i++ ) 
    {
        // allocate a new _FILEX, set _piob[i] to it and return a pointer to it.
        if(!(__piob[i] = _malloc_crt(sizeof(_FILEX))))
        {
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            return FALSE;
        }
        memset(__piob[i], 0, sizeof(_FILEX));
        InitializeCriticalSection( &(__piob[i]->lock) );
        __piob[i]->fd = i;
        __piob[i]->osfhnd = INVALID_HANDLE_VALUE;
        __piob[i]->peekch = '\n';

        // These have been initialize them with invalid handles. When anyone tries actual 
        // IO to these handles we'll catch them & open the console then
        // however these must be set like it's all A-OK
        __piob[i]->osfile = (BYTE)(FTEXT|FDEV|FOPEN); 
        __piob[i]->_flag = ((i==0) ? _IOREAD : _IOWRT);
    }
    return TRUE;
}

/***
* TermPiob
*
*   (1) Flush all streams.  (Do this even if we're going to
*   call fcloseall since that routine won't do anything to the
*   std streams.)
*
*   (2) If returning to caller, close all streams.  This is
*   not necessary if the exe is terminating because the OS will
*   close the files for us (much more efficiently, too).
*
*******************************************************************************/

void __cdecl TermPiob(void)
{
    // We are inside the csInitStdioLock critsec
    
    // flush all streams 
    _flushall();
        _fcloseall();

    }

BOOL __cdecl LowioInit(void)
{
    // We are inside the csInitStdioLock critsec
    // Read the console-redir registry key
    ConsoleRedirInit();
    
    // but don't do anything else with the console YET
    hConsoleDevice = NULL;
    iConsoleNumber = -1;
    hCOMPort = INVALID_HANDLE_VALUE;
    return TRUE;
}

void __cdecl MarkConsoleForDereg(void)
{
    int i;
    DWORD dwDummy;
    // NOTE: This IOCTL is here to avoid a deadlock between (a) us being in our 
    // DllMain calling DeregisterDevice (and hence trying to acquire the device 
    // CS *after* the loader CS and (b) Various other devices which acquire the 
    // device CS *before* the Loader CS (by calling LoadLib, FreeLib etc inside
    // the device fns etc). See #4165. 

    // IOCTL call has to be on a *file* handle, not a device handle, so we try
    // all 3 of stdin, out & err
    if(hConsoleDevice)
    {
        for(i=0; i<3; i++)
        {
            if(__piob[i]->osfhnd != INVALID_HANDLE_VALUE)
                DeviceIoControl(__piob[i]->osfhnd, IOCTL_DEVICE_AUTODEREGISTER, NULL, 0, NULL, 0, &dwDummy, NULL);
        }
        hConsoleDevice = NULL;
        iConsoleNumber = -1;
    }
}

void __cdecl LowioTerm(void)
{
    // does nothing now 
}

/*------------------------------------------------------------
 * This function is called from LowioInit() to just read the 
 * Console redirect registry key. No action is taken based on

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -