Menu

A Spooky problem

gho
2026-05-06
2026-05-07
  • gho

    gho - 2026-05-06

    @crazyc :
    There is another problem that, once fixed, could offer advantages for a long list of games, at least all the "I Spy" games that show the same behavior.
    The problem is not preventing these games to be run with DxWnd, but for some obscure reason they require the CD to be mounted and fail when using the fake-CD feature. Mounting a CD is not that big issue, but it is for me that I'm trying to set a collection of easily installed and played games for my internal tests. But also regular users could find very easy the procedure of installing a game by simply unpacking all the files in one shot, with the further advantage that you have no limits for the number of CD games installed on one machine.
    So, about the problem, these "I Spy" games load Director player's files from the CD and make some controls about their capabilities: I see the usage of the msvcrt _accesscall and I fake a positive result, like here:

    msvcrt._access: path="H:\DATA\ISPYMAIN8.DXR" mode=0
    TranslatePath: fake CD new FileName="C:\Games\I SPY Spooky Mansion Deluxe\cd\\DATA\ISPYMAIN8.DXR"
    msvcrt._access: REMAP path="C:\Games\I SPY Spooky Mansion Deluxe\cd\\DATA\ISPYMAIN8.DXR"
    msvcrt._access: ret=0
    

    The game continues, but a little later, after some control in temporary folders, the game complains with a message telling that the file is not a good Director file (see screenshot).

    kernel32.FindFirstFileA: path="C:\Users\gho\AppData\Local\Temp\TempFolder.*"
    kernel32.FindFirstFileExW: path="C:\Users\gho\AppData\Local\Temp\TempFolder.*" level=0 opt=0 flags=0
    kernel32.CreateFileA: FileName="C:\Users\gho\AppData\Local\Temp\TempFolder.aaa\Macromedia.lok" DesiredAccess=0x80000000(GENERIC_READ) SharedMode=0 Disposition=0x3(OPEN_EXISTING) Flags=0x1(FILE_ATTRIBUTE_READONLY)
    kernel32.FindFirstFileA: path="C:\Users\gho\AppData\Local\Temp\TempFolder.aaa\*.*"
    kernel32.FindFirstFileExW: path="C:\Users\gho\AppData\Local\Temp\TempFolder.aaa\*.*" level=0 opt=0 flags=0
    kernel32.FindNextFileA: hfile=0x7a7008
    kernel32.FindNextFileA: hfile=0x7a7008
    kernel32.DeleteFileA: path="C:\Users\gho\AppData\Local\Temp\TempFolder.aaa\dirapi.mch"
    kernel32.FindNextFileA: hfile=0x7a7008
    kernel32.DeleteFileA: path="C:\Users\gho\AppData\Local\Temp\TempFolder.aaa\Macromedia.lok"
    kernel32.FindNextFileA: hfile=0x7a7008
    kernel32.FindNextFileA: NO_MORE_FILES
    kernel32.FindClose: hFindFile=0x7a7008
    kernel32.FindClose: OK
    kernel32.RemoveDirectoryA: path="C:\Users\gho\AppData\Local\Temp\TempFolder.aaa\"
    kernel32.FindNextFileA: hfile=0x7a6d08
    kernel32.FindNextFileA: NO_MORE_FILES
    kernel32.FreeLibrary: hModule=0xd90000
    kernel32.FreeLibrary: ret=1
    kernel32.FreeLibrary: hModule=0x77520000
    kernel32.FreeLibrary: ret=1
    kernel32.SetErrorMode: mode=0x1
    kernel32.SetErrorMode: ret=0x1
    kernel32.GetModuleFileNameA: hmod=0x20000000 nSize=260
    kernel32.GetModuleFileNameA: ret(len)=48 fname="C:\Games\I SPY Spooky Mansion Deluxe\spooky2.exe"
    kernel32._lopen: lpPathName="C:\Games\I SPY Spooky Mansion Deluxe\spooky2.exe" rw=0
    kernel32._lopen: res=0x26c
    kernel32.SetErrorMode: mode=0x1
    kernel32.SetErrorMode: ret=0x1
    kernel32.FindFirstFileA: path="C:\Users\gho\AppData\Local\Temp\TempFolder.*"
    kernel32.FindFirstFileExW: path="C:\Users\gho\AppData\Local\Temp\TempFolder.*" level=0 opt=0 flags=0
    kernel32.FindFirstFileExW: ERROR res=0xffffffff err=2
    kernel32.FindFirstFileA: ERROR res=0xffffffff err=2
    

    Honestly, I can't understand where is the difference ....

    p.s. there is a "I Spy Spooky Mansion Deluxe" disk image on Internet Archive

     

    Last edit: gho 2026-05-06
    • huh

      huh - 2026-05-06

      I tried this and I see a lot of lines in the log
      dxwnd.IATPatchDefault: PE unreferenced function kernelbase.dll:......
      I guess this is not right.

       

      Last edit: huh 2026-05-06
      • gho

        gho - 2026-05-06

        Actually I don't think so. The message should mean that DxWnd has tried to hook a system call (in kernelbase.dll in this case) that is not referenced (or used) by the program. This happens regularly.
        The message is activated by the "Logs > Hook op." topic that is disabled by default (even not visible in non-Extended mode). Maybe you set it inadvertently?

         
  • crazyc

    crazyc - 2026-05-06

    Well, it uses msvcrt!_sopen which then calls CreateFileA and dxwnd doesn't hook it. Works with this change.

    diff --git a/src/msvcrt.cpp b/src/msvcrt.cpp
    index d714a37..7dd3bd1 100644
    --- a/src/msvcrt.cpp
    +++ b/src/msvcrt.cpp
    @@ -53,6 +53,7 @@ typedef LPVOID (CDECL *realloc_Type)(LPVOID, size_t);
     typedef VOID (CDECL *free_Type)(LPVOID);
     typedef FILE * (CDECL *fopen_Type)(const char *, const char *);
     typedef int (CDECL *_open_Type)(const char *, int, int);
    +typedef int (CDECL *_sopen_Type)(const char *, int, int, int);
     typedef void (CDECL *__set_app_type_Type)(int);
     typedef void (CDECL *_initterm_Type)(LPVOID, LPVOID);
    
    @@ -61,6 +62,7 @@ realloc_Type prealloc;
     free_Type pfree;
     fopen_Type pfopen;
     _open_Type p_open;
    +_sopen_Type p_sopen;
     __set_app_type_Type p__set_app_type;
     _initterm_Type p_initterm;
    
    @@ -69,6 +71,7 @@ LPVOID CDECL extrealloc(LPVOID, size_t);
     VOID CDECL extfree(LPVOID);
     FILE * CDECL extfopen(const char *, const char *);
     int CDECL ext_open(const char *, int, int);
    +int CDECL ext_sopen(const char *, int, int, int);
     void CDECL ext__set_app_type(int);
     void CDECL ext_initterm(LPVOID, LPVOID);
    
    @@ -161,6 +164,7 @@ static HookEntryEx_Type HooksAlloc[]={
     static HookEntryEx_Type HooksFiles[]={
        {HOOK_IAT_CANDIDATE, 0x0000, "fopen", (FARPROC)NULL, (FARPROC *)&pfopen, (FARPROC)extfopen},
        {HOOK_IAT_CANDIDATE, 0x0000, "_open", (FARPROC)NULL, (FARPROC *)&p_open, (FARPROC)ext_open},
    
    +   {HOOK_IAT_CANDIDATE, 0x0000, "_sopen", (FARPROC)NULL, (FARPROC *)&p_sopen, (FARPROC)ext_sopen},
        {HOOK_IAT_CANDIDATE, 0x0000, "_stat", (FARPROC)NULL, (FARPROC *)&p_stat, (FARPROC)ext_stat},
        {HOOK_IAT_CANDIDATE, 0x0000, "_access", (FARPROC)NULL, (FARPROC *)&p_access, (FARPROC)ext_access},
        {HOOK_IAT_CANDIDATE, 0x0000, "_waccess", (FARPROC)NULL, (FARPROC *)&p_waccess, (FARPROC)ext_waccess},
    @@ -351,6 +355,32 @@ int CDECL ext_open(const char *fname, int oflag, int mode)
        return ret;
     }
    
    +int CDECL ext_sopen(const char *fname, int oflag, int shflag, int mode)
    +{
    
    +   ApiName("_sopen");
    +   int ret;
    +   OutTraceSYS("%s: path=\"%s\" oflag=%#x shflag=%#x mode=%#x\n", ApiRef, fname, oflag, shflag, mode);
    +
    +   if(dxw.dwFlags10 & (FAKEHDDRIVE | FAKECDDRIVE)) {
    +       DWORD mapping;
    +       fname = dxwTranslatePathA(fname, &mapping);
    +
    +       // if mapped on virtual CD and write access required, you should fake a no access error code
    +       if(mapping == DXW_FAKE_CD){
    +           if(oflag & (_O_WRONLY | _O_RDWR | _O_APPEND | _O_CREAT | _O_TRUNC | _O_EXCL)){ 
    +               OutTraceDW("%s: simulate ERROR_ACCESS_DENIED on CD\n", ApiRef);
    +               // should set lasterror here?
    +               SetLastError(ERROR_ACCESS_DENIED);// assuming the file was there, ERROR_FILE_NOT_FOUND otherwise ?
    +               return -1;
    +           }
    +       }
    +   }
    +
    +   ret = (*p_sopen)(fname, oflag, shflag, mode);
    +   OutTraceSYS("%s: path=\"%s\" ret(fd)=%#x\n", ApiRef, fname, ret);
    +   return ret;
    +}
    +
     /*
     struct _stat64i32 {
             _dev_t     st_dev;
    @@ -624,4 +654,4 @@ wchar_t * CDECL ext_wfullpath(wchar_t *absPath, const wchar_t *relPath, size_t m
        OutTraceSYS("%s: ret=%ls\n", ApiRef, ret);
        return ret;
     }
    
     

    Last edit: crazyc 2026-05-06
    • gho

      gho - 2026-05-06

      Good, it works! I will have to pay attention to other msvcrt file functions accepting a pathname in input, there seems to be quite a lot of calls!! (Or maybe I'd better remove msvcrt from the list of hooked libs and let DxWnd drill down to the kernel32 level).

       
      • huh

        huh - 2026-05-07

        Actually I don't think so.
        ...Maybe you set it inadvertently?

        Well, I turned it on hoping to find out more. Never mind, I'll make a note that this message isn't important.

         

Log in to post a comment.

MongoDB Logo MongoDB