global.c

来自「一个类似windows」· C语言 代码 · 共 736 行 · 第 1/2 页

C
736
字号

   Status = ZwQuerySystemInformation(SystemBasicInformation,
                                     &SysBasicInfo,
                                     sizeof(SysBasicInfo),
                                     NULL);
   if (!NT_SUCCESS(Status))
     {
       SetLastErrorByStatus(Status);
       return FALSE;
     }

   Status = ZwQuerySystemInformation(SystemPerformanceInformation,
                                     &SysPerfInfo,
                                     sizeof(SysPerfInfo),
                                     NULL);
   if (!NT_SUCCESS(Status))
     {
       SetLastErrorByStatus(Status);
       return FALSE;
     }

   Status = ZwQuerySystemInformation(SystemFullMemoryInformation,
                                     &UserMemory,
                                     sizeof(ULONG),
                                     NULL);
   if (!NT_SUCCESS(Status))
     {
       SetLastErrorByStatus(Status);
       return FALSE;
     }

/*
 * Load percentage 0 thru 100. 0 is good and 100 is bad.
 *
 *	Um = allocated memory / physical memory
 *	Um =      177 MB      /     256 MB        = 69.1%
 *
 *	Mult allocated memory by 100 to move decimal point up.
 */
   lpBuffer->dwMemoryLoad = (SysBasicInfo.NumberOfPhysicalPages -
  			     SysPerfInfo.AvailablePages) * 100 /
    			     SysBasicInfo.NumberOfPhysicalPages;

   DPRINT1("Memory Load: %d%%\n",lpBuffer->dwMemoryLoad );

   lpBuffer->ullTotalPhys = SysBasicInfo.NumberOfPhysicalPages *
   					SysBasicInfo.PageSize;
   lpBuffer->ullAvailPhys = SysPerfInfo.AvailablePages *
    					SysBasicInfo.PageSize;

	DPRINT("%d\n",SysPerfInfo.AvailablePages );
	DPRINT("%d\n",lpBuffer->ullAvailPhys );

   lpBuffer->ullTotalPageFile = SysPerfInfo.CommitLimit *
    					SysBasicInfo.PageSize;

	DPRINT("%d\n",lpBuffer->ullTotalPageFile );

   lpBuffer->ullAvailPageFile = ((SysPerfInfo.CommitLimit -
    					SysPerfInfo.CommittedPages) *
    					SysBasicInfo.PageSize);

/* VM available to the calling processes, User Mem? */
   lpBuffer->ullTotalVirtual = SysBasicInfo.MaximumUserModeAddress -
    					SysBasicInfo.MinimumUserModeAddress;

   lpBuffer->ullAvailVirtual = (lpBuffer->ullTotalVirtual -
    					(UserMemory *
    					 SysBasicInfo.PageSize));

	DPRINT("%d\n",lpBuffer->ullAvailVirtual );
	DPRINT("%d\n",UserMemory);
	DPRINT("%d\n",SysBasicInfo.PageSize);

/* lol! Memory from beyond! */
   lpBuffer->ullAvailExtendedVirtual = 0;
   return TRUE;
}

/*
 * @implemented
 */
VOID STDCALL
GlobalMemoryStatus(LPMEMORYSTATUS lpBuffer)
{
    MEMORYSTATUSEX lpBufferEx;
#if 0
    if (lpBuffer->dwLength != sizeof(MEMORYSTATUS))
      {
        SetLastError(ERROR_INVALID_PARAMETER);
        return;
      }
#endif
    lpBufferEx.dwLength = sizeof(MEMORYSTATUSEX);

    if (GlobalMemoryStatusEx(&lpBufferEx))
      {

	 lpBuffer->dwLength 	   = sizeof(MEMORYSTATUS);

         lpBuffer->dwMemoryLoad    = lpBufferEx.dwMemoryLoad;
         lpBuffer->dwTotalPhys     = lpBufferEx.ullTotalPhys;
         lpBuffer->dwAvailPhys     = lpBufferEx.ullAvailPhys;
         lpBuffer->dwTotalPageFile = lpBufferEx.ullTotalPageFile;
         lpBuffer->dwAvailPageFile = lpBufferEx.ullAvailPageFile;
         lpBuffer->dwTotalVirtual  = lpBufferEx.ullTotalVirtual;
         lpBuffer->dwAvailVirtual  = lpBufferEx.ullAvailVirtual;
      }
}


