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

📄 apis.c

📁 不错的东西 请查看 WINCE OS
💻 C
📖 第 1 页 / 共 4 页
字号:
    @parm DWORD | dwTlsIndex | TLS index to retrieve value for

    @comm Follows the Win32 reference description without restrictions or modifications.
*/
LPVOID WINAPI TlsGetValue(DWORD slot) {
    LPDWORD tlsptr = UTlsPtr ();
    LPVOID lpRet = NULL;
    if (tlsptr && (slot < TLS_MINIMUM_AVAILABLE)) {
        DEBUGCHK ((slot < TLSSLOT_NUMRES) || ((HANDLE) GetCurrentProcessId () == GetOwnerProcess ()));
        // from SDK help:
        // Note  The data stored in a TLS slot can have a value of zero. In this case,
        // the return value is zero and GetLastError returns NO_ERROR.

        // fail TlsGetValue in non-ship build if current process != owner process
#ifndef SHIP_BUILD
        if ((slot >= TLSSLOT_NUMRES) && ((HANDLE) GetCurrentProcessId () != GetOwnerProcess ()))
            SetLastError (ERROR_INVALID_PARAMETER);
        else
#endif
        if (!(lpRet = (LPVOID) tlsptr[slot])) {
            SetLastError (NO_ERROR);
        }
    } else {
        SetLastError (ERROR_INVALID_PARAMETER);
    }
    return lpRet;
}
    
/*
    @doc BOTH EXTERNAL
    
    @func BOOL | TlsSetValue | Stores a 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.
    @parm DWORD | dwTlsIndex | TLS index to set value for
    @parm LPVOID | lpvTlsValue | value to be stored

    @comm Follows the Win32 reference description without restrictions or modifications.
*/
BOOL WINAPI TlsSetValue(DWORD slot, LPVOID value) {
    LPDWORD tlsptr = UTlsPtr ();
    if (tlsptr && (slot < TLS_MINIMUM_AVAILABLE)) {
        DEBUGCHK ((slot < TLSSLOT_NUMRES) || ((HANDLE) GetCurrentProcessId () == GetOwnerProcess ()));

        // fail TlsSetValue in non-ship build if current process != owner process
#ifndef SHIP_BUILD
        if ((slot < TLSSLOT_NUMRES) || ((HANDLE) GetCurrentProcessId () == GetOwnerProcess ()))
#endif
        {
            tlsptr[slot] = (DWORD)value;
            return TRUE;
        }
    }
    SetLastError (ERROR_INVALID_PARAMETER);
    return FALSE;
}

BOOL IsProcessDying() {
    return (UTlsPtr()[TLSSLOT_KERNEL] & TLSKERN_TRYINGTODIE) ? 1 : 0;
}

typedef DWORD (*threadfunctype)(ulong);
typedef DWORD (*comthreadfunctype)(ulong,ulong,ulong,ulong,ulong,ulong,ulong);

// Dupe of structure in showerr.c, change both or move to shared header file
typedef struct _ErrInfo {
    DWORD dwExcpCode;
    DWORD dwExcpAddr;
} ErrInfo, *PErrInfo;

DWORD WINAPI ShowErrThrd (LPVOID lpParam);

HANDLE hMainThread;

VOID WINAPI ThreadExceptionExit (DWORD dwExcpCode, DWORD dwExcpAddr)
{

    // for safety measure, on excpetion, don't call anything in KMode directly
    // or we might hit another exception.
    UTlsPtr ()[PRETLS_THRDINFO] &= ~UTLS_INKMODE;

    // we should've try-excepted all code that can generate an exception while
    // hold ProcCS.
    DEBUGCHK ((HANDLE) GetCurrentThreadId () != ProcCS.OwnerThread);
    ReleaseProcCS ();

    if ((GetCurrentThreadId () == (DWORD) hMainThread) && !(UTlsPtr()[TLSSLOT_KERNEL] & TLSKERN_TRYINGTODIE)) {
        // main thread faulted, show error bux
        ErrInfo errInfo = {dwExcpCode, dwExcpAddr};
        HANDLE hThrd = CreateThread (NULL, 0, ShowErrThrd, &errInfo, 0, NULL);

        if (!hThrd) {
            // if we can't create a thread, don't bother showing the error box since it's likely the system is
            // in a really stressed condition.
            RETAILMSG (1, (L"Main thread in proc %8.8lx faulted, Exception code = %8.8lx, Exception Address = %8.8x!\r\n",
                GetCurrentProcessId(), dwExcpCode, dwExcpAddr));
            RETAILMSG (1, (L"Main thread in proc %8.8lx faulted - cleaning up!\r\n", GetCurrentProcessId()));
        } else {
            WaitForSingleObject (hThrd, INFINITE);
            xxx_CloseHandle (hThrd);
        }

    } else {
        // secondary thread faulted (or stack is completely messed up)
        LPCWSTR pname;
        pname = GetProcName();
        // don't terminate GWES.EXE or DEVICE.EXE
        RETAILMSG(1,(L"%s thread in proc %8.8lx (%s) faulted!\r\n",
                (GetCurrentThreadId () == (DWORD) hMainThread)? L"Main" : L"Secondary",
                GetCurrentProcessId(),pname));
        if (wcsicmp(pname,L"device.exe") && wcsicmp(pname,L"gwes.exe") && wcsicmp(pname,L"services.exe") && wcsicmp(pname,L"filesys.exe")) {
            RETAILMSG(1,(L"Terminating process %8.8lx (%s)!\r\n",GetCurrentProcessId(),pname));
            TerminateThread(hMainThread, dwExcpCode);
        }
    }
    ExitThread (dwExcpCode);
}

void
RegisterDlgClass(
    void
    );


DWORD MainThreadInit (DWORD dwModCnt)
{
    PDLLMAININFO pList = NULL;
    DWORD dwErr = 0;

    if (dwModCnt && !(pList = (PDLLMAININFO) _alloca (dwModCnt * sizeof(DLLMAININFO)))) {
        return ERROR_OUTOFMEMORY;
    }
    EnterCriticalSection (&ProcCS);
    if (dwModCnt) {
        // we need to retrieve the module list before calling CoreDllInit because
        // we might load lmemdebug and destroy the list.
        GetProcModList (pList, dwModCnt);
    }
    CoreDllInit (hInstCoreDll, DLL_PROCESS_ATTACH, 0);
    if (dwModCnt) {
        dwErr = _CallDllMains (pList, dwModCnt, DLL_PROCESS_ATTACH);
    }
    LeaveCriticalSection (&ProcCS);
    return dwErr;
}

#if defined(x86)
// Turn off FPO optimization for base functions so that debugger can correctly unwind retail x86 call stacks
#pragma optimize("y",off)
#endif

void
MainThreadBaseFunc(
    LPVOID      pfn,
    ulong       param1,
    DWORD       dwModCnt,
    ulong       param3,
    HINSTANCE   hCoreDll,
    DWORD       dwRva14,
    DWORD       dwSize14,
    DWORD       dwExeBase
    )
{
    DWORD dwErr;
    extern BOOL InitSysTime (void);

    hMainThread = (HANDLE)GetCurrentThreadId();
    hInstCoreDll = hCoreDll;
    InitSysTime ();

    InitializeCriticalSection (&ProcCS);

    DebugNotify (DLL_PROCESS_ATTACH, (DWORD)pfn);

    // purposely make MainThreadInit a function so the stack used by _alloc can be reused.
    dwErr = MainThreadInit (dwModCnt);

    if (!dwErr) {
        Imm_DllEntry(hInstCoreDll, DLL_PROCESS_ATTACH, 0);

        RegisterDlgClass();

        PSLNotify (DLL_PROCESS_ATTACH, GetCurrentProcessId(), (DWORD) hMainThread);

        dwErr = ((comthreadfunctype)pfn) (param1, 0, param3, SW_SHOW, dwExeBase, dwRva14, dwSize14);
    }
    /* ExitThread stops execution of the current thread */
    ExitThread (dwErr);

}

void ThreadBaseFunc(LPVOID pfn, ulong param)
{
    DWORD retval = 0;
    if (GetCurrentProcessIndex()) {
        Imm_DllEntry (hInstCoreDll, DLL_THREAD_ATTACH, 0);
        DebugNotify(DLL_THREAD_ATTACH,(DWORD)pfn);
        PSLNotify(DLL_THREAD_ATTACH,GetCurrentProcessId(),GetCurrentThreadId());

        // Don't bother calling DLL_THREAD_ATTACH if we're exiting due to exception.
        // Or we might run into deadlock if THREAD_ATTACH calls Heap API.
        if ((LPVOID)ShowErrThrd != pfn) {
            EnterCriticalSection (&ProcCS);
            retval = ThreadAttachOrDetach ();
            CallDllMains (retval, DLL_THREAD_ATTACH);
            LeaveCriticalSection (&ProcCS);
        }
    }

    retval = ((threadfunctype)pfn)(param);
    ExitThread(retval);
    /* ExitThread stops execution of the current thread */
}

#if defined(x86)
// Re-Enable optimization
#pragma optimize("",on)
#endif

/*
    @doc BOTH EXTERNAL
    
    @func VOID | GlobalMemoryStatus | Gets information on the physical and virtual memory of the system
    @parm LPMEMORYSTATUS | lpmst | pointer to structure to receive information
    @comm Follows the Win32 reference description without restrictions or modifications.
*/

