⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psapi.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 3 页
字号:
/* $Id: psapi.c 21880 2006-05-10 17:47:44Z ion $
 */
/*
 * COPYRIGHT:   See COPYING in the top level directory
 * LICENSE:     See LGPL.txt in the top level directory
 * PROJECT:     ReactOS system libraries
 * FILE:        reactos/lib/psapi/misc/win32.c
 * PURPOSE:     Win32 interfaces for PSAPI
 * PROGRAMMER:  KJK::Hyperion <noog@libero.it>
 *              Thomas Weidenmueller <w3seek@reactos.com>
 * UPDATE HISTORY:
 *              10/06/2002: Created
 */

#include "precomp.h"

#define NDEBUG
#include <debug.h>

BOOLEAN
WINAPI
DllMain(HINSTANCE hDllHandle,
        DWORD nReason,
        LPVOID Reserved)
{
  switch(nReason)
  {
    case DLL_PROCESS_ATTACH:
      DisableThreadLibraryCalls(hDllHandle);
      break;
  }

  return TRUE;
}

/* INTERNAL *******************************************************************/

typedef struct _ENUM_DEVICE_DRIVERS_CONTEXT
{
  LPVOID *lpImageBase;
  DWORD nCount;
} ENUM_DEVICE_DRIVERS_CONTEXT, *PENUM_DEVICE_DRIVERS_CONTEXT;

NTSTATUS STDCALL
EnumDeviceDriversCallback(IN PRTL_PROCESS_MODULE_INFORMATION CurrentModule,
                          IN OUT PVOID CallbackContext)
{
  PENUM_DEVICE_DRIVERS_CONTEXT Context = (PENUM_DEVICE_DRIVERS_CONTEXT)CallbackContext;

  /* no more buffer space */
  if(Context->nCount == 0)
  {
    return STATUS_INFO_LENGTH_MISMATCH;
  }

  /* return current module */
  *Context->lpImageBase = CurrentModule->ImageBase;

  /* go to next array slot */
  Context->lpImageBase++;
  Context->nCount--;

  return STATUS_SUCCESS;
}


typedef struct _ENUM_PROCESSES_CONTEXT
{
  DWORD *lpidProcess;
  DWORD nCount;
} ENUM_PROCESSES_CONTEXT, *PENUM_PROCESSES_CONTEXT;

NTSTATUS STDCALL
EnumProcessesCallback(IN PSYSTEM_PROCESS_INFORMATION CurrentProcess,
                      IN OUT PVOID CallbackContext)
{
  PENUM_PROCESSES_CONTEXT Context = (PENUM_PROCESSES_CONTEXT)CallbackContext;

  /* no more buffer space */
  if(Context->nCount == 0)
  {
    return STATUS_INFO_LENGTH_MISMATCH;
  }

  /* return current process */
  *Context->lpidProcess = (DWORD)CurrentProcess->UniqueProcessId;

  /* go to next array slot */
  Context->lpidProcess++;
  Context->nCount--;

  return STATUS_SUCCESS;
}


typedef struct _ENUM_PROCESS_MODULES_CONTEXT
{
  HMODULE *lphModule;
  DWORD nCount;
} ENUM_PROCESS_MODULES_CONTEXT, *PENUM_PROCESS_MODULES_CONTEXT;

NTSTATUS STDCALL
EnumProcessModulesCallback(IN HANDLE ProcessHandle,
                           IN PLDR_DATA_TABLE_ENTRY CurrentModule,
                           IN OUT PVOID CallbackContext)
{
  PENUM_PROCESS_MODULES_CONTEXT Context = (PENUM_PROCESS_MODULES_CONTEXT)CallbackContext;

  /* no more buffer space */
  if(Context->nCount == 0)
  {
    return STATUS_INFO_LENGTH_MISMATCH;
  }

  /* return current process */
  *Context->lphModule = CurrentModule->DllBase;

  /* go to next array slot */
  Context->lphModule++;
  Context->nCount--;

  return STATUS_SUCCESS;
}


typedef struct _GET_DEVICE_DRIVER_NAME_CONTEXT
{
  LPVOID ImageBase;
  struct
  {
    ULONG bFullName : sizeof(ULONG) * 8 / 2;
    ULONG bUnicode : sizeof(ULONG) * 8 / 2;
  };
  DWORD nSize;
  union
  {
    LPVOID lpName;
    LPSTR lpAnsiName;
    LPWSTR lpUnicodeName;
  };
} GET_DEVICE_DRIVER_NAME_CONTEXT, *PGET_DEVICE_DRIVER_NAME_CONTEXT;

NTSTATUS STDCALL
GetDeviceDriverNameCallback(IN PRTL_PROCESS_MODULE_INFORMATION CurrentModule,
                            IN OUT PVOID CallbackContext)
{
  PGET_DEVICE_DRIVER_NAME_CONTEXT Context = (PGET_DEVICE_DRIVER_NAME_CONTEXT)CallbackContext;

  /* module found */
  if(Context->ImageBase == CurrentModule->ImageBase)
  {
    PCHAR pcModuleName;
    ULONG l;

    /* get the full name or just the filename part */
    if(Context->bFullName)
      pcModuleName = &CurrentModule->FullPathName[0];
    else
      pcModuleName = &CurrentModule->FullPathName[CurrentModule->OffsetToFileName];

    /* get the length of the name */
    l = strlen(pcModuleName);

    if(Context->nSize <= l)
    {
      /* use the user buffer's length */
      l = Context->nSize;
    }
    else
    {
      /* enough space for the null terminator */
      Context->nSize = ++l;
    }

    /* copy the string */
    if(Context->bUnicode)
    {
      ANSI_STRING AnsiString;
      UNICODE_STRING UnicodeString;

      UnicodeString.Length = 0;
      UnicodeString.MaximumLength = l * sizeof(WCHAR);
      UnicodeString.Buffer = Context->lpUnicodeName;

      RtlInitAnsiString(&AnsiString, pcModuleName);
      /* driver names should always be in language-neutral ASCII, so we don't
         bother calling AreFileApisANSI() */
      RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
    }
    else
    {
      memcpy(Context->lpAnsiName, pcModuleName, l);
    }

    /* terminate the enumeration */
    return STATUS_NO_MORE_FILES;
  }
  else
  {
    /* continue searching */
    return STATUS_SUCCESS;
  }
}


static DWORD
InternalGetDeviceDriverName(BOOLEAN bUnicode,
                            BOOLEAN bFullName,
                            LPVOID ImageBase,
                            LPVOID lpName,
                            DWORD nSize)
{
  GET_DEVICE_DRIVER_NAME_CONTEXT Context;
  NTSTATUS Status;

  if(lpName == NULL || nSize == 0)
  {
    return 0;
  }

  if(ImageBase == NULL)
  {
    SetLastError(ERROR_INVALID_HANDLE);
    return 0;
  }

  Context.ImageBase = ImageBase;
  Context.bFullName = bFullName;
  Context.bUnicode = bUnicode;
  Context.nSize = nSize;
  Context.lpName = lpName;

  /* start the enumeration */
  Status = PsaEnumerateSystemModules(GetDeviceDriverNameCallback, &Context);

  if(Status == STATUS_NO_MORE_FILES)
  {
    /* module was found, return string size */
    return Context.nSize;
  }
  else if(NT_SUCCESS(Status))
  {
    /* module was not found */
    SetLastError(ERROR_INVALID_HANDLE);
  }
  else
  {
    /* an error occurred */
    SetLastErrorByStatus(Status);
  }
  return 0;
}


static DWORD
InternalGetMappedFileName(BOOLEAN bUnicode,
                          HANDLE hProcess,
                          LPVOID lpv,
                          LPVOID lpName,
                          DWORD nSize)
{
  PMEMORY_SECTION_NAME pmsnName;
  ULONG nBufSize;
  NTSTATUS Status;

  if(nSize == 0 || lpName == NULL)
  {
    return 0;
  }

  if(nSize > (0xFFFF / sizeof(WCHAR)))
  {
    /* if the user buffer contains more characters than would fit in an
       UNICODE_STRING, limit the buffer size. RATIONALE: we don't limit buffer
       size elsewhere because here superfluous buffer size will mean a larger
       temporary buffer */
    nBufSize = 0xFFFF / sizeof(WCHAR);
  }
  else
  {
    nBufSize = nSize * sizeof(WCHAR);
  }

  /* allocate the memory */
  pmsnName = PsaiMalloc(nBufSize + sizeof(MEMORY_SECTION_NAME));

  if(pmsnName == NULL)
  {
    SetLastError(ERROR_OUTOFMEMORY);
    return 0;
  }

   /* initialize the destination buffer */
   pmsnName->SectionFileName.Length = 0;
   pmsnName->SectionFileName.Length = nBufSize;

#if 0
   __try
   {
#endif
   /* query the name */
   Status = NtQueryVirtualMemory(hProcess,
                                 lpv,
                                 MemorySectionName,
                                 pmsnName,
                                 nBufSize,
                                 NULL);
   if(!NT_SUCCESS(Status))
   {
     PsaiFree(pmsnName);
     SetLastErrorByStatus(Status);
     return 0;
   }

   if(bUnicode)
   {
     /* destination is an Unicode string: direct copy */
     memcpy((LPWSTR)lpName, pmsnName + 1, pmsnName->SectionFileName.Length);

     PsaiFree(pmsnName);

     if(pmsnName->SectionFileName.Length < nSize)
     {
       /* null-terminate the string */
       ((LPWSTR)lpName)[pmsnName->SectionFileName.Length] = 0;
       return pmsnName->SectionFileName.Length + 1;
     }

     return pmsnName->SectionFileName.Length;
   }
   else
   {
     ANSI_STRING AnsiString;

     AnsiString.Length = 0;
     AnsiString.MaximumLength = nSize;
     AnsiString.Buffer = (LPSTR)lpName;

     if(AreFileApisANSI())
       RtlUnicodeStringToAnsiString(&AnsiString, &pmsnName->SectionFileName, FALSE);
     else
       RtlUnicodeStringToOemString(&AnsiString, &pmsnName->SectionFileName, FALSE);

     PsaiFree(pmsnName);

     if(AnsiString.Length < nSize)
     {
       /* null-terminate the string */
       ((LPSTR)lpName)[AnsiString.Length] = 0;
       return AnsiString.Length + 1;
     }

     return AnsiString.Length;
   }

#if 0
   }
   __finally
   {
     PsaiFree(pmsnName);
   }
#endif
}


