I have a win32 application that uses winsock to create TCPIP sockets.
This is great, except in some cases I would like to know statistics on the actual socket. Stuff like packets sent, received, total bytes sent, etc. But the most important piece of data I want to see is packet loss.
I have not been able to find the right call to get such data, I have looked at getsockopt and cannot find a good way to get such data.
Is there a way to get low level statistics of a TCP socket on the windows API?
For reference I am using Windows 7 (64-bit version)
Thank you!
You can try GetTcpStatisticsEx. It returns the MIB_TCPSTATS structure, which contains among other things the retransmission count:
typedef struct _MIB_TCPSTATS {
DWORD dwRtoAlgorithm;
DWORD dwRtoMin;
DWORD dwRtoMax;
DWORD dwMaxConn;
DWORD dwActiveOpens;
DWORD dwPassiveOpens;
DWORD dwAttemptFails;
DWORD dwEstabResets;
DWORD dwCurrEstab;
DWORD dwInSegs;
DWORD dwOutSegs;
DWORD dwRetransSegs; // <=========
DWORD dwInErrs;
DWORD dwOutRsts;
DWORD dwNumConns;
} MIB_TCPSTATS;
dwRetransSegs
Type: DWORD
The number of segments retransmitted.
Related
I am using the masm assembler, and I am using the kernel32.lib to create heap memory, however on the windows API page for the HeapCreate procedure it does not tell me where it's return value is stored. (i.e. the handle to the heap)
I would assume that it is stored in EAX? since most procedures place their return value in EAX. After I call HeapCreate, I call HealAlloc to allocate some memory in my heap:
INCLUDE \masm32\include\kernel32.inc
INCLUDELIB \masm32\lib\kernel32.lib
.CODE
PUSH DWORD PTR 00h ;max size
PUSH DWORD PTR 00h ;initial size
PUSH DWORD PTR 04h ;flOption
CALL HeapCreate
PUSH DWORD PTR 04h ;dwBytes (the size in bytes)
PUSH DWORD PTR 04h ;dwFlag
PUSH EAX ;I am not sure if the heap handle is stored in EAX or not?
CALL HeapAlloc
END
Essentially, I do not know where the return value to HeapCreate is stored. If anyone could clarify where, I would appreciate it.
Thanks
The MSDN page for HeapCreate gives the following prototype for the function:
HANDLE WINAPI HeapCreate(
_In_ DWORD flOptions,
_In_ SIZE_T dwInitialSize,
_In_ SIZE_T dwMaximumSize
);
All x86 calling conventions leave the return value in R/EAX, so the resulting HANDLE will be found in either EAX (in 32-bit builds) or RAX (in 64-bit builds).
It depends on whether you are compiling for 32-bit or 64-bit.
The declaration of HeapCreate() is as follows:
HANDLE WINAPI HeapCreate(
_In_ DWORD flOptions,
_In_ SIZE_T dwInitialSize,
_In_ SIZE_T dwMaximumSize
);
WINAPI is a preprocessor macro that resolves to the __stdcall calling convention, which is meaningful only in 32-bit and is ignored in 64-bit.
In 32-bit, __stdcall stores return values up to 32 bits in EAX, and larger return values in EAX:EDX.
In 64-bit, the x64 calling convention stores return values in RAX (the first 32 bits of which are EAX).
HANDLE is a pointer type, so it is 32 bits in size on a 32-bit compilation, and 64 bits in size on a 64-bit compilation. However, MSDN states:
64-bit versions of Windows use 32-bit handles for interoperability. When sharing a handle between 32-bit and 64-bit applications, only the lower 32 bits are significant, so it is safe to truncate the handle (when passing it from 64-bit to 32-bit) or sign-extend the handle (when passing it from 32-bit to 64-bit). Handles that can be shared include handles to user objects such as windows (HWND), handles to GDI objects such as pens and brushes (HBRUSH and HPEN), and handles to named objects such as mutexes, semaphores, and file handles.
Because of this, using EAX alone may be valid for HANDLE values returned by HeapCreate() in both 32-bit and 64-bit compilations. However, the HANDLE returned by HeapCreate() is not generally shared across process boundaries, so it may take up more than 32 bits.
Best not to take chances one way or the other. Use EAX in 32-bit, and RAX in 64-bit, since that is what the respective calling conventions dictate.
I read some code about debugger, and I'm confused about the variable the code use to define memory address. Sometimes it use DWORD, and sometimes it use LPVOID, can anyone tell me that why windows use LPVOID to define address?
LPVOID in so-called "hungarian" notation means "long pointer to void", that is void far *. The latter originates in 16-bit code and nowadays has no meaning. So, LPVOID now is just the same as void *, but the name is still maintained for the compatibility.
My guess would be that there is no guarantee that a pointer value will fit into a DWORD (eg. on a 64-bit OS)
In windows, a DWORD is explicitly a 32 bit int. A LPVOID value is explicitly pointer-size.
I need to access the WinMain parameters using assembly, but I don't seem to be able to do so despite that I supposedly know where they are in the stack (DWORD offsets 0 to 16, and 0 to 20 when pushing EBP before operations). Below there's an example for showing the lpszCmdline string which contains the command line of the program, but it always seems to contain 0, so nothing is displayed. If I try to use other arguments in the assembly code, no valid string pointer seems to be present and/or the program crashes, as expected.
;[esp+20]==nCmdShow
;[esp+16]==lpszCmdLine
;[esp+12]==0 in win32
;[esp+8]==hInst
;[esp+4]==EIP
;[esp+0]==EBP
push ebp
mov ebp,esp
mov eax,[ebp+16]
push dword 0x00001030 ;UINT uType
push eax ;LPCTSTR lpCaption
push eax ;LPCTSTR lpText
push dword 0 ;HWND hWnd
call dword[MessageBoxA#USER32.DLL]
pop ebp
However, if I use GetCommandLine I can get a valid pointer to the command line string, and it displays.
call dword[GetCommandLineA#KERNEL32.DLL]
push dword 0x00001030 ;UINT uType
push eax ;LPCTSTR lpCaption
push eax ;LPCTSTR lpText
push dword 0 ;HWND hWnd
call dword[MessageBoxA#USER32.DLL]
Where's the error in the first code block? What do I need to get the parameters, and being able to implement my own code to return a valid pointer to lpszCmdLine just like GetCommandLine and as a result, to the other WinMain parameters? If I can't get the command line pointer from the stack, then I presumably won't be able to get the other parameters, like nCmdShow, for other important initializations.
Please let me know if you need more code than the provided above. If it is useful for you to know, I used no linker but fully manual EXE generation (does it make any difference in WinMain, like further stack parameters?), but basically it's just a program for which Windows automatically calls its entry point and the above would be the 2 different options of what program it would contain.
#include <Windows.h>
int CALLBACK WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) {
__asm {
mov eax, [ebp+16]
push 0
push eax
push eax
push 0
call dword ptr ds:[MessageBoxA]
}
return ERROR_SUCCESS;
}
This runs just fine for me within Visual Studio. Oddly running it in a debugger and single stepping causes an access violation when the MessageBox is called. I'm unsure why this is, but running in debug without single stepping as well as running the final binary gives the expected result, ie. a messagebox with caption/message as the argument
I want to monitore swap space usage on windows 2003 server. If the usage is over 80% for 10 minutes, an alarm will be generated. There are lot of tools for RAM, but how about swap usage? How do I simulate that condition and do the test?
Use the built-in performance counters. You can fetch them via WMI/Win32_Perf:
http://msdn.microsoft.com/en-us/library/aa394270%28v=VS.85%29.aspx
or the raw Performance counter/registry interfaces:
http://msdn.microsoft.com/en-us/library/aa373083%28v=VS.85%29.aspx
To force the page file to be used. Start Commiting Memmory. Use the VirtualAlloc api call:
LPVOID WINAPI VirtualAlloc(
__in_opt LPVOID lpAddress,
__in SIZE_T dwSize,
__in DWORD flAllocationType,
__in DWORD flProtect
);
and set flAllocationType to MEM_COMMIT (0x1000), this should start memory being used. Once memory is suffcient exhausted, then the page file should be automatically employed. I suspect you'll have to start measuring usage and then determine heuristically as to when %usage you require happens.
To monitor it read the performance counters. The paging file set has a %usage counter you can read. Start here on how to consume them. All you need is to create a windows service that reads the info and then rings the appropriate alarms.
.Net : https://learn.microsoft.com/en-us/archive/blogs/bclteam/how-to-read-performance-counters-ryan-byington
C++ : http://msdn.microsoft.com/en-us/library/aa373219(v=VS.85).aspx or http://msdn.microsoft.com/en-us/library/aa373214(v=VS.85).aspx
Specifically, I want to use Point-to-point Message Queue but because I am still using legacy codes in eVC++ 4 and it only support until PocketPC 2003SE SDK, I cannot find CreateMsgQueue and friends in the headers (the port to newer VisualStudio is still in progess)
I am using the Message Queue to do IPC with apps developed with WM-6.5-DTK (VS2005).
Update:
I am using the following code (taken from msgqueue.h) to store function pointers and load CoreDLL.dll using GetProcAddress() and LoadLibrary() respectively.
HANDLE /*WINAPI*/ (*CreateMsgQueue)(LPCWSTR lpName, LPMSGQUEUEOPTIONS lpOptions);
HANDLE /*WINAPI*/ (*OpenMsgQueue)(HANDLE hSrcProc, HANDLE hMsgQ
, LPMSGQUEUEOPTIONS lpOptions);
BOOL /*WINAPI*/ (*ReadMsgQueue)(HANDLE hMsgQ,
/*__out_bcount(cbBufferSize)*/ LPVOID lpBuffer, DWORD cbBufferSize,
LPDWORD lpNumberOfBytesRead, DWORD dwTimeout, DWORD *pdwFlags);
BOOL /*WINAPI*/ (*WriteMsgQueue)(HANDLE hMsgQ, LPVOID lpBuffer, DWORD cbDataSize,
DWORD dwTimeout, DWORD dwFlags);
BOOL /*WINAPI*/ (*GetMsgQueueInfo)(HANDLE hMsgQ, LPMSGQUEUEINFO lpInfo);
BOOL /*WINAPI*/ (*CloseMsgQueue)(HANDLE hMsgQ);
Is the above code alright since I need to comment out WINAPI and __out_bcount(cbBufferSize) in order for them to compile.
As pointed out by ctacke, it is actually available on PPC2003 SDK. The Requirement in the MSDN is wrong.
Btw, the above approach seems to work fine even after commenting out WINAPI and __out_bcount(cbBufferSize)