📄 apis.c
字号:
@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 + -