Usage of InternetGetConnectedStateEx - c++

I'm trying to use InternetGetConnectedStateEx but I'm not able to retrieve lpszConnectionName. If I initialise it as 0 I don't get any value, but if I initialised with _T("hol"); I get an access violation
DWORD dwFlags;
LPTSTR lpszConnectionName = _T("hol");
DWORD dwNameLen = 3;
if (InternetGetConnectedStateEx(&dwFlags, lpszConnectionName, dwNameLen, NULL))
{
printf("Connected to internet");
}
else {
printf("not connected");
}
Thanks!

The documentation says (emphasis mine):
lpszConnectionName [out]
Pointer to a string value that receives the connection name.
That is an output parameter, that will be filled with the connection name if there is one active. Specifying the contents of this parameter yourself is a mistake, having it point to a string literal doubly so (since modifying it will trigger undefined behavior).
The appropriate way to invoke the function would be something like:
DWORD dwFlags;
TCHAR lpszConnectionName[512];
if (InternetGetConnectedStateEx(&dwFlags, lpszConnectionName,
_countof(lpszConnectionName), NULL)) {
// ...
} else {
// ...
}

Related

sending a struct with MapViewOfFile and reading an unknown value

I am basically trying to cast or copy my struct to my other process section view but I keep getting an error
C2760: syntax error: unexpected token 'identifier', expected 'declaration'
This is what I am doing:
type RPM(UINT_PTR ReadAddress)
{
if (hDriver == INVALID_HANDLE_VALUE) {
return {};
}
DWORD64 Bytes;
KM_READ_REQUEST ReadRequest{};
type response{};
ReadRequest.ProcessId = PID;
ReadRequest.Address = ReadAddress;
ReadRequest.Size = sizeof(type);
ReadRequest.Output = &response;
The problem is here:
auto pBuf = (ReadRequest)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 4096);
if (!pBuf)
{
printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
system("pause");
}
printf("MapViewOfFile(write) created ! \n");
I am having another problem trying to read an unknown value from my kernel driver. It basically reads memory and then changes that value to another thing based on what I am reading from if its int, float, etc..
PKM_READ_REQUEST ReadInput = (PKM_READ_REQUEST)SharedSection; // cast readRequest to our struct which is in SharedSection.
void* ReadOutput = ReadInput->Output;
Status = ReadKernelMemory(Process, ReadInput->Address, ReadOutput, ReadInput->Size);
I am trying to copy it to my shared section so I can read it from user mode, but idk how to cast it or what the value would be.
memcpy(SharedSection, &ReadOutput, sizeof(ReadOutput));
This is how I want to try to read it, but cast it as the same way because I don't want to read it as void, I want to read it as the value that was given from my kernel mode.
auto pBuf = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 4096);
if (!pBuf)
{
printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
system("pause");
}
printf("MapViewOfFile(write) created ! \n");
BTW, I am using the un-documented function mmcopyvirtualmemory in my kernel driver.
1.
auto pBuf = (ReadRequest)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 4096);
The ReadRequest is not a type but an object, If you want to write the file map address as the struct KM_READ_REQUEST, you should convert the return pointer to the type of PKM_READ_REQUEST, and also take the control of the size of file map:
auto pBuf = (PKM_READ_REQUEST)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, sizeof(KM_READ_REQUEST));
So that you can set the PID,Address,Size and Output for it.
2.
memcpy(SharedSection, &ReadOutput, sizeof(ReadOutput));
ReadOutput is already the address of output value, So you don't
need the operation &.
Sizeof(a pointer) is always equal to 4(in 32-bit) and 8(in
64-bit);
You'd better use a new variable to store copied values, Instead of overwriting previous data。
So
type new_var;
memcpy(&new_var, ReadOutput, sizeof(KM_READ_REQUEST));
EDIT: Answer your comments,
You can set a single Event to communicate between driver and UM.
App:
hDevice = CreateFile(Device);
hEvent = CreateEvent(...);
DeviceIoControl(hDevice, IOCTL_SET_EVENT, &hEvent,...);
WaitForSingleObject(hEvent, INFINITE);
Driver:
case IOCTL_SET_EVENT:
{
HANDLE hUserEvent = *(HANDLE *)pIrp->AssociatedIrp.SystemBuffer;
status = ObReferenceObjectByHandle(hUserEvent, EVENT_MODIFY_STATE,*ExEventObjectType, KernelMode, (PVOID*)&pDevExt->pEvent, NULL);
ObDereferenceObject(pDevExt->pEvent);
break;
}
Then set event:
KeSetEvent(pdx->pEvent,...);

