Hello, I am using NetServerEnum to get a list of local networking computer (LAN)
I'd like to know its return (out) addresses
For example, should they be something like
\192.168.1.10\ComputerName1
\192.168.1.10\ComputerName2
\192.168.1.10\ComputerName3
? Or just the computer names existing on the networking router ?
I am not on a networking machine to test it, it'll be really kind of you to inform me this.
Thank you.
NetServerEnum is basically a leftover from the NetBIOS days, so it only deals in "flat" (NetBIOS) names. Here's a bit of code to show what names it can give you though:
#include <windows.h>
#include <lm.h>
#include <iostream>
int main() {
SERVER_INFO_100 *info;
DWORD count;
DWORD total_servers;
DWORD resume = 0;
NetServerEnum(NULL,
100,
(BYTE **)&info,
MAX_PREFERRED_LENGTH,
&count,
&total_servers,
SV_TYPE_NT, NULL,
&resume);
for (int i=0; i<count; i++)
std::wcout << info[i].sv100_name << "\n";
NetApiBufferFree(info);
return 0;
}
Name or IP-address of network router is not returned. Only computer name is returned in sv100_name or sv101_name field of SERVER_INFO_10x structure as:
ComputerName0
ComputerName1
ComputerName2
...
ComputerNameN
Related
I retrieve the serial number of the physical hard-drive using the function DeviceIoControl following the suggestions from Blacktempel in this post. Getting the number works fine in principle, but I (still) have trouble with the format of the serial number as it keeps changing from computer to computer and with time. Also I experienced a format change on some computers between running the program as normal user or as admin.
For example, I retrieved a number with the following format:
WD-WCAZAF632086
when I tested the program first and after a few weeks it looks like:
2020202057202d4443575a414641333630323638
This is still the same number, only the characters have been replaced by their hex codes and swapped pair-wise. I've encountered different formats like a normal string with the characters exchanged pair-wise. Among other values, I need to check this number to verify if a software license is valid for a certain computer. Having an instable and unknown format is annoying and if the format changes to something I'm not yet aware of, I risk that the software license check fails although the license is still valid.
Does anyone know how to get the serial number in a stable format, or how to predict the format so it can be adapted for comparison?
Here is minimal C++ example of code that I used to retrieve the serial number of the first physical disc. I build it using Visual Studio 2015:
#include "stdafx.h"
#include "Windows.h"
#include <string>
#include <vector>
#include <iostream>
bool GetDeviceString(std::string &serialnumber)
{
HANDLE deviceHandle = CreateFileW(L"//./PhysicalDrive0", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); // Get Handle to device
if (deviceHandle == INVALID_HANDLE_VALUE) // Check if Handle is valid
return false;
STORAGE_PROPERTY_QUERY query{};
query.PropertyId = StorageDeviceProperty;
query.QueryType = PropertyStandardQuery;
STORAGE_DESCRIPTOR_HEADER storageDescriptorHeader = { 0 };
DWORD dwBytesReturned;
if (!DeviceIoControl(deviceHandle, IOCTL_STORAGE_QUERY_PROPERTY,
&query, sizeof(STORAGE_PROPERTY_QUERY),
&storageDescriptorHeader, sizeof(STORAGE_DESCRIPTOR_HEADER), &dwBytesReturned, NULL))
{
}
// Alloc the output buffer
const DWORD dwOutBufferSize = storageDescriptorHeader.Size;
std::vector<BYTE> pOutBuffer(dwOutBufferSize,0);
if (!DeviceIoControl(deviceHandle, IOCTL_STORAGE_QUERY_PROPERTY,
&query, sizeof(STORAGE_PROPERTY_QUERY),
pOutBuffer.data(), dwOutBufferSize,
&dwBytesReturned, NULL))
{
// handle error, do cleanup and return
}
STORAGE_DEVICE_DESCRIPTOR* pDeviceDescriptor = (STORAGE_DEVICE_DESCRIPTOR*)pOutBuffer.data();
const DWORD dwSerialNumberOffset = pDeviceDescriptor->SerialNumberOffset;
if (dwSerialNumberOffset != 0)
{
// Finally, get the serial number
serialnumber = (char*)(pOutBuffer.data() + dwSerialNumberOffset);
}
}
int main()
{
std::string serialnumber;
if (GetDeviceString(serialnumber))
{
std::cout << "serial number of first disc: " << serialnumber << std::endl;
}
else
{
std::cout << "Failed!" << std::endl;
}
std::cin.ignore();
return 0;
}
I hope someone can help me with this issue. I made an application to read some data from a smartphone and display in an application. It worked fine at my house, so I took it to my friend's house to show him and it didn't work. So after the panic, I realized that the address had changed slightly due to being connected to a new PC not a problem there must be a simple solution on winapi.
\\?\usb#vid_045e&pid_0040#6&ff454f2&0&3#{a5dcbf10-6530-11d2-901f-00c04fb951ed}\
I have only found code for C++ and my app is in C so it's no use. I also found libusb on google, however this doesn't return the full paths like in my example above.
Is there a simple fix like search by GUID? Hope you can help.
BR
This was the LIBUSB I used
#include <stdio.h>
#include <sys/types.h>
#include <windows.h>
#include <libusb.h>
static void print_devs(libusb_device **devs)
{
libusb_device *dev;
int i = 0;
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0) {
fprintf(stderr, "failed to get device descriptor");
return;
}
printf("%04x:%04x (bus %d, device %d)\n",
desc.idVendor, desc.idProduct,
libusb_get_bus_number(dev), libusb_get_device_address(dev));
}
}
int main(void)
{
libusb_device **devs;
int r;
ssize_t cnt;
r = libusb_init(NULL);
if (r < 0)
return r;
cnt = libusb_get_device_list(NULL, &devs);
if (cnt < 0)
return (int) cnt;
print_devs(devs);
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
system("pause");
return 0;
}
This just returns for example
1033:0194 (bus 1, device 255)
Yes you can get a list of all the device identifiers on your computer, but it's not really all that simple, especially if you need to filter it for a particular kind of device.
You start with SetupDiGetClassDevs. After enumerating the matching devices, use SetupDiGetDeviceInstanceId to get the device path, like the one shown in your question.
I'm trying to read the memory of a process using task_for_pid / vm_read.
uint32_t sz;
pointer_t buf;
task_t task;
pid_t pid = 9484;
kern_return_t error = task_for_pid(current_task(), pid, &task);
vm_read(task, 0x10e448000, 2048, &buf, &sz);
In this case I read the first 2048 bytes.
This works when I know the base address of the process (which I can find out using gdb "info shared" - in this case 0x10e448000), but how do I find out the base address at runtime (without looking at it with gdb)?
Answering my own question. I was able to get the base address using mach_vm_region_recurse like below. The offset lands in vmoffset. If there is another way that is more "right" - don't hesitate to comment!
#include <stdio.h>
#include <mach/mach_init.h>
#include <sys/sysctl.h>
#include <mach/mach_vm.h>
...
mach_port_name_t task;
vm_map_offset_t vmoffset;
vm_map_size_t vmsize;
uint32_t nesting_depth = 0;
struct vm_region_submap_info_64 vbr;
mach_msg_type_number_t vbrcount = 16;
kern_return_t kr;
if ((kr = mach_vm_region_recurse(task, &vmoffset, &vmsize,
&nesting_depth,
(vm_region_recurse_info_t)&vbr,
&vbrcount)) != KERN_SUCCESS)
{
printf("FAIL");
}
Since you're calling current_task(), I assume you're aiming at your own process at runtime. So the base address you mentioned should be the dynamic base address, i.e. static base address + image slide caused by ASLR, right? Based on this assumption, you can use "Section and Segment Accessors" to get the static base address of your process, and then use the dyld functions to get the image slide. Here's a snippet:
#import <Foundation/Foundation.h>
#include </usr/include/mach-o/getsect.h>
#include <stdio.h>
#include </usr/include/mach-o/dyld.h>
#include <string.h>
uint64_t StaticBaseAddress(void)
{
const struct segment_command_64* command = getsegbyname("__TEXT");
uint64_t addr = command->vmaddr;
return addr;
}
intptr_t ImageSlide(void)
{
char path[1024];
uint32_t size = sizeof(path);
if (_NSGetExecutablePath(path, &size) != 0) return -1;
for (uint32_t i = 0; i < _dyld_image_count(); i++)
{
if (strcmp(_dyld_get_image_name(i), path) == 0)
return _dyld_get_image_vmaddr_slide(i);
}
return 0;
}
uint64_t DynamicBaseAddress(void)
{
return StaticBaseAddress() + ImageSlide();
}
int main (int argc, const char *argv[])
{
printf("dynamic base address (%0llx) = static base address (%0llx) + image slide (%0lx)\n", DynamicBaseAddress(), StaticBaseAddress(), ImageSlide());
while (1) {}; // you can attach to this process via gdb/lldb to view the base address now :)
return 0;
}
Hope it helps!
alt text http://www.freeimagehosting.net/uploads/b350914deb.png
i want to retrieve the list of user and local service and network service
WMI has a Win32_UserAccount class, but enumerating it looks like it produces the same list as NetEnumUsers, which only produces (more or less) "Normal" accounts, not the built in security principals like "Local Service" and "Network Service".
You can retrieve everything with NetLocalGroupEnum and NetLocalGroupGetMembers, but you'd have to do it from something that lets you work with the Win32 API directly, not (at least AFAIK) via WMI. In case that's still useful, here's a bit of sample code that lists groups and members:
#define UNICODE
#include <windows.h>
#include <lmaccess.h>
#include <lmapibuf.h>
#include <iostream>
int main() {
LOCALGROUP_INFO_0 *l_info;
DWORD read;
DWORD total;
NetLocalGroupEnum(NULL,
0,
(unsigned char **)&l_info,
MAX_PREFERRED_LENGTH,
&read,
&total,
NULL);
std::wcout << L"Local Groups\n";
for (int i=0; i<read; i++) {
std::wcout << l_info[i].lgrpi0_name << std::endl;
LOCALGROUP_MEMBERS_INFO_1 *members;
DWORD entries, total_entries;
NetLocalGroupGetMembers(NULL,
l_info[i].lgrpi0_name,
1,
reinterpret_cast<BYTE **>(&members),
MAX_PREFERRED_LENGTH,
&entries,
&total_entries,
NULL);
for (int mem_num = 0; mem_num<entries; mem_num++)
std::wcout << L"\t" << members[mem_num].lgrmi1_name << L"\n";
NetApiBufferFree(members);
}
NetApiBufferFree(l_info);
GROUP_INFO_0 *g_info;
NetGroupEnum(NULL,
0,
(unsigned char **)&g_info,
MAX_PREFERRED_LENGTH,
&read,
&total,
NULL);
std::wcout << L"\nGlobal Groups\n";
for (i=0; i<read; i++)
std::wcout << g_info[i].grpi0_name << std::endl;
NetApiBufferFree(g_info);
return 0;
}
You can do this via WSH. Here is an example in JavaScript: http://www.winscripter.com/WSH/ADSI/56.aspx
and a sample in C#: http://www.geekzone.co.nz/chakkaradeep/3938
I found several answers on BING by searching win32 list user accounts
And finally a sample from Microsoft: http://gallery.technet.microsoft.com/ScriptCenter/en-us/827623f5-eb55-4035-8f57-25c4afb444cd
I have one application which reads user default locale in Windows Vista and above. When i tried calling the API for getting User default Locale API is crashing. Below is the code, It will be helpfull if any points the reason
#include <iostream>
#include <WinNls.h>
#include <Windows.h>
int main()
{
LPWSTR lpLocaleName=NULL;
cout << "Calling GetUserDefaultLocaleName";
int ret = GetUserDefaultLocaleName(lpLocaleName, LOCALE_NAME_MAX_LENGTH);
cout << lpLocaleName<<endl;
}
You need to have lpLocaleName initialized to a buffer prior to calling the API. As a general consensus, if an API has a LPWSTR data type parameter, call malloc or new on it first, to the desired length, in this case, LOCALE_NAME_MAX_LENGTH. Setting it to NULL and passing it to the API function is a guaranteed way to crash!
Hope this helps,
Best regards,
Tom.
In addition to the previous answers, you should also be aware that you can't print a wide string with cout; instead, you should use wcout.
So:
#include <iostream>
#include <WinNls.h>
#include <Windows.h>
#define ARRSIZE(arr) (sizeof(arr)/sizeof(*(arr)))
using namespace std;
int main()
{
WCHAR_T localeName[LOCALE_NAME_MAX_LENGTH]={0};
cout<<"Calling GetUserDefaultLocaleName";
int ret = GetUserDefaultLocaleName(localeName,ARRSIZE(localeName));
if(ret==0)
cout<<"Cannot retrieve the default locale name."<<endl;
else
wcout<<localeName<<endl;
return 0;
}
I believe you need to initialise lpLocaleName to an empty string of 256 chars (for example) then pass the length (256) where you have LOCALE_NAME_MAX_LENGTH