VOID WINAPI GlobalMemoryStatus(LPMEMORYSTATUS lpmst) {
    DWORD addr;
    MEMORY_BASIC_INFORMATION mbi;
    lpmst->dwLength = sizeof(MEMORYSTATUS);
    lpmst->dwMemoryLoad = 100 - ((UserKInfo[KINX_PAGEFREE]*100) / UserKInfo[KINX_NUMPAGES]);
    lpmst->dwTotalPhys = UserKInfo[KINX_NUMPAGES]*UserKInfo[KINX_PAGESIZE];
    lpmst->dwAvailPhys = UserKInfo[KINX_PAGEFREE]*UserKInfo[KINX_PAGESIZE];
    lpmst->dwTotalPageFile = 0;
    lpmst->dwAvailPageFile = 0;
    lpmst->dwTotalVirtual = 32*1024*1024;
    lpmst->dwAvailVirtual = 0;
    for (addr = 0x10000; addr < 32*1024*1024; addr += (DWORD)mbi.RegionSize) {
        if (!VirtualQuery((LPCVOID)addr,&mbi,sizeof(mbi)))
            break;
        if (mbi.State == MEM_FREE)
            lpmst->dwAvailVirtual += (mbi.RegionSize - ((~(DWORD)mbi.BaseAddress+1)&0xffff)) & 0xffff0000;
    }
}

BOOL AttachDebugger(LPCWSTR dbgname) {
    if (CeGetCurrentTrust() != OEM_CERTIFY_TRUST) {
        ERRORMSG(1,(L"AttachDebugger failed due to insufficient trust\r\n"));
        SetLastError(ERROR_ACCESS_DENIED);
        return FALSE;
    }
    if (!LoadKernelLibrary(dbgname)) {
        SetLastError(ERROR_FILE_NOT_FOUND);
        return FALSE;
    }
    if (!ConnectDebugger(NULL)) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    return TRUE;
}

BOOL AttachHdstub (LPCWSTR dbgname) {
    if (CeGetCurrentTrust () != OEM_CERTIFY_TRUST) {
        ERRORMSG (1,(L"AttachHdstub failed due to insufficient trust\r\n"));
        SetLastError (ERROR_ACCESS_DENIED);
        return FALSE;
    }
    if (!LoadKernelLibrary (dbgname)) {
        SetLastError (ERROR_FILE_NOT_FOUND);
        return FALSE;
    }
    if (!ConnectHdstub (NULL)) {
        SetLastError (ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    return TRUE;
}


BOOL AttachOsAxsT0 (LPCWSTR dbgname) {
    if (CeGetCurrentTrust () != OEM_CERTIFY_TRUST) {
        ERRORMSG (1,(L"AttachOsAxsT0 failed due to insufficient trust\r\n"));
        SetLastError (ERROR_ACCESS_DENIED);
        return FALSE;
    }
    if (!LoadKernelLibrary (dbgname)) {
        SetLastError (ERROR_FILE_NOT_FOUND);
        return FALSE;
    }
    if (!ConnectOsAxsT0 (NULL)) {
        SetLastError (ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    return TRUE;
}

BOOL AttachOsAxsT1 (LPCWSTR dbgname) {
    if (CeGetCurrentTrust () != OEM_CERTIFY_TRUST) {
        ERRORMSG (1,(L"AttachOsAxsT1 failed due to insufficient trust\r\n"));
        SetLastError (ERROR_ACCESS_DENIED);
        return FALSE;
    }
    if (!LoadKernelLibrary (dbgname)) {
        SetLastError (ERROR_FILE_NOT_FOUND);
        return FALSE;
    }
    if (!ConnectOsAxsT1 (NULL)) {
        SetLastError (ERROR_INVALID_PARAMETER);
        return FALSE;
    }
    return TRUE;
}


#if defined(x86)
// Turn off FPO optimization for CaptureDumpFileOnDevice function so that Watson can correctly unwind retail x86 call stacks
#pragma optimize("y",off)
#endif

BOOL CaptureDumpFileOnDevice(DWORD dwProcessId, DWORD dwThreadId, LPCWSTR pwzExtraFilesPath)
{
    BOOL fHandled = FALSE;
    DWORD dwArguments[5];
    WCHAR wzCanonicalExtraFilesPath[MAX_PATH];
    BOOL  fReportFault = (dwProcessId == (-1)) && (dwThreadId == (-1));
    DWORD dwArg2 = 0;

    if (!fReportFault)
    {
        if (pwzExtraFilesPath)
        {
            if (!CeGetCanonicalPathNameW(pwzExtraFilesPath, wzCanonicalExtraFilesPath, ARRAY_SIZE(wzCanonicalExtraFilesPath), 0))
            {
                fHandled = FALSE;
                SetLastError(ERROR_BAD_PATHNAME);
                goto Exit;
            }
            dwArg2 = (DWORD)wzCanonicalExtraFilesPath;
        }
    }
    else
    {
        // For ReportFault this is actually the pointer to the exception
        dwArg2 = (DWORD)pwzExtraFilesPath;
    }
    
    dwArguments[0] = dwProcessId;
    dwArguments[1] = dwThreadId;
    dwArguments[2] = dwArg2;

    // We pass in the CurrentTrust as an extra safety check in DwDmpGen.cpp
    // DwDmpGen.cpp will do additional trust level checking.
    dwArguments[3] = CeGetCurrentTrust();  
    dwArguments[4] = (DWORD)&CaptureDumpFileOnDevice;
    

⌨️ 快捷键说明

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