static int mw_rename_w32_atomic(const char* oldf, const char* newf)
{
    HANDLE tx;

    tx = __CreateTransaction(NULL, NULL, 0, 0, 0, 0, L"AtomicFileRenameTransaction");
    if (!tx)
    {
        mwPerrorW32("Failed to create transaction for renaming '%s' to '%s'", oldf, newf);
        return 1;
    }

    if (!__MoveFileTransacted(oldf, newf, NULL, NULL, MOVEFILE_REPLACE_EXISTING, tx))
    {
        mwPerrorW32("Failed to move file '%s' to '%s'", oldf, newf);
        return 1;
    }

    if (!__CommitTransaction(tx))
    {
        mwPerrorW32("Failed to commit move of '%s' to '%s'", oldf, newf);
        return 1;
    }

    if (!CloseHandle(tx))
    {
        mwPerrorW32("Failed to close transaction handle for move of '%s' to '%s'", oldf, newf);
        return 1;
    }

    return 0;
}
/* The transactional stuff is only available on Vista and later */
static void initW32TransactionalFunctions()
{
    HMODULE ktm32Lib;
    HMODULE kernel32Lib;

    transactionFuncsInit = TRUE;

    kernel32Lib = LoadLibrary("Kernel32.dll");
    if (!kernel32Lib)
    {
        mwPerrorW32("Could not load Kernel32.dll");
        return;
    }

    ktm32Lib = LoadLibrary("KtmW32.dll");
    if (!ktm32Lib)
    {
        mwPerrorW32("Could not load Ktm32.dll");
        return;
    }

    __CreateTransaction = GetProcAddress(ktm32Lib, "CreateTransaction");
    __CommitTransaction = GetProcAddress(ktm32Lib, "CommitTransaction");
    __MoveFileTransacted = GetProcAddress(kernel32Lib, "MoveFileTransactedA");

    transactionFuncsOK = (__CreateTransaction && __MoveFileTransacted && __CommitTransaction);

    if (!transactionFuncsOK)
    {
        mw_printf("Failed to get transaction functions\n");
    }
}
int mwSetProcessPriority(MWPriority priority)
{
    HANDLE handle;
    DWORD pClass;

    if (!DuplicateHandle(GetCurrentProcess(),
                         GetCurrentProcess(),
                         GetCurrentProcess(),
                         &handle,
                         0,
                         FALSE,
                         DUPLICATE_SAME_ACCESS))
    {
        mwPerrorW32("Failed to get process handle");
        return 1;
    }

    pClass = mwPriorityToPriorityClass(priority);
    if (!SetPriorityClass(handle, pClass))
    {
        mwPerrorW32("Failed to set process priority class to %ld", pClass);
        return 1;
    }

    return 0;
}
int nbDetachSharedScene(NBodyState* st)
{
  #if USE_POSIX_SHMEM
    if (st->scene)
    {
        if (shm_unlink(st->scene->shmemName) < 0)
        {
            mwPerror("Closing shared scene memory '%s'", st->scene->shmemName);
            return 1;
        }
    }
  #elif USE_WIN32_SHARED_MAP
    if (st->scene)
    {
        if (!UnmapViewOfFile((LPCVOID) st->scene))
        {
            mwPerrorW32("Error unmapping shared scene memory");
            return 1;
        }
    }
  #endif /* USE_POSIX_SHMEM */

    st->scene = NULL;
    return 0;
}
int mwOSHasAVXSupport(void)
{
    OSVERSIONINFOEX vInfo;

    vInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    if (!GetVersionEx(&vInfo))
    {
        mwPerrorW32("Error getting Windows version info");
        return FALSE;
    }

    /* Windows 7 SP1 or greater required. Can't find a real way to check. */
    return (vInfo.dwMajorVersion > 6)
        || (vInfo.dwMajorVersion == 6 && vInfo.dwMinorVersion >= 1 && vInfo.wServicePackMajor >= 1);
}