/* Internal interfaces for the Windows code
   Copyright (C) 1995-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "gdbsupport/common-defs.h"
#include "nat/windows-nat.h"
#include "gdbsupport/common-debug.h"

namespace windows_nat
{

HANDLE current_process_handle;
DWORD current_process_id;
DWORD main_thread_id;
enum gdb_signal last_sig = GDB_SIGNAL_0;
DEBUG_EVENT current_event;

/* The most recent event from WaitForDebugEvent.  Unlike
   current_event, this is guaranteed never to come from a pending
   stop.  This is important because only data from the most recent
   event from WaitForDebugEvent can be used when calling
   ContinueDebugEvent.  */
static DEBUG_EVENT last_wait_event;

DWORD desired_stop_thread_id = -1;
std::vector<pending_stop> pending_stops;
EXCEPTION_RECORD siginfo_er;

#ifdef __x86_64__
bool wow64_process = false;
bool ignore_first_breakpoint = false;
#endif

AdjustTokenPrivileges_ftype *AdjustTokenPrivileges;
DebugActiveProcessStop_ftype *DebugActiveProcessStop;
DebugBreakProcess_ftype *DebugBreakProcess;
DebugSetProcessKillOnExit_ftype *DebugSetProcessKillOnExit;
EnumProcessModules_ftype *EnumProcessModules;
#ifdef __x86_64__
EnumProcessModulesEx_ftype *EnumProcessModulesEx;
#endif
GetModuleInformation_ftype *GetModuleInformation;
GetModuleFileNameExA_ftype *GetModuleFileNameExA;
GetModuleFileNameExW_ftype *GetModuleFileNameExW;
LookupPrivilegeValueA_ftype *LookupPrivilegeValueA;
OpenProcessToken_ftype *OpenProcessToken;
GetCurrentConsoleFont_ftype *GetCurrentConsoleFont;
GetConsoleFontSize_ftype *GetConsoleFontSize;
#ifdef __x86_64__
Wow64SuspendThread_ftype *Wow64SuspendThread;
Wow64GetThreadContext_ftype *Wow64GetThreadContext;
Wow64SetThreadContext_ftype *Wow64SetThreadContext;
Wow64GetThreadSelectorEntry_ftype *Wow64GetThreadSelectorEntry;
#endif
GenerateConsoleCtrlEvent_ftype *GenerateConsoleCtrlEvent;

/* Note that 'debug_events' must be locally defined in the relevant
   functions.  */