HGLOBAL STDCALL
GlobalReAlloc(HGLOBAL hMem,
	      DWORD dwBytes,
	      UINT uFlags)
{

    LPVOID         palloc = 0;
    HGLOBAL        hnew = 0;
    PGLOBAL_HANDLE phandle = 0;
    ULONG          heap_flags = 0;

    DPRINT("GlobalReAlloc( 0x%lX, 0x%lX, 0x%X )\n", (ULONG)hMem, dwBytes, uFlags);

    if (uFlags & GMEM_ZEROINIT)
    {
        heap_flags = HEAP_ZERO_MEMORY;
    }

    HeapLock(GetProcessHeap());

    if(uFlags & GMEM_MODIFY) /* modify flags */
    {
        if( ISPOINTER(hMem) && (uFlags & GMEM_MOVEABLE))
        {
            /* make a fixed block moveable
            * actually only NT is able to do this. And it's soo simple
            */
            if (0 == hMem)
            {
                SetLastError( ERROR_NOACCESS );
                hnew = 0;
            }
            else
            {
                dwBytes   = RtlSizeHeap(GetProcessHeap(), 0, (LPVOID) hMem);
                hnew      = GlobalAlloc( uFlags, dwBytes);
                palloc    = GlobalLock(hnew);
                memcpy(palloc, (LPVOID) hMem, dwBytes);
                GlobalUnlock(hnew);
                RtlFreeHeap(GetProcessHeap(),0,hMem);
            }
        }
        else if(ISPOINTER(hMem) && (uFlags & GMEM_DISCARDABLE))
        {
            /* change the flags to make our block "discardable" */
            phandle = HANDLE_TO_INTERN(hMem);
            phandle->Flags = phandle->Flags | (GMEM_DISCARDABLE >> 8);
            hnew = hMem;
        }
        else
        {
            SetLastError(ERROR_INVALID_PARAMETER);
            hnew = 0;
        }
    }
    else
    {
        if(ISPOINTER(hMem))
        {
            if (!(uFlags & GMEM_MOVEABLE))
            {
                heap_flags |= HEAP_REALLOC_IN_PLACE_ONLY;
            }

            /* reallocate fixed memory */
            hnew = (HANDLE)RtlReAllocateHeap(GetProcessHeap(), heap_flags, (LPVOID) hMem, dwBytes);
        }
        else
        {
            /* reallocate a moveable block */
            phandle= HANDLE_TO_INTERN(hMem);
            hnew = hMem;
            
            if (0 != dwBytes)
            {
               if(phandle->Pointer)
               {

                   if (phandle->LockCount && !(uFlags & GMEM_MOVEABLE))
                   {
                       /* Locked memory cant normally move but the MEM_MOVEABLE flag
                        * override this behaviour. But in this case that flag was not passed.
                        */ 
                       heap_flags |= HEAP_REALLOC_IN_PLACE_ONLY;
                   }

                   palloc = RtlReAllocateHeap(GetProcessHeap(), heap_flags,
                                      (PVOID)((ULONG_PTR)phandle->Pointer - HANDLE_SIZE),
                                      dwBytes + HANDLE_SIZE);
                   if (0 == palloc)
                   {
                       hnew = 0;
                   }
                   else
                   {
                       *(PHANDLE)palloc = hMem;
                       phandle->Pointer = (PVOID)((ULONG_PTR)palloc + HANDLE_SIZE);
                   }
               }
               else
               {
                   palloc = RtlAllocateHeap(GetProcessHeap(), heap_flags, dwBytes + HANDLE_SIZE);
                   if (0 == palloc)
                   {
                       hnew = 0;
                   }
                   else
                   {
                       *(PHANDLE)palloc = hMem;
                       phandle->Pointer = (PVOID)((ULONG_PTR)palloc + HANDLE_SIZE);
                   }
               }
            }
            else
            {
                if(phandle->Pointer)
                {
                    RtlFreeHeap(GetProcessHeap(), 0, (PVOID)((ULONG_PTR)phandle->Pointer - HANDLE_SIZE));
                    phandle->Pointer = 0;
                }
            }
        }
    }

    HeapUnlock(GetProcessHeap());

    return hnew;
}


