📄 ntmisc.c
字号:
0, /* creation flags */ envBlock, /* an environment block, consisting * of a null-terminated block of * null-terminated strings. Each * string is in the form: * name=value * XXX: usually NULL */ cwd, /* current drive and directory */ &startupInfo, &procInfo ); if (retVal == FALSE) { /* XXX what error code? */ PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); goto errorExit; } CloseHandle(procInfo.hThread); proc->md.handle = procInfo.hProcess; proc->md.id = procInfo.dwProcessId; PR_DELETE(cmdLine); if (newEnvp) { PR_DELETE(newEnvp); } if (envBlock) { PR_DELETE(envBlock); } return proc;errorExit: if (cmdLine) { PR_DELETE(cmdLine); } if (newEnvp) { PR_DELETE(newEnvp); } if (envBlock) { PR_DELETE(envBlock); } if (proc) { PR_DELETE(proc); } return NULL;} /* _PR_CreateWindowsProcess */PRStatus _PR_DetachWindowsProcess(PRProcess *process){ CloseHandle(process->md.handle); PR_DELETE(process); return PR_SUCCESS;}/* * XXX: This implementation is a temporary quick solution. * It can be called by native threads only (not by fibers). */PRStatus _PR_WaitWindowsProcess(PRProcess *process, PRInt32 *exitCode){ DWORD dwRetVal; dwRetVal = WaitForSingleObject(process->md.handle, INFINITE); if (dwRetVal == WAIT_FAILED) { PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); return PR_FAILURE; } PR_ASSERT(dwRetVal == WAIT_OBJECT_0); if (exitCode != NULL && GetExitCodeProcess(process->md.handle, exitCode) == FALSE) { PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); return PR_FAILURE; } CloseHandle(process->md.handle); PR_DELETE(process); return PR_SUCCESS;}PRStatus _PR_KillWindowsProcess(PRProcess *process){ /* * On Unix, if a process terminates normally, its exit code is * between 0 and 255. So here on Windows, we use the exit code * 256 to indicate that the process is killed. */ if (TerminateProcess(process->md.handle, 256)) { return PR_SUCCESS; } PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); return PR_FAILURE;}PRStatus _MD_WindowsGetHostName(char *name, PRUint32 namelen){ PRIntn rv; PRInt32 syserror; rv = gethostname(name, (PRInt32) namelen); if (0 == rv) { return PR_SUCCESS; } syserror = WSAGetLastError(); PR_ASSERT(WSANOTINITIALISED != syserror); _PR_MD_MAP_GETHOSTNAME_ERROR(syserror); return PR_FAILURE;}PRStatus _MD_WindowsGetSysInfo(PRSysInfo cmd, char *name, PRUint32 namelen){ OSVERSIONINFO osvi; PR_ASSERT((cmd == PR_SI_SYSNAME) || (cmd == PR_SI_RELEASE)); ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (! GetVersionEx (&osvi) ) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); return PR_FAILURE; } switch (osvi.dwPlatformId) { case VER_PLATFORM_WIN32_NT: if (PR_SI_SYSNAME == cmd) (void)PR_snprintf(name, namelen, "Windows_NT"); else if (PR_SI_RELEASE == cmd) (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, osvi.dwMinorVersion); break; case VER_PLATFORM_WIN32_WINDOWS: if (PR_SI_SYSNAME == cmd) { if ((osvi.dwMajorVersion > 4) || ((osvi.dwMajorVersion == 4) && (osvi.dwMinorVersion > 0))) (void)PR_snprintf(name, namelen, "Windows_98"); else (void)PR_snprintf(name, namelen, "Windows_95"); } else if (PR_SI_RELEASE == cmd) { (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, osvi.dwMinorVersion); } break; default: if (PR_SI_SYSNAME == cmd) (void)PR_snprintf(name, namelen, "Windows_Unknown"); else if (PR_SI_RELEASE == cmd) (void)PR_snprintf(name, namelen, "%d.%d",0,0); break; } return PR_SUCCESS;}PRStatus _MD_WindowsGetReleaseName(char *name, PRUint32 namelen){ OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (! GetVersionEx (&osvi) ) { _PR_MD_MAP_DEFAULT_ERROR(GetLastError()); return PR_FAILURE; } switch (osvi.dwPlatformId) { case VER_PLATFORM_WIN32_NT: case VER_PLATFORM_WIN32_WINDOWS: (void)PR_snprintf(name, namelen, "%d.%d",osvi.dwMajorVersion, osvi.dwMinorVersion); break; default: (void)PR_snprintf(name, namelen, "%d.%d",0,0); break; } return PR_SUCCESS;}/* ********************************************************************** * * Memory-mapped files * ********************************************************************** */PRStatus _MD_CreateFileMap(PRFileMap *fmap, PRInt64 size){ DWORD dwHi, dwLo; DWORD flProtect; PRUint32 osfd; osfd = ( fmap->fd == (PRFileDesc*)-1 )? -1 : fmap->fd->secret->md.osfd; dwLo = (DWORD) (size & 0xffffffff); dwHi = (DWORD) (((PRUint64) size >> 32) & 0xffffffff); if (fmap->prot == PR_PROT_READONLY) { flProtect = PAGE_READONLY; fmap->md.dwAccess = FILE_MAP_READ; } else if (fmap->prot == PR_PROT_READWRITE) { flProtect = PAGE_READWRITE; fmap->md.dwAccess = FILE_MAP_WRITE; } else { PR_ASSERT(fmap->prot == PR_PROT_WRITECOPY); flProtect = PAGE_WRITECOPY; fmap->md.dwAccess = FILE_MAP_COPY; } fmap->md.hFileMap = CreateFileMapping( (HANDLE) osfd, NULL, flProtect, dwHi, dwLo, NULL); if (fmap->md.hFileMap == NULL) { PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); return PR_FAILURE; } return PR_SUCCESS;}PRInt32 _MD_GetMemMapAlignment(void){ SYSTEM_INFO info; GetSystemInfo(&info); return info.dwAllocationGranularity;}#include "prlog.h"extern PRLogModuleInfo *_pr_shma_lm;void * _MD_MemMap( PRFileMap *fmap, PROffset64 offset, PRUint32 len){ DWORD dwHi, dwLo; void *addr; dwLo = (DWORD) (offset & 0xffffffff); dwHi = (DWORD) (((PRUint64) offset >> 32) & 0xffffffff); if ((addr = MapViewOfFile(fmap->md.hFileMap, fmap->md.dwAccess, dwHi, dwLo, len)) == NULL) { { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &lpMsgBuf, 0, NULL ); PR_LOG( _pr_shma_lm, PR_LOG_DEBUG, ("md_memmap(): %s", lpMsgBuf )); } PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); } return addr;}PRStatus _MD_MemUnmap(void *addr, PRUint32 len){ if (UnmapViewOfFile(addr)) { return PR_SUCCESS; } else { PR_SetError(PR_UNKNOWN_ERROR, GetLastError()); return PR_FAILURE; }}PRStatus _MD_CloseFileMap(PRFileMap *fmap){ CloseHandle(fmap->md.hFileMap); PR_DELETE(fmap); return PR_SUCCESS;}/* *********************************************************************** * * Atomic increment and decrement operations for x86 processors * * We don't use InterlockedIncrement and InterlockedDecrement * because on NT 3.51 and Win95, they return a number with * the same sign as the incremented/decremented result, rather * than the result itself. On NT 4.0 these functions do return * the incremented/decremented result. * * The result is returned in the eax register by the inline * assembly code. We disable the harmless "no return value" * warning (4035) for these two functions. * *********************************************************************** */#if defined(_M_IX86) || defined(_X86_)#pragma warning(disable: 4035)PRInt32 _PR_MD_ATOMIC_INCREMENT(PRInt32 *val){ #if defined(__GNUC__) PRInt32 result; asm volatile ("lock ; xadd %0, %1" : "=r"(result), "=m"(*val) : "0"(1), "m"(*val)); return result + 1;#else __asm { mov ecx, val mov eax, 1 lock xadd dword ptr [ecx], eax inc eax }#endif /* __GNUC__ */}#pragma warning(default: 4035)#pragma warning(disable: 4035)PRInt32 _PR_MD_ATOMIC_DECREMENT(PRInt32 *val){#if defined(__GNUC__) PRInt32 result; asm volatile ("lock ; xadd %0, %1" : "=r"(result), "=m"(*val) : "0"(1), "m"(*val)); //asm volatile("lock ; xadd %0, %1" : "=m" (val), "=a" (result) : "-1" (1)); return result - 1;#else __asm { mov ecx, val mov eax, 0ffffffffh lock xadd dword ptr [ecx], eax dec eax }#endif /* __GNUC__ */}#pragma warning(default: 4035)#pragma warning(disable: 4035)PRInt32 _PR_MD_ATOMIC_ADD(PRInt32 *intp, PRInt32 val){#if defined(__GNUC__) PRInt32 result; //asm volatile("lock ; xadd %1, %0" : "=m" (intp), "=a" (result) : "1" (val)); asm volatile ("lock ; xadd %0, %1" : "=r"(result), "=m"(intp) : "0"(val), "m"(intp)); return result + val;#else __asm { mov ecx, intp mov eax, val mov edx, eax lock xadd dword ptr [ecx], eax add eax, edx }#endif /* __GNUC__ */}#pragma warning(default: 4035)#ifdef _PR_HAVE_ATOMIC_CAS#pragma warning(disable: 4035)void PR_StackPush(PRStack *stack, PRStackElem *stack_elem){#if defined(__GNUC__) void **tos = (void **) stack; void *tmp; retry: if (*tos == (void *) -1) goto retry; __asm__("lock xchg %0,%1" : "=r" (tmp), "=m"(*tos) : "0" (-1), "m"(*tos)); if (tmp == (void *) -1) goto retry; *(void **)stack_elem = tmp; __asm__("" : : : "memory"); *tos = stack_elem;#else __asm { mov ebx, stack mov ecx, stack_elemretry: mov eax,[ebx] cmp eax,-1 je retry mov eax,-1 xchg dword ptr [ebx], eax cmp eax,-1 je retry mov [ecx],eax mov [ebx],ecx }#endif /* __GNUC__ */}#pragma warning(default: 4035)#pragma warning(disable: 4035)PRStackElem * PR_StackPop(PRStack *stack){#if defined(__GNUC__) void **tos = (void **) stack; void *tmp; retry: if (*tos == (void *) -1) goto retry; __asm__("lock xchg %0,%1" : "=r" (tmp), "=m"(*tos) : "0" (-1), "m"(*tos)); if (tmp == (void *) -1) goto retry; if (tmp != (void *) 0) { void *next = *(void **)tmp; *tos = next; *(void **)tmp = 0; } else *tos = tmp; return tmp;#else __asm { mov ebx, stackretry: mov eax,[ebx] cmp eax,-1 je retry mov eax,-1 xchg dword ptr [ebx], eax cmp eax,-1 je retry cmp eax,0 je empty mov ecx,[eax] mov [ebx],ecx mov [eax],0 jmp doneempty: mov [ebx],eaxdone: }#endif /* __GNUC__ */}#pragma warning(default: 4035)#endif /* _PR_HAVE_ATOMIC_CAS */#endif /* x86 processors */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -