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(a)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