Windows Resource Monitors "Network Activity" c++ - c++

I'm trying to figure out how to get all network activity for a given process. In the Windows "Resource Monitor" application in the "Network Activity" box, you are able to see all tcp / udp connections, and the data being sent etc. I first tried using the cmd netstat, and was going to parse this but quickly realized it "misses" a whole bunch of udp connections. So that was out. Now I've been looking into using iphlpapi.h in c++ along with its GetExtendedUdpTable function. But even this doesn't seem to be showing all the data that Resource Monitor shows. Can anyone direct me to the proper windows API that can get the same information as seen in the Network Activity tab under Resource Monitor. I've been searching for a while now and everything I've found is extremely old, I'm hoping to use whatever is the current/modern approach. This doesn't have to be backwards compatible, windows 10 only is fine.
Basically my end-goal is to build an app that can geo-locate ip's using a database automatically for a target application (including UDP connections). Now I'm sure there are many libraries/apps out there that can already do this. I'm just wanting to do it as a learning process so I'd like to avoid any libraries/API other than windows provided ones.
This is currently what I've been working with, please forgive the use of poor practices such as using printf and not using static_cast etc. I'll be rewriting everything properly once I've found a way of obtaining the information I'm after.
MIB_UDPTABLE_OWNER_PID* pUdpTable;
MIB_UDPROW_OWNER_PID* owner;
DWORD dwSize;
DWORD dwResult;
dwResult = GetExtendedUdpTable(NULL, &dwSize, false, AF_INET, UDP_TABLE_OWNER_PID, 0);
pUdpTable = (MIB_UDPTABLE_OWNER_PID*)MALLOC(dwSize);
dwResult = GetExtendedUdpTable(pUdpTable, &dwSize, false, AF_INET, UDP_TABLE_OWNER_PID, 0);
for (DWORD dwLoop = 0; dwLoop < pUdpTable->dwNumEntries; dwLoop++) {
owner = &pUdpTable->table[dwLoop];
printf("%ld ", owner->dwOwningPid);
HANDLE Handle = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE,
owner->dwOwningPid
);
if (Handle) {
TCHAR Buffer[MAX_PATH];
if (GetModuleFileNameEx(Handle, 0, Buffer, MAX_PATH)) {
printf(Buffer);
printf("\n");
} else {
printf("Error GetModuleFileNameEx : %lu\n", GetLastError());
}
CloseHandle(Handle);
} else {
printf("Error OpenProcess : %lu\n", GetLastError());
}
}
FREE(pUdpTable);

Related

Windows 7 Shutdown Issue / ExitWindowsEx/AdjustTokenPrivileges

Hello to all stackoverflow great minds!! I need some explanation and suggestion on how to determine what have cause this problem. I hope nobody would be harass and will judge directly. If there are not clear here please be kind to reply.
I have an application that i am investigating right now. The application will shutdown the Windows if a power-off message was posted from one of its child processes.
Scenario:
When i start the application and post a power-off message nothing happens to windows only the application was exited. The second time I start the application then post again a power off message the windows shutdown or reboot depending on the condition i had send.
HANDLE hToken;
TOKEN_PRIVILEGES tp;
OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
LookupPrivilegeValue(NULL,
SE_SHUTDOWN_NAME, &(tp.Privileges[0].Luid));
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
if ( iApplicationProblemOccured == 1 ){
ExitWindowsEx(EWX_FORCE | EWX_SHUTDOWN | EWX_POWEROFF, 0L);
} else {
if(wShutdownType != 1) {
ExitWindowsEx(EWX_FORCE | EWX_REBOOT, 0L);
} else {
ExitWindowsEx(EWX_FORCE | EWX_SHUTDOWN | EWX_POWEROFF, 0L);
}
}
AdjustTokenPrivileges(hToken, TRUE, &tp, sizeof(tp), NULL, NULL);
ExitProcess(0);
The problem is why the execution of the ExitWindowsEx from the first power off does not works?
I have checked the tokenpriveleges from the first poweroff but it was enabled.
I have also change the dwReason to planned in the ExitWindowsEx but nothing happens.
From what i read in
https://msdn.microsoft.com/en-us/library/windows/desktop/aa376868(v=vs.85).aspx
if the return of ExitWindowsEx is 0, it does not necessarily determines that the execution of windows shutdown will be successful because the function will only initiate the shutdown process.
I am thinking that there is something process/services that blocks stops the windows shutdown process from the first power off..
Is there a way to debug the windows shutdown process after my application send the shutdown request?
I am hoping someone can help me with this issue!!
Thanks a lot..

C++ USB communication

