|
Thank you for your response.
OK, so if the system calls back into my application at the appropriate time, why must the system load the DLL containing the filter function into each process that is hooked?
IOW, if the hook function is run inside the installing application, why must the hook function DLL be injected into every targeted application?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Sorry I don't know the answer to that one. There is an implication that injecting the hook into another process can be done of the call-back function is in a dll. If that is the case then the dll must be associated withe the address space of that process. I must admit it is a long time since I used this feature so my recollection of it is not 100%.
|
|
|
|
|
OK Thank you for your contributions thus far.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
You need an instance handle to load the DLL ... guess what happens to the instance handle when the application terminates
In vino veritas
|
|
|
|
|
Yes, thank you. I progressed to the point where I'm creating the hook and processing it successfully.
But now the problem is that when the hook installer application terminates, it crashes all of the hooked applications *even though* I call UnhookWindowsHookEx() to remove the hook before terminating.
Would you have any hints what I can do about that?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
The unhook is usually just done in WM_DESTROY of the main application.
From memory it must be before you post WM_QUIT which will kill the instance handle.
In vino veritas
|
|
|
|
|
Do you mean that the system waits until the window receives the WM_DESTROY message before it actually unhooks the hook?
Or do you mean that I must call UnhookWindowsHookEx BEFORE the WM_QUIT message is posted?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Unhook it before you post the WM_QUIT message
In vino veritas
|
|
|
|
|
How is the way to open a HDD drive with _open function in such a way to read even the boot section of this drive ? Here is the code:
int hd_h = _open(device, O_BINARY | O_RDWR | O_EXCL);
device is provided with
"\\\\?\\E:"
This is the code from ntfs library GitHub - vitalif/ntfs-3g: Fork of git://ntfs-3g.git.sourceforge.net/gitroot/ntfs-3g/ntfs-3g with FIEMAP support patch[^]
Why I am asking that ? Even if _open return 3, further more, the reading of boot section has failed.
Function
ntfs_boot_sector_is_ntfs say that my boot device is not NTFS:
if (! ntfs_boot_sector_is_ntfs(bs))
{
errno = EINVAL;
goto error_exit;
}
BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR* b)
{
u32 i;
BOOL ret = FALSE;
ntfs_log_debug("Beginning bootsector check.\n");
ntfs_log_debug("Checking OEMid, NTFS signature.\n");
if (b->oem_id != const_cpu_to_le64(0x202020205346544eULL))
{
ntfs_log_error("NTFS signature is missing.\n");
goto not_ntfs;
}
....
Of course, this debugging session ran as admin mode.
|
|
|
|
|
I not sure that you can access the boot sector using a drive letter. I think you need to address it as something like Device\Partition0. Google can probably find the correct syntax.
|
|
|
|
|
Good point, I have tried in this way:
"\\\\.\\PHYSICALDRIVE2" ... but with exactly the same result ... strange ...
|
|
|
|
|
I think there is a page somewhere on MSDN that explains how to access low level disks.
|
|
|
|
|
I haven't gotten around to check this out myself yet, but I am studying the "Windows Internals" book by Mark Russinovich (the guy creating the Sysinternals suite). There I found that the object name \Device\HarddiskX\DRX (with 'X' being replaced by a digit from 0 upwards; you can find it using the Sysinternals WinObj utility).
It is not clear to me when to use this name and when to use the \Global??\PhysicalDriveX name. Russinovich writes that "The Windows application layer converts the name to \Global??\PhysicalDriveX berofe handling the name to the Windwows object manager" - it seems like that PhysicalDriveX format is some old legacy format. It is far from clear to me!
So you may try a Global??\ prefix, or you might try \Device\HarddiskX\DRX (appearently with X replaced by 2 in your case). When you find out what works, tell it, and I will use it when I get that far myself!
|
|
|
|
|
|
As that document say, I have tried "\\\\.\\PhysicalDrive2 ", with exactly the same result.
|
|
|
|
|
Are you sure that is a valid disk name? If you enter the command Get-PhysicalDisk in a PowerShell window, you will get a list of the known physical disks on your system. See Get-PhysicalDisk[^].
[edit]
Here is a better command:
Get-WmiObject Win32_DiskDrive
[/edit]
|
|
|
|
|
I just tried the following code and it returns a valid handle. Note that this must run with administrator privileges:
HANDLE hFile = CreateFileW(L"\\\\.\\PhysicalDrive0",
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
cout << "Handle: " << hex << hFile << endl;
CloseHandle(hFile);
|
|
|
|
|
Yes, the name of the drive is correct, that is for sure. And I have tried:
HANDLE hFile = CreateFileW(L"\\\\.\\PhysicalDrive2",
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
TRACE("Handle: %X %p", hFile, hFile);
CloseHandle(hFile);
and the result was: Handle: 434 00000434 . So this prove that I have read it successfully ?
|
|
|
|
|
I was not pointing out the name to be used -- I was pointing out the access that must be used. Since your disk name is correct (assuming that drive 2 exists ), the access mode seems like a good subject for investigation. A quick google indicates this is OS-dependent when using the open function.
Be wary of strong drink. It can make you shoot at tax collectors - and miss.
Lazarus Long, "Time Enough For Love" by Robert A. Heinlein
|
|
|
|
|
There is this structure:
typedef struct _D3DLOCKED_RECT
{
INT Pitch;
void* pBits;
} D3DLOCKED_RECT;
How do I interpret pBits here?
|
|
|
|
|
fearless_ wrote: How do I interpret pBits Any way you like. What does it point to?
|
|
|
|
|
it`s a pointer back to a texture (surface) data.
(I found people do this:
DWORD* pBits=(DWORD*)lockedrect.pBits; )
I don`t understand how void works though Richard. isn`t a variable a sequence of bytes? long is 8 bytes so the data is split at an 8 size step? which doesn`t make sense since a pixel is made of 3 maybe 4 bytes.
modified 11-Apr-20 5:01am.
|
|
|
|
|
fearless_ wrote: I don`t understand how void works It's just a way of allowing the compiler to generate the correct code for a pointer, without needing to know what it actually points to. It is often used when the ultimate data may be more than one type. In order to access the actual content you need to use a cast, like you have shown above.
As to the structure of the real data, you will need to look at the documentation.
|
|
|
|
|
Your struct contains one int and one pointer. If the second member said int* rather than void*, it would be exactly the same at run time - but at compile time, you would be warned if you tried to set .pBits to point to anything but an int. A void* can be set to point to anything.
Remember that in C, a pointer is nothing but a runtime address - no type info, no size info. An array name is a pointer to the start of a memory area; the index is an offset from this start address (the index value must be multiplied with the element size to get the offset in bytes). Runtime info knows only of the start address, and nothing of index limits and element type. In memory, a 1-element DWORD array is identical to a single DWORD variable. It looks like an array because you write code to address memory locations with some offset.
If you ask the compiler to address something pointed to by .pBits, the compiler doesn't know what to find there. Do you want to fetch a single byte from memory? Or a DWORD? Maybe .pBits really is a pointer to a struct, and you want to address a struct member at a given offset (i.e. member name). You have to tell the compiler how to interpret the pointer. This is because you haven't declared it as e.g. a DWORD* but as a void*.
In your example, the programmer tells the compiler: "Treat .pBits as a DWORD*, a pointer to a double word!" Here, the pointer itself is copied to another pointer, which can be used to access the DWORD pointed to - that is just as a convenient shorthand notation. Whether following code uses the typed DWORD* 'pbits' or '(DWORD*)lockedrect.pBits' makes no difference (at least not until you want to change one of the two pointers without changing the other one).
I can't tell why the void* was cast to a DWORD*. My guess, from the name D3DLOCKED_RECT, is that .pBits points to a 3D coordinate, like a 3 element array (or maybe even an array of 3D points). The code you quote wants to manipulate the 3 values as a single unit (e.g for more efficient moving/copying). Why is a void* used, instead of a typed pointer? Probably because the struct can be used with different resolutions (maybe that is what is indicated by the .pitch member?): In some applications, the coordinates are represented by three 16 bit values, in other applications by three 32 bit values. In low-resolution applications, it could even be three 8-bit values. You cast it to whatever coordinate size you use.
The quoted code makes it look as if the coordinates could be three 64 bit values. I very much doubt that any graphical system would use 64 bit coordinates (unless you make 3D model of the known universe...). So probably the use of DWORD is just for efficiency, doing moving/copying of as few operations as possible. That you could probably find out reading the rest of the code where you found this line.
|
|
|
|
|
is nothing but a runtime address - no type info, no size info.
is this a figure of speech or a fact?
|
|
|
|