static void UninstallDriver() { SC_HANDLE hSCM = OpenServiceControlManager(); if(!hSCM) return; SC_HANDLE hService = OpenServiceW(hSCM, AKEN_NAME, SERVICE_ALL_ACCESS); if(!hService) return; // stop service SERVICE_STATUS serviceStatus; if(!ControlService(hService, SERVICE_CONTROL_STOP, &serviceStatus)) { // if the problem wasn't that the service is already stopped, // something actually went wrong. const DWORD err = GetLastError(); ENSURE(err == ERROR_SERVICE_NOT_ACTIVE || err == ERROR_SERVICE_CANNOT_ACCEPT_CTRL); } // delete service BOOL ok; ok = DeleteService(hService); WARN_IF_FALSE(ok); ok = CloseServiceHandle(hService); WARN_IF_FALSE(ok); ok = CloseServiceHandle(hSCM); WARN_IF_FALSE(ok); }
static void PopulateNodes() { WUTIL_FUNC(pGetNumaNodeProcessorMask, BOOL, (UCHAR, PULONGLONG)); WUTIL_IMPORT_KERNEL32(GetNumaNodeProcessorMask, pGetNumaNodeProcessorMask); if(!pGetNumaNodeProcessorMask) return; DWORD_PTR processAffinity, systemAffinity; { const BOOL ok = GetProcessAffinityMask(GetCurrentProcess(), &processAffinity, &systemAffinity); WARN_IF_FALSE(ok); } ENSURE(PopulationCount(processAffinity) <= PopulationCount(systemAffinity)); for(UCHAR nodeNumber = 0; nodeNumber <= HighestNodeNumber(); nodeNumber++) { ULONGLONG affinity; { const BOOL ok = pGetNumaNodeProcessorMask(nodeNumber, &affinity); WARN_IF_FALSE(ok); } if(!affinity) continue; // empty node, skip Node* node = AddNode(); node->nodeNumber = nodeNumber; node->processorMask = wcpu_ProcessorMaskFromAffinity(processAffinity, (DWORD_PTR)affinity); } }
WinScopedDisableWow64Redirection::~WinScopedDisableWow64Redirection() { if(!wutil_IsWow64()) return; const BOOL ok = pWow64RevertWow64FsRedirection(m_wasRedirectionEnabled); WARN_IF_FALSE(ok); }
int sem_init(sem_t* sem, int pshared, unsigned value) { SECURITY_ATTRIBUTES sec = { sizeof(SECURITY_ATTRIBUTES) }; sec.bInheritHandle = (BOOL)pshared; HANDLE h = CreateSemaphore(&sec, (LONG)value, 0x7fffffff, 0); WARN_IF_FALSE(h); *sem = (sem_t)h; return 0; }
/* * Send Stereo Metadata. Used mainly to re-route calls * from ImageLayerD3D9 to the 3DV COM object */ void Nv3DVUtils::SendNv3DVMetaData(unsigned int dwWidth, unsigned int dwHeight, HANDLE hSrcLuma, HANDLE hDst) { if (!m3DVStreaming) return; DebugOnly<bool> rv = m3DVStreaming->Nv3DVMetaData((DWORD)dwWidth, (DWORD)dwHeight, hSrcLuma, hDst); WARN_IF_FALSE(rv, "Nv3DVStreaming Nv3DVMetaData failed!"); }
/* * Send Stereo Control Information. Used mainly to re-route * calls from ImageLayerD3D9 to the 3DV COM object */ void Nv3DVUtils::SendNv3DVControl(Nv_Stereo_Mode eStereoMode, bool bEnableStereo, DWORD dw3DVAppHandle) { if (!m3DVStreaming) return; DebugOnly<bool> rv = m3DVStreaming->Nv3DVControl(eStereoMode, bEnableStereo, dw3DVAppHandle); WARN_IF_FALSE(rv, "Nv3DVStreaming Nv3DVControl failed!"); }
Status sys_clipboard_set(const wchar_t* text) { if(!OpenClipboard(hWndNewOwner)) WARN_RETURN(ERR::FAIL); WARN_IF_FALSE(EmptyClipboard()); // NB: to enable copy/pasting something other than text, add // message handlers for WM_RENDERFORMAT and WM_RENDERALLFORMATS. HGLOBAL hMem; Status ret = SetClipboardText(text, hMem); WARN_IF_FALSE(CloseClipboard()); // must happen before GlobalFree ENSURE(GlobalFree(hMem) == 0); // (0 indicates success) return ret; }
static void StartDriver(const OsPath& driverPathname) { const SC_HANDLE hSCM = OpenServiceControlManager(); if(!hSCM) { ENSURE(GetLastError() == ERROR_ACCESS_DENIED); SetLastError(0); return; } SC_HANDLE hService = OpenServiceW(hSCM, AKEN_NAME, SERVICE_ALL_ACCESS); // during development, we want to ensure the newest build is used, so // unload and re-create the service if it's running/installed. // as of 2008-03-24 no further changes to Aken are pending, so this is // disabled (thus also avoiding trouble when running multiple instances) #if 0 if(hService) { BOOL ok = CloseServiceHandle(hService); WARN_IF_FALSE(ok); hService = 0; UninstallDriver(); } #endif // create service (note: this just enters the service into SCM's DB; // no error is raised if the driver binary doesn't exist etc.) if(!hService) { LPCWSTR startName = 0; // LocalSystem // NB: Windows 7 seems to insist upon backslashes (i.e. external_file_string) hService = CreateServiceW(hSCM, AKEN_NAME, AKEN_NAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, OsString(driverPathname).c_str(), 0, 0, 0, startName, 0); ENSURE(hService != 0); } // start service { DWORD numArgs = 0; BOOL ok = StartService(hService, numArgs, 0); if(!ok) { if(GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) { // starting failed. don't raise a warning because this // always happens on least-permission user accounts. //DEBUG_WARN_ERR(ERR::LOGIC); } } } CloseServiceHandle(hService); CloseServiceHandle(hSCM); }
HWND wutil_AppWindow() { if(!hAppWindow) { WARN_IF_FALSE(EnumWindows(FindAppWindowByPid, 0)); // (hAppWindow may still be 0 if we haven't created a window yet) } return hAppWindow; }
WinScopedDisableWow64Redirection::WinScopedDisableWow64Redirection() { // note: don't just check if the function pointers are valid. 32-bit // Vista includes them but isn't running Wow64, so calling the functions // would fail. since we have to check if actually on Wow64, there's no // more need to verify the pointers (their existence is implied). if(!wutil_IsWow64()) return; const BOOL ok = pWow64DisableWow64FsRedirection(&m_wasRedirectionEnabled); WARN_IF_FALSE(ok); }
void mahaf_WriteModelSpecificRegister(u64 reg, u64 value) { AkenWriteRegisterIn in; in.reg = reg; in.value = value; DWORD bytesReturned; // unused but must be passed to DeviceIoControl LPOVERLAPPED ovl = 0; // synchronous BOOL ok = DeviceIoControl(hAken, (DWORD)IOCTL_AKEN_WRITE_MSR, &in, sizeof(in), 0, 0u, &bytesReturned, ovl); WARN_IF_FALSE(ok); }
wchar_t* sys_clipboard_get() { if(!OpenClipboard(hWndNewOwner)) return 0; wchar_t* text; Status ret = GetClipboardText(text); WARN_IF_FALSE(CloseClipboard()); return (ret == INFO::OK)? text : 0; }
static void WritePort(u16 port, u32 value, u8 numBytes) { AkenWritePortIn in; in.value = (DWORD32)value; in.port = (USHORT)port; in.numBytes = (UCHAR)numBytes; DWORD bytesReturned; // unused but must be passed to DeviceIoControl LPOVERLAPPED ovl = 0; // synchronous BOOL ok = DeviceIoControl(hAken, (DWORD)IOCTL_AKEN_WRITE_PORT, &in, sizeof(in), 0, 0u, &bytesReturned, ovl); WARN_IF_FALSE(ok); }
static UCHAR HighestNodeNumber() { WUTIL_FUNC(pGetNumaHighestNodeNumber, BOOL, (PULONG)); WUTIL_IMPORT_KERNEL32(GetNumaHighestNodeNumber, pGetNumaHighestNodeNumber); if(!pGetNumaHighestNodeNumber) return 0; // NUMA not supported => only one node ULONG highestNodeNumber; const BOOL ok = pGetNumaHighestNodeNumber(&highestNodeNumber); WARN_IF_FALSE(ok); return (UCHAR)highestNodeNumber; }
void mahaf_UnmapPhysicalMemory(volatile void* virtualAddress) { ENSURE(!mahaf_IsPhysicalMappingDangerous()); AkenUnmapIn in; in.virtualAddress = (DWORD64)virtualAddress; DWORD bytesReturned; // unused but must be passed to DeviceIoControl LPOVERLAPPED ovl = 0; // synchronous BOOL ok = DeviceIoControl(hAken, (DWORD)IOCTL_AKEN_UNMAP, &in, sizeof(in), 0, 0u, &bytesReturned, ovl); WARN_IF_FALSE(ok); }
static void DetectWow64() { // function not found => running on 32-bit Windows if(!pIsWow64Process) { isWow64 = false; return; } BOOL isWow64Process = FALSE; const BOOL ok = pIsWow64Process(GetCurrentProcess(), &isWow64Process); WARN_IF_FALSE(ok); isWow64 = (isWow64Process == TRUE); }
size_t numa_AvailableMemory(size_t node) { // note: it is said that GetNumaAvailableMemoryNode sometimes incorrectly // reports zero bytes. the actual cause may however be unexpected // RAM configuration, e.g. not all slots filled. WUTIL_FUNC(pGetNumaAvailableMemoryNode, BOOL, (UCHAR, PULONGLONG)); WUTIL_IMPORT_KERNEL32(GetNumaAvailableMemoryNode, pGetNumaAvailableMemoryNode); if(pGetNumaAvailableMemoryNode) { const UCHAR nodeNumber = NodeNumberFromNode(node); ULONGLONG availableBytes; const BOOL ok = pGetNumaAvailableMemoryNode(nodeNumber, &availableBytes); WARN_IF_FALSE(ok); const size_t availableMiB = size_t(availableBytes / MiB); return availableMiB; } // NUMA not supported - return available system memory else return os_cpu_MemoryAvailable(); }
/** * Sets the device info, along with any other initialization that is needed after device creation * Pass the D3D9 device pointer is an IUnknown input argument. */ void Nv3DVUtils::SetDeviceInfo(IUnknown *devUnknown) { if (!devUnknown) { WARNING("D3D Device Pointer (IUnknown) is NULL.\n"); return; } if (!m3DVStreaming) { return; } bool rv = m3DVStreaming->Nv3DVSetDevice(devUnknown); if (!rv) { WARNING("Nv3DVStreaming Nv3DVControl failed!"); return; } rv = m3DVStreaming->Nv3DVControl(NV_STEREO_MODE_RIGHT_LEFT, true, FIREFOX_3DV_APP_HANDLE); WARN_IF_FALSE(rv, "Nv3DVStreaming Nv3DVControl failed!"); }
Status wutil_SetPrivilege(const wchar_t* privilege, bool enable) { WinScopedPreserveLastError s; HANDLE hToken; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken)) return ERR::_1; TOKEN_PRIVILEGES tp; if (!LookupPrivilegeValueW(NULL, privilege, &tp.Privileges[0].Luid)) return ERR::_2; tp.PrivilegeCount = 1; tp.Privileges[0].Attributes = enable? SE_PRIVILEGE_ENABLED : 0; SetLastError(0); const BOOL ok = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, 0, 0); if(!ok || GetLastError() != 0) return ERR::_3; WARN_IF_FALSE(CloseHandle(hToken)); return INFO::OK; }
int uname(struct utsname* un) { OSVERSIONINFOW vi = { sizeof(OSVERSIONINFOW) }; GetVersionExW(&vi); // OS implementation name sprintf_s(un->sysname, ARRAY_SIZE(un->sysname), "%ls", wversion_Family()); // release info const wchar_t* vs = vi.szCSDVersion; int sp; if(swscanf_s(vs, L"Service Pack %d", &sp) == 1) sprintf_s(un->release, ARRAY_SIZE(un->release), "SP %d", sp); else un->release[0] = '\0'; // version sprintf_s(un->version, ARRAY_SIZE(un->version), "%ls.%lu", wversion_String(), vi.dwBuildNumber & 0xFFFF); // node name { WinScopedPreserveLastError s; // GetComputerName DWORD bufSize = sizeof(un->nodename); WARN_IF_FALSE(GetComputerNameA(un->nodename, &bufSize)); } // hardware type SYSTEM_INFO si; GetSystemInfo(&si); if(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) strcpy_s(un->machine, ARRAY_SIZE(un->machine), "x64"); else strcpy_s(un->machine, ARRAY_SIZE(un->machine), "x86"); return 0; }
int sem_post(sem_t* sem) { HANDLE h = HANDLE_from_sem_t(sem); WARN_IF_FALSE(ReleaseSemaphore(h, 1, 0)); return 0; }
static void NotifyCurrentThread() { // (we leave it to the OS to clean these up at process exit - threads are not created often) WARN_IF_FALSE(DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &hCurrentThread, 0, FALSE, DUPLICATE_SAME_ACCESS)); }
Status prof_shutdown() { WARN_IF_FALSE(CloseHandle(prof_target_thread)); return INFO::OK; }
int sem_destroy(sem_t* sem) { HANDLE h = HANDLE_from_sem_t(sem); WARN_IF_FALSE(CloseHandle(h)); return 0; }