Sign in to follow this  
Followers 0
Albuquerquefx

Dll Experts: what am I missing?

10 posts in this topic

I've been searching through these forums for a way to "see" a 16-bit Windows app running, and it looks like there wasn't much luck thus far. A few people mentioned VDMDBG.DLL available from Win2K on, so I referenced this MSKB article and arrived at this really basic chunk of code:

$astrNTVDM = ProcessList("ntvdm.exe")
For $i = 1 to $astrNTVDM[0][0]
    _VDMEnumTaskWOWEx(Hex($astrNTVDM[$i][1]))
Next

Func _VDMEnumTaskWOWEx($dwProcessId)
    MsgBox(Default,Default,"Got here: " & $dwProcessId)
    $hDll = DllOpen("vdmdbg.dll")
    $hFnc = DllCallbackRegister("_TaskEnumProcEx","int","dword;hwnd;hwnd;str;str;lparam")
    DllCall($hDll,"int","VDMEnumTaskWOWEx","dword",$dwProcessId,"ptr",DllCallbackGetPtr($hFnc),"lparam",Chr(0))
    If @error Then
       MsgBox(Default,Default,"DllCall didn't work")
    EndIf
    DllClose($hDll)
    DllCallbackFree($hFnc)
EndFunc

Func _TaskEnumProcEx($dwThreadID,$hMod16,$hTask16,$strModName,$strFileName,$lparam)
    MsgBox(Default,Default,$dwThreadID & ": " & $strModName & "|" & $strFileName)
    Return False
EndFunc

So here's what is supposed to happen... I poll the current processlist for any running NTVDM's, and from their PID's I can then do a DLL call to enumerate all the 16-bit tasks (module, full path, and thread ID) inside of it. The documentation is very clear on how it works, and I'm not getting any errors. But I'm also not getting ANY output while running a known 16-bit Windows app.

They have me do a VDMEnumProcessWow() to get all those NTVDM PID's to make sure they don't contain DOS apps, but for sake of this example, I'm running a little crappy 16-bit Windows app that isn't DOS so I know my only running NTVDM is acceptable for using with the VDMEnumTaskWowEx() function. Nevertheless, I also wrote the appropriate VDMEnumProcessWow() dllcall + callback function with the exact same results as this one: absolutely zero output and no errors.

Is there something obvious that I'm just not doing?

Share this post


Link to post
Share on other sites



Your going to be missing your posting abilities if you keep starting the same thread over and over.


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

You mustn't convert to hex :)

CODE
#include <Array.au3>

; With _VDMEnumProcessWOW()

$astrNTVDM = _VDMEnumProcessWOW()

For $i = 1 to $astrNTVDM[0]

_VDMEnumTaskWOWEx($astrNTVDM[$i])

Next

; with ProcessList >_<

$astrNTVDM = ProcessList("ntvdm.exe")

For $i = 1 to $astrNTVDM[0][0]

_VDMEnumTaskWOWEx($astrNTVDM[$i][1])

Next

Func _VDMEnumTaskWOWEx($dwProcessId)

MsgBox(Default,Default,"Got here: " & $dwProcessId)

$hDll = DllOpen("vdmdbg.dll")

Local $hFnc = DllCallbackRegister("_TaskEnumProcEx","int","dword;ushort;ushort;str;str;lparam")

DllCall($hDll,"int","VDMEnumTaskWOWEx","dword",$dwProcessId,"ptr",DllCallbackGetPtr($hFnc),"lparam",Chr(0))

If @error Then

MsgBox(Default,Default,"DllCall didn't work")

EndIf

DllClose($hDll)

DllCallbackFree($hFnc)

EndFunc

Func _TaskEnumProcEx($dwThreadID,$hMod16,$hTask16,$strModName,$strFileName,$lparam)

MsgBox(Default,Default,$dwThreadID & ": " & $strModName & "|" & $strFileName)

Return False

EndFunc

Func _VDMEnumProcessWOW()

$hDll = DllOpen("vdmdbg.dll")

Global $_VDMEnumProcessWOW_Processes[1]

Local $hFnc = DllCallbackRegister("_VDMEnumProcessWOWProc","int","dword;dword;lparam")