What is the preferred way to get a device path for CreateFile() in a UWP C++ App?

I am converting a project to a UWP App, and thus have been following guidelines outlined in the MSDN post here. The existing project heavily relies on CreateFile() to communicate with connected devices.
There are many posts in SO that show us how to get a CreateFile()-accepted device path using SetupAPI's SetupDiGetDeviceInterfaceDetail() Is there an alternative way to do this using the PnP Configuration Manager API? Or an alternative, user-mode way at all?
I had some hope when I saw this example in Windows Driver Samples github, but quickly became dismayed when I saw that the function they used in the sample is ironically not intended for developer use, as noted in this MSDN page.
function GetDevicePath in general correct and can be used as is. about difference between CM_*(..) and CM_*_Ex(.., HMACHINE hMachine) - the CM_*(..) simply call CM_*_Ex(.., NULL) - so for local computer versions with and without _Ex suffix the same.
about concrete GetDevicePath code - call CM_Get_Device_Interface_List_Size and than CM_Get_Device_Interface_List only once not 100% correct - because between this two calls new device with this interface can be arrived to system and buffer size returned by CM_Get_Device_Interface_List_Size can be already not enough for CM_Get_Device_Interface_List. of course possibility of this very low, and you can ignore this. but i prefer make code maximum theoretical correct and call this in loop, until we not receive error other than CR_BUFFER_SMALL. also need understand that CM_Get_Device_Interface_List return multiple, NULL-terminated Unicode strings - so we need iterate here. in [example] always used only first returned symbolic link name of an interface instance. but it can be more than 1 or at all - 0 (empty). so better name function - GetDevicePaths - note s at the end. i be use code like this:
ULONG GetDevicePaths(LPGUID InterfaceClassGuid, PWSTR* pbuf)
{
CONFIGRET err;
ULONG len = 1024;//first try with some reasonable buffer size, without call *_List_SizeW
for(PWSTR buf;;)
{
if (!(buf = (PWSTR)LocalAlloc(0, len * sizeof(WCHAR))))
{
return ERROR_NO_SYSTEM_RESOURCES;
}
switch (err = CM_Get_Device_Interface_ListW(InterfaceClassGuid, 0, buf, len, CM_GET_DEVICE_INTERFACE_LIST_PRESENT))
{
case CR_BUFFER_SMALL:
err = CM_Get_Device_Interface_List_SizeW(&len, InterfaceClassGuid, 0, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
default:
LocalFree(buf);
if (err)
{
return CM_MapCrToWin32Err(err, ERROR_UNIDENTIFIED_ERROR);
}
continue;
case CR_SUCCESS:
*pbuf = buf;
return NOERROR;
}
}
}
and usage example:
void example()
{
PWSTR buf, sz;
if (NOERROR == GetDevicePaths((GUID*)&GUID_DEVINTERFACE_VOLUME, &buf))
{
sz = buf;
while (*sz)
{
DbgPrint("%S\n", sz);
HANDLE hFile = CreateFile(sz, FILE_GENERIC_READ, FILE_SHARE_VALID_FLAGS, 0, OPEN_EXISTING, 0, 0);
if (hFile != INVALID_HANDLE_VALUE)
{
// do something
CloseHandle(hFile);
}
sz += 1 + wcslen(sz);
}
LocalFree(buf);
}
}
so we must not simply use in returned DevicePathS (sz) only first string, but iterate it
while (*sz)
{
// use sz
sz += 1 + wcslen(sz);
}
I got a valid Device Path to a USB Hub Device, and used it successfully to get various device descriptors by sending some IOCTLs, by using the function I posted in my own answer to another question
I'm reporting the same function below:
This function returns a list of NULL-terminated Device Paths (that's what we get from CM_Get_Device_Interface_List())
You need to pass it the DEVINST, and the wanted interface GUID.
Since both the DEVINST and interface GUID are specified, it is highly likely that CM_Get_Device_Interface_List() will return a single Device Path for that interface, but technically you should be prepared to get more than one result.
It is responsibility of the caller to delete[] the returned list if the function returns successfully (return code 0)
int GetDevInstInterfaces(DEVINST dev, LPGUID interfaceGUID, wchar_t**outIfaces, ULONG* outIfacesLen)
{
CONFIGRET cres;
if (!outIfaces)
return -1;
if (!outIfacesLen)
return -2;
// Get System Device ID
WCHAR sysDeviceID[256];
cres = CM_Get_Device_ID(dev, sysDeviceID, sizeof(sysDeviceID) / sizeof(sysDeviceID[0]), 0);
if (cres != CR_SUCCESS)
return -11;
// Get list size
ULONG ifaceListSize = 0;
cres = CM_Get_Device_Interface_List_Size(&ifaceListSize, interfaceGUID, sysDeviceID, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cres != CR_SUCCESS)
return -12;
// Allocate memory for the list
wchar_t* ifaceList = new wchar_t[ifaceListSize];
// Populate the list
cres = CM_Get_Device_Interface_List(interfaceGUID, sysDeviceID, ifaceList, ifaceListSize, CM_GET_DEVICE_INTERFACE_LIST_PRESENT);
if (cres != CR_SUCCESS) {
delete[] ifaceList;
return -13;
}
// Return list
*outIfaces = ifaceList;
*outIfacesLen = ifaceListSize;
return 0;
}
Please note that, as RbMm already said in his answer, you may get a CR_BUFFER_SMALL error from the last CM_Get_Device_Interface_List() call, since the device list may have been changed in the time between the CM_Get_Device_Interface_List_Size() and CM_Get_Device_Interface_List() calls.

How to pass function pointer as lpParameter to CreateThread?

I have the following function which will be called by CreateThread:
DWORD WINAPI start_thread(LPVOID handleFunction)
{
int prio = 4;
// call handleFunction()
handleFunction(prio);
return TRUE;
}
And I create the thread here:
DECL_PREFIX tid_t so_fork(so_handler *handleFunction, unsigned priority) {
DWORD dw;
hThr[currentThread] = CreateThread(
NULL, // default security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE)start_thread, // thread function name
(LPVOID)&handleFunction, // argument to thread function
0, // use default creation flags
&dw); // returns the thread identifier
return 0;
}
I get the following error when I am builind it:
Error C2064 term does not evaluate to a function taking 1 arguments libscheduler
expression preceding parentheses of apparent call must have (pointer-to-) function type libscheduler
What am I doing it wrong?
Passing &handleFunction to CreateThread() is wrong, because you are passing the local address of the handleFunction variable itself, not the address of the so_handler that it is pointing at.
Since handleFunction is already a pointer, try something more like this instead:
DWORD WINAPI start_thread(LPVOID handleFunction)
{
int prio = 4;
// call handleFunction()
so_handler *handler = (so_handler *) handleFunction;
handler(prio); // or maybe (*handler)(prio), depending on how so_handler is actually defined...
return TRUE;
}
DECL_PREFIX tid_t so_fork(so_handler *handleFunction, unsigned priority) {
DWORD dw;
hThr[currentThread] = CreateThread(
NULL, // default security attributes
0, // use default stack size
&start_thread, // thread function name
handleFunction, // argument to thread function
0, // use default creation flags
&dw); // returns the thread identifier
return 0;
}

CreateFileMapping returns ERROR_INVALID_HANDLE

I am trying to use CreateFileMapping for the first time and it is giving me this error when I use GetLastError():
ERROR_INVALID_HANDLE: The handle is invalid.
Here is my code:
// create the name of our file-mapping object
nTry++; // Ensures a unique string is used in case user closes and reopens
wsprintfA(szName, FS6IPC_MSGNAME1 ":%X:%X", GetCurrentProcessId(), nTry);
// stuff the name into a global atom
m_atom = GlobalAddAtomA(szName);
if (m_atom == 0)
{ *pdwResult = ERR_ATOM;
return FALSE;
}
// create the file-mapping object
m_hMap = CreateFileMappingA(
(HANDLE)0xFFFFFFFF, // use system paging file
NULL, // security
PAGE_READWRITE, // protection
0, MAX_SIZE+256, // size
szName); //
EDIT:
The first issue was resolved, but now my program crashes somewhere else.
#define FS6IPC_MESSAGE_SUCCESS 1
#define FS6IPC_MESSAGE_FAILURE 0
// IPC message types
#define FS6IPC_READSTATEDATA_ID 1
#define FS6IPC_WRITESTATEDATA_ID 2
// read request structure
typedef struct tagFS6IPC_READSTATEDATA_HDR
{
DWORD dwId; // FS6IPC_READSTATEDATA_ID
DWORD dwOffset; // state table offset
DWORD nBytes; // number of bytes of state data to read
void* pDest; // destination buffer for data (client use only)
} FS6IPC_READSTATEDATA_HDR;
// write request structure
typedef struct tagFS6IPC_WRITESTATEDATA_HDR
{
DWORD dwId; // FS6IPC_WRITESTATEDATA_ID
DWORD dwOffset; // state table offset
DWORD nBytes; // number of bytes of state data to write
} FS6IPC_WRITESTATEDATA_HDR;
while (*pdw)
{ switch (*pdw)
{ case FS6IPC_READSTATEDATA_ID:
pHdrR = (FS6IPC_READSTATEDATA_HDR *) pdw;
m_pNext += sizeof(FS6IPC_READSTATEDATA_HDR);
if (pHdrR->pDest && pHdrR->nBytes)
CopyMemory(pHdrR->pDest, m_pNext, pHdrR->nBytes);
m_pNext += pHdrR->nBytes; // Debugger says the issue is here
break;
case FS6IPC_WRITESTATEDATA_ID:
// This is a write, so there's no returned data to store
pHdrW = (FS6IPC_WRITESTATEDATA_HDR *) pdw;
m_pNext += sizeof(FS6IPC_WRITESTATEDATA_HDR) + pHdrW->nBytes;
break;
default:
// Error! So terminate the scan
*pdw = 0;
break;
}
pdw = (DWORD *) m_pNext;
}
I'm guessing you're running on a 64-bit system, on which HANDLEs are 64 bits. The OS is quite right—the handle value 0x00000000FFFFFFFF is an invalid handle value for your process.
What exactly are you trying to do? If you want to create a file mapping backed by an actual file, pass in the handle for that file. If you want to a create a file mapping backed by the paging file instead, pass in INVALID_HANDLE_VALUE. INVALID_HANDLE_VALUE happens to be (HANDLE)-1, which is 0xFFFFFFFF on 32-bit systems but 0xFFFFFFFFFFFFFFFF on 64-bit systems, but that doesn't really matter since you should just use the symbolic value INVALID_HANDLE_VALUE in any case.
If your application is crashing when you pass in INVALID_HANDLE_VALUE, it's not because the call to CreateFileMapping is failing, it's for some other reason, and you should debug that.

I want to copy the data in (wchar_t *)buffer but i am unable to do so bcz there are other incompatible types,typecasting but not getting the result?

I want to print buffer data at one instance avoiding all other wprintf instances but unable to convert data in compatible type with buffer.
Have a look at code:
Kindly tell me how to get through it:
DWORD PrintEvent(EVT_HANDLE hEvent)
{
DWORD status = ERROR_SUCCESS;
PEVT_VARIANT pRenderedValues = NULL;
WCHAR wsGuid[50];
LPWSTR pwsSid = NULL;
//
// Beginning of functional Logic
//
for (;;)
{
if (!EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount))
{
if (ERROR_INSUFFICIENT_BUFFER == (status = GetLastError()))
{
dwBufferSize = dwBufferUsed;
dwBytesToWrite = dwBufferSize;
pRenderedValues = (PEVT_VARIANT)malloc(dwBufferSize);
if (pRenderedValues)
{
EvtRender(hContext, hEvent, EvtRenderEventValues, dwBufferSize, pRenderedValues, &dwBufferUsed, &dwPropertyCount);
}
else
{
printf("malloc failed\n");
status = ERROR_OUTOFMEMORY;
break;
}
}
}
Buffer = (wchar_t*) malloc (1*wcslen(pRenderedValues[EvtSystemProviderName].StringVal));
//
// Print the values from the System section of the element.
wcscpy(Buffer,pRenderedValues[EvtSystemProviderName].StringVal);
int i = wcslen(Buffer);
if (NULL != pRenderedValues[EvtSystemProviderGuid].GuidVal)
{
StringFromGUID2(*(pRenderedValues[EvtSystemProviderGuid].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wcscpy(Buffer+i,(wchar_t*)pRenderedValues[EvtSystemProviderGuid].GuidVal);
wprintf(L"Provider Guid: %s\n", wsGuid);
}
//Getting "??????" on screen after inclusion of guidval tell me the correct way to copy it??
wprintf(L"Buffer = %ls",Buffer);
//Also tell the way to copy unsigned values into buffer
wprintf(L"EventID: %lu\n", EventID);
wprintf(L"Version: %u\n", pRenderedValues[EvtSystemVersion].ByteVal);
wprintf(L"Level: %u\n", pRenderedValues[EvtSystemLevel].ByteVal);
wprintf(L"EventRecordID: %I64u\n", pRenderedValues[EvtSystemEventRecordId].UInt64Val);
if (EvtVarTypeNull != pRenderedValues[EvtSystemActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation ActivityID: %s\n", wsGuid);
}
if (EvtVarTypeNull != pRenderedValues[EvtSystemRelatedActivityID].Type)
{
StringFromGUID2(*(pRenderedValues[EvtSystemRelatedActivityID].GuidVal), wsGuid, sizeof(wsGuid)/sizeof(WCHAR));
wprintf(L"Correlation RelatedActivityID: %s\n", wsGuid);
}
wprintf(L"Execution ProcessID: %lu\n", pRenderedValues[EvtSystemProcessID].UInt32Val);
wprintf(L"Execution ThreadID: %lu\n", pRenderedValues[EvtSystemThreadID].UInt32Val);
wprintf(L"Channel: %s\n",pRenderedValues[EvtSystemChannel].StringVal);
wprintf(L"Computer: %s\n", pRenderedValues[EvtSystemComputer].StringVal);
//
// Final Break Point
//
break;
}
}
The first error is when starting to write to the buffer:
Buffer = (wchar_t*) malloc (1*wcslen(pRenderedValues[EvtSystemProviderName].StringVal));
wcscpy(Buffer,pRenderedValues[EvtSystemProviderName].StringVal);
StringVal points to a wide character string with a trailing null byte, so you should
Buffer = malloc (sizeof(wchar_t)*(wcslen(pRenderedValues[EvtSystemProviderName].StringVal)+1));
or even better
Buffer = wcsdup(pRenderedValues[EvtSystemProviderName].StringVal);
Second error is when appending the GUID.
You are not allocating enough memory, you are just appending to the already full Buffer. And you are appending the raw GUID, not the GUID string. You should replace
int i = wcslen(Buffer);
wcscpy(Buffer+i,(wchar_t*)pRenderedValues[EvtSystemProviderGuid].GuidVal);
with something like
// Attention: memory leak if realloc returns NULL! So better use a second variable for the return code and check that before assigning to Buffer.
Buffer = realloc(Buffer, wcslen(Buffer) + wcslen(wsGuid) + 1);
wcscat(Buffer,wsGuid);
Also:
Besides, you should do better error checking for EvtRender. And you should check dwPropertyCount before accessing pRenderedValues[i].
BTW, wprintf(L"Buffer = %s",Buffer); (with %s instead of %ls) is sufficient with wprintf.
And to your last question: if you want to append unsigned values to a buffer you can use wsprintf to write to a string. If you can do it C++-only then you should consider using std::wstring. This is much easier for you with regard to allocating the buffers the right size.