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

📄 apis.c

📁 不错的东西 请查看 WINCE OS
💻 C
📖 第 1 页 / 共 4 页
字号:
//
// 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.
//

#define EDB 1
#include "windows.h"
#include "nkintr.h"
#include "bldver.h"
#include "kernel.h"
#include "edbaccess.h"
#include "cnnclpth.h"
#include "errorrep.h"

#undef bIntrIndexHigh
#undef bIntrNumber

extern PEDBACCESS pEDBAccess;


DWORD IsExiting;
DWORD fIsDying;

#include "cscode.c"

extern HANDLE hInstCoreDll;
BOOL Imm_DllEntry(HANDLE hinstDll, DWORD dwReason, LPVOID lpvReserved);
BOOL WINAPI xxx_CloseHandle(HANDLE hObject);
BOOL WINAPI CoreDllInit (HANDLE  hinstDLL, DWORD fdwReason, LPVOID lpvReserved);

CRITICAL_SECTION ProcCS;

static void ReleaseProcCS ()
{
    HANDLE hCurrentThread = (HANDLE) GetCurrentThreadId ();

    if (hCurrentThread == ProcCS.OwnerThread) {
        // if we reach here, we're being terminated while calling DllMain
        // need to clean up the module list
        GetProcModList (NULL, 0);

        do {
            LeaveCriticalSection (&ProcCS);
        } while (hCurrentThread && (hCurrentThread == ProcCS.OwnerThread));
    }
}

typedef BOOL (*comentry_t)(HANDLE,DWORD,LPVOID,LPVOID,DWORD,DWORD);
typedef BOOL (*dllntry_t)(HANDLE,DWORD,LPVOID);

BOOL CallEntry (PDLLMAININFO pInfo, DWORD dwReason)
{
    return pInfo->dwSect14rva
        ? ((comentry_t)pInfo->pDllMain) (pInfo->hLib, dwReason, (LPVOID)IsExiting, pInfo->pBasePtr, pInfo->dwSect14rva, pInfo->dwSect14size)
        : ((dllntry_t)pInfo->pDllMain) (pInfo->hLib, dwReason, (LPVOID)IsExiting);
}

DWORD _CallDllMains (PDLLMAININFO pList, DWORD dwCnt, DWORD dwReason)
{
    // call all the DllMains one by one
    DWORD           dwErr = 0;
    PDLLMAININFO    pTrav;
    DEBUGCHK ((HANDLE) GetCurrentThreadId () == ProcCS.OwnerThread);
    for (pTrav = pList ; dwCnt --; pTrav ++) {
        __try {
            if (!CallEntry (pTrav, dwReason)) {
                dwErr = ERROR_DLL_INIT_FAILED;
            }
        } __except (EXCEPTION_EXECUTE_HANDLER) {
            dwErr = ERROR_DLL_INIT_FAILED;
        }

        // don't continue process-attach if error
        if (dwErr && (DLL_PROCESS_ATTACH == dwReason)) {
            // fail to load libries, call DLL_PROCESS_DETACH on the modules
            // that we've called so far in reverse order
            while (pTrav -- > pList) {
                __try {
                    CallEntry (pTrav, DLL_PROCESS_DETACH);
                } __except (EXCEPTION_EXECUTE_HANDLER) {
                }
            }

            break;
        }
    }
    return dwErr;
}

DWORD CallDllMains (DWORD dwCnt, DWORD dwReason)
{
    DEBUGCHK ((HANDLE) GetCurrentThreadId () == ProcCS.OwnerThread);
    if (dwCnt) {
        DWORD dwErr = ERROR_DLL_INIT_FAILED;
        PDLLMAININFO pList;
        DEBUGCHK ((DWORD) ProcCS.OwnerThread == GetCurrentThreadId ());
        if ((pList = (PDLLMAININFO) _alloca (dwCnt * sizeof (DLLMAININFO)))
            && GetProcModList (pList, dwCnt)) {
            dwErr = _CallDllMains (pList, dwCnt, dwReason);

            // call all the DllMains one by one
            if (DLL_PROCESS_DETACH == dwReason) {
                FreeModFromCurrProc (pList, dwCnt);
            }
        }
        return dwErr;
    }
    return 0;
}

/*
    @doc BOTH EXTERNAL
    
    @func BOOL | IsAPIReady | Tells whether the specified API set has been registered
    @parm DWORD | hAPI | The predefined system handle of the desired API set (from syscall.h)
    @comm During system initialization, some of the components may rely on other
          components that are not yet loaded.  IsAPIReady can be used to check
          if the desired API set is available and thus avoid taking an exception.
*/
BOOL
IsAPIReady(
    DWORD hAPI
    )
{
    if (hAPI > NUM_SYS_HANDLES)
        return FALSE;
    return (UserKInfo[KINX_API_MASK] & (1 << hAPI)) != 0;
}