DllCall($hDll,"int","VDMEnumProcessWOW","ptr",DllCallbackGetPtr($hFnc),"lparam",Chr(0))

If @error Then

MsgBox(Default,Default,"DllCall didn't work")

EndIf

DllClose($hDll)

DllCallbackFree($hFnc)

$_VDMEnumProcessWOW_Processes[0] = UBound($_VDMEnumProcessWOW_Processes)-1

Return $_VDMEnumProcessWOW_Processes

EndFunc

Func _VDMEnumProcessWOWProc($pid, $attribute, $lparam)

ReDim $_VDMEnumProcessWOW_Processes[uBound($_VDMEnumProcessWOW_Processes)+1]

$_VDMEnumProcessWOW_Processes[uBound($_VDMEnumProcessWOW_Processes)-1] = $pid

EndFunc


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Your going to be missing your posting abilities if you keep starting the same thread over and over.

Huh? I don't know what you're talking about? I previewed my post a few times to make sure the code looked correct, but I only posted it once (and searching by my own user ID, I haven't posted anything in this forum in months...)

You mustn't convert to hex :)

CODE
#include <Array.au3>

; With _VDMEnumProcessWOW()

$astrNTVDM = _VDMEnumProcessWOW()

For $i = 1 to $astrNTVDM[0]

_VDMEnumTaskWOWEx($astrNTVDM[$i])

Next

; with ProcessList >_<

$astrNTVDM = ProcessList("ntvdm.exe")

For $i = 1 to $astrNTVDM[0][0]

_VDMEnumTaskWOWEx($astrNTVDM[$i][1])

Next

Func _VDMEnumTaskWOWEx($dwProcessId)

MsgBox(Default,Default,"Got here: " & $dwProcessId)

$hDll = DllOpen("vdmdbg.dll")

Local $hFnc = DllCallbackRegister("_TaskEnumProcEx","int","dword;ushort;ushort;str;str;lparam")

DllCall($hDll,"int","VDMEnumTaskWOWEx","dword",$dwProcessId,"ptr",DllCallbackGetPtr($hFnc),"lparam",Chr(0))

If @error Then

MsgBox(Default,Default,"DllCall didn't work")

EndIf

DllClose($hDll)

DllCallbackFree($hFnc)

EndFunc

Func _TaskEnumProcEx($dwThreadID,$hMod16,$hTask16,$strModName,$strFileName,$lparam)

MsgBox(Default,Default,$dwThreadID & ": " & $strModName & "|" & $strFileName)

Return False

EndFunc

Func _VDMEnumProcessWOW()

$hDll = DllOpen("vdmdbg.dll")

Global $_VDMEnumProcessWOW_Processes[1]

Local $hFnc = DllCallbackRegister("_VDMEnumProcessWOWProc","int","dword;dword;lparam")

DllCall($hDll,"int","VDMEnumProcessWOW","ptr",DllCallbackGetPtr($hFnc),"lparam",Chr(0))

If @error Then

MsgBox(Default,Default,"DllCall didn't work")

EndIf

DllClose($hDll)

DllCallbackFree($hFnc)

$_VDMEnumProcessWOW_Processes[0] = UBound($_VDMEnumProcessWOW_Processes)-1

Return $_VDMEnumProcessWOW_Processes

EndFunc

Func _VDMEnumProcessWOWProc($pid, $attribute, $lparam)

ReDim $_VDMEnumProcessWOW_Processes[uBound($_VDMEnumProcessWOW_Processes)+1]

$_VDMEnumProcessWOW_Processes[uBound($_VDMEnumProcessWOW_Processes)-1] = $pid

EndFunc

Tried that, didn't work :idiot: Did it work for you? Edited by Albuquerquefx

Share this post


Link to post
Share on other sites

Huh? I don't know what you're talking about? I previewed my post a few times to make sure the code looked correct, but I only posted it once (and searching by my own user ID, I haven't posted anything in this forum in months...)

You won't find the other 3 either, I deleted them. You started 4 threads earlier.


SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Share this post


Link to post
Share on other sites

You won't find the other 3 either, I deleted them. You started 4 threads earlier.

Only posted once, didn't refresh my page, didn't encounter any errors, but I did preview my post probably abou that many times. And it was a preview, this isn't my first time using a forum. Sounds like a bug to me...

Share this post


Link to post
Share on other sites

There you go.

Compile and run a Console so that ConsoleWrite works.

#NoTrayIcon
#RequireAdmin
Opt("MustDeclareVars", 1)

Func VDMEnumProcessWOW($fp, $lparam)
    Local $buffer

    SetError(0)
    $buffer = DllCall("vdmdbg.dll", "INT", "VDMEnumProcessWOW", "ptr", $fp, "LPARAM", $lparam)
    If @error <> 0 Then
        SetError(1)
        Return 0
    EndIf

    Return $buffer[0]
EndFunc

Func VDMEnumTaskWOWEx($dwProcessId, $fp, $lparam)
    Local $buffer

    ConsoleWrite("PID: " & $dwProcessId & @CRLF) ; Of the 32-bit process.
    ConsoleWrite(@CRLF)

    SetError(0)
    $buffer = DllCall("vdmdbg.dll", "INT", "VDMEnumTaskWOWEx", "DWORD", $dwProcessId, "ptr", $fp, "LPARAM", $lparam)
    If @error <> 0 Then
        SetError(1)
        Return 0
    EndIf

    Return $buffer[0]
EndFunc

Func TASKENUMPROCEX($dwThreadId, $hMod16, $hTask16, $pszModName, $pszFileName, $lpUserDefined)
    Local $ModuleName, $FileName

    Local $Index = StringInStr($pszModName, Chr(0))

    ConsoleWrite("Module Handle: " & $hMod16 & @CRLF)
    ConsoleWrite("Task Handle: " & $hTask16 & @CRLF)
    ConsoleWrite("Module Name: " & $pszModName & @CRLF)
    ConsoleWrite("File Name: " & $pszFileName & @CRLF)
    ConsoleWrite(@CRLF)
EndFunc

Func PROCESSENUMPROC($dwProcessId, $dwAttributes, $lpUserDefined)
    Local $Handle2

    $Handle2 = DllCallbackRegister("TASKENUMPROCEX", "BOOLEAN", "DWORD;WORD;WORD;str;str;LPARAM")

    VDMEnumTaskWOWEx($dwProcessId, DllCallbackGetPtr($Handle2), $lpUserDefined)

    DllCallbackFree($Handle2)
EndFunc

Local $Handle

$Handle = DllCallbackRegister("PROCESSENUMPROC", "BOOLEAN", "DWORD;DWORD;LPARAM")

VDMEnumProcessWOW(DllCallbackGetPtr($Handle), 0)

DllCallbackFree($Handle)

Output sample:

PID: 3672

Module Handle: 5919
Task Handle: 5903
Module Name: JMAN
File Name: C:PROGRA~1JMANJMAN.EXE

Module Handle: 895
Task Handle: 911

Share this post


Link to post
Share on other sites

6 years odd old thread, but not a record.

Unlucky.

 

Not cared how old it is, if someone else finds this page, as I did, at least he'll/she'll come right.

I landed up here because AutoIt ProcessExists doesn't natively support 16-bit processes, so I made my own.

I needed to get a list of running 16-bit processes (if any) so that I could use a .BAT to change the screen resolution to 640x480x8, then run a Windows 3.1 (16-bit) game, wait for the game to finish, and finally restore the screen resolution.

Both Process Wait and Sleep (see below) are excellent for running older games that will only run under certain circumstances.

StarCraft needs to have EXPLORER.EXE terminated. Shivers must run in 8-bit color. Process Wait is nice because many games don't support the Command Prompt command "START /W".

Enjoy!

Both of these were written in AutoIt:

Process Wait 1.0.1

Used for waiting for 16-bit, 32-bit or 64-bit processes. Includes binaries and source code.

http://doropie.com/files/process_wait_1_0_1.zip

Sleep 1.0.0

Used for putting the current thread to sleep for a specific number of seconds. Includes binaries and source code

http://doropie.com/files/sleep_1_0_0.zip

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0