Menu

Proxy dll relative paths tip

2018-10-16
2018-10-17
  • dippy dipper

    dippy dipper - 2018-10-16

    When using the proxy dll it is useful to edit dxwnd.dxw and change the path fields from absolute to relative.

    E.g. change this:
    path0=C:\game\game.exe

    to this:
    path0=.\game.exe

    This makes the proxy fully portable.

    Side note:
    Virtual CD audio does not seem to work when using a proxy dll. Copying "dxwplay.dll, libogg.dll, libvorbis.dll, libvorbisfile.dll" to the game folder did not help either.

     
  • FunkyFr3sh

    FunkyFr3sh - 2018-10-16

    I think I posted some code here somewhere that makes the proxy portable by removing the path completely, not sure if it's included with DxWnd though

     
  • gho

    gho - 2018-10-16

    I'm not even sure that a path0 field is necessary in proxy mode, the dxwnd.dll is loaded by the proxy library (es. ddraw.dll) and may not need an executable name at all. But I'm not sure, let me check ...

     
  • dippy dipper

    dippy dipper - 2018-10-17

    I see that the "path0" field is not needed for the proxy at all. (Neither is "startfolder0" or "launchpath0" I assume.)

    Problem is that when you install a proxy from the Dxwnd GUI that field gets copied to the dxwnd.dxw file that stores the all the game specific settings. So possibly one would need to edit the source at “proxy\init.cpp” so that the path0 field gets omitted or just replaced by ".\" or something...

    As for the Virtual CD audio not working with a proxy setup it might be enough to build a small winmm.dll proxy. And modify the proxy installation to also copy "winmm.dll, dxwplay.dll, libogg.dll, libvorbis.dll, libvorbisfile.dll" to the game folder. Maybe add a check in there to see if the user has enabled the Virtual CD audio flag before copying those extra files?

     
    • gho

      gho - 2018-10-17

      I think you're right: the proxy mode is enabled by the fact that the game links the fake system dll (either ddraw.dll, dinput.dll, .... Beware: NEVER put more than one proxy dll in the game folder or the trick won't work!) who automatically loads dxwnd.dll, so there's no check for task names.
      Furthermore, when dxwnd.dll is loaded the game is started already, so there's no possible use for startfolder or launchpath. All these fields could be cleared in the dxwnd.dxw file generation, but they make no harm (and could be useful to re-import the configuration back in DxWnd.exe, so why do that?

      About Virtual CD audio, a small (ehm.. small? try counting the number of function calls in there ...) winmm.dll proxy is the original solution, also existing in GOG games, but it could bring a problem: winmm.dll doesn't hold only mci sound calls, it also have system calls for movie, joystick, timing and other stuff that DxWnd could be interested in hooking. I fear that a winmm.dll proxy could interfere with that. I should try to be sure.

       
  • dippy dipper

    dippy dipper - 2018-10-17

    All these fields could be cleared in the dxwnd.dxw file generation, but they make no harm (and could be useful to re-import the configuration back in DxWnd.exe, so why do that?

    Right you are. The proxy does not care about those path fields at all so this is really a completely moot point.

    As for the winmm.dll proxy I see what you mean now. The number of calls in there is quite daunting. I was looking at the already existing stand alone winmm wrappers and it seems that they have a lot of issues. Mainly they are no where near as good as what is included with Dxwnd.

     
    • dippy dipper

      dippy dipper - 2018-10-17

      Here is a winmm.def listing from the stand alone winmm-ogg wrapper:

      LIBRARY winmm.dll
      
      EXPORTS
          auxGetVolume                     = fake_auxGetVolume
          auxSetVolume                     = fake_auxSetVolume
          auxGetDevCapsA                   = fake_auxGetDevCapsA
          auxGetNumDevs                    = fake_auxGetNumDevs
          mciSendCommandA                  = fake_mciSendCommandA
          mciSendStringA                   = fake_mciSendStringA
      
          auxGetDevCapsW                   = fake_auxGetDevCapsW
          auxOutMessage                    = fake_auxOutMessage
          CloseDriver                      = fake_CloseDriver
          DefDriverProc                    = fake_DefDriverProc
          DriverCallback                   = fake_DriverCallback
          DrvGetModuleHandle               = fake_DrvGetModuleHandle
          GetDriverModuleHandle            = fake_GetDriverModuleHandle
          joyConfigChanged                 = fake_joyConfigChanged
          joyGetDevCapsA                   = fake_joyGetDevCapsA
          joyGetDevCapsW                   = fake_joyGetDevCapsW
          joyGetNumDevs                    = fake_joyGetNumDevs
          joyGetPos                        = fake_joyGetPos
          joyGetPosEx                      = fake_joyGetPosEx
          joyGetThreshold                  = fake_joyGetThreshold
          joyReleaseCapture                = fake_joyReleaseCapture
          joySetCapture                    = fake_joySetCapture
          joySetThreshold                  = fake_joySetThreshold
          mciExecute                       = fake_mciExecute
          mciFreeCommandResource           = fake_mciFreeCommandResource
          mciGetCreatorTask                = fake_mciGetCreatorTask
          mciGetDeviceIDA                  = fake_mciGetDeviceIDA
          mciGetDeviceIDFromElementIDA     = fake_mciGetDeviceIDFromElementIDA
          mciGetDeviceIDFromElementIDW     = fake_mciGetDeviceIDFromElementIDW
          mciGetDeviceIDW                  = fake_mciGetDeviceIDW
          mciGetErrorStringA               = fake_mciGetErrorStringA
          mciGetErrorStringW               = fake_mciGetErrorStringW
          mciGetYieldProc                  = fake_mciGetYieldProc
          mciLoadCommandResource           = fake_mciLoadCommandResource
          mciSendCommandW                  = fake_mciSendCommandW
          mciSendStringW                   = fake_mciSendStringW
          mciSetYieldProc                  = fake_mciSetYieldProc
          midiConnect                      = fake_midiConnect
          midiDisconnect                   = fake_midiDisconnect
          midiInAddBuffer                  = fake_midiInAddBuffer
          midiInClose                      = fake_midiInClose
          midiInGetDevCapsA                = fake_midiInGetDevCapsA
          midiInGetDevCapsW                = fake_midiInGetDevCapsW
          midiInGetErrorTextA              = fake_midiInGetErrorTextA
          midiInGetErrorTextW              = fake_midiInGetErrorTextW
          midiInGetID                      = fake_midiInGetID
          midiInGetNumDevs                 = fake_midiInGetNumDevs
          midiInMessage                    = fake_midiInMessage
          midiInOpen                       = fake_midiInOpen
          midiInPrepareHeader              = fake_midiInPrepareHeader
          midiInReset                      = fake_midiInReset
          midiInStart                      = fake_midiInStart
          midiInStop                       = fake_midiInStop
          midiInUnprepareHeader            = fake_midiInUnprepareHeader
          midiOutCacheDrumPatches          = fake_midiOutCacheDrumPatches
          midiOutCachePatches              = fake_midiOutCachePatches
          midiOutClose                     = fake_midiOutClose
          midiOutGetDevCapsA               = fake_midiOutGetDevCapsA
          midiOutGetDevCapsW               = fake_midiOutGetDevCapsW
          midiOutGetErrorTextA             = fake_midiOutGetErrorTextA
          midiOutGetErrorTextW             = fake_midiOutGetErrorTextW
          midiOutGetID                     = fake_midiOutGetID
          midiOutGetNumDevs                = fake_midiOutGetNumDevs
          midiOutGetVolume                 = fake_midiOutGetVolume
          midiOutLongMsg                   = fake_midiOutLongMsg
          midiOutMessage                   = fake_midiOutMessage
          midiOutOpen                      = fake_midiOutOpen
          midiOutPrepareHeader             = fake_midiOutPrepareHeader
          midiOutReset                     = fake_midiOutReset
          midiOutSetVolume                 = fake_midiOutSetVolume
          midiOutShortMsg                  = fake_midiOutShortMsg
          midiOutUnprepareHeader           = fake_midiOutUnprepareHeader
          midiStreamClose                  = fake_midiStreamClose
          midiStreamOpen                   = fake_midiStreamOpen
          midiStreamOut                    = fake_midiStreamOut
          midiStreamPause                  = fake_midiStreamPause
          midiStreamPosition               = fake_midiStreamPosition
          midiStreamProperty               = fake_midiStreamProperty
          midiStreamRestart                = fake_midiStreamRestart
          midiStreamStop                   = fake_midiStreamStop
          mixerClose                       = fake_mixerClose
          mixerGetControlDetailsA          = fake_mixerGetControlDetailsA
          mixerGetControlDetailsW          = fake_mixerGetControlDetailsW
          mixerGetDevCapsA                 = fake_mixerGetDevCapsA
          mixerGetDevCapsW                 = fake_mixerGetDevCapsW
          mixerGetID                       = fake_mixerGetID
          mixerGetLineControlsA            = fake_mixerGetLineControlsA
          mixerGetLineControlsW            = fake_mixerGetLineControlsW
          mixerGetLineInfoA                = fake_mixerGetLineInfoA
          mixerGetLineInfoW                = fake_mixerGetLineInfoW
          mixerGetNumDevs                  = fake_mixerGetNumDevs
          mixerMessage                     = fake_mixerMessage
          mixerOpen                        = fake_mixerOpen
          mixerSetControlDetails           = fake_mixerSetControlDetails
          mmGetCurrentTask                 = fake_mmGetCurrentTask
          mmTaskBlock                      = fake_mmTaskBlock
          mmTaskCreate                     = fake_mmTaskCreate
          mmTaskSignal                     = fake_mmTaskSignal
          mmTaskYield                      = fake_mmTaskYield
          mmioAdvance                      = fake_mmioAdvance
          mmioAscend                       = fake_mmioAscend
          mmioClose                        = fake_mmioClose
          mmioCreateChunk                  = fake_mmioCreateChunk
          mmioDescend                      = fake_mmioDescend
          mmioFlush                        = fake_mmioFlush
          mmioGetInfo                      = fake_mmioGetInfo
          mmioInstallIOProcA               = fake_mmioInstallIOProcA
          mmioInstallIOProcW               = fake_mmioInstallIOProcW
          mmioOpenA                        = fake_mmioOpenA
          mmioOpenW                        = fake_mmioOpenW
          mmioRead                         = fake_mmioRead
          mmioRenameA                      = fake_mmioRenameA
          mmioRenameW                      = fake_mmioRenameW
          mmioSeek                         = fake_mmioSeek
          mmioSendMessage                  = fake_mmioSendMessage
          mmioSetBuffer                    = fake_mmioSetBuffer
          mmioSetInfo                      = fake_mmioSetInfo
          mmioStringToFOURCCA              = fake_mmioStringToFOURCCA
          mmioStringToFOURCCW              = fake_mmioStringToFOURCCW
          mmioWrite                        = fake_mmioWrite
          mmsystemGetVersion               = fake_mmsystemGetVersion
          NotifyCallbackData               = fake_NotifyCallbackData
          OpenDriver                       = fake_OpenDriver
          PlaySound                        = fake_PlaySound
          PlaySoundA                       = fake_PlaySoundA
          PlaySoundW                       = fake_PlaySoundW
          SendDriverMessage                = fake_SendDriverMessage
          sndPlaySoundA                    = fake_sndPlaySoundA
          sndPlaySoundW                    = fake_sndPlaySoundW
          timeBeginPeriod                  = fake_timeBeginPeriod
          timeEndPeriod                    = fake_timeEndPeriod
          timeGetDevCaps                   = fake_timeGetDevCaps
          timeGetSystemTime                = fake_timeGetSystemTime
          timeGetTime                      = fake_timeGetTime
          timeKillEvent                    = fake_timeKillEvent
          timeSetEvent                     = fake_timeSetEvent
          waveInAddBuffer                  = fake_waveInAddBuffer
          waveInClose                      = fake_waveInClose
          waveInGetDevCapsA                = fake_waveInGetDevCapsA
          waveInGetDevCapsW                = fake_waveInGetDevCapsW
          waveInGetErrorTextA              = fake_waveInGetErrorTextA
          waveInGetErrorTextW              = fake_waveInGetErrorTextW
          waveInGetID                      = fake_waveInGetID
          waveInGetNumDevs                 = fake_waveInGetNumDevs
          waveInGetPosition                = fake_waveInGetPosition
          waveInMessage                    = fake_waveInMessage
          waveInOpen                       = fake_waveInOpen
          waveInPrepareHeader              = fake_waveInPrepareHeader
          waveInReset                      = fake_waveInReset
          waveInStart                      = fake_waveInStart
          waveInStop                       = fake_waveInStop
          waveInUnprepareHeader            = fake_waveInUnprepareHeader
          waveOutBreakLoop                 = fake_waveOutBreakLoop
          waveOutClose                     = fake_waveOutClose
          waveOutGetDevCapsA               = fake_waveOutGetDevCapsA
          waveOutGetDevCapsW               = fake_waveOutGetDevCapsW
          waveOutGetErrorTextA             = fake_waveOutGetErrorTextA
          waveOutGetErrorTextW             = fake_waveOutGetErrorTextW
          waveOutGetID                     = fake_waveOutGetID
          waveOutGetNumDevs                = fake_waveOutGetNumDevs
          waveOutGetPitch                  = fake_waveOutGetPitch
          waveOutGetPlaybackRate           = fake_waveOutGetPlaybackRate
          waveOutGetPosition               = fake_waveOutGetPosition
          waveOutGetVolume                 = fake_waveOutGetVolume
          waveOutMessage                   = fake_waveOutMessage
          waveOutOpen                      = fake_waveOutOpen
          waveOutPause                     = fake_waveOutPause
          waveOutPrepareHeader             = fake_waveOutPrepareHeader
          waveOutReset                     = fake_waveOutReset
          waveOutRestart                   = fake_waveOutRestart
          waveOutSetPitch                  = fake_waveOutSetPitch
          waveOutSetPlaybackRate           = fake_waveOutSetPlaybackRate
          waveOutSetVolume                 = fake_waveOutSetVolume
          waveOutUnprepareHeader           = fake_waveOutUnprepareHeader
          waveOutWrite                     = fake_waveOutWrite
      
       
  • gho

    gho - 2018-10-17

    I was looking at the already existing stand alone winmm wrappers and it seems that they have a lot of issues. Mainly they are no where near as good as what is included with Dxwnd

    The ones I saw until now were mainly designed having one specific game in mind: this is why they're not as good as DxWnd: each game uses a tiny bit of mci capabilities and there's no point in adding unnecessary stuff, both unused call wrappers or variations in the syntax. On the contrary, DWnd tries to be a one-fits-all software, so you have good chances that it could apply to untested games, and in any case you can always post here your "case" and wait for me to fix the code ;)

    P.s. another weird idea I have in mind (but it's not at all a invention of mine) is to automate the proxy code generation: now that I learnt how to walk the dll PE structure, it should be easy to make a tool that outputs some C code with all function declarations and other stuff to build a generic proxy... this way the number of dll entries wouldn't frighten me no more.

     

    Last edit: gho 2018-10-17
  • dippy dipper

    dippy dipper - 2018-10-17

    Wait just a minute here...

    Now I got the Virtual CD audio playing just fine with the proxy setup.

    Testing with the game Pandemonium!
    All I did was install the ddraw proxy from the Dxwnd GUI making sure the sound tab had "virtual CD audio" enabled of course. Then I also manually copied the "dxwplay.dll", "libogg.dll", "libvorbis.dll" and "libvorbisfile.dll" to the game folder.

    I swear I tried to do exactly the same thing several times before and the music did not play. And now it is suddenly working just fine.

     
    • gho

      gho - 2018-10-17

      Weird, but I'm rather used to weidness with proxy configurations. Anyway, there's a little trick to try getting more information about what's going wrong: the proxy command clears all the log flag when writing the dxwnd.dxw file, but after that you can copy the value from a dflagn field from within dxwnd.ini (picking one entry that has the logging you wish, of course) and paste that value in dxwnd.dxw (making sure that the left part remains "dflag0"). This way the proxed game will write its own dxwnd.log file.
      Maybe I should add a small dialog to the procedure to select whether to keep or clear the log flags ...

       

      Last edit: gho 2018-10-17

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.