clGetProfilingEventInfo: How to get multiple profiling info? - profiling

I would like to get profiling info. My commandqueue is already enabled for profiling.
This is my code:
status = clEnqueueNDRangeKernel(
commandQueue,
kernl,
2,
NULL,
globalThreads,
localThreads,
0,
NULL,
&ndrEvt);
CHECK_OPENCL_ERROR(status, "clEnqueueNDRangeKernel failed.");
//Won't proceed ahead if all work-items have not finished processing; Synchronization point
status = clFinish(commandQueue);
CHECK_OPENCL_ERROR(status, "clFlush failed.");
//fetch performance data
clGetEventProfilingInfo(ndrEvt, CL_PROFILING_COMMAND_QUEUED, sizeof(cl_ulong), &time_start2, NULL);
//clRetainEvent(ndrEvt);
clGetEventProfilingInfo(ndrEvt, CL_PROFILING_COMMAND_SUBMIT, sizeof(cl_ulong), &time_end2, NULL);
single_exec_time2 = time_end2 - time_start2;
clGetEventProfilingInfo(ndrEvt, CL_PROFILING_COMMAND_END, sizeof(cl_ulong), &time_end, NULL);
single_exec_time = time_end - time_start2;
Signle_exec_time_2 shows me a correct result, but single_exec_time = 0.
I think the problem lies in event handling, the reference count of ndrEvt goes to zero.
I've tried to introduce clRetainEvent(ndrEvt) (you can see it as comment) and it "worked", so at this point I'm wondering if introducing clRetainEvent() would give me the right result?

Related

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.

Directory relative ZwCreateFile

I have to implement cross view file integrity checker for my University project. For that how do I list the files of a Directory in Kernel Mode??
Your starting point would be ZwCreateFile - which has options such as "FILE_LIST_DIRECTORY".
You will then use ZwQueryDirectoryFile to get the information about the file(s) within that directory.
Make SURE that you are not forgetting to ZwClose after you open something - it's not so critical in a user-mode application that closes again after it's been used. But the kernel doesn't know when a driver stops using a file (or, for that matter, if some other driver has been given that filehandle, and will be using it at some point), so even if your driver is unloaded, files that it opened will remain open until the system restarts - I quite like to "not restart" my systems, and with a good set of drivers, running a machine for more than a year should be possible. If your driver so much as leaks one handle a day, that's 365 handles leaked.
So, the code would look something like this:
HANDLE h;
NTSTATUS status;
OBJECT_ATTRIBUTES oa = { sizeof(OBJECT_ATTRIBUTES), NULL, L"mydir",
OPEN_CASE_INSENSITIVE, NULL, NULL };
IO_STATUS_BLOCK iosb = {};
status = ZwCreateFile(&h, FILE_LIST_DIRECTORY, &oa, &iosb, NULL,
FILE_ATTRIBUTE_NORMAL, FILE_OPEN, FILE_DIRECTORY_FILE,
NULL, 0);
if (status != STATUS_SUCCESS)
{
... do something...
return errorcode;
}
else
{
FILE_DIRECTORY_INFORMATION info;
for(;;)
{
status = ZwQueryDirectoryFile(h, NULL, NULL, &iosb, &info, sizeof(info),
FileDirectoryInformation, TRUE, L"*.*",
FALSE);
if (status != STATUS_SUCCESS)
{
... check error code and perhaps print if unexpected error ...
break;
}
... do soemthing with `info` ...
}
}
ZwClose(h);
This is just a "rough sketch". I don't have a setup to compile this right now, and I may have missed something important. But it should give you some idea. There are LOTS of optional parameters and optional choices here, and some I've "guessed" what you'd want, but I think I've made reasonable choices. There may be details missing that make this not work, but as a rough starting point, it should give you an idea at least.

How do I get the version of a driver on Windows from C++

I'm looking for a programmatic way to get the version number of a driver. I want the same number that device manager shows in the driver properties for a device.
Background: I have an application that talks to some custom hardware. The device driver for the custom hardware has known bugs before a certain version number. I want the application to check the driver version and warn the user if they need to update it. The application runs on Windows XP and 7 and is written in C++.
A previous hack I used was to read the .sys file directly from system32/drivers and search for "FileVersion" directly. This is bad for many reasons. In particular it seems to need admin privileges on Windows 7.
I know the class GUID and the hardware ID (ie "USB\VID_1234&PID_5678").
The application currently uses SetupDiGetClassDevs, SetupDiEnumDeviceInterfaces and then SetupDiGetDeviceInterfaceDetail to get the "DevicePath". It then calls CreateFile with that path to talk to the driver.
It looks like I need to get a SP_DRVINFO_DATA structure from somewhere. I've tried various functions from setupapi.h, such as SetupDiGetDeviceInterfaceDetail. Here's some code I've tried that fails:
int main(void)
{
HDEVINFO DeviceInfoSet = SetupDiGetClassDevs((LPGUID)&GUID_DEVINTERFACE_USBSPI, NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
SP_INTERFACE_DEVICE_DATA InterfaceDeviceData;
InterfaceDeviceData.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
// Cycle through all devices.
for (int i = 0; i < 32; i++)
{
if (!SetupDiEnumDeviceInterfaces(DeviceInfoSet, 0, (LPGUID)&GUID_DEVINTERFACE_USBSPI, i, &InterfaceDeviceData))
break;
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData;
DWORD RequiredSize;
SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &InterfaceDeviceData, NULL, 0, &RequiredSize, NULL);
DeviceInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, RequiredSize);
try
{
DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &InterfaceDeviceData, DeviceInterfaceDetailData, RequiredSize, NULL, NULL);
// Try to get the driver info. This part always fails with code
// 259 (ERROR_NO_MORE_ITEMS).
SP_DRVINFO_DATA drvInfo;
drvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
if (!SetupDiEnumDriverInfo(DeviceInfoSet, NULL, SPDIT_CLASSDRIVER, i, &drvInfo))
printf("error = %d\n", GetLastError());
printf("Driver version is %08x %08x\n", drvInfo.DriverVersion >> 32, drvInfo.DriverVersion & 0xffffffff);
}
catch(...)
{
HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
throw;
}
HeapFree(GetProcessHeap(), 0, DeviceInterfaceDetailData);
}
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return 0;
}
Edit - My updated code now looks like this:
HDEVINFO devInfoSet = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USBSPI, NULL, NULL,
DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
// Cycle through all devices.
for (int i = 0; ; i++)
{
// Get the device info for this device
SP_DEVINFO_DATA devInfo;
devInfo.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiEnumDeviceInfo(devInfoSet, i, &devInfo))
break;
// Get the first info item for this driver
SP_DRVINFO_DATA drvInfo;
drvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
if (!SetupDiEnumDriverInfo(devInfoSet, &devInfo, SPDIT_COMPATDRIVER, 0, &drvInfo))
printf("err - %d\n", GetLastError()); // Still fails with "no more items"
}
SetupDiDestroyDeviceInfoList(devInfoSet);
You're incorrectly reusing i as index in SetupDiEnumDriverInfo. That should be an inner loop for each driver info element per driver. As a result, you fail to retrieve driver info #0 for device #1.
Still, that doesn't explain why info #0 for device #0 fails. For that, you have to look at the second parameter of SetupDiEnumDriverInfo. That is a SP_DEVINFO_DATA structure for your device, but you leave it set to NULL. That gets you the list of drivers associated with the device class, not the device. I.e. that works for mice and USB sticks, which have class drivers. Your device probably has a vendor-specific driver, so you need the driver for that specific device.
As you asked a nearly identical question I post only the link to my answer here:
Why does SetupDiEnumDriverInfo give two version numbers for my driver

TCP winsock File uploading using C++ TransmitFile and overlapped I/O