typedef struct _GET_MODULE_INFORMATION_FLAGS
{
  ULONG bWantName : sizeof(ULONG) * 8 / 4;
  ULONG bUnicode : sizeof(ULONG) * 8 / 4;
  ULONG bFullName : sizeof(ULONG) * 8 / 4;
} GET_MODULE_INFORMATION_FLAGS, *PGET_MODULE_INFORMATION_FLAGS;

typedef struct _GET_MODULE_INFORMATION_CONTEXT
{
  HMODULE hModule;
  GET_MODULE_INFORMATION_FLAGS Flags;
  DWORD nBufSize;
  union
  {
    LPWSTR lpUnicodeName;
    LPSTR lpAnsiName;
    LPMODULEINFO lpmodinfo;
    LPVOID lpBuffer;
  };
} GET_MODULE_INFORMATION_CONTEXT, *PGET_MODULE_INFORMATION_CONTEXT;

NTSTATUS STDCALL
GetModuleInformationCallback(IN HANDLE ProcessHandle,
                             IN PLDR_DATA_TABLE_ENTRY CurrentModule,
                             IN OUT PVOID CallbackContext)
{
  PGET_MODULE_INFORMATION_CONTEXT Context = (PGET_MODULE_INFORMATION_CONTEXT)CallbackContext;

  /* found the module we were looking for */
  if(CurrentModule->DllBase == Context->hModule)
  {
    /* we want the module name */
    if(Context->Flags.bWantName)
    {
      PUNICODE_STRING SourceString;
      ULONG l;
      NTSTATUS Status;

      if(Context->Flags.bFullName)
        SourceString = &(CurrentModule->FullDllName);
      else
        SourceString = &(CurrentModule->BaseDllName);

      SourceString->Length -= SourceString->Length % sizeof(WCHAR);

      /* l is the byte size of the user buffer */
      l = Context->nBufSize * sizeof(WCHAR);

      /* if the user buffer has room for the string and a null terminator */
      if(l >= (SourceString->Length + sizeof(WCHAR)))
      {
        /* limit the buffer size */
        l = SourceString->Length;

        /* null-terminate the string */
        if(Context->Flags.bUnicode)
          Context->lpUnicodeName[l / sizeof(WCHAR)] = 0;
        else
          Context->lpAnsiName[l / sizeof(WCHAR)] = 0;
      }

      if(Context->Flags.bUnicode)
      {
        /* Unicode: direct copy */
        /* NOTE: I've chosen not to check for ProcessHandle == NtCurrentProcess(),
                 this function is complicated enough as it is */
        Status = NtReadVirtualMemory(ProcessHandle,
                                     SourceString->Buffer,
                                     Context->lpUnicodeName,
                                     l,
                                     NULL);

        if(!NT_SUCCESS(Status))
        {
          Context->nBufSize = 0;
          return Status;
        }

        Context->nBufSize = l / sizeof(WCHAR);
      }
      else
      {
        /* ANSI/OEM: convert and copy */
        LPWSTR pwcUnicodeBuf;
        ANSI_STRING AnsiString;
        UNICODE_STRING UnicodeString;

        AnsiString.Length = 0;
        AnsiString.MaximumLength = Context->nBufSize;
        AnsiString.Buffer = Context->lpAnsiName;

        /* allocate the local buffer */
        pwcUnicodeBuf = PsaiMalloc(SourceString->Length);

#if 0
        __try
        {
#endif
        if(pwcUnicodeBuf == NULL)
        {
          Status = STATUS_NO_MEMORY;
          goto exitWithStatus;
        }

        /* copy the string in the local buffer */
        Status = NtReadVirtualMemory(ProcessHandle,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -