Implementing wtmpnam in msvcrt

Tim Holy holy at wustl.edu
Sat Nov 29 10:27:39 CST 2008


Hi Juan,

Many thanks for your help. This compiles now. I think I must not have 
something else defined, though, because when I run the program I still get a 
message saying wtmpnam is not implemented. Do I have to do something 
else to "register" the function?

Here's the output:

tim at diva:~/bin/filesforconversion$ wine XConvert.exe
fixme:iphlpapi:NotifyAddrChange (Handle 0x7d8a49f8, overlapped 
0x7d8a49dc): stub
fixme:shell:DllCanUnloadNow stub
wine: configuration in '/home/tim/.wine' has been updated.
err:listview:LISTVIEW_WindowProc unknown msg 3e9d wp=0032ef78 
lp=00000000
err:listview:LISTVIEW_WindowProc unknown msg 3e9d wp=0032ef78 
lp=00000000
wine: Call from 0x223de1e to unimplemented function 
MSVCRT.dll._wtmpnam, aborting
wine: Call from 0x223de1e to unimplemented function 
MSVCRT.dll._wtmpnam, aborting

For reference, the current state of the patch is pasted below.

Thanks,
--Tim

diff -U 3 -r winecopy/wine-1.1.8/dlls/msvcrt/file.c wine-1.1.8/dlls/msvcrt/file.c
--- winecopy/wine-1.1.8/dlls/msvcrt/file.c	2008-11-07 10:09:33.000000000 
-0600
+++ wine-1.1.8/dlls/msvcrt/file.c	2008-11-29 10:16:03.000000000 -0600
@@ -88,6 +88,7 @@
 
 /* INTERNAL: Static buffer for temp file name */
 static char MSVCRT_tmpname[MAX_PATH];
+static MSVCRT_wchar_t MSVCRT_wtmpname[MAX_PATH];
 
 static const unsigned int EXE = 'e' << 16 | 'x' << 8 | 'e';
 static const unsigned int BAT = 'b' << 16 | 'a' << 8 | 't';
@@ -2990,6 +2991,36 @@
 }
 
 /*********************************************************************
+ *		wtmpnam (MSVCRT.@)
+ */
+extern int CDECL MSVCRT_swprintf( MSVCRT_wchar_t *str, const 
MSVCRT_wchar_t *format, ... );  /* Defined in wcs.c */
+
+MSVCRT_wchar_t * CDECL MSVCRT_wtmpnam(MSVCRT_wchar_t *s)
+{
+  static int unique;
+  char tmpstr[16];
+  MSVCRT_wchar_t wtmpstr[16];
+  MSVCRT_wchar_t *p;
+  int count;
+  static const MSVCRT_wchar_t tmpFmt[] = { '\\','s','%','s','.',0 };
+
+  if (s == 0)
+    s = MSVCRT_wtmpname;
+  msvcrt_int_to_base32(GetCurrentProcessId(), tmpstr);
+  p = s + MSVCRT_swprintf(s, tmpFmt, tmpstr);
+  for (count = 0; count < MSVCRT_TMP_MAX; count++)
+  {
+    msvcrt_int_to_base32(unique++, tmpstr);
+    MultiByteToWideChar(CP_ACP, 0, tmpstr, strlen(tmpstr), wtmpstr, 16);
+    strcpyW(p, wtmpstr);
+    if (GetFileAttributesW(s) == INVALID_FILE_ATTRIBUTES &&
+        GetLastError() == ERROR_FILE_NOT_FOUND)
+      break;
+  }
+  return s;
+}
+
+/*********************************************************************
  *		tmpfile (MSVCRT.@)
  */
 MSVCRT_FILE* CDECL MSVCRT_tmpfile(void)
diff -U 3 -r winecopy/wine-1.1.8/dlls/msvcrt/msvcrt.spec 
wine-1.1.8/dlls/msvcrt/msvcrt.spec
--- winecopy/wine-1.1.8/dlls/msvcrt/msvcrt.spec	2008-11-07 
10:09:33.000000000 -0600
+++ wine-1.1.8/dlls/msvcrt/msvcrt.spec	2008-11-29 07:12:10.000000000 
-0600
@@ -579,7 +579,7 @@
 @ cdecl _wstrtime(ptr)
 @ cdecl _wsystem(wstr)
 @ cdecl _wtempnam(wstr wstr)
-@ stub _wtmpnam #(ptr)
+@ cdecl wtmpnam(ptr) MSVCRT_wtmpnam
 @ cdecl _wtoi(wstr) ntdll._wtoi
 @ cdecl _wtoi64(wstr) ntdll._wtoi64
 @ cdecl _wtol(wstr) ntdll._wtol
 


On Saturday 29 November 2008 10:00:00 am Juan Lang wrote:
> Hi Tim,
>
> > +  p = s + MSVCRT_swprintf(s, "\\s%s.", tmpstr);  // "implicit
> > declaration" error, function is defined in wcs (but no wcs.h); but how to
> > convert format string to MSVCRT_wchar_t?
>
> Declare the format string as a const buffer, e.g.:
> static const MSVCRT_wchar_t tmpFmt[] = { '\\','s','%','s','.',0 };
>
> > +    mbstowcs(wtmpstr,tmpstr,strlen(tmpstr));  // need a MSVCRT_wchar
> > version
>
> MultiByteToWideChar should be enough.
>
> > +    wcscpy(p, wtmpstr);    // need a MSVCRT_wchar version
>
> Just use strcpyW, as other files in msvcrt do.
>
> > +@ cdecl wtmpnam(ptr) MSVCRT_wtmpnam  // needs an underscore?
>
> The name in the .spec file must match the name in the .c file, that's all.
> --Juan



More information about the wine-devel mailing list