Index: dll/win32/kernel32/file/file.c =================================================================== --- dll/win32/kernel32/file/file.c (revision 50815) +++ dll/win32/kernel32/file/file.c (working copy) @@ -24,7 +24,54 @@ /* FUNCTIONS ****************************************************************/ +/*********************************************************************** + * FILE_name_AtoW + * + * Convert a file name to Unicode, taking into account the OEM/Ansi API mode. + * + * If alloc is FALSE uses the TEB static buffer, so it can only be used when + * there is no possibility for the function to do that twice, taking into + * account any called function. + */ +WCHAR *FILE_name_AtoW( LPCSTR name, BOOL alloc ) +{ + ANSI_STRING str; + UNICODE_STRING strW, *pstrW; + NTSTATUS status; + RtlInitAnsiString( &str, name ); + pstrW = alloc ? &strW : &NtCurrentTeb()->StaticUnicodeString; + if (bIsFileApiAnsi) + status = RtlOemStringToUnicodeString( pstrW, &str, alloc ); + else + status = RtlAnsiStringToUnicodeString( pstrW, &str, alloc ); + if (status == STATUS_SUCCESS) return pstrW->Buffer; + + if (status == STATUS_BUFFER_OVERFLOW) + SetLastError( ERROR_FILENAME_EXCED_RANGE ); + else + SetLastError( RtlNtStatusToDosError(status) ); + return NULL; +} + + +/*********************************************************************** + * FILE_name_WtoA + * + * Convert a file name back to OEM/Ansi. Returns number of bytes copied. + */ +DWORD FILE_name_WtoA( LPCWSTR src, INT srclen, LPSTR dest, INT destlen ) +{ + DWORD ret; + + if (srclen < 0) srclen = strlenW( src ) + 1; + if (bIsFileApiAnsi) + RtlUnicodeToOemN( dest, destlen, &ret, src, srclen * sizeof(WCHAR) ); + else + RtlUnicodeToMultiByteN( dest, destlen, &ret, (PWSTR)src, srclen * sizeof(WCHAR) ); + return ret; +} + PWCHAR FilenameA2W(LPCSTR NameA, BOOL alloc) { @@ -1214,23 +1261,18 @@ */ UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer) { - WCHAR BufferW[MAX_PATH]; - PWCHAR PathW; - WCHAR PrefixW[3+1]; - UINT ret; + WCHAR *pathW, *prefixW = NULL; + WCHAR bufferW[MAX_PATH]; + UINT ret; - if (!(PathW = FilenameA2W(path, FALSE))) - return 0; + if (!(pathW = FILE_name_AtoW( path, FALSE ))) return 0; + if (prefix && !(prefixW = FILE_name_AtoW( prefix, TRUE ))) return 0; - if (prefix) - FilenameA2W_N(PrefixW, 3+1, prefix, -1); + ret = GetTempFileNameW(pathW, prefixW, unique, bufferW); + if (ret) FILE_name_WtoA( bufferW, -1, buffer, MAX_PATH ); - ret = GetTempFileNameW(PathW, prefix ? PrefixW : NULL, unique, BufferW); - - if (ret) - FilenameW2A_N(buffer, MAX_PATH, BufferW, -1); - - return ret; + HeapFree( GetProcessHeap(), 0, prefixW ); + return ret; } /*********************************************************************** @@ -1238,10 +1280,11 @@ */ UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR buffer ) { - static const WCHAR formatW[] = L"%x.tmp"; + static const WCHAR formatW[] = {'%','x','.','t','m','p',0}; int i; LPWSTR p; + DWORD attr; if ( !path || !buffer ) { @@ -1249,13 +1292,22 @@ return 0; } - wcscpy( buffer, path ); - p = buffer + wcslen(buffer); + /* ensure that the provided directory exists */ + attr = GetFileAttributesW(path); + if (attr == INVALID_FILE_ATTRIBUTES || !(attr & FILE_ATTRIBUTE_DIRECTORY)) + { + TRACE("path not found %s\n", debugstr_w(path)); + SetLastError( ERROR_DIRECTORY ); + return 0; + } + strcpyW( buffer, path ); + p = buffer + strlenW(buffer); + /* add a \, if there isn't one */ if ((p == buffer) || (p[-1] != '\\')) *p++ = '\\'; - if ( prefix ) + if (prefix) for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++; unique &= 0xffff; @@ -1266,7 +1318,10 @@ /* get a "random" unique number and try to create the file */ HANDLE handle; UINT num = GetTickCount() & 0xffff; + static UINT last; + /* avoid using the same name twice in a short interval */ + if (last - num < 10) num = last + 1; if (!num) num = 1; unique = num; do @@ -1278,6 +1333,7 @@ { /* We created it */ TRACE("created %S\n", buffer); CloseHandle( handle ); + last = unique; break; } if (GetLastError() != ERROR_FILE_EXISTS && @@ -1287,7 +1343,7 @@ } while (unique != num); } - TRACE("returning %S\n", buffer); + TRACE("returning %s\n", debugstr_w(buffer) ); return unique; }