📄 random.c
字号:
static int isWorkstation = -1;
PPERF_DATA_BLOCK pPerfData;
static int cbPerfData = 0x10000;
HANDLE hDevice;
LPBYTE lpBuffer;
DWORD dwSize, status;
LPWSTR lpszLanW, lpszLanS;
int nDrive;
/* Find out whether this is an NT server or workstation if necessary */
if (isWorkstation == -1)
{
HKEY hKey;
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
0, KEY_READ, &hKey) == ERROR_SUCCESS)
{
unsigned char szValue[32];
dwSize = sizeof (szValue);
isWorkstation = TRUE;
status = RegQueryValueEx (hKey, "ProductType", 0, NULL,
szValue, &dwSize);
if (status == ERROR_SUCCESS && _stricmp ((char *) szValue, "WinNT"))
/* Note: There are (at least) three cases for
ProductType: WinNT = NT Workstation,
ServerNT = NT Server, LanmanNT = NT Server
acting as a Domain Controller */
isWorkstation = FALSE;
RegCloseKey (hKey);
}
}
/* Initialize the NetAPI32 function pointers if necessary */
if (hNetAPI32 == NULL)
{
/* Obtain a handle to the module containing the Lan Manager
functions */
hNetAPI32 = LoadLibrary ("NETAPI32.DLL");
if (hNetAPI32 != NULL)
{
/* Now get pointers to the functions */
pNetStatisticsGet = (NETSTATISTICSGET) GetProcAddress (hNetAPI32,
"NetStatisticsGet");
pNetApiBufferSize = (NETAPIBUFFERSIZE) GetProcAddress (hNetAPI32,
"NetApiBufferSize");
pNetApiBufferFree = (NETAPIBUFFERFREE) GetProcAddress (hNetAPI32,
"NetApiBufferFree");
/* Make sure we got valid pointers for every NetAPI32
function */
if (pNetStatisticsGet == NULL ||
pNetApiBufferSize == NULL ||
pNetApiBufferFree == NULL)
{
/* Free the library reference and reset the
static handle */
FreeLibrary (hNetAPI32);
hNetAPI32 = NULL;
}
}
}
/* Get network statistics. Note: Both NT Workstation and NT Server
by default will be running both the workstation and server
services. The heuristic below is probably useful though on the
assumption that the majority of the network traffic will be via
the appropriate service */
lpszLanW = (LPWSTR) WIDE ("LanmanWorkstation");
lpszLanS = (LPWSTR) WIDE ("LanmanServer");
if (hNetAPI32 &&
pNetStatisticsGet (NULL,
isWorkstation ? lpszLanW : lpszLanS,
0, 0, &lpBuffer) == 0)
{
pNetApiBufferSize (lpBuffer, &dwSize);
RandaddBuf ((unsigned char *) lpBuffer, dwSize);
pNetApiBufferFree (lpBuffer);
}
/* Get disk I/O statistics for all the hard drives */
for (nDrive = 0;; nDrive++)
{
DISK_PERFORMANCE diskPerformance;
char szDevice[24];
/* Check whether we can access this device */
sprintf (szDevice, "\\\\.\\PhysicalDrive%d", nDrive);
hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
break;
/* Note: This only works if you have turned on the disk
performance counters with 'diskperf -y'. These counters
are off by default */
if (DeviceIoControl (hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
&diskPerformance, sizeof (DISK_PERFORMANCE),
&dwSize, NULL))
{
RandaddBuf ((unsigned char *) &diskPerformance, dwSize);
}
CloseHandle (hDevice);
}
/* Get the performance counters */
pPerfData = (PPERF_DATA_BLOCK) TCalloc (cbPerfData);
while (pPerfData)
{
dwSize = cbPerfData;
status = RegQueryValueEx (HKEY_PERFORMANCE_DATA, "Global", NULL,
NULL, (LPBYTE) pPerfData, &dwSize);
if (status == ERROR_SUCCESS)
{
RegCloseKey (HKEY_PERFORMANCE_DATA);
if (memcmp (pPerfData->Signature, WIDE ("PERF"), 8) == 0)
RandaddBuf (pPerfData, dwSize);
TCfree (pPerfData);
pPerfData = NULL;
}
else if (status == ERROR_MORE_DATA)
{
cbPerfData += 4096;
pPerfData = (PPERF_DATA_BLOCK) realloc (pPerfData, cbPerfData);
}
}
}
/* Win9x typedefs and variables for toolhelp32 use */
typedef BOOL (WINAPI * MODULEWALK) (HANDLE hSnapshot, LPMODULEENTRY32 lpme);
typedef BOOL (WINAPI * THREADWALK) (HANDLE hSnapshot, LPTHREADENTRY32 lpte);
typedef BOOL (WINAPI * PROCESSWALK) (HANDLE hSnapshot, LPPROCESSENTRY32 lppe);
typedef BOOL (WINAPI * HEAPLISTWALK) (HANDLE hSnapshot, LPHEAPLIST32 lphl);
typedef BOOL (WINAPI * HEAPFIRST) (LPHEAPENTRY32 lphe, DWORD th32ProcessID, DWORD th32HeapID);
typedef BOOL (WINAPI * HEAPNEXT) (LPHEAPENTRY32 lphe);
typedef HANDLE (WINAPI * CREATESNAPSHOT) (DWORD dwFlags, DWORD th32ProcessID);
CREATESNAPSHOT pCreateToolhelp32Snapshot = NULL;
MODULEWALK pModule32First = NULL;
MODULEWALK pModule32Next = NULL;
PROCESSWALK pProcess32First = NULL;
PROCESSWALK pProcess32Next = NULL;
THREADWALK pThread32First = NULL;
THREADWALK pThread32Next = NULL;
HEAPLISTWALK pHeap32ListFirst = NULL;
HEAPLISTWALK pHeap32ListNext = NULL;
HEAPFIRST pHeap32First = NULL;
HEAPNEXT pHeap32Next = NULL;
void
SlowPollWin9x (void)
{
PROCESSENTRY32 pe32;
THREADENTRY32 te32;
MODULEENTRY32 me32;
HEAPLIST32 hl32;
HANDLE hSnapshot;
/* Initialize the Toolhelp32 function pointers if necessary */
if (pCreateToolhelp32Snapshot == NULL)
{
HANDLE hKernel = NULL;
/* Obtain the module handle of the kernel to retrieve the
addresses of the Toolhelp32 functions */
if ((hKernel = GetModuleHandle ("KERNEL32.DLL")) == NULL)
return;
/* Now get pointers to the functions */
pCreateToolhelp32Snapshot = (CREATESNAPSHOT) GetProcAddress (hKernel,
"CreateToolhelp32Snapshot");
pModule32First = (MODULEWALK) GetProcAddress (hKernel,
"Module32First");
pModule32Next = (MODULEWALK) GetProcAddress (hKernel,
"Module32Next");
pProcess32First = (PROCESSWALK) GetProcAddress (hKernel,
"Process32First");
pProcess32Next = (PROCESSWALK) GetProcAddress (hKernel,
"Process32Next");
pThread32First = (THREADWALK) GetProcAddress (hKernel,
"Thread32First");
pThread32Next = (THREADWALK) GetProcAddress (hKernel,
"Thread32Next");
pHeap32ListFirst = (HEAPLISTWALK) GetProcAddress (hKernel,
"Heap32ListFirst");
pHeap32ListNext = (HEAPLISTWALK) GetProcAddress (hKernel,
"Heap32ListNext");
pHeap32First = (HEAPFIRST) GetProcAddress (hKernel,
"Heap32First");
pHeap32Next = (HEAPNEXT) GetProcAddress (hKernel,
"Heap32Next");
/* Make sure we got valid pointers for every Toolhelp32
function */
if (pModule32First == NULL || pModule32Next == NULL || \
pProcess32First == NULL || pProcess32Next == NULL || \
pThread32First == NULL || pThread32Next == NULL || \
pHeap32ListFirst == NULL || pHeap32ListNext == NULL || \
pHeap32First == NULL || pHeap32Next == NULL || \
pCreateToolhelp32Snapshot == NULL)
{
/* Mark the main function as unavailable in case for
future reference */
pCreateToolhelp32Snapshot = NULL;
return;
}
}
/* Take a snapshot of everything we can get to which is currently in
the system */
hSnapshot = pCreateToolhelp32Snapshot (TH32CS_SNAPALL, 0);
if (!hSnapshot)
return;
/* Walk through the local heap */
hl32.dwSize = sizeof (HEAPLIST32);
if (pHeap32ListFirst (hSnapshot, &hl32))
do
{
HEAPENTRY32 he32;
/* First add the information from the basic
Heaplist32 structure */
RandaddBuf ((BYTE *) & hl32, sizeof (HEAPLIST32));
/* Now walk through the heap blocks getting
information on each of them */
he32.dwSize = sizeof (HEAPENTRY32);
if (pHeap32First (&he32, hl32.th32ProcessID, hl32.th32HeapID))
do
{
RandaddBuf ((BYTE *) & he32, sizeof (HEAPENTRY32));
}
while (pHeap32Next (&he32));
}
while (pHeap32ListNext (hSnapshot, &hl32));
/* Walk through all processes */
pe32.dwSize = sizeof (PROCESSENTRY32);
if (pProcess32First (hSnapshot, &pe32))
do
{
RandaddBuf ((BYTE *) & pe32, sizeof (PROCESSENTRY32));
}
while (pProcess32Next (hSnapshot, &pe32));
/* Walk through all threads */
te32.dwSize = sizeof (THREADENTRY32);
if (pThread32First (hSnapshot, &te32))
do
{
RandaddBuf ((BYTE *) & te32, sizeof (THREADENTRY32));
}
while (pThread32Next (hSnapshot, &te32));
/* Walk through all modules associated with the process */
me32.dwSize = sizeof (MODULEENTRY32);
if (pModule32First (hSnapshot, &me32))
do
{
RandaddBuf ((BYTE *) & me32, sizeof (MODULEENTRY32));
}
while (pModule32Next (hSnapshot, &me32));
/* Clean up the snapshot */
CloseHandle (hSnapshot);
}
/* This is the fastpoll function which gathers up info by calling various
api's */
void
FastPoll (void)
{
static BOOL addedFixedItems = FALSE;
FILETIME creationTime, exitTime, kernelTime, userTime;
DWORD minimumWorkingSetSize, maximumWorkingSetSize;
LARGE_INTEGER performanceCount;
MEMORYSTATUS memoryStatus;
HANDLE handle;
POINT point;
/* Get various basic pieces of system information */
RandaddLong (GetActiveWindow ()); /* Handle of active window */
RandaddLong (GetCapture ()); /* Handle of window with mouse
capture */
RandaddLong (GetClipboardOwner ()); /* Handle of clipboard owner */
RandaddLong (GetClipboardViewer ()); /* Handle of start of
clpbd.viewer list */
RandaddLong (GetCurrentProcess ()); /* Pseudohandle of current
process */
RandaddLong (GetCurrentProcessId ()); /* Current process ID */
RandaddLong (GetCurrentThread ()); /* Pseudohandle of current
thread */
RandaddLong (GetCurrentThreadId ()); /* Current thread ID */
RandaddLong (GetCurrentTime ()); /* Milliseconds since Windows
started */
RandaddLong (GetDesktopWindow ()); /* Handle of desktop window */
RandaddLong (GetFocus ()); /* Handle of window with kb.focus */
RandaddLong (GetInputState ()); /* Whether sys.queue has any events */
RandaddLong (GetMessagePos ()); /* Cursor pos.for last message */
RandaddLong (GetMessageTime ()); /* 1 ms time for last message */
RandaddLong (GetOpenClipboardWindow ()); /* Handle of window with
clpbd.open */
RandaddLong (GetProcessHeap ()); /* Handle of process heap */
RandaddLong (GetProcessWindowStation ()); /* Handle of procs
window station */
RandaddLong (GetQueueStatus (QS_ALLEVENTS)); /* Types of events in
input queue */
/* Get multiword system information */
GetCaretPos (&point); /* Current caret position */
RandaddBuf ((unsigned char *) &point, sizeof (POINT));
GetCursorPos (&point); /* Current mouse cursor position */
RandaddBuf ((unsigned char *) &point, sizeof (POINT));
/* Get percent of memory in use, bytes of physical memory, bytes of
free physical memory, bytes in paging file, free bytes in paging
file, user bytes of address space, and free user bytes */
memoryStatus.dwLength = sizeof (MEMORYSTATUS);
GlobalMemoryStatus (&memoryStatus);
RandaddBuf ((unsigned char *) &memoryStatus, sizeof (MEMORYSTATUS));
/* Get thread and process creation time, exit time, time in kernel
mode, and time in user mode in 100ns intervals */
handle = GetCurrentThread ();
GetThreadTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
handle = GetCurrentProcess ();
GetProcessTimes (handle, &creationTime, &exitTime, &kernelTime, &userTime);
RandaddBuf ((unsigned char *) &creationTime, sizeof (FILETIME));
RandaddBuf ((unsigned char *) &exitTime, sizeof (FILETIME));
RandaddBuf ((unsigned char *) &kernelTime, sizeof (FILETIME));
RandaddBuf ((unsigned char *) &userTime, sizeof (FILETIME));
/* Get the minimum and maximum working set size for the current
process */
GetProcessWorkingSetSize (handle, &minimumWorkingSetSize,
&maximumWorkingSetSize);
RandaddLong (minimumWorkingSetSize);
RandaddLong (maximumWorkingSetSize);
/* The following are fixed for the lifetime of the process so we only
add them once */
if (addedFixedItems == 0)
{
STARTUPINFO startupInfo;
/* Get name of desktop, console window title, new window
position and size, window flags, and handles for stdin,
stdout, and stderr */
startupInfo.cb = sizeof (STARTUPINFO);
GetStartupInfo (&startupInfo);
RandaddBuf ((unsigned char *) &startupInfo, sizeof (STARTUPINFO));
addedFixedItems = TRUE;
}
/* The docs say QPC can fail if appropriate hardware is not
available. It works on 486 & Pentium boxes, but hasn't been tested
for 386 or RISC boxes */
if (QueryPerformanceCounter (&performanceCount))
RandaddBuf ((unsigned char *) &performanceCount, sizeof (LARGE_INTEGER));
else
{
/* Millisecond accuracy at best... */
DWORD dwTicks = GetTickCount ();
RandaddBuf ((unsigned char *) &dwTicks, sizeof (dwTicks));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -