I'm new to C++
I need to return the path to the file that the user has selected. For this i use winapi -> OPENFILENAME. When i try to return file path, i get only 1 character ("C" for disk C).
My code:
LPWSTR fileBuffer = new wchar_t[256];
OPENFILENAME ofn = { 0 };
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hwnd;
ofn.lpstrFile = fileBuffer;
ofn.lpstrFile[0] = '\0';
ofn.nMaxFile = 256;
ofn.lpstrFilter = NULL;
ofn.nFilterIndex = 1;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
if (GetOpenFileName(&ofn) == TRUE)
{
printf("File name: %s\n", ofn.lpstrFile);
}
i tried to increase the buffer size, return the value of ofn.lpstrFile. The first does not change anything, the second returns a int value of disk letter
You are using wchar_t (needed by OPENFILENAME) which is not the same as char (as expected with printf()) if you are using wide APIs on Windows.
Use wprintf(), or you can use %S (capital) to tell printf() to print wide characters.
I am trying to access the ListView control (located within an Dialog) in another application, and get the data from within the control. Here is the Win32 code (with appropiate comments) that I am writing :
HWND hListView32 = hRoot; //HANDLE to the ListView control within the Dialog, having class name - "SysListView32"
int cnt = (int) ::SendMessage(hListView32, LVM_GETITEMCOUNT, 0, 0L); //returns CORRECT item count of the ListView Control
int nItem=0,nRes;
for(int nItem=0;nItem<cnt;nItem++)
{
LVITEM LvItem; // ListView Item struct
char Text[255]={0};
char Temp[255]={0};
char Temp1[255]={0};
memset(&LvItem,0,sizeof(LvItem));
LvItem.mask=LVIF_TEXT;
LvItem.iSubItem=1; //Trying to get the 2nd Colomn text
LvItem.pszText=Text; //Does not returns any Text, after the below SendMessage is executed???
LvItem.cchTextMax=256;
LvItem.iItem=nItem;
nRes = (int)::SendMessage(hListView32,LVM_GETITEMTEXT, nItem, (LPARAM)&LvItem);
DWORD dd = ::GetLastError(); //returns 0
}
Though the code is executing, I am not getting any data from within the control. However, I am able to retrieve the correct Item count from within the control, but no data.
Another approach maybe would be to use an MSAA hook to get the data. But that would be a very long and cumbersome process. Running out of ideas here. Pls help.
Thanks,
There a few possibilities.
DLL Injection Using windows hooks. Pros: simple and straight forward. Cons: many processes get this dll loaded.
DLL Injection Making process to load library by opening it for debugging, allocating a chunc of virtual memory using VallocEx in the context of this process, writing it's memory with WriteProcessMemory and creating a remote thread with start address of LoadLibrary function. Pros: a single process is affected. Cons: A bit more complex than hooks solution.
Read of process memory. Same as option 2 but instead of writing this memory and executing the code remotely, send the message LVM_GETITEMTEXT to the window in question providing a valid known memory location and then read that location with ReadProcessMemory.
ListView messages that pass around buffers only work within the address space of the process that owns the ListView. You will have to use VirtualAllocEx() to allocate a memory block within that same process, then you can write to it with WriteProcessMemory() and have the ListView fill it as needed, then you can read it with ReadProcessMemory() and deallocate it with VirtualFreeEx().
Try this (error handling omitted for brevity):
HWND hListView32 = hRoot;
int cnt = (int) ::SendMessage(hListView32, LVM_GETITEMCOUNT, 0, 0);
if (cnt > 0)
{
DWORD dwProcessId;
GetWindowThreadProcessId(hListView32, &dwProcessId);
HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, dwProcessId);
LVITEM *pLvItem = (LVITEM*) VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
LPTSTR pText = (LPTSTR) VirtualAllocEx(hProcess, NULL, sizeof(TCHAR)*256, MEM_COMMIT, PAGE_READWRITE);
for(int nItem = 0; nItem < cnt; ++nItem)
{
TCHAR Text[256] = {0};
LVITEM LvItem = {0};
LvItem.mask = LVIF_TEXT;
LvItem.iSubItem = 1;
LvItem.pszText = pText;
LvItem.cchTextMax = 256;
LvItem.iItem = nItem;
WriteProcessMemory(hProcess, pLvItem, &LvItem, sizeof(LVITEM), NULL);
int nRes = (int) ::SendMessage(hListView32, LVM_GETITEMTEXT, nItem, (LPARAM)pLvItem);
if (nRes > 0)
ReadProcessMemory(hProcess, pText, &Text[0], sizeof(TCHAR)*nRes, NULL);
// use Text as needed...
}
VirtualFreeEx(hProcess, pText, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pLvItem, 0, MEM_RELEASE);
CloseHandle(hProcess);
}
I copypasted code by Remy Lebeau, but it is working very strange in my particular case. The number of elements is retreived correctly via SendMessage(listview, LVM_GETITEMCOUNT, 0, 0)
, but the cycle reads jast the same element every time! It is not the first or last element, not the selected, but seems to be random. Here is my code:
HWND win=FindWindowEx(NULL, NULL, _("TEventLogView"), NULL);
HWND listview=FindWindowEx(win, NULL, _("TListView"), NULL);
int cnt = (int) ::SendMessage(listview, LVM_GETITEMCOUNT, 0, 0);
if (cnt > 0)
{
DWORD dwProcessId;
GetWindowThreadProcessId(listview, &dwProcessId);
int n = grdEvents->GetNumberRows();
HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, dwProcessId);
LVITEM *pLvItem = (LVITEM*) VirtualAllocEx(hProcess, NULL, sizeof(LVITEM), MEM_COMMIT, PAGE_READWRITE);
LPTSTR pText = (LPTSTR) VirtualAllocEx(hProcess, NULL, sizeof(TCHAR)*255, MEM_COMMIT, PAGE_READWRITE);
for(int nItem = 0; nItem < cnt; ++nItem)
{
// need to read 1 - 3 subitems
for (int j = 1; j < 4; j++)
{
TCHAR Text[255] = {0};
LVITEM LvItem = {0};
LvItem.mask = LVIF_STATE | LVIF_TEXT;
LvItem.pszText = pText;
LvItem.cchTextMax = sizeof(TCHAR)*255;
LvItem.iItem = nItem;
LvItem.iSubItem = j;
int nRes1 = WriteProcessMemory(hProcess, pLvItem, &LvItem, sizeof(LVITEM), NULL);
int nRes2 = (int) ::SendMessage(listview, LVM_GETITEMTEXT, (WPARAM)nItem, (LPARAM)pLvItem);
if (nRes2 > 0)
{
ReadProcessMemory(hProcess, pText, &Text[0], sizeof(TCHAR)*nRes2, NULL);
// insert into wxWidgets grid
grdEvents->SetCellValue(nItem, j - 1, Text);
}
}
VirtualFreeEx(hProcess, pText, 0, MEM_RELEASE);
VirtualFreeEx(hProcess, pLvItem, 0, MEM_RELEASE);
CloseHandle(hProcess);
}
}
I am trying to identify a device using ATA_PASS_THROUGH_EX.
When I see the output buffer, it has all invalid data. Can someone help me what I am doing wrong?
#include <Windows.h>
#include <ntddscsi.h>
#include <iostream>
void main() {
WCHAR *fileName = (WCHAR * ) "\\.\PhysicalDrive0";
HANDLE handle = CreateFile(
fileName,
GENERIC_READ | GENERIC_WRITE, //IOCTL_ATA_PASS_THROUGH requires read-write
FILE_SHARE_READ,
NULL, //no security attributes
OPEN_EXISTING,
0, //flags and attributes
NULL //no template file
);
ATA_PASS_THROUGH_EX inputBuffer;
inputBuffer.Length = sizeof(ATA_PASS_THROUGH_EX);
inputBuffer.AtaFlags = ATA_FLAGS_DATA_IN;
inputBuffer.DataTransferLength = 0;
inputBuffer.DataBufferOffset = 0;
IDEREGS *ir = (IDEREGS *) inputBuffer.CurrentTaskFile;
ir->bCommandReg = 0xEC; //identify device
ir->bSectorCountReg = 1;
unsigned int inputBufferSize = sizeof(ATA_PASS_THROUGH_EX);
UINT8 outputBuffer[512];
UINT32 outputBufferSize = 512;
LPDWORD bytesReturned = 0;
DeviceIoControl( handle, IOCTL_ATA_PASS_THROUGH_DIRECT, &inputBuffer, inputBufferSize, &outputBuffer, outputBufferSize, bytesReturned, NULL);
DWORD error = GetLastError();
std::cout << outputBuffer << std::endl;
system("pause");
}
update:
When I check the error value, it is 5, which means it is an access violation. I am running in admin mode. Am I doing something wrong?
-Nick
I've done this using code that looks like this:
int foo()
{
int iRet( 0 );
// Open handle to disk.
HANDLE hDevice( ::CreateFileW( L"\\\\.\\PhysicalDrive0", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ) );
if( hDevice == INVALID_HANDLE_VALUE )
{
std::wcout << L"CreateFileW( " << sPath << L" ) failed. LastError: " << GetLastError() << std::endl;
return -1;
}
//
// Use IOCTL_ATA_PASS_THROUGH
//
std::vector< UCHAR > vBuffer( sizeof( ATA_PASS_THROUGH_EX ) + sizeof( IDENTIFY_DEVICE_DATA ), 0 );
PATA_PASS_THROUGH_EX pATARequest( reinterpret_cast< PATA_PASS_THROUGH_EX >( &vBuffer[0] ) );
pATARequest->AtaFlags = ATA_FLAGS_DATA_IN | ATA_FLAGS_DRDY_REQUIRED;
pATARequest->Length = sizeof( ATA_PASS_THROUGH_EX );
pATARequest->DataBufferOffset = sizeof( ATA_PASS_THROUGH_EX );
pATARequest->DataTransferLength = sizeof( IDENTIFY_DEVICE_DATA );
pATARequest->TimeOutValue = 2;
pATARequest->CurrentTaskFile[6] = ID_CMD;
ULONG ulBytesRead;
if( DeviceIoControl( hDevice, IOCTL_ATA_PASS_THROUGH,
&vBuffer[0], ULONG( vBuffer.size() ),
&vBuffer[0], ULONG( vBuffer.size() ),
&ulBytesRead, NULL ) == FALSE )
{
std::cout << "DeviceIoControl(IOCTL_ATA_PASS_THROUGH) failed. LastError: " << GetLastError() << std::endl;
iRet = -1;
}
else
{
// Fetch identity blob from output buffer.
PIDENTIFY_DEVICE_DATA pIdentityBlob( reinterpret_cast< PIDENTIFY_DEVICE_DATA >( &vBuffer[ sizeof( ATA_PASS_THROUGH_EX ) ] ) );
}
CloseHandle( hDevice );
return iRet;
}
Note that this must be run from an administrator account or elevated context.
I'm trying to read the .pdata section of a x64 exe.
I'm mapping the file to the memory, finding the .pdata section, and then I use it's PointerToRawData to get to the actual data of the section...
But then my "pdata" pointer points at a illegal address :(
This is what I do:
void* mappingHandle = CreateFileMapping(fileHandle,
NULL,
PAGE_READONLY,
0,
1,
NULL);
char* fileMemory = (char*)MapViewOfFile(mappingHandle, FILE_MAP_READ, 0, 0, 1);
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)fileMemory;
IMAGE_SECTION_HEADER* pdataSectionHeader = NULL;
if (dosHeader->e_magic == IMAGE_DOS_SIGNATURE) // "MZ" signature
{
IMAGE_NT_HEADERS* ntHeaders = (IMAGE_NT_HEADERS*)(fileMemory + dosHeader->e_lfanew);
if (ntHeaders->Signature == IMAGE_NT_SIGNATURE) // Supposed to be "PE"
{
unsigned int sectionCount = ntHeaders->FileHeader.NumberOfSections;
IMAGE_SECTION_HEADER* sectionHeaders = IMAGE_FIRST_SECTION(ntHeaders);
pdataSectionHeader = sectionHeaders + 3; // Going to .pdata section.
}
}
unsigned long pdataSize = pdataSectionHeader->SizeOfRawData;
char* pdata = fileMemory + pdataSectionHeader->PointerToRawData;
can anybody tell me what I doing wrong?
The problem was in the way I mapped the file to the memory.
I should have done it this way:
void* mappingHandle = CreateFileMapping(fileHandle,
NULL,
PAGE_READONLY,
0,
0, //Here: 0 instead of 1
NULL);
I'm trying to implement a renderengine using Direct3D 10 (SlimDX) and WPF.
I create my device and rendertargetview with the right MultiSample parameters ( 1,0 / 2,0 and 4,0 are working)
this.multiSamplingDescription = new SampleDescription(sampleCount, qualityLevel - 1); // 4,1
Texture2DDescription colordesc = new Texture2DDescription();
colordesc.BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource;
colordesc.Format = this.renderTargetViewFormat; // Format.B8G8R8A8_UNorm
colordesc.Width = width;
colordesc.Height = height;
colordesc.MipLevels = 1;
colordesc.SampleDescription = multiSamplingDescription;
colordesc.Usage = ResourceUsage.Default;
colordesc.OptionFlags = ResourceOptionFlags.Shared;
colordesc.CpuAccessFlags = CpuAccessFlags.None;
colordesc.ArraySize = 4;[/code]
Then I've got a problem while trying to create the shared texture for D3DImage ...
this.Direct3D9Context = new Direct3DEx();
this.presentParams = new PresentParameters();
this.presentParams.Windowed = true;
this.presentParams.SwapEffect = SwapEffect.Discard;
this.presentParams.DeviceWindowHandle = GetDesktopWindow();
this.presentParams.PresentationInterval = PresentInterval.Immediate;
this.presentParams.Multisample = MultisampleType.None;
this.presentParams.MultisampleQuality = 0;
this.Device = new DeviceEx(this.Direct3D9Context, 0, DeviceType.Hardware, IntPtr.Zero, CreateFlags.HardwareVertexProcessing | CreateFlags.Multithreaded | CreateFlags.FpuPreserve, this.presentParams);
...
this.presentParams.Multisample = sampleCount; // = 4
this.presentParams.MultisampleQuality = 0;
this.Device.Reset(this.presentParams);
...
this.SharedTexture = new Texture(this.Device, texture.Description.Width, texture.Description.Height, 1, Usage.RenderTarget, format, Pool.Default, ref Handle);
// format = Format.A8R8G8B8
// Width = 1244 , same as colordesc
// height = 699, same as colordesc
I'm missing something ?