DWORD STDCALL
GlobalSize(HGLOBAL hMem)
{
    SIZE_T         retval  = 0;
    PGLOBAL_HANDLE phandle = 0;

    DPRINT("GlobalSize( 0x%lX )\n", (ULONG)hMem);

    if(ISPOINTER(hMem)) /*FIXED*/
    {
        retval = RtlSizeHeap(GetProcessHeap(), 0, hMem);
    }
    else /*MOVEABLE*/
    {
        HeapLock(GetProcessHeap());

        phandle = HANDLE_TO_INTERN(hMem);

        if (MAGIC_GLOBAL_USED == phandle->Magic)
        {
            if (0 != phandle->Pointer)/*NOT DISCARDED*/
            {
                retval = RtlSizeHeap(GetProcessHeap(), 0, (PVOID)((ULONG_PTR)phandle->Pointer - HANDLE_SIZE));

                if (retval == (SIZE_T)-1) /*RtlSizeHeap failed*/
                {
                    /*
                    **TODO: RtlSizeHeap does not set last error.
                    **      We should choose an error value to set as
                    **      the last error. Which One?
                    */
                    DPRINT("GlobalSize:  RtlSizeHeap failed.\n");
                    retval = 0;
                }
                else /*Everything is ok*/
                {
                    retval = retval - HANDLE_SIZE;
                }
            }
        }
        else
        {
            DPRINT("GlobalSize: invalid handle\n");
        }
        HeapUnlock(GetProcessHeap());
    }
    return retval;
}


/*
 * @implemented
 */
VOID STDCALL
GlobalUnfix(HGLOBAL hMem)
{
   if (hMem != INVALID_HANDLE_VALUE)
     GlobalUnlock(hMem);
}


/*
 * @implemented
 */
BOOL STDCALL
GlobalUnlock(HGLOBAL hMem)
{

   PGLOBAL_HANDLE	phandle;
   BOOL			    locked = FALSE;

   DPRINT("GlobalUnlock( 0x%lX )\n", (ULONG)hMem);

   if(ISPOINTER(hMem))
   {
       SetLastError(ERROR_NOT_LOCKED);
      return FALSE;
   }

   HeapLock(GetProcessHeap());

   phandle = HANDLE_TO_INTERN(hMem);
   if(MAGIC_GLOBAL_USED == phandle->Magic)
   {
      if (0 >= phandle->LockCount)
      {
          locked = FALSE;
          SetLastError(ERROR_NOT_LOCKED);
      }
      else if (GLOBAL_LOCK_MAX > phandle->LockCount)
      {
         phandle->LockCount--;
         locked = (0 != phandle->LockCount) ? TRUE : FALSE;
         SetLastError(NO_ERROR);
      }
   }
   else
   {
      DPRINT("GlobalUnlock: invalid handle\n");
      locked = FALSE;
   }
   HeapUnlock(GetProcessHeap());
   return locked;
}


/*
 * @implemented
 */
BOOL STDCALL
GlobalUnWire(HGLOBAL hMem)
{
   return GlobalUnlock(hMem);
}


/*
 * @implemented
 */
LPVOID STDCALL
GlobalWire(HGLOBAL hMem)
{
   return GlobalLock(hMem);
}

/* EOF */

⌨️ 快捷键说明

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