#if defined(x86)
void DoPslFuncCall(DWORD flags, DWORD proc, DWORD thread, DWORD index) {
    IMPLICIT_DECL(void, index, 0, (DWORD,DWORD,DWORD))(flags,proc,thread);
}
#endif

void PSLNotify(DWORD flags, DWORD proc, DWORD thread) {
    DWORD loop = NUM_SYS_HANDLES;
    while (--loop >= SH_LAST_NOTIFY)
        if (UserKInfo[KINX_API_MASK] & (1 << loop)) {
#if defined(x86)
            DoPslFuncCall(flags,proc,thread,loop);
#else
            IMPLICIT_DECL(void, loop, 0, (DWORD,DWORD,DWORD))(flags,proc,thread);
#endif
        }
}

// @func int | GetAPIAddress | Find API function address
// @rdesc Returns the function address of the requested API (0 if not valid)
// @parm int | setId | API Set index (via QueryAPISetID)
// @parm int | iMethod | method # within the API Set
// @comm Returns the kernel trap address used to invoke the given method within
// the given API Set.

FARPROC GetAPIAddress(int setId, int iMethod)
{
    if (!IsAPIReady((DWORD)setId) || (iMethod > METHOD_MASK))
        return 0;
    return (FARPROC)IMPLICIT_CALL((DWORD)setId, (DWORD)iMethod);
}


/* Support functions which do simple things and then (usually) trap into the kernel */

/* Zero's out critical section info */

/*
    @doc BOTH EXTERNAL
    
    @func BOOL | GetVersionEx | Returns version information for the OS.
    @parm LPOSVERSIONINFO | lpver | address of structure to fill in.

    @comm Follows the Win32 reference description without restrictions or modifications.
*/
BOOL GetVersionEx(LPOSVERSIONINFO lpver) {
    DEBUGCHK(lpver->dwOSVersionInfoSize >= sizeof(OSVERSIONINFO));
    lpver->dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    lpver->dwMajorVersion = CE_MAJOR_VER;
    lpver->dwMinorVersion = CE_MINOR_VER;
    lpver->dwBuildNumber = CE_BUILD_VER;
    lpver->dwPlatformId = VER_PLATFORM_WIN32_CE;
    lpver->szCSDVersion[0] = '\0';
    return TRUE;
}

extern BOOL xxx_SystemParametersInfo_GWE(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);

BOOL SystemParametersInfoW(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni) {
    BOOL retval = FALSE;
    DWORD bytesused;
    switch (uiAction) {
        case SPI_GETPLATFORMTYPE:
        case SPI_GETOEMINFO:
        case SPI_GETPLATFORMVERSION:
            __try  {
                retval = KernelIoControl(IOCTL_HAL_GET_DEVICE_INFO,&uiAction,4,pvParam,uiParam,&bytesused);
            }
            __except (EXCEPTION_EXECUTE_HANDLER) {
                ;
            }
            break;
        default:
            if (IsAPIReady(SH_WMGR))
                retval = xxx_SystemParametersInfo_GWE(uiAction, uiParam, pvParam, fWinIni);
            break;
    }
    return retval;
}

/* Alloc memory for stack, and then create thread (via kernel call) */

/*
    @doc BOTH EXTERNAL
    
    @func HANDLE | CreateThread | Creates a thread to execute within the address space of
    the calling process.

    @parm LPSECURITY_ATTRIBUTES | lpThreadAttributes | address of thread (<p must be NULL>.)
    security attributes.
    @parm DWORD | dwStackSize |  initial thread stack size, in bytes. (<p must be 0>)
    @parm LPTHREAD_START_ROUTINE | lpStartAddress | address of thread function
    @parm LPVOID | lpParameter | argument for new thread
    @parm DWORD | dwCreationFlags | creation flags
    @parm LPDWORD | lpThreadId | address of returned thread identifier


    @comm Follows the Win32 reference description with these restrictions:
    Certain parameters must be set as indicated above.

*/

/* Create a process.  Also creates an event to block on to synchronize the actual
   loading of the process so we can get the return value correctly */

/*
    @doc BOTH EXTERNAL
    
    @func BOOL | CreateProcess | Creates a new process and its primary thread.
    The new process executes the specified executable file.
    @parm LPCTSTR | lpApplicationName | pointer to name of executable module
    @parm LPTSTR | lpCommandLine | pointer to command line string
    @parm LPSECURITY_ATTRIBUTES | lpProcessAttributes | <p Must be NULL> Pointer to process security attributes
    @parm LPSECURITY_ATTRIBUTES | lpThreadAttributes | <p Must be NULL> Pointer to thread security attributes
    @parm BOOL | bInheritHandles | <p Must be FALSE> Handle inheritance flag
    @parm DWORD | dwCreationFlags | creation flag. <p See restrictions below>
    @parm LPVOID | lpEnvironment | <p Must be NULL> Pointer to new environment block
    @parm LPCTSTR | lpCurrentDirectory | <p Must be NULL> Pointer to current directory name
    @parm LPSTARTUPINFO | lpStartupInfo | <p Must be NULL> Pointer to STARTUPINFO
    @parm LPPROCESS_INFORMATION | lpProcessInformation | pointer to PROCESS_INFORMATION

    @comm Follows the Win32 reference description with these restrictions:
    Certain parameters must be set as indicated above.
    The loader does not search a path. Only the following <p dwCreationFlags> parameters are
    supported: CREATE_SUSPENDED.  The command line cannot contain parameters and the parameter
    list cannot contain the name of the executable as the first element.  The parameters and
    command line must be in the two variables, not combined in either one.
    
*/

/*
    @doc BOTH EXTERNAL
    
    @func BOOL | TerminateProcess | Terminates a process
    @parm HANDLE | hProc | handle of process (ProcessID)
    @parm DWORD | dwRetVal | return value of process (ignored)
    @comm You cannot terminate a PSL.
          You may not be able to terminate a process wedged inside a PSL.

*/


VOID WINAPI SystemMemoryLow(void) {
    PSLNotify(DLL_MEMORY_LOW,0,0);
}

/* Terminate thread routine */

/*
    @doc BOTH EXTERNAL
    
    @func VOID | ExitThread | Ends a thread.
    @parm DWORD | dwExitCode | exit code for this thread
    
    @comm Follows the Win32 reference description with the following restriction:
            If the primary thread calls ExitThread, the application will exit

*/
VOID WINAPI ExitThread (DWORD dwExitCode)
{
    // if hInstCoreDll is NULL, the process hasn't even started when it got terminated.
    // don't bother notifying PSL or calling DllMain.
    if (hInstCoreDll) {
        DWORD i = 0;
        DWORD dwReason = DLL_THREAD_DETACH;

        ReleaseProcCS ();

        SetLastError(dwExitCode);
        CloseProcOE(2);
        if (IsPrimaryThread()) {
            IsExiting = 1;
            dwReason = DLL_PROCESS_DETACH;
            KillAllOtherThreads();
            while (OtherThreadsRunning()) {
                if (i < 2) {
                    if (++i == 2)
                        PSLNotify(DLL_PROCESS_EXITING,GetCurrentProcessId(),GetCurrentThreadId());
                }
                KillAllOtherThreads();
                if (i > 1)
                    Sleep(250*(i-1));
            }
            EnterCriticalSection (&ProcCS);
            i = ProcessDetachAllDLLs ();
            CallDllMains (i, dwReason);
            CoreDllInit (hInstCoreDll, dwReason, 0);

            LeaveCriticalSection (&ProcCS);
            DebugNotify(DLL_PROCESS_DETACH,dwExitCode);

            CloseProcOE(1);
            CloseAllHandles();
            PSLNotify(DLL_PROCESS_DETACH,GetCurrentProcessId(),GetCurrentThreadId());
        } else {
            if (!IsExiting && GetCurrentProcessIndex()) {
                EnterCriticalSection (&ProcCS);
                i = ThreadAttachOrDetach ();
                CallDllMains (i, dwReason);
                LeaveCriticalSection (&ProcCS);
                PSLNotify(DLL_THREAD_DETACH,GetCurrentProcessId(),GetCurrentThreadId());
                DebugNotify(DLL_THREAD_DETACH,dwExitCode);
            }
            CloseProcOE(0);
        }
        if (GetCurrentProcessIndex()) {
            LPVOID pBuf;
            Imm_DllEntry (hInstCoreDll, dwReason, 0);
            if ((pBuf = TlsGetValue(TLSSLOT_RUNTIME)) && ((DWORD)pBuf >= 0x10000)) {
                LocalFree((LPVOID)ZeroPtr(pBuf));
            }
        }
    }
    NKTerminateThread(dwExitCode);
}

/* Thread local storage routines (just like Win32) */

/*
    @doc BOTH EXTERNAL
    
    @func LPVOID | TlsGetValue | Retrieves the value in the calling thread's thread local
    storage (TLS) slot for a specified TLS index. Each thread of a process has its own slot
    for each TLS index.

⌨️ 快捷键说明

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