I have a problem regarding communication with a USB device on Windows. I can't use libusb or WinUSB as I have a specific driver for that (Silabs USB to UART, which is a USB-to-serial bridge). This is how I initialize a device file, send&read data and close the handle.
HANDLE hDevFile = CreateFile(L"\\??\\USB#VID_10C4&PID_EA60#0001#{a5dcbf10-6530-11d2-901f-00c04fb951ed}",
GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
PurgeComm(hDevFile, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
DCB dcbInitState;
GetCommState(hDevFile, &dcbInitState);
DCB dcbNewState = dcbInitState;
dcbNewState.BaudRate = 57600;
dcbNewState.Parity = NOPARITY;
dcbNewState.ByteSize = 8;
dcbNewState.StopBits = ONESTOPBIT;
if (SetCommState(hDevFile, &dcbNewState) == 0)
{
printf("Could not set COM state. Error: %i", GetLastError());
return -1;
}
Sleep(60);
BYTE outData[8];
outData[0] = 0x53;
outData[1] = 0x10;
outData[2] = 0x04;
outData[3] = 0x10;
outData[4] = 0x40;
outData[5] = outData[3] ^ outData[4];
outData[6] = 0xAA;
outData[7] = 0x00;
DWORD dwWritten;
if (!WriteData(hDevFile, outData, 8, &dwWritten))
{
printf("Could not write data. Error: %i", GetLastError());
return -1;
}
BYTE inData[8];
DWORD dwRead;
if (!ReadData(hDevFile, inData, 8, &dwRead, 2000))
{
printf("Could not read data. Error: %i", GetLastError());
return -1;
}
SetCommState(hDevFile, &dcbInitState);
Sleep(60);
CloseHandle(hDevFile);
hDevFile = INVALID_HANDLE_VALUE;
(I get the device symbolic name from the registry but I've skipped that part to make my question concise. WriteData() and ReadData() are custom functions that write and read accordingly.)
The problem is that SetCommState() returns a zero-value. GetLastError() returns 122, which is ERROR_INSUFFICIENT_BUFFER.
The problem now is that PurgeComm() generates ERROR_INSUFFICIENT_BUFFER, too. CreateFile() gives ERROR_SUCCESS, so it must be opened properly.
What's wrong? Did I miss something?
Edit: I tried enumerating COM ports and found an interesting thing - there are no COM ports on my computer. Even though the device is connected and enabled, with the driver present and all that stuff. I also tried forcefully putting \\.\COM1, \\.\COM2, and so on as the file name for CreateFile, but with no luck. Everytime got an ERROR_FILE_NOT_FOUND.
Please, help. This is very important to me.
Because this is a CP210x device, it's a virtual COM port, so you should be opening it as such in CreateFile. You had it right when you said that you tried using \.\COMx, you just need to find out which COM port your CP210x device has been assigned and you will not get the ERROR_FILE_NOT_FOUND error. You can find this by looking in device manager:
Take a look a the Serial Communications Guide for the CP210x, this explains how to make these types of calls to your device, there's even a COM port discovery function that will help you find the COMxx name dynamically. It also has accompanying software, AN197SW.zip.
You can use the Win32 Communication Functions just fine with a handle gotten from passing the device interface path to CreateFile. I do this all the time. Ignore the people telling you that you must use COMx.
However, it is important that you use the device interface path corresponding to the (virtual) serial port device (GUID_DEVINTERFACE_COMPORT). Many drivers are implemented as a pair of (USB device, serial port device), where the serial port is a child of the USB device. Opening the USB device (GUID_DEVINTERFACE_USB_DEVICE) will not give you working communication functions, such as PurgeCommState. (And this is exactly what you're trying now, note that the tail end of your device interface path exactly matches the GUID documented on MSDN)
If you don't have anything listed under the Ports section in Device Manager, you either don't have the driver correctly installed, or the device is not connected.
Once you get a port device found, you can use CM_Get_Parent to pair up the GUID_DEVINTERFACE_COMPORT instance with the GUID_DEVINTERFACE_USB_DEVICE, solving your question of "What serial port is attached to USB in this particular way?"

OpenProcessToken fails with ERROR_ACCESS_DENIED from a local system service

Let me explain my situation first. The issue I describe below comes from an end-user's machine, and all I have to work with is just a copy of the Windows Event Log. I cannot access the machine itself to run any debugging tests.
Now the issue. I have a service application that I create as such:
SC_HANDLE hScService = CreateService(hScManager,
L"MyServiceID",
L"My Service Name",
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
SrvcPath,
NULL, NULL, NULL, NULL, _T(""));
The service process later has its SE_DEBUG_NAME privilege set using the AdjustTokenPrivileges API.
Later on I have a method that enumerates running processes and later gets processes LUIDs, using a code as such:
//'pProcIDs' = list of process IDs obtained from EnumProcesses()
for(UINT i = 0; i < nNumProc; i++)
{
DWORD dwProcID = pProcIDs[i];
//Skip obvious system processes
if(dwProcID != 0 &&
dwProcID != 4)
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwProcID);
if(hProcess)
{
HANDLE hTokenHandle;
if(::OpenProcessToken(hProcess, TOKEN_QUERY, &hTokenHandle))
{
TOKEN_STATISTICS ts;
DWORD dwcbSz = 0;
if(::GetTokenInformation(hTokenHandle, TokenStatistics, &ts, sizeof(ts), &dwcbSz))
{
//And so on...
}
else
{
//Handle error here
}
::CloseHandle(hTokenHandle);
}
else
{
//***Here's where I get my error in question***
}
::CloseHandle(hProcess);
}
else
{
//Handle error here
}
}
}
When I run the code above on my own development computers, it runs just fine. Note that those computers run "stock" copies of the OS without any AVP or other third-party software installed.
The event log copy I received from a customer running Windows 7 Professional machine (that is a member of an Active Directory domain) has 3 processes that return ERROR_ACCESS_DENIED when I call OpenProcessToken on them from the code above. Their PIDs are just regular values, such as 1824, 2760, 5024 (that obviously change after a reboot.)
Does anyone have any idea why it happens? Do I need to set additional privileges for my service?
PS. From the event log I can tell that the workstation in question has some Symantec Antivirus product installed, judging by this line:
New virus definition file loaded. Version: 140217066.
Symantec antivirus software (as well as that of many other security software vendors) may attempt to prevent tampering with their processes by un-authorized actors. Acquiring the process token for one of their processes just might qualify.
That said, you can quickly verify that the PIDs in question are in fact part of the Symantec package by examining the path to executable images that back the processes. If they are part of the Symantec AV software package, you'll need to look in to configuring it to trust your application, or disable it while you run this code (not recommended), or simply ignore errors of this type.

How to create a progress bar while downloading a file using the windows API?

i'm working on an application in MS Visual C++ using Windows API that must download a file and place it in a folder.
I have already implemented the download using URLDownloadToFile function, but i want to create a PROGRESS_CLASS progress bar with marquee style while the file is being downloaded, but it doesn't seems to get animated in the process.
This is the function I use for downloading:
BOOL SOXDownload()
{
HRESULT hRez = URLDownloadToFile(NULL,
"url","C:\\sox.zip", 0, NULL);
if (hRez == E_OUTOFMEMORY ) {
MessageBox(hWnd, "Out of memory Error","", MB_OK);
return FALSE;
}
if (hRez != S_OK) {
MessageBox(hWnd, "Error downloading sox.", "Error!", MB_ICONERROR | MB_SYSTEMMODAL);
return FALSE;
}
if (hRez == S_OK) {
BSTR file = SysAllocString(L"C:\\sox.zip");
BSTR folder = SysAllocString(L"C:\\");
Unzip2Folder(file, folder);
::MessageBoxA(hWnd, "Sox Binaries downloaded succesfully", "Success", MB_OK);
}
return TRUE;
}
Later I call inside WM_CREATE (in my main window's message processor):
if (!fileExists("C:\\SOX\\SOX.exe")) {
components[7] = CreateWindowEx(0, PROGRESS_CLASS,
NULL, WS_VISIBLE | PBS_MARQUEE,
GetSystemMetrics(SM_CXSCREEN) / 2 - 80,
GetSystemMetrics(SM_CYSCREEN) / 2 + 25,
200, 50, hWnd, NULL, NULL, NULL);
SetWindowText(components[7], "Downloading SoX");
SendMessage(components[7], PBM_SETRANGE, 0, (LPARAM) MAKELPARAM(0, 50));
SendMessage(components[7], PBM_SETMARQUEE, TRUE, MAKELPARAM( 0, 50));
SOXDownload();
SendMessage(components[7], WM_CLOSE, NULL, NULL);
}
And as I want, I get a tiny progress bar... But it's not animated, and when I place the cursor over the bar, the cursor indicates that the program is busy downloading the file.
When the download is complete, the window closes as i requested: SendMessage(components[7], WM_CLOSE, NULL, NULL);
So the question is how can I make the bar move while downloading the file? Considering that i want it done with marquee style for simplicity.
Thanks in advance.
Create a class that implements the IBindStatusCallback interface and then pass it to the last parameter of URLDownloadToFile(). You will then receive OnProgress events during the download, which you can use to update your UI as needed, pump the message queue for pending messages, etc.
I think I'd use InternetReadFile (or InternetReadFileEx). This will let you read a small amount at a time (e.g., 4 kilobytes) so you can update your status bar periodically (and handle any other messages as well).
To maximize UI responsiveness, you can do an asynchronous read. This will let you process messages immediately during the download instead of waiting for the next 4K (or whatever) block to finish. Over a fast connection, it probably won't make a noticeable difference (4K doesn't normally take long) but over a slow or undependable connection, it could be a fairly major help. Doing asynchronous downloading also gives you a chance to cleanly cancel the transaction if it takes too long.

CreateFile: direct write operation to raw disk "Access is denied" - Vista, Win7

The relevant Microsoft doc is:
Blocking Direct Write Operations to Volumes and Disks
CreateFile, remarks on Physical Disks and Volumes
The executable is written in C++ and it calls CreateFile() to open an SD card that has no filesystem. The CreateFile() and consecutive ReadFile() calls are successful for GENERIC_READ without Administrator privileges.
CreateFile fails for GENERIC_WRITE even with Administrator privileges. In the explorer, I set Run as Administrator under Properties > Compatibility > Privilege Level. I also tried to run the executable from an Administrator cmd (started with Ctrl+Shift+Enter, "Administrator:" is in the window title, properly elevated). Still, I get ERROR_ACCESS_DENIED (0x5).
Do I have to pass something else to CreateFile? I have no idea what security attributes are, I just pass NULL, relevant code is here at line 92, and here at line 48.
Or is there anything else that should be set to run the process with Administrator privileges?
A related questions:
Can I get write access to raw disk sectors under Vista and Windows 7 in user mode?
Raw partition access in Windows Vista
How to obtain direct access to raw HD data in C?
Is there a clean way to obtain exclusive access to a physical partition under Windows?
While the answer of #MSalters makes sense, it is not how my code works. In fact it is so counter-intuitive, I spent several days making sure the code does in fact work.
These code snippets are in a proven, mass consumer market software product. When it needs to modify an on-disk structure, it dismounts the win32 volume so it can modify NTFS or FAT filesystem structures. Interestingly, the volume access handle is read-only:
char fn [30];
snprintf (fn, sizeof fn, "\\\\.\\%s:", vol -> GetVolName ());
vol_handle = CreateFile (fn, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING,
FILE_FLAG_NO_BUFFERING | FILE_FLAG_RANDOM_ACCESS,
NULL);
if (vol_handle == INVALID_HANDLE_VALUE)
{
// show error message and exit
}
If unable to get write access to a volume or partition, this code forces a dismount if the user authorizes such after a stern warning:
if (!DeviceIoControl (vol_handle, FSCTL_DISMOUNT_VOLUME,
NULL, 0, NULL, 0, &status, NULL))
{
DWORD err = GetLastError ();
errormsg ("Error %d attempting to dismount volume: %s",
err, w32errtxt (err));
}
// lock volume
if (!DeviceIoControl (vol_handle, FSCTL_LOCK_VOLUME,
NULL, 0, NULL, 0, &status, NULL))
{
// error handling; not sure if retrying is useful
}
Writing is then fairly straightforward, except for positioning the file pointer by 512-byte sector:
long hipart = sect >> (32-9);
long lopart = sect << 9;
long err;
SetLastError (0); // needed before SetFilePointer post err detection
lopart = SetFilePointer (vol_handle, lopart, &hipart, FILE_BEGIN);
if (lopart == -1 && NO_ERROR != (err = GetLastError ()))
{
errormsg ("HWWrite: error %d seeking drive %x sector %ld: %s",
err, drive, sect, w32errtxt (err));
return false;
}
DWORD n;
if (!WriteFile (vol_handle, buf, num_sects*512, &n, NULL))
{
err = GetLastError ();
errormsg ("WriteFile: error %d writing drive %x sectors %lu..%lu: %s",
err, drv, sect, sect + num_sects - 1,
w32errtxt (err));
return false;
}
It's quite rare to want only GENERIC_WRITE. You most likely want GENERIC_READ|GENERIC_WRITE.
There is note in MSDN in documentation of CreateFile:
Direct access to the disk or to a volume is restricted. For more information, see "Changes to the file system and to the storage stack to restrict direct disk access and direct volume access in Windows Vista and in Windows Server 2008" in the Help and Support Knowledge Base at http://support.microsoft.com/kb/942448.
It refers to Vista/2008, but maybe apply to Win7 also.
I had a similar issue when porting from x86 to x64 code. You mention that you are passing null for your SECURITY_ATTRIBUTES parameter; I was getting access-denied errors myself using this approach until I actually began creating/passing this parameter.