Find what is the channel using Windows API - c++

I am trying to get the Channel using the windows API. So far, I have tried to use the wlan_intf_opcode_channel_number with the WlanQueryInterface function.
I am not too sure what the reply means on that thread and was hoping someone could clarify.
ULONG channel = 0;
DWORD dwSizeChannel = sizeof(channel);
dwResult = WlanQueryInterface(
hClient,
InterfaceGuid,
wlan_intf_opcode_channel_number,
NULL,
&dwSizeChannel,
(PVOID*)&channel,
NULL);
I am not sure what to do after here. Any help would be appreciated!
After checking i found out that i always get the same value as channel has befor calling the WlanQueryInterface

The MS docs for the op-code seems to be wrong. If you try something similar here:
ULONG *channel = NULL;
DWORD dwSizeChannel = sizeof(*channel);
DWORD rc = WlanQueryInterface (
hClient, InterfaceGuid,
wlan_intf_opcode_channel_number,
NULL, &dwSizeChannel, &channel, NULL);
if (rc == ERROR_SUCCESS && channel) {
printf ("Channel: %lu\n", *channel):
WlanFreeMemory (channel);
}
I do get the expected Channel: 5.
The same goes for wlan_intf_opcode_current_operation_mode and possibly other op-codes that's simply an ULONG.

I tried out WlanQueryInterface with the inputs from the documentation:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms706765(v=vs.85).aspx
When query based on "wlan_intf_opcode_channel_number" was triggered, I got the data as "13". And the frequency could be made out as 2472Mhz from the WLAN information provided by the following wikipedia link:
https://en.wikipedia.org/wiki/List_of_WLAN_channels
Hope this helps.

Related

C++ Win32 - Getting App Name using PID and Executable Path

I'd like to get the name of an application on Windows.
Currently I'm using EnumProcesses() to enumerate all processes and receive a list of PIDs.
Then I'm looping through all PIDs, each iteration looks like this, when aProcess[i] is the current PID:
HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, aProcesses[i]);
std::string processName = get_process_name(proc);
My get_process_name(proc) function uses GetModuleFileNameEx to get the executable path and GetProcessImageFileName in order to retrieve the name of the executable file.
What I want to retrieve is basically the App Name, as it is displayed in the Windows Task Manager.
I've looked throughout Win32 API's documentation and could not find a clue on how to achieve this.
I've tried looking for other ways such as Windows Shell tasklist but it outputs different things, for example- Google Chrome:
Image Name: chrome.exe PID: 84 Session Name: Console
I'd really appreciate any thought on the matter, whether it be the Win32 API or some other way I can implement through C++ code.
You can do this with GetFileVersionInfoA and VerQueryValueA.
You just need to follow the example given in the VerQueryValueA document.
Here is my sample:
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
int main()
{
HANDLE handle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION , FALSE, 2140); //Modify pid to the pid of your application
if (!handle) return 0;
wchar_t pszFile[MAX_PATH] = L"";
DWORD len = MAX_PATH;
QueryFullProcessImageName(handle, 0, pszFile, &len);
UINT dwBytes, cbTranslate;
DWORD dwSize = GetFileVersionInfoSize(pszFile, (DWORD*)&dwBytes);
if (dwSize == 0) return 0;
LPVOID lpData = (LPVOID)malloc(dwSize);
ZeroMemory(lpData, dwSize);
if (GetFileVersionInfo(pszFile, 0, dwSize, lpData))
{
VerQueryValue(lpData,
L"\\VarFileInfo\\Translation",
(LPVOID*)&lpTranslate,
&cbTranslate);
wchar_t strSubBlock[MAX_PATH] = { 0 };
wchar_t* lpBuffer;
for (int i = 0; i < (cbTranslate / sizeof(struct LANGANDCODEPAGE)); i++)
{
StringCchPrintf(strSubBlock,50,
L"\\StringFileInfo\\%04x%04x\\FileDescription",
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
VerQueryValue(lpData,
strSubBlock,
(void**)&lpBuffer,
&dwBytes);
std::wcout << lpBuffer << std::endl;
}
}
if(lpData) free(lpData);
if (handle) CloseHandle(handle);
return 0;
}
And it works for me:
I think what you want are the "version" resources embedded in the PE file (the executables.)
You seem to be familiar with using Win32 API, so I'm just going to give you some hints.
You have to use LoadLibraryEx to load the EXE file (the Ex suffix is to enable passing the LOAD_LIBRARY_AS_DATAFILE flag,) and then call EnumResourceTypes (also see EnumResourceNames) to enumerate all the resource types/resources in the file, and find what you are looking for and then extract the data with LoadResource. The resource type you want is RT_VERSION.
I'm sure I'm omitting a lot of details (as per usual for Win32 programming,) and there might not be a need for enumeration at all; in which case you may want to call FindResource or FindResourceEx directly (if there is a fixed name for this particular resource.)
As further clarification, this gives you the date you see if you right-click on the EXE file (not the shortcut) in Windows Explorer and select "Properties", then go to the "Details" tab. If that information is indeed what you want (e.g. the "File description" field) then the above method should give you the data.

c++ can't get local user groups by NetUserGetGroups()