#define DEBUG_EVENTS(fmt, ...) \
  debug_prefixed_printf_cond (debug_events, "windows events", fmt, \
			      ## __VA_ARGS__)

windows_thread_info::~windows_thread_info ()
{
}

void
windows_thread_info::suspend ()
{
  if (suspended != 0)
    return;

  if (SuspendThread (h) == (DWORD) -1)
    {
      DWORD err = GetLastError ();

      /* We get Access Denied (5) when trying to suspend
	 threads that Windows started on behalf of the
	 debuggee, usually when those threads are just
	 about to exit.
	 We can get Invalid Handle (6) if the main thread
	 has exited.  */
      if (err != ERROR_INVALID_HANDLE && err != ERROR_ACCESS_DENIED)
	warning (_("SuspendThread (tid=0x%x) failed. (winerr %u)"),
		 (unsigned) tid, (unsigned) err);
      suspended = -1;
    }
  else
    suspended = 1;
}

void
windows_thread_info::resume ()
{
  if (suspended > 0)
    {
      stopped_at_software_breakpoint = false;

      if (ResumeThread (h) == (DWORD) -1)
	{
	  DWORD err = GetLastError ();
	  warning (_("warning: ResumeThread (tid=0x%x) failed. (winerr %u)"),
		   (unsigned) tid, (unsigned) err);
	}
    }
  suspended = 0;
}

/* Return the name of the DLL referenced by H at ADDRESS.  UNICODE
   determines what sort of string is read from the inferior.  Returns
   the name of the DLL, or NULL on error.  If a name is returned, it
   is stored in a static buffer which is valid until the next call to
   get_image_name.  */

static const char *
get_image_name (HANDLE h, void *address, int unicode)
{
#ifdef __CYGWIN__
  static char buf[MAX_PATH];
#else
  static char buf[(2 * MAX_PATH) + 1];
#endif
  DWORD size = unicode ? sizeof (WCHAR) : sizeof (char);
  char *address_ptr;
  int len = 0;
  char b[2];
  SIZE_T done;

  /* Attempt to read the name of the dll that was detected.
     This is documented to work only when actively debugging
     a program.  It will not work for attached processes.  */
  if (address == NULL)
    return NULL;

  /* See if we could read the address of a string, and that the
     address isn't null.  */
  if (!ReadProcessMemory (h, address,  &address_ptr,
			  sizeof (address_ptr), &done)
      || done != sizeof (address_ptr)
      || !address_ptr)
    return NULL;

  /* Find the length of the string.  */
  while (ReadProcessMemory (h, address_ptr + len++ * size, &b, size, &done)
	 && (b[0] != 0 || b[size - 1] != 0) && done == size)
    continue;

  if (!unicode)
    ReadProcessMemory (h, address_ptr, buf, len, &done);
  else
    {
      WCHAR *unicode_address = (WCHAR *) alloca (len * sizeof (WCHAR));
      ReadProcessMemory (h, address_ptr, unicode_address, len * sizeof (WCHAR),
			 &done);
#ifdef __CYGWIN__
      wcstombs (buf, unicode_address, MAX_PATH);
#else
      WideCharToMultiByte (CP_ACP, 0, unicode_address, len, buf, sizeof buf,
			   0, 0);
#endif
    }

  return buf;
}

/* The exception thrown by a program to tell the debugger the name of
   a thread.  The exception record contains an ID of a thread and a
   name to give it.  This exception has no documented name, but MSDN
   dubs it "MS_VC_EXCEPTION" in one code example.  */
#define MS_VC_EXCEPTION 0x406d1388

handle_exception_result
handle_exception (struct target_waitstatus *ourstatus, bool debug_exceptions)
{
#define DEBUG_EXCEPTION_SIMPLE(x)       if (debug_exceptions) \
  debug_printf ("gdb: Target exception %s at %s\n", x, \
    host_address_to_string (\
      current_event.u.Exception.ExceptionRecord.ExceptionAddress))

  EXCEPTION_RECORD *rec = &current_event.u.Exception.ExceptionRecord;
  DWORD code = rec->ExceptionCode;
  handle_exception_result result = HANDLE_EXCEPTION_HANDLED;

  memcpy (&siginfo_er, rec, sizeof siginfo_er);

  ourstatus->kind = TARGET_WAITKIND_STOPPED;

  /* Record the context of the current thread.  */
  thread_rec (ptid_t (current_event.dwProcessId, current_event.dwThreadId, 0),
	      DONT_SUSPEND);

  switch (code)
    {
    case EXCEPTION_ACCESS_VIOLATION:
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
      ourstatus->value.sig = GDB_SIGNAL_SEGV;
      if (handle_access_violation (rec))
	return HANDLE_EXCEPTION_UNHANDLED;
      break;
    case STATUS_STACK_OVERFLOW:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
      ourstatus->value.sig = GDB_SIGNAL_SEGV;
      break;
    case STATUS_FLOAT_DENORMAL_OPERAND:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case STATUS_FLOAT_INEXACT_RESULT:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case STATUS_FLOAT_INVALID_OPERATION:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case STATUS_FLOAT_OVERFLOW:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case STATUS_FLOAT_STACK_CHECK:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case STATUS_FLOAT_UNDERFLOW:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case STATUS_FLOAT_DIVIDE_BY_ZERO:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case STATUS_INTEGER_DIVIDE_BY_ZERO:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case STATUS_INTEGER_OVERFLOW:
      DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
      ourstatus->value.sig = GDB_SIGNAL_FPE;
      break;
    case EXCEPTION_BREAKPOINT:
#ifdef __x86_64__
      if (ignore_first_breakpoint)
	{
	  /* For WOW64 processes, there are always 2 breakpoint exceptions
	     on startup, first a BREAKPOINT for the 64bit ntdll.dll,
	     then a WX86_BREAKPOINT for the 32bit ntdll.dll.
	     Here we only care about the WX86_BREAKPOINT's.  */
	  ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
	  ignore_first_breakpoint = false;
	}
      else if (wow64_process)
	{
	  /* This breakpoint exception is triggered for WOW64 processes when
	     reaching an int3 instruction in 64bit code.
	     gdb checks for int3 in case of SIGTRAP, this fails because
	     Wow64GetThreadContext can only report the pc of 32bit code, and
	     gdb lets the target process continue.
	     So handle it as SIGINT instead, then the target is stopped
	     unconditionally.  */
	  DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
	  rec->ExceptionCode = DBG_CONTROL_C;
	  ourstatus->value.sig = GDB_SIGNAL_INT;
	  break;
	}
#endif
      /* FALLTHROUGH */
    case STATUS_WX86_BREAKPOINT:
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
      ourstatus->value.sig = GDB_SIGNAL_TRAP;
      break;
    case DBG_CONTROL_C:
      DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
      ourstatus->value.sig = GDB_SIGNAL_INT;
      break;
    case DBG_CONTROL_BREAK:
      DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
      ourstatus->value.sig = GDB_SIGNAL_INT;
      break;
    case EXCEPTION_SINGLE_STEP:
    case STATUS_WX86_SINGLE_STEP:
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
      ourstatus->value.sig = GDB_SIGNAL_TRAP;
      break;
    case EXCEPTION_ILLEGAL_INSTRUCTION:
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
      ourstatus->value.sig = GDB_SIGNAL_ILL;
      break;
    case EXCEPTION_PRIV_INSTRUCTION:
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
      ourstatus->value.sig = GDB_SIGNAL_ILL;
      break;
    case EXCEPTION_NONCONTINUABLE_EXCEPTION:
      DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
      ourstatus->value.sig = GDB_SIGNAL_ILL;
      break;
    case MS_VC_EXCEPTION:
      DEBUG_EXCEPTION_SIMPLE ("MS_VC_EXCEPTION");
      if (handle_ms_vc_exception (rec))
	{
	  ourstatus->value.sig = GDB_SIGNAL_TRAP;
	  result = HANDLE_EXCEPTION_IGNORED;
	  break;
	}
	/* treat improperly formed exception as unknown */
	/* FALLTHROUGH */
    default:
      /* Treat unhandled first chance exceptions specially.  */
      if (current_event.u.Exception.dwFirstChance)
	return HANDLE_EXCEPTION_UNHANDLED;
      debug_printf ("gdb: unknown target exception 0x%08x at %s\n",
	(unsigned) current_event.u.Exception.ExceptionRecord.ExceptionCode,
	host_address_to_string (
	  current_event.u.Exception.ExceptionRecord.ExceptionAddress));
      ourstatus->value.sig = GDB_SIGNAL_UNKNOWN;
      break;
    }

  last_sig = ourstatus->value.sig;
  return result;

#undef DEBUG_EXCEPTION_SIMPLE
}

/* Iterate over all DLLs currently mapped by our inferior, looking for
   a DLL which is loaded at LOAD_ADDR.  If found, add the DLL to our
   list of solibs; otherwise do nothing.  LOAD_ADDR NULL means add all
   DLLs to the list of solibs; this is used when the inferior finishes
   its initialization, and all the DLLs it statically depends on are
   presumed loaded.  */

static void
windows_add_dll (LPVOID load_addr)
{
  HMODULE dummy_hmodule;
  DWORD cb_needed;
  HMODULE *hmodules;
  int i;

#ifdef __x86_64__
  if (wow64_process)
    {
      if (EnumProcessModulesEx (current_process_handle, &dummy_hmodule,
				sizeof (HMODULE), &cb_needed,
				LIST_MODULES_32BIT) == 0)
	return;
    }
  else
#endif
    {
      if (EnumProcessModules (current_process_handle, &dummy_hmodule,
			      sizeof (HMODULE), &cb_needed) == 0)
	return;
    }

  if (cb_needed < 1)
    return;

  hmodules = (HMODULE *) alloca (cb_needed);
#ifdef __x86_64__
  if (wow64_process)
    {
      if (EnumProcessModulesEx (current_process_handle, hmodules,
				cb_needed, &cb_needed,
				LIST_MODULES_32BIT) == 0)
	return;
    }
  else
#endif
    {
      if (EnumProcessModules (current_process_handle, hmodules,
			      cb_needed, &cb_needed) == 0)
	return;
    }

  char system_dir[MAX_PATH];
  char syswow_dir[MAX_PATH];
  size_t system_dir_len = 0;
  bool convert_syswow_dir = false;
#ifdef __x86_64__
  if (wow64_process)
#endif
    {
      /* This fails on 32bit Windows because it has no SysWOW64 directory,
	 and in this case a path conversion isn't necessary.  */
      UINT len = GetSystemWow64DirectoryA (syswow_dir, sizeof (syswow_dir));
      if (len > 0)
	{
	  /* Check that we have passed a large enough buffer.  */
	  gdb_assert (len < sizeof (syswow_dir));

	  len = GetSystemDirectoryA (system_dir, sizeof (system_dir));
	  /* Error check.  */
	  gdb_assert (len != 0);
	  /* Check that we have passed a large enough buffer.  */
	  gdb_assert (len < sizeof (system_dir));

	  strcat (system_dir, "\\");
	  strcat (syswow_dir, "\\");
	  system_dir_len = strlen (system_dir);

	  convert_syswow_dir = true;
	}

    }
  for (i = 1; i < (int) (cb_needed / sizeof (HMODULE)); i++)
    {
      MODULEINFO mi;
#ifdef __USEWIDE
      wchar_t dll_name[MAX_PATH];
      char dll_name_mb[MAX_PATH];
#else
      char dll_name[MAX_PATH];
#endif
      const char *name;
      if (GetModuleInformation (current_process_handle, hmodules[i],
				&mi, sizeof (mi)) == 0)
	continue;

      if (GetModuleFileNameEx (current_process_handle, hmodules[i],
			       dll_name, sizeof (dll_name)) == 0)
	continue;
#ifdef __USEWIDE
      wcstombs (dll_name_mb, dll_name, MAX_PATH);
      name = dll_name_mb;
#else
      name = dll_name;
#endif
      /* Convert the DLL path of 32bit processes returned by
	 GetModuleFileNameEx from the 64bit system directory to the
	 32bit syswow64 directory if necessary.  */
      std::string syswow_dll_path;
      if (convert_syswow_dir
	  && strncasecmp (name, system_dir, system_dir_len) == 0
	  && strchr (name + system_dir_len, '\\') == nullptr)
	{
	  syswow_dll_path = syswow_dir;
	  syswow_dll_path += name + system_dir_len;
	  name = syswow_dll_path.c_str();
	}

      /* Record the DLL if either LOAD_ADDR is NULL or the address
	 at which the DLL was loaded is equal to LOAD_ADDR.  */
      if (!(load_addr != nullptr && mi.lpBaseOfDll != load_addr))
	{
	  handle_load_dll (name, mi.lpBaseOfDll);
	  if (load_addr != nullptr)
	    return;
	}
    }
}

/* See nat/windows-nat.h.  */

void
dll_loaded_event ()
{
  gdb_assert (current_event.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT);

  LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
  const char *dll_name;

  /* Try getting the DLL name via the lpImageName field of the event.
     Note that Microsoft documents this fields as strictly optional,
     in the sense that it might be NULL.  And the first DLL event in
     particular is explicitly documented as "likely not pass[ed]"
     (source: MSDN LOAD_DLL_DEBUG_INFO structure).  */
  dll_name = get_image_name (current_process_handle,
			     event->lpImageName, event->fUnicode);
  /* If the DLL name could not be gleaned via lpImageName, try harder
     by enumerating all the DLLs loaded into the inferior, looking for
     one that is loaded at base address = lpBaseOfDll. */
  if (dll_name != nullptr)
    handle_load_dll (dll_name, event->lpBaseOfDll);
  else if (event->lpBaseOfDll != nullptr)
    windows_add_dll (event->lpBaseOfDll);
}

/* See nat/windows-nat.h.  */

void
windows_add_all_dlls ()
{
  windows_add_dll (nullptr);
}

/* See nat/windows-nat.h.  */

bool
matching_pending_stop (bool debug_events)
{
  /* If there are pending stops, and we might plausibly hit one of
     them, we don't want to actually continue the inferior -- we just
     want to report the stop.  In this case, we just pretend to
     continue.  See the comment by the definition of "pending_stops"
     for details on why this is needed.  */
  for (const auto &item : pending_stops)
    {
      if (desired_stop_thread_id == -1
	  || desired_stop_thread_id == item.thread_id)
	{
	  DEBUG_EVENTS ("pending stop anticipated, desired=0x%x, item=0x%x",
			desired_stop_thread_id, item.thread_id);
	  return true;
	}
    }

  return false;
}

/* See nat/windows-nat.h.  */

gdb::optional<pending_stop>
fetch_pending_stop (bool debug_events)
{
  gdb::optional<pending_stop> result;
  for (auto iter = pending_stops.begin ();
       iter != pending_stops.end ();
       ++iter)
    {
      if (desired_stop_thread_id == -1
	  || desired_stop_thread_id == iter->thread_id)
	{
	  result = *iter;
	  current_event = iter->event;

	  DEBUG_EVENTS ("pending stop found in 0x%x (desired=0x%x)",
			iter->thread_id, desired_stop_thread_id);

	  pending_stops.erase (iter);
	  break;
	}
    }

  return result;
}

/* See nat/windows-nat.h.  */

BOOL
continue_last_debug_event (DWORD continue_status, bool debug_events)
{
  DEBUG_EVENTS ("ContinueDebugEvent (cpid=%d, ctid=0x%x, %s)",
		(unsigned) last_wait_event.dwProcessId,
		(unsigned) last_wait_event.dwThreadId,
		continue_status == DBG_CONTINUE ?
		"DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED");

  return ContinueDebugEvent (last_wait_event.dwProcessId,
			     last_wait_event.dwThreadId,
			     continue_status);
}

/* See nat/windows-nat.h.  */

BOOL
wait_for_debug_event (DEBUG_EVENT *event, DWORD timeout)
{
  BOOL result = WaitForDebugEvent (event, timeout);
  if (result)
    last_wait_event = *event;
  return result;
}

/* Define dummy functions which always return error for the rare cases where
   these functions could not be found.  */
template<typename... T>
BOOL WINAPI
bad (T... args)
{
  return FALSE;
}

template<typename... T>
DWORD WINAPI
bad (T... args)
{
  return 0;
}

static BOOL WINAPI
bad_GetCurrentConsoleFont (HANDLE w, BOOL bMaxWindow, CONSOLE_FONT_INFO *f)
{
  f->nFont = 0;
  return 1;
}

static COORD WINAPI
bad_GetConsoleFontSize (HANDLE w, DWORD nFont)
{
  COORD size;
  size.X = 8;
  size.Y = 12;
  return size;
}
 
/* See windows-nat.h.  */

bool
initialize_loadable ()
{
  bool result = true;
  HMODULE hm = NULL;

#define GPA(m, func)					\
  func = (func ## _ftype *) GetProcAddress (m, #func)

  hm = LoadLibrary (TEXT ("kernel32.dll"));
  if (hm)
    {
      GPA (hm, DebugActiveProcessStop);
      GPA (hm, DebugBreakProcess);
      GPA (hm, DebugSetProcessKillOnExit);
      GPA (hm, GetConsoleFontSize);
      GPA (hm, DebugActiveProcessStop);
      GPA (hm, GetCurrentConsoleFont);
#ifdef __x86_64__
      GPA (hm, Wow64SuspendThread);
      GPA (hm, Wow64GetThreadContext);
      GPA (hm, Wow64SetThreadContext);
      GPA (hm, Wow64GetThreadSelectorEntry);
#endif
      GPA (hm, GenerateConsoleCtrlEvent);
    }

  /* Set variables to dummy versions of these processes if the function
     wasn't found in kernel32.dll.  */
  if (!DebugBreakProcess)
    DebugBreakProcess = bad;
  if (!DebugActiveProcessStop || !DebugSetProcessKillOnExit)
    {
      DebugActiveProcessStop = bad;
      DebugSetProcessKillOnExit = bad;
    }
  if (!GetConsoleFontSize)
    GetConsoleFontSize = bad_GetConsoleFontSize;
  if (!GetCurrentConsoleFont)
    GetCurrentConsoleFont = bad_GetCurrentConsoleFont;

  /* Load optional functions used for retrieving filename information
     associated with the currently debugged process or its dlls.  */
  hm = LoadLibrary (TEXT ("psapi.dll"));
  if (hm)
    {
      GPA (hm, EnumProcessModules);
#ifdef __x86_64__
      GPA (hm, EnumProcessModulesEx);
#endif
      GPA (hm, GetModuleInformation);
      GPA (hm, GetModuleFileNameExA);
      GPA (hm, GetModuleFileNameExW);
    }

  if (!EnumProcessModules || !GetModuleInformation
      || !GetModuleFileNameExA || !GetModuleFileNameExW)
    {
      /* Set variables to dummy versions of these processes if the function
	 wasn't found in psapi.dll.  */
      EnumProcessModules = bad;
      GetModuleInformation = bad;
      GetModuleFileNameExA = bad;
      GetModuleFileNameExW = bad;

      result = false;
    }

  hm = LoadLibrary (TEXT ("advapi32.dll"));
  if (hm)
    {
      GPA (hm, OpenProcessToken);
      GPA (hm, LookupPrivilegeValueA);
      GPA (hm, AdjustTokenPrivileges);
      /* Only need to set one of these since if OpenProcessToken fails nothing
	 else is needed.  */
      if (!OpenProcessToken || !LookupPrivilegeValueA
	  || !AdjustTokenPrivileges)
	OpenProcessToken = bad;
    }

#undef GPA

  return result;
}

}
