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 + -
显示快捷键?