- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I need to subclass a window in a different process. Evidently, the way to do this is to inject my DLL via a hook into the target process' address space. For this to work, my DLL needs to be able to pass a few data values (the hook and target window handles) between the source and target process' address spaces.
There is a fair amount of chat (MSDN, Richter, etc.) on how to do this in C, which apparently allows linker directives to be imbedded directly into the source code to create a named data segment for any variable, which can then be given the "/section:myseg,RWS" link attribute, so data in that segment will be identically available (shared) among all process instances of the DLL.
Can this be done in F90? I cannot find any means within DevStudio to name data segments and set their sharing attributes, and the CVF documentation doesn't address this issue. Alternatively, if anyone can provide a working example of DLL injection which solves this problem in some other way, that would be greatly appreciated.
TIA,
Paul Curtis, pcurtis@kiltel.com
There is a fair amount of chat (MSDN, Richter, etc.) on how to do this in C, which apparently allows linker directives to be imbedded directly into the source code to create a named data segment for any variable, which can then be given the "/section:myseg,RWS" link attribute, so data in that segment will be identically available (shared) among all process instances of the DLL.
Can this be done in F90? I cannot find any means within DevStudio to name data segments and set their sharing attributes, and the CVF documentation doesn't address this issue. Alternatively, if anyone can provide a working example of DLL injection which solves this problem in some other way, that would be greatly appreciated.
TIA,
Paul Curtis, pcurtis@kiltel.com
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know you can specify /section by just typing it in on the Link settings page. I don't know offhand how you would create your own section.
Steve
Steve
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I've only read about this dll injection business but I have no direct experience in doing it.
Search for /SECTION in the VC++ docs to find out how to set the attributes of a section, including 'sharing' with the target process(es).
Search for /SECTION in the VC++ docs to find out how to set the attributes of a section, including 'sharing' with the target process(es).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know about global hooking technique only in general; I've never used it myself. Perhaps the attached file could help establish a global memory segment (via MapViewOfFile). Disclaimer: I didn't use it and I forgot where I downloaded it from (probably www.fortranlib.com). On a quick glance, you should create your own DllEntryPoint:
[/pre]
INTEGER FUNCTION DllEntryPoint(hModule, fdwReason, lpvReserved)
!DEC$ATTRIBUTES STDCALL:: DllEntryPoint
USE DFWIN
IMPLICIT NONE
INTEGER:: hModule, fdwReason, lpvReserved
SELECT CASE (fdwReason)
CASE(DLL_PROCESS_ATTACH)
DllEntryPoint=1
CASE DEFAULT
DllEntryPoint=1
END SELECT
END FUNCTION DllEntryPoint[/pre]
On DLL_PROCESS_ATTACH, try to OpenShareBuffer, and if it fails CreateShareBuffer. Use cray pointers to read from *bufferAddress. Of course, bufferAddress must be global to DllEntryPoint and hook routine.
HTH
Jugoslav
[/pre]
INTEGER FUNCTION DllEntryPoint(hModule, fdwReason, lpvReserved)
!DEC$ATTRIBUTES STDCALL:: DllEntryPoint
USE DFWIN
IMPLICIT NONE
INTEGER:: hModule, fdwReason, lpvReserved
SELECT CASE (fdwReason)
CASE(DLL_PROCESS_ATTACH)
DllEntryPoint=1
CASE DEFAULT
DllEntryPoint=1
END SELECT
END FUNCTION DllEntryPoint[/pre]
On DLL_PROCESS_ATTACH, try to OpenShareBuffer, and if it fails CreateShareBuffer. Use cray pointers to read from *bufferAddress. Of course, bufferAddress must be global to DllEntryPoint and hook routine.
HTH
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for the replies. However... DLL injection is evidently too complicated and I needed a quick fix, so I dropped back & punted.
The original goal was to subclass the other (child) process, launched from my main thread, to trap SC_MINIMIZE messages and prevent its being minimized (my app gets rid of the taskbar, start button, etc.). The other process is typically Notepad, Excel or Paint.
Here is a poor-man's method of doing the same thing; it works fine, but lacks elegance:
TYPE(T_WINDOWPLACEMENT) :: wp
INTEGER :: rval
IF (IsWindow(hwnd_ChildProcess) /= 0) THEN
wp%length = SIZEOF(wp)
rval = GetWindowPlacement (hwnd_ChildProcess, wp)
IF (wp%showCmd == SW_SHOWMINIMIZED) THEN
wp%showCmd = SW_SHOWNORMAL
rval = SetWindowPlacement (hwnd_ChildProcess, wp)
CALL SetFocus (hwnd_ChildProcess)
END IF
END IF
The original goal was to subclass the other (child) process, launched from my main thread, to trap SC_MINIMIZE messages and prevent its being minimized (my app gets rid of the taskbar, start button, etc.). The other process is typically Notepad, Excel or Paint.
Here is a poor-man's method of doing the same thing; it works fine, but lacks elegance:
TYPE(T_WINDOWPLACEMENT) :: wp
INTEGER :: rval
IF (IsWindow(hwnd_ChildProcess) /= 0) THEN
wp%length = SIZEOF(wp)
rval = GetWindowPlacement (hwnd_ChildProcess, wp)
IF (wp%showCmd == SW_SHOWMINIMIZED) THEN
wp%showCmd = SW_SHOWNORMAL
rval = SetWindowPlacement (hwnd_ChildProcess, wp)
CALL SetFocus (hwnd_ChildProcess)
END IF
END IF
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now I see what you were doing. You don't need to subclass for this. If I want the character map, say, to be always available and not minimized I do:
integer id !global
...
! poll Windows for the app; if it's not running, start it, and if it is, restore it
use ... !whatever api mods required
type(T_STARTUPINFO) StartInfo
type(T_PROCESS_INFORMATION) ProcessInfo
integer r
...
If (FindWindow(NULL, "Unicode Character Map") /= 0) then
StartInfo%wShowWindow = SW_NORMAL
StartInfo%cb = len(StartInfo)
r = CreateProcess(NULL, "charmap.exe"C, 0, 0, 0, 0, CREATE_SEPARATE_WOW_VDM, NULL, StartInfo, ProcessInfo)
Sleep(500)
id = ProcessInfo%hProcess
r = CloseHandle(ProcessInfo%hThread)
Else
r = ShowWindow(FindWindow(NULL, "Unicode Character Map"), SW_RESTORE)
End If
...
!Do cleanup
integer r
use ... !whatever api mods required
If id > 0 Then
r = TerminateProcess(id, 0)
r = CloseHandle(id)
End If
The user is free to minimize or close the app and you respond by opening it up again. In the case of Excel, etc. they could loose data but the app will let them know and they'll soon get the message.
This is similar to what you've been doing. I don't consider it inelegant.
integer id !global
...
! poll Windows for the app; if it's not running, start it, and if it is, restore it
use ... !whatever api mods required
type(T_STARTUPINFO) StartInfo
type(T_PROCESS_INFORMATION) ProcessInfo
integer r
...
If (FindWindow(NULL, "Unicode Character Map") /= 0) then
StartInfo%wShowWindow = SW_NORMAL
StartInfo%cb = len(StartInfo)
r = CreateProcess(NULL, "charmap.exe"C, 0, 0, 0, 0, CREATE_SEPARATE_WOW_VDM, NULL, StartInfo, ProcessInfo)
Sleep(500)
id = ProcessInfo%hProcess
r = CloseHandle(ProcessInfo%hThread)
Else
r = ShowWindow(FindWindow(NULL, "Unicode Character Map"), SW_RESTORE)
End If
...
!Do cleanup
integer r
use ... !whatever api mods required
If id > 0 Then
r = TerminateProcess(id, 0)
r = CloseHandle(id)
End If
The user is free to minimize or close the app and you respond by opening it up again. In the case of Excel, etc. they could loose data but the app will let them know and they'll soon get the message.
This is similar to what you've been doing. I don't consider it inelegant.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Maybe changing Excel's window styles (remove WS_MINIMIZEBUTTON & WS_THICKFRAME, add possibly WS_DLGFRAME) could be a more ellegant solution?
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page