Can't figure out how to work with all these "wide unicode strings". Can anyone tell me what am i doing wrong? I Just want to get all local user groups, so i do:
LPBYTE buffer;
DWORD entries, total_entries;
NetUserGetLocalGroups(NULL, L"rovnyart", 0, LG_INCLUDE_INDIRECT, &buffer, MAX_PREFERRED_SIZE, &entries, &total_entries);
LOCALGROUP_USERS_INFO_0 *groups = (LOCALGROUP_USERS_INFO_0 *) buffer;
unsigned int i;
for (i=0; i<entries;i++)
wprintf(L"%s\n", groups[i].lgrui0_name);
And this is what i get:
t
╝4╝<╝8╝=╝8╝A╝B╝#╝0╝B╝>╝#╝K╝
╝>╝;╝L╝7╝>╝2╝0╝B╝5╝;╝8╝
Process finished with exit code 0
My windows language is Russian, but i created one group called "testgroup1", and as you can see it doesn't display correct too.
i tried wprintf() - result was the same :(
What am i doing wrong?
UPD:
Ok, I changed the code to fit your advices. I created a group called "test" which is non-cyrillic and put my user there.
Here's my code:
LPBYTE pBuf = NULL;
NET_API_STATUS nStatus;
DWORD entries, total_entries;
nStatus = NetUserGetLocalGroups(NULL, L"rovnyart", 0, LG_INCLUDE_INDIRECT, &pBuf, MAX_PREFERRED_LENGTH, &entries, &total_entries);
LOCALGROUP_USERS_INFO_0 *groups = (LOCALGROUP_USERS_INFO_0 *) pBuf;
if (nStatus == 0) {
unsigned int i;
for (i = 0; i < entries; i++)
wprintf(L"%s\n", groups[i].lgrui0_name);
NetApiBufferFree(pBuf);
}
Here is the output:
t
╝4╝<╝8╝=╝8╝A╝B╝#╝0╝B╝>╝#╝K╝
╝>╝;╝L╝7╝>╝2╝0╝B╝5╝;╝8╝
Process finished with exit code 0
Thanks everyone, including guys who downvoted me. The solution of my problem was in %s format specifier. I needed to use %S.My program correctly outputs group names with:
wprintf(L"%S\n", groups[i].lgruiu0_name);
Although this code is error-higlighted in my CLion, it works for some reason.
Thanks for all helpful links.

RSSI using Windows API

I am trying to get the RSSI using the windows API. So far, I have found this thread saying to use the wlan_intf_opcode_rssi with the WlanQueryInterface function. I am not too sure what the reply means on that thread and was hoping someone could clarify.
All i have managed to understand from the other thread is this:
WlanQueryInterface(hClient,
&pInfo->InterfaceGuid,
wlan_intf_opcode_rssi,
NULL,
&connectInfoSize,
(PVOID*)&pConnectInfo,
&opCode);
I am not sure what to do after here. Any help would be appreciated!
You're passing the wrong type of argument to WlanQueryInterface. MSDN says that the return type for wlan_intf_opcode_rssi is LONG, so you need to pass a pointer to a LONG variable, like this:
LONG rssi = 0;
DWORD dwSizeRssi = sizeof(rssi);
dwResult = WlanQueryInterface(hClient,
&pIfInfo->InterfaceGuid,
wlan_intf_opcode_rssi,
NULL,
&dwSizeRssi,
(PVOID *)&rssi,
&opCode);
if (dwResult == ERROR_SUCCESS)
{
wprintf(L"RSSI = %u \n", rssi);
}

Sending keyboard input via DeviceIoControl

For the past 3 hours or so I've been attempting to send keyboard input by writing to the keyboard device. I have successfully found and opened the keyboard device, but I'm stuck at the final step. I don't know exactly how to format the DeviceIoControl parameters and I don't really know where to start getting the values.
Currently I have the following taken partly from a library called Interception posted in another answer here. I left out all the device opening stuff to save space.
#define IOCTL_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x820, METHOD_BUFFERED, FILE_ANY_ACCESS)
if(device != INVALID_HANDLE_VALUE) {
DWORD dwReturned;
KEYBOARD_INPUT_DATA kbinput;
kbinput.UnitId = 0;
kbinput.MakeCode = 0x2D;
kbinput.Flags = KEY_MAKE;
kbinput.Reserved = 0;
kbinput.ExtraInformation = 0;
DeviceIoControl(device, IOCTL_WRITE, &kbinput, sizeof(KEYBOARD_INPUT_DATA), NULL, 0, &dwReturned, NULL);
kbinput.Flags = KEY_BREAK;
DeviceIoControl(device, IOCTL_WRITE, &kbinput, sizeof(KEYBOARD_INPUT_DATA), NULL, 0, &dwReturned, NULL);
}
If I call GetLastError after the DeviceIoControl calls I get a return value of ERROR_INVALID_FUNCTION(1). I assume that means IOCTL_WRITE isn't the correct value, but I haven't the faintest idea on how to find the correct value and no amount of searching has gotten me any further.

Bad counter path, pdhAddCounter; performance monitor in windows

I'm trying to count the number of processes on windoes 2008 server using pdh.h.
CONST PWSTR COUNTER_PATH = L"\\System\\Processes";
HQUERY hQuery = NULL;
HCOUNTER hCounter;
PDH_STATUS pdhStatus = ERROR_SUCCESS;
pdhStatus = PdhOpenQuery(NULL, 0, &hQuery);
pdhStatus = PdhAddCounter(hQuery, (LPCSTR)COUNTER_PATH, 0, &hCounter);
I got the COUNTER_PATH name from here, and the example can be found in here. But somehow I'm getting 0xC0000BC0 (PDH_CSTATUS_BAD_COUNTERNAME) error message at PdhAddCounter. Can anybody pick up any mistake I made? I'm not sure what I'm missing here. Is there anything wrong with COUNTER_PATH?
You're casting COUNTER_PATH to a LPCSTR in PdhAddCounter which you shouldn't be doing.
PdhAddCounter's second parameter is a LPCTSTR which is the same as CONST PWSTR.