I am writing an application responsible for uploading files to server, in C++ Winsock, i wrote it successfully using the multithreading technique and it works fine with no errors. But when i want to make use of Overlapped I/O techniques, i faced a problem that not all the file is received by the server.
I will post code sections that are related to sending and receiving files.
int iRecv = WSARecv(AcceptSocket, &DataBuf, 1, &RecvBytes, &Flags, &AcceptOverlapped, NULL);
int iBytesReceived = 0;
while(true)
{
printf("error =%d\r",WSAGetLastError());
// Step 7:
// Determine the status of the overlapped
// request
WSAGetOverlappedResult(AcceptSocket, &AcceptOverlapped, &BytesTransferred, FALSE, &Flags);
// Step 5:
// Wait for the overlapped I/O call to complete
Index = WSAWaitForMultipleEvents(EventTotal, EventArray, FALSE, WSA_INFINITE, FALSE);
// Index should be 0 because we
// have only one event handle in EventArray
// Step 6:
// Reset the signaled event
WSAResetEvent(EventArray[Index - WSA_WAIT_EVENT_0]);
if( iRecv>=0)
{
iBytesReceived += RecvBytes;
fwrite(DataBuf.buf,sizeof(char), RecvBytes,flUploadedFile);
}
if (lReceivedBytes>=iFilesize) break;
Flags = 0;
ZeroMemory(&AcceptOverlapped, sizeof(WSAOVERLAPPED));
AcceptOverlapped.hEvent = EventArray[Index - WSA_WAIT_EVENT_0];
DataBuf.len = DATA_BUFSIZE;//1024
DataBuf.buf = buffer;
iRecv=WSARecv(AcceptSocket, &DataBuf, 1, &RecvBytes, &Flags, &AcceptOverlapped, NULL);
}
I have to mention that server is receiving the filename and file size correctly.
Client-side
void UploadFile(....)
{
.
.
.
hFile = CreateFile(fp,GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
bTrans= TransmitFile(connectedSocket,hFile,0,0,NULL,NULL,0) ;
.
.
}
Does their exist any error in my code? Any suggestion or help? i am stuck.
In seems that the first WSARecv() returns immediate with the first portion of data (file name and size). Then the code blocks because you want to get the overlapped result before the OS signals that the result is available (by setting the event handle).
Perhaps you should use a completion routine when using overlapped I/O, this will make it more easy.

CreateFileMapping and OpenFileMapping not cooperating in different processes

I'm trying to use CreateFileMapping and OpenFileMapping to share memory between processes. This isn't working as I want it to - OpenFileMapping returns null and GetLastError is 5 - access denied. Any ideas what I am doing wrong? Name is something like MemoryTest.
Edit:
using CreateFileMapping both times I can read the data written in the other process. The reason this is a problem is that I get Error 183 - memory area already exists. However, it still returns a handle to the existing memory.
var map_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(int), name.c_str());
....
var handle = MapViewOfFile(map_handle, FILE_MAP_ALL_ACCESS , 0, 0, 0)
*handle = 10;
UnMapViewOfFile(map_handle);
getchar();
Other process:
var map_handle = OpenFileMapping(PAGE_READWRITE, false, name.c_str())
....
var handle = MapViewOfFile(map_handle, FILE_MAP_ALL_ACCESS , 0, 0, 0) //returns null
var out = *handle;
getchar();
This works for the second process though:
var map_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(int), name.c_str());
....
var handle = MapViewOfFile(map_handle, FILE_MAP_ALL_ACCESS , 0, 0, 0) //returns null
var out = *handle;
getchar();
Simple things to be aware of from the very start:
Error code 5: ERROR_ACCESS_DENIED "Access is denied."
Error code 183: ERROR_ALREADY_EXISTS "Cannot create a file when that file already exists."
ERROR_ALREADY_EXISTS is a documented behavior and is an indication of scenario that you do receive handle, but it is a handle to already existing object, not created.
The problem with not working OpenFileMapping is around its first argument: the API function expects values/flags from another enumeration, it takes FILE_MAP_* values and not PAGE_*. Incorrect argument results in failure to open you the mapping you want.
In case someone else needed, in my case the error has nothing to do with the access to the file, it's with the size provided to the CreateFileMapping, after spending hours with a similar error I'd to use a working sample posted somewhere else and line by line compare what was the difference.
If you don't know the size of the file when executing the CreateFileMapping you need to use 0, this will tell the API to use the file size of the mapped file. Most of the answers in SO around this are wrong and people is not bothering testing what is the problem about, I wasted hours reading other posts with similar suggestions.
To solve the problem the code should look like this:
var map_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, 0, name.c_str());
Hope this saves hours to other fellow developers.