b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/* $Id$ */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/** @file
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * VBoxService - Guest page sharing testcase
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2011 Oracle Corporation
2f139cbf73f9adba01382892f33558ad7bcb40cbvboxsync *
2f139cbf73f9adba01382892f33558ad7bcb40cbvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2f139cbf73f9adba01382892f33558ad7bcb40cbvboxsync * available from http://www.virtualbox.org. This file is free software;
2f139cbf73f9adba01382892f33558ad7bcb40cbvboxsync * you can redistribute it and/or modify it under the terms of the GNU
2f139cbf73f9adba01382892f33558ad7bcb40cbvboxsync * General Public License (GPL) as published by the Free Software
2f139cbf73f9adba01382892f33558ad7bcb40cbvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2f139cbf73f9adba01382892f33558ad7bcb40cbvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2f139cbf73f9adba01382892f33558ad7bcb40cbvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/*******************************************************************************
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync* Header Files *
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync*******************************************************************************/
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <iprt/assert.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <iprt/asm.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <iprt/mem.h>
230bd8589bba39933ac5ec21482d6186d675e604vboxsync#include <iprt/messages.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <iprt/stream.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <iprt/string.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <iprt/initterm.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <VBox/VBoxGuestLib.h>
2d97f8baccdd684bc0a8a15eb86bbe9ff2b85374vboxsync#include <iprt/x86.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <stdio.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
2d97f8baccdd684bc0a8a15eb86bbe9ff2b85374vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/*******************************************************************************
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync* Global Variables *
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync*******************************************************************************/
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#ifdef RT_OS_WINDOWS
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <Windows.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <process.h> /* Needed for file version information. */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <tlhelp32.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <psapi.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#include <winternl.h>
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#define SystemModuleInformation 11
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsynctypedef struct _RTL_PROCESS_MODULE_INFORMATION
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync{
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ULONG Section;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync PVOID MappedBase;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync PVOID ImageBase;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ULONG ImageSize;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ULONG Flags;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync USHORT LoadOrderIndex;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync USHORT InitOrderIndex;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync USHORT LoadCount;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync USHORT OffsetToFileName;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync CHAR FullPathName[256];
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsynctypedef struct _RTL_PROCESS_MODULES
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync{
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ULONG NumberOfModules;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync RTL_PROCESS_MODULE_INFORMATION Modules[1];
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsynctypedef NTSTATUS (WINAPI *PFNZWQUERYSYSTEMINFORMATION)(ULONG, PVOID, ULONG, PULONG);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncstatic PFNZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncstatic HMODULE hNtdll = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#define PAGE_STATE_INVALID 0
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#define PAGE_STATE_SHARED 1
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#define PAGE_STATE_READ_WRITE 2
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#define PAGE_STATE_READ_ONLY 3
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#define PAGE_STATE_NOT_PRESENT 4
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/* Page counters. */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncstatic unsigned cNotPresentPages = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncstatic unsigned cWritablePages = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncstatic unsigned cSharedPages = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncstatic unsigned cPrivatePages = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/**
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * Registers a new module with the VMM
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * @param pModule Module ptr
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncvoid VBoxServicePageSharingCheckModule(MODULEENTRY32 *pModule)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync{
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync DWORD dwModuleSize = pModule->modBaseSize;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync BYTE *pBaseAddress = pModule->modBaseAddr;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync bool fFirstLine = true;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync unsigned uPageState, uLastPageState;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync bool fLastWritable = false;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync BYTE *pLastBaseAddress = pBaseAddress;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync uPageState = uLastPageState = PAGE_STATE_INVALID;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("Check module %s base %p size %x\n", pModule->szModule, pBaseAddress, dwModuleSize);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync do
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync bool fShared;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync uint64_t uPageFlags;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#ifdef RT_ARCH_X86
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync int rc = VbglR3PageIsShared((uint32_t)pLastBaseAddress, &fShared, &uPageFlags);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#else
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync int rc = VbglR3PageIsShared((RTGCPTR)pLastBaseAddress, &fShared, &uPageFlags);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#endif
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (RT_FAILURE(rc))
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("VbglR3PageIsShared %p failed with %d\n", pLastBaseAddress, rc);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (RT_SUCCESS(rc))
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (uPageFlags & X86_PTE_P)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (uPageFlags & X86_PTE_RW)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync cWritablePages++;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync uPageState = PAGE_STATE_READ_WRITE;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync else
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (fShared)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync cSharedPages++;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync uPageState = PAGE_STATE_SHARED;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync else
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync cPrivatePages++;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync uPageState = PAGE_STATE_READ_ONLY;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync else
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync cNotPresentPages++;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync uPageState = PAGE_STATE_NOT_PRESENT;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if ( !fFirstLine
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync && uPageState != uLastPageState)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("0x%p\n", pLastBaseAddress + 0xfff);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (uPageState != uLastPageState)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync switch (uPageState)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync case PAGE_STATE_READ_WRITE:
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("%s RW 0x%p - ", pModule->szModule, pBaseAddress);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync break;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync case PAGE_STATE_SHARED:
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("%s SHARED 0x%p - ", pModule->szModule, pBaseAddress);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync break;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync case PAGE_STATE_READ_ONLY:
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("%s PRIV 0x%p - ", pModule->szModule, pBaseAddress);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync break;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync case PAGE_STATE_NOT_PRESENT:
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("%s NP 0x%p - ", pModule->szModule, pBaseAddress);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync break;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync fFirstLine = false;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync uLastPageState = uPageState;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync else
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (!fFirstLine)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("0x%p\n", pLastBaseAddress + 0xfff);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync fFirstLine = true;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (dwModuleSize > PAGE_SIZE)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync dwModuleSize -= PAGE_SIZE;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync else
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync dwModuleSize = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync pLastBaseAddress = pBaseAddress;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync pBaseAddress += PAGE_SIZE;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync while (dwModuleSize);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("0x%p\n", pLastBaseAddress + 0xfff);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync return;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync}
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/**
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * Inspect all loaded modules for the specified process
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * @param dwProcessId Process id
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncvoid VBoxServicePageSharingInspectModules(DWORD dwProcessId)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync{
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (hSnapshot == INVALID_HANDLE_VALUE)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("VBoxServicePageSharingInspectModules: CreateToolhelp32Snapshot failed with %d\n", GetLastError());
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync return;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("VBoxServicePageSharingInspectModules\n");
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync MODULEENTRY32 ModuleInfo;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync BOOL bRet;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ModuleInfo.dwSize = sizeof(ModuleInfo);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync bRet = Module32First(hSnapshot, &ModuleInfo);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync do
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /** todo when changing this make sure VBoxService.exe is excluded! */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync char *pszDot = strrchr(ModuleInfo.szModule, '.');
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if ( pszDot
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync && (pszDot[1] == 'e' || pszDot[1] == 'E'))
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync continue; /* ignore executables for now. */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync VBoxServicePageSharingCheckModule(&ModuleInfo);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync while (Module32Next(hSnapshot, &ModuleInfo));
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync CloseHandle(hSnapshot);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync}
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/**
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * Inspect all running processes for executables and dlls that might be worth sharing
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * with other VMs.
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync *
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncvoid VBoxServicePageSharingInspectGuest()
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync{
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync VBoxServicePageSharingInspectModules(GetCurrentProcessId());
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("\n\nUSER RESULTS\n");
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("cNotPresentPages = %d\n", cNotPresentPages);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("cWritablePages = %d\n", cWritablePages);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("cPrivatePages = %d\n", cPrivatePages);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("cSharedPages = %d\n", cSharedPages);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync cNotPresentPages = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync cWritablePages = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync cPrivatePages = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync cSharedPages = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /* Check all loaded kernel modules. */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (ZwQuerySystemInformation)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ULONG cbBuffer = 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync PVOID pBuffer = NULL;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync PRTL_PROCESS_MODULES pSystemModules;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync NTSTATUS ret = ZwQuerySystemInformation(SystemModuleInformation, (PVOID)&cbBuffer, 0, &cbBuffer);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (!cbBuffer)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("ZwQuerySystemInformation returned length 0\n");
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync goto skipkernelmodules;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync pBuffer = RTMemAllocZ(cbBuffer);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (!pBuffer)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync goto skipkernelmodules;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ret = ZwQuerySystemInformation(SystemModuleInformation, pBuffer, cbBuffer, &cbBuffer);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (ret != 0)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("ZwQuerySystemInformation returned %x (1)\n", ret);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync goto skipkernelmodules;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync pSystemModules = (PRTL_PROCESS_MODULES)pBuffer;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync for (unsigned i = 0; i < pSystemModules->NumberOfModules; i++)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /* User-mode modules seem to have no flags set; skip them as we detected them above. */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (pSystemModules->Modules[i].Flags == 0)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync continue;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /* New module; register it. */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync char szFullFilePath[512];
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync MODULEENTRY32 ModuleInfo;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync strcpy(ModuleInfo.szModule, &pSystemModules->Modules[i].FullPathName[pSystemModules->Modules[i].OffsetToFileName]);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync GetSystemDirectoryA(szFullFilePath, sizeof(szFullFilePath));
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /* skip \Systemroot\system32 */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync char *lpPath = strchr(&pSystemModules->Modules[i].FullPathName[1], '\\');
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (!lpPath)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("Unexpected kernel module name %s\n", pSystemModules->Modules[i].FullPathName);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync break;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync lpPath = strchr(lpPath+1, '\\');
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (!lpPath)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("Unexpected kernel module name %s\n", pSystemModules->Modules[i].FullPathName);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync break;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync strcat(szFullFilePath, lpPath);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync strcpy(ModuleInfo.szExePath, szFullFilePath);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ModuleInfo.modBaseAddr = (BYTE *)pSystemModules->Modules[i].ImageBase;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ModuleInfo.modBaseSize = pSystemModules->Modules[i].ImageSize;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync VBoxServicePageSharingCheckModule(&ModuleInfo);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncskipkernelmodules:
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (pBuffer)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync RTMemFree(pBuffer);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("\n\nKERNEL RESULTS\n");
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("cNotPresentPages = %d\n", cNotPresentPages);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("cWritablePages = %d\n", cWritablePages);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("cPrivatePages = %d\n", cPrivatePages);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("cSharedPages = %d\n", cSharedPages);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync}
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#else
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncvoid VBoxServicePageSharingInspectGuest()
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync{
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /* @todo other platforms */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync}
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#endif
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync/** @copydoc VBOXSERVICE::pfnInit */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncstatic DECLCALLBACK(int) VBoxServicePageSharingInit(void)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync{
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("VBoxServicePageSharingInit\n");
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#ifdef RT_OS_WINDOWS
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync hNtdll = LoadLibrary("ntdll.dll");
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (hNtdll)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync ZwQuerySystemInformation = (PFNZWQUERYSYSTEMINFORMATION)GetProcAddress(hNtdll, "ZwQuerySystemInformation");
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#endif
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /* @todo report system name and version */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /* Never fail here. */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync return VINF_SUCCESS;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync}
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncstatic DECLCALLBACK(void) VBoxServicePageSharingTerm(void)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync{
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("VBoxServicePageSharingTerm\n");
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#ifdef RT_OS_WINDOWS
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (hNtdll)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync FreeLibrary(hNtdll);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync#endif
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync return;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync}
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsyncint main(int argc, char **argv)
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync{
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /*
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * Init globals and such.
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync */
230bd8589bba39933ac5ec21482d6186d675e604vboxsync int rc = RTR3InitExe(argc, &argv, 0);
230bd8589bba39933ac5ec21482d6186d675e604vboxsync if (RT_FAILURE(rc))
230bd8589bba39933ac5ec21482d6186d675e604vboxsync return RTMsgInitFailure(rc);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync /*
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * Connect to the kernel part before daemonizing so we can fail
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * and complain if there is some kind of problem. We need to initialize
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * the guest lib *before* we do the pre-init just in case one of services
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync * needs do to some initial stuff with it.
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync */
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("Calling VbgR3Init()\n");
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync rc = VbglR3Init();
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync if (RT_FAILURE(rc))
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync {
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync printf("VbglR3Init failed with rc=%Rrc.\n", rc);
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync return -1;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync }
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync VBoxServicePageSharingInit();
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync VBoxServicePageSharingInspectGuest();
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync VBoxServicePageSharingTerm();
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync return 0;
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync}
b35e3948f1287430503b6b432945b8cf4bfd3a23vboxsync