kernel32: Move some path functions to kernelbase.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-09-17 16:19:03 +02:00
parent 5f10545b19
commit e3e1bede1b
4 changed files with 586 additions and 649 deletions

View File

@ -624,8 +624,8 @@
@ stdcall -import GetCurrentActCtx(ptr)
@ stdcall GetCurrentConsoleFont(long long ptr)
# @ stub GetCurrentConsoleFontEx
@ stdcall GetCurrentDirectoryA(long ptr)
@ stdcall GetCurrentDirectoryW(long ptr)
@ stdcall -import GetCurrentDirectoryA(long ptr)
@ stdcall -import GetCurrentDirectoryW(long ptr)
@ stdcall GetCurrentPackageFamilyName(ptr ptr)
@ stdcall GetCurrentPackageFullName(ptr ptr)
@ stdcall GetCurrentPackageId(ptr ptr)
@ -688,10 +688,10 @@
@ stdcall GetFinalPathNameByHandleW(long ptr long long)
@ stdcall GetFirmwareEnvironmentVariableA(str str ptr long)
@ stdcall GetFirmwareEnvironmentVariableW(wstr wstr ptr long)
@ stdcall GetFullPathNameA(str long ptr ptr)
@ stdcall -import GetFullPathNameA(str long ptr ptr)
# @ stub GetFullPathNameTransactedA
# @ stub GetFullPathNameTransactedW
@ stdcall GetFullPathNameW(wstr long ptr ptr)
@ stdcall -import GetFullPathNameW(wstr long ptr ptr)
@ stdcall GetGeoInfoA(long long ptr long long)
@ stdcall GetGeoInfoW(long long ptr long long)
@ stdcall GetHandleContext(long)
@ -711,10 +711,10 @@
@ stdcall GetLogicalDrives()
@ stdcall GetLogicalProcessorInformation(ptr ptr)
@ stdcall GetLogicalProcessorInformationEx(long ptr ptr)
@ stdcall GetLongPathNameA (str long long)
@ stdcall -import GetLongPathNameA (str long long)
# @ stub GetLongPathNameTransactedA
# @ stub GetLongPathNameTransactedW
@ stdcall GetLongPathNameW (wstr long long)
@ stdcall -import GetLongPathNameW (wstr long long)
@ stdcall GetMailslotInfo(long ptr ptr ptr ptr)
@ stdcall GetMaximumProcessorCount(long)
# @ stub GetMaximumProcessorGroupCount
@ -808,7 +808,7 @@
@ stub -i386 GetSLCallbackTarget
@ stub -i386 GetSLCallbackTemplate
@ stdcall GetShortPathNameA(str ptr long)
@ stdcall GetShortPathNameW(wstr ptr long)
@ stdcall -import GetShortPathNameW(wstr ptr long)
@ stdcall GetStartupInfoA(ptr)
@ stdcall -import GetStartupInfoW(ptr)
@ stdcall -import GetStdHandle(long)
@ -842,10 +842,10 @@
@ stdcall GetTapeParameters(ptr long ptr ptr)
@ stdcall GetTapePosition(ptr long ptr ptr ptr)
@ stdcall GetTapeStatus(ptr)
@ stdcall GetTempFileNameA(str str long ptr)
@ stdcall GetTempFileNameW(wstr wstr long ptr)
@ stdcall GetTempPathA(long ptr)
@ stdcall GetTempPathW(long ptr)
@ stdcall -import GetTempFileNameA(str str long ptr)
@ stdcall -import GetTempFileNameW(wstr wstr long ptr)
@ stdcall -import GetTempPathA(long ptr)
@ stdcall -import GetTempPathW(long ptr)
@ stdcall -import GetThreadContext(long ptr)
@ stdcall -import GetThreadErrorMode()
@ stdcall -import GetThreadGroupAffinity(long ptr)
@ -1095,8 +1095,8 @@
@ stdcall MoveFileWithProgressW(wstr wstr ptr ptr long)
@ stdcall MulDiv(long long long)
@ stdcall MultiByteToWideChar(long long str long ptr long)
@ stdcall NeedCurrentDirectoryForExePathA(str)
@ stdcall NeedCurrentDirectoryForExePathW(wstr)
@ stdcall -import NeedCurrentDirectoryForExePathA(str)
@ stdcall -import NeedCurrentDirectoryForExePathW(wstr)
# @ stub NlsCheckPolicy
# @ stub NlsConvertIntegerToString
# @ stub NlsEventDataDescCreate
@ -1374,8 +1374,8 @@
@ stdcall -import SetConsoleWindowInfo(long long ptr)
@ stdcall SetCriticalSectionSpinCount(ptr long) ntdll.RtlSetCriticalSectionSpinCount
@ stdcall SetCurrentConsoleFontEx(long long ptr)
@ stdcall SetCurrentDirectoryA(str)
@ stdcall SetCurrentDirectoryW(wstr)
@ stdcall -import SetCurrentDirectoryA(str)
@ stdcall -import SetCurrentDirectoryW(wstr)
@ stub SetDaylightFlag
@ stdcall SetDefaultCommConfigA(str ptr long)
@ stdcall SetDefaultCommConfigW(wstr ptr long)

View File

@ -45,8 +45,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(file);
static int path_safe_mode = -1; /* path mode set by SetSearchPathMode */
static const WCHAR wildcardsW[] = {'*','?',0};
/* check if a file name is for an executable file (.exe or .com) */
static inline BOOL is_executable( const WCHAR *name )
{
@ -233,340 +231,6 @@ static BOOL add_boot_rename_entry( LPCWSTR source, LPCWSTR dest, DWORD flags )
}
/***********************************************************************
* GetFullPathNameW (KERNEL32.@)
* NOTES
* if the path closed with '\', *lastpart is 0
*/
DWORD WINAPI GetFullPathNameW( LPCWSTR name, DWORD len, LPWSTR buffer,
LPWSTR *lastpart )
{
return RtlGetFullPathName_U(name, len * sizeof(WCHAR), buffer, lastpart) / sizeof(WCHAR);
}
/***********************************************************************
* GetFullPathNameA (KERNEL32.@)
* NOTES
* if the path closed with '\', *lastpart is 0
*/
DWORD WINAPI GetFullPathNameA( LPCSTR name, DWORD len, LPSTR buffer,
LPSTR *lastpart )
{
WCHAR *nameW;
WCHAR bufferW[MAX_PATH], *lastpartW = NULL;
DWORD ret;
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return 0;
ret = GetFullPathNameW( nameW, MAX_PATH, bufferW, &lastpartW);
if (!ret) return 0;
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
ret = copy_filename_WtoA( bufferW, buffer, len );
if (ret < len && lastpart)
{
if (lastpartW)
*lastpart = buffer + FILE_name_WtoA( bufferW, lastpartW - bufferW, NULL, 0 );
else
*lastpart = NULL;
}
return ret;
}
/***********************************************************************
* GetLongPathNameW (KERNEL32.@)
*
* NOTES
* observed (Win2000):
* shortpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* shortpath="": LastError=ERROR_PATH_NOT_FOUND, ret=0
*/
DWORD WINAPI GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen )
{
WCHAR tmplongpath[MAX_PATHNAME_LEN];
LPCWSTR p;
DWORD sp = 0, lp = 0;
DWORD tmplen;
BOOL unixabsolute;
WIN32_FIND_DATAW wfd;
HANDLE goit;
BOOL is_legal_8dot3;
TRACE("%s,%p,%u\n", debugstr_w(shortpath), longpath, longlen);
if (!shortpath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!shortpath[0])
{
SetLastError(ERROR_PATH_NOT_FOUND);
return 0;
}
if (shortpath[0] == '\\' && shortpath[1] == '\\')
{
FIXME("UNC pathname %s\n", debugstr_w(shortpath));
tmplen = strlenW(shortpath);
if (tmplen < longlen)
{
if (longpath != shortpath) strcpyW( longpath, shortpath );
return tmplen;
}
return tmplen + 1;
}
unixabsolute = (shortpath[0] == '/');
/* check for drive letter */
if (!unixabsolute && shortpath[1] == ':' )
{
tmplongpath[0] = shortpath[0];
tmplongpath[1] = ':';
lp = sp = 2;
}
if (strpbrkW(shortpath + sp, wildcardsW))
{
SetLastError(ERROR_INVALID_NAME);
return 0;
}
while (shortpath[sp])
{
/* check for path delimiters and reproduce them */
if (shortpath[sp] == '\\' || shortpath[sp] == '/')
{
tmplongpath[lp++] = shortpath[sp++];
tmplongpath[lp] = 0; /* terminate string */
continue;
}
p = shortpath + sp;
for (; *p && *p != '/' && *p != '\\'; p++);
tmplen = p - (shortpath + sp);
lstrcpynW(tmplongpath + lp, shortpath + sp, tmplen + 1);
if (tmplongpath[lp] == '.')
{
if (tmplen == 1 || (tmplen == 2 && tmplongpath[lp + 1] == '.'))
{
lp += tmplen;
sp += tmplen;
continue;
}
}
/* Check if the file exists */
goit = FindFirstFileW(tmplongpath, &wfd);
if (goit == INVALID_HANDLE_VALUE)
{
TRACE("not found %s!\n", debugstr_w(tmplongpath));
SetLastError ( ERROR_FILE_NOT_FOUND );
return 0;
}
FindClose(goit);
is_legal_8dot3 = FALSE;
CheckNameLegalDOS8Dot3W(tmplongpath + lp, NULL, 0, NULL, &is_legal_8dot3);
/* Use the existing file name if it's a short name */
if (is_legal_8dot3)
strcpyW(tmplongpath + lp, wfd.cFileName);
lp += strlenW(tmplongpath + lp);
sp += tmplen;
}
tmplen = strlenW(shortpath) - 1;
if ((shortpath[tmplen] == '/' || shortpath[tmplen] == '\\') &&
(tmplongpath[lp - 1] != '/' && tmplongpath[lp - 1] != '\\'))
tmplongpath[lp++] = shortpath[tmplen];
tmplongpath[lp] = 0;
tmplen = strlenW(tmplongpath) + 1;
if (tmplen <= longlen)
{
strcpyW(longpath, tmplongpath);
TRACE("returning %s\n", debugstr_w(longpath));
tmplen--; /* length without 0 */
}
return tmplen;
}
/***********************************************************************
* GetLongPathNameA (KERNEL32.@)
*/
DWORD WINAPI GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
{
WCHAR *shortpathW;
WCHAR longpathW[MAX_PATH];
DWORD ret;
TRACE("%s\n", debugstr_a(shortpath));
if (!(shortpathW = FILE_name_AtoW( shortpath, FALSE ))) return 0;
ret = GetLongPathNameW(shortpathW, longpathW, MAX_PATH);
if (!ret) return 0;
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
return copy_filename_WtoA( longpathW, longpath, longlen );
}
/***********************************************************************
* GetShortPathNameW (KERNEL32.@)
*
* NOTES
* observed:
* longpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* longpath="" or invalid: LastError=ERROR_BAD_PATHNAME, ret=0
*
* more observations ( with NT 3.51 (WinDD) ):
* longpath <= 8.3 -> just copy longpath to shortpath
* longpath > 8.3 ->
* a) file does not exist -> return 0, LastError = ERROR_FILE_NOT_FOUND
* b) file does exist -> set the short filename.
* - trailing slashes are reproduced in the short name, even if the
* file is not a directory
* - the absolute/relative path of the short name is reproduced like found
* in the long name
* - longpath and shortpath may have the same address
* Peter Ganten, 1999
*/
DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortlen )
{
WCHAR *tmpshortpath;
LPCWSTR p;
DWORD sp = 0, lp = 0;
DWORD tmplen, buf_len;
WIN32_FIND_DATAW wfd;
HANDLE goit;
TRACE("%s,%p,%u\n", debugstr_w(longpath), shortpath, shortlen);
if (!longpath)
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
if (!longpath[0])
{
SetLastError(ERROR_BAD_PATHNAME);
return 0;
}
/* code below only removes characters from string, never adds, so this is
* the largest buffer that tmpshortpath will need to have */
buf_len = strlenW(longpath) + 1;
tmpshortpath = HeapAlloc(GetProcessHeap(), 0, buf_len * sizeof(WCHAR));
if (!tmpshortpath)
{
SetLastError(ERROR_OUTOFMEMORY);
return 0;
}
if (longpath[0] == '\\' && longpath[1] == '\\' && longpath[2] == '?' && longpath[3] == '\\')
{
memcpy(tmpshortpath, longpath, 4 * sizeof(WCHAR));
sp = lp = 4;
}
if (strpbrkW(longpath + lp, wildcardsW))
{
HeapFree(GetProcessHeap(), 0, tmpshortpath);
SetLastError(ERROR_INVALID_NAME);
return 0;
}
/* check for drive letter */
if (longpath[lp] != '/' && longpath[lp + 1] == ':' )
{
tmpshortpath[sp] = longpath[lp];
tmpshortpath[sp + 1] = ':';
sp += 2;
lp += 2;
}
while (longpath[lp])
{
/* check for path delimiters and reproduce them */
if (longpath[lp] == '\\' || longpath[lp] == '/')
{
tmpshortpath[sp++] = longpath[lp++];
tmpshortpath[sp] = 0; /* terminate string */
continue;
}
p = longpath + lp;
for (; *p && *p != '/' && *p != '\\'; p++);
tmplen = p - (longpath + lp);
lstrcpynW(tmpshortpath + sp, longpath + lp, tmplen + 1);
if (tmpshortpath[sp] == '.')
{
if (tmplen == 1 || (tmplen == 2 && tmpshortpath[sp + 1] == '.'))
{
sp += tmplen;
lp += tmplen;
continue;
}
}
/* Check if the file exists and use the existing short file name */
goit = FindFirstFileW(tmpshortpath, &wfd);
if (goit == INVALID_HANDLE_VALUE) goto notfound;
FindClose(goit);
/* In rare cases (like "a.abcd") short path may be longer than original path.
* Make sure we have enough space in temp buffer. */
if (wfd.cAlternateFileName[0] && tmplen < strlenW(wfd.cAlternateFileName))
{
WCHAR *new_buf;
buf_len += strlenW(wfd.cAlternateFileName) - tmplen;
new_buf = HeapReAlloc(GetProcessHeap(), 0, tmpshortpath, buf_len * sizeof(WCHAR));
if(!new_buf)
{
HeapFree(GetProcessHeap(), 0, tmpshortpath);
SetLastError(ERROR_OUTOFMEMORY);
return 0;
}
tmpshortpath = new_buf;
}
strcpyW(tmpshortpath + sp, wfd.cAlternateFileName[0] ? wfd.cAlternateFileName : wfd.cFileName);
sp += strlenW(tmpshortpath + sp);
lp += tmplen;
}
tmpshortpath[sp] = 0;
tmplen = strlenW(tmpshortpath) + 1;
if (tmplen <= shortlen)
{
strcpyW(shortpath, tmpshortpath);
TRACE("returning %s\n", debugstr_w(shortpath));
tmplen--; /* length without 0 */
}
HeapFree(GetProcessHeap(), 0, tmpshortpath);
return tmplen;
notfound:
HeapFree(GetProcessHeap(), 0, tmpshortpath);
TRACE("not found!\n" );
SetLastError ( ERROR_FILE_NOT_FOUND );
return 0;
}
/***********************************************************************
* GetShortPathNameA (KERNEL32.@)
@ -592,182 +256,6 @@ DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath, DWORD shortlen
return copy_filename_WtoA( shortpathW, shortpath, shortlen );
}
/***********************************************************************
* GetTempPathA (KERNEL32.@)
*/
DWORD WINAPI GetTempPathA( DWORD count, LPSTR path )
{
WCHAR pathW[MAX_PATH];
UINT ret;
ret = GetTempPathW(MAX_PATH, pathW);
if (!ret)
return 0;
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
return copy_filename_WtoA( pathW, path, count );
}
/***********************************************************************
* GetTempPathW (KERNEL32.@)
*/
DWORD WINAPI GetTempPathW( DWORD count, LPWSTR path )
{
static const WCHAR tmp[] = { 'T', 'M', 'P', 0 };
static const WCHAR temp[] = { 'T', 'E', 'M', 'P', 0 };
static const WCHAR userprofile[] = { 'U','S','E','R','P','R','O','F','I','L','E',0 };
WCHAR tmp_path[MAX_PATH];
UINT ret;
TRACE("%u,%p\n", count, path);
if (!(ret = GetEnvironmentVariableW( tmp, tmp_path, MAX_PATH )) &&
!(ret = GetEnvironmentVariableW( temp, tmp_path, MAX_PATH )) &&
!(ret = GetEnvironmentVariableW( userprofile, tmp_path, MAX_PATH )) &&
!(ret = GetWindowsDirectoryW( tmp_path, MAX_PATH )))
return 0;
if (ret > MAX_PATH)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
ret = GetFullPathNameW(tmp_path, MAX_PATH, tmp_path, NULL);
if (!ret) return 0;
if (ret > MAX_PATH - 2)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
if (tmp_path[ret-1] != '\\')
{
tmp_path[ret++] = '\\';
tmp_path[ret] = '\0';
}
ret++; /* add space for terminating 0 */
if (count >= ret)
{
lstrcpynW(path, tmp_path, count);
/* the remaining buffer must be zeroed up to 32766 bytes in XP or 32767
* bytes after it, we will assume the > XP behavior for now */
memset(path + ret, 0, (min(count, 32767) - ret) * sizeof(WCHAR));
ret--; /* return length without 0 */
}
else if (count)
{
/* the buffer must be cleared if contents will not fit */
memset(path, 0, count * sizeof(WCHAR));
}
TRACE("returning %u, %s\n", ret, debugstr_w(path));
return ret;
}
/***********************************************************************
* GetTempFileNameA (KERNEL32.@)
*/
UINT WINAPI GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer)
{
WCHAR *pathW, *prefixW = NULL;
WCHAR bufferW[MAX_PATH];
UINT ret;
if (!(pathW = FILE_name_AtoW( path, FALSE ))) return 0;
if (prefix && !(prefixW = FILE_name_AtoW( prefix, TRUE ))) return 0;
ret = GetTempFileNameW(pathW, prefixW, unique, bufferW);
if (ret) FILE_name_WtoA( bufferW, -1, buffer, MAX_PATH );
HeapFree( GetProcessHeap(), 0, prefixW );
return ret;
}
/***********************************************************************
* GetTempFileNameW (KERNEL32.@)
*/
UINT WINAPI GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR buffer )
{
static const WCHAR formatW[] = {'%','x','.','t','m','p',0};
int i;
LPWSTR p;
DWORD attr;
if ( !path || !buffer )
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
/* 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)
for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++;
unique &= 0xffff;
if (unique) sprintfW( p, formatW, unique );
else
{
/* get a "random" unique number and try to create the file */
HANDLE handle;
UINT num = NtGetTickCount() & 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
{
sprintfW( p, formatW, unique );
handle = CreateFileW( buffer, GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
if (handle != INVALID_HANDLE_VALUE)
{ /* We created it */
TRACE("created %s\n", debugstr_w(buffer) );
CloseHandle( handle );
last = unique;
break;
}
if (GetLastError() != ERROR_FILE_EXISTS &&
GetLastError() != ERROR_SHARING_VIOLATION)
break; /* No need to go on */
if (!(++unique & 0xffff)) unique = 1;
} while (unique != num);
}
TRACE("returning %s\n", debugstr_w(buffer) );
return unique;
}
/***********************************************************************
* get_path_safe_mode
*/
@ -1686,77 +1174,6 @@ BOOL WINAPI RemoveDirectoryA( LPCSTR path )
}
/***********************************************************************
* GetCurrentDirectoryW (KERNEL32.@)
*/
UINT WINAPI GetCurrentDirectoryW( UINT buflen, LPWSTR buf )
{
return RtlGetCurrentDirectory_U( buflen * sizeof(WCHAR), buf ) / sizeof(WCHAR);
}
/***********************************************************************
* GetCurrentDirectoryA (KERNEL32.@)
*/
UINT WINAPI GetCurrentDirectoryA( UINT buflen, LPSTR buf )
{
WCHAR bufferW[MAX_PATH];
DWORD ret;
if (buflen && buf && ((ULONG_PTR)buf >> 16) == 0)
{
/* Win9x catches access violations here, returning zero.
* This behaviour resulted in some people not noticing
* that they got the argument order wrong. So let's be
* nice and fail gracefully if buf is invalid and looks
* more like a buflen. */
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
ret = RtlGetCurrentDirectory_U( sizeof(bufferW), bufferW );
if (!ret) return 0;
if (ret > sizeof(bufferW))
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
return 0;
}
return copy_filename_WtoA( bufferW, buf, buflen );
}
/***********************************************************************
* SetCurrentDirectoryW (KERNEL32.@)
*/
BOOL WINAPI SetCurrentDirectoryW( LPCWSTR dir )
{
UNICODE_STRING dirW;
NTSTATUS status;
RtlInitUnicodeString( &dirW, dir );
status = RtlSetCurrentDirectory_U( &dirW );
if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/***********************************************************************
* SetCurrentDirectoryA (KERNEL32.@)
*/
BOOL WINAPI SetCurrentDirectoryA( LPCSTR dir )
{
WCHAR *dirW;
UNICODE_STRING strW;
NTSTATUS status;
if (!(dirW = FILE_name_AtoW( dir, FALSE ))) return FALSE;
RtlInitUnicodeString( &strW, dirW );
status = RtlSetCurrentDirectory_U( &strW );
if (status != STATUS_SUCCESS) SetLastError( RtlNtStatusToDosError(status) );
return !status;
}
/***********************************************************************
* GetSystemDirectoryW (KERNEL32.@)
*
@ -1838,42 +1255,6 @@ BOOLEAN WINAPI Wow64EnableWow64FsRedirection( BOOLEAN enable )
}
/***********************************************************************
* NeedCurrentDirectoryForExePathW (KERNEL32.@)
*/
BOOL WINAPI NeedCurrentDirectoryForExePathW( LPCWSTR name )
{
static const WCHAR env_name[] = {'N','o','D','e','f','a','u','l','t',
'C','u','r','r','e','n','t',
'D','i','r','e','c','t','o','r','y',
'I','n','E','x','e','P','a','t','h',0};
WCHAR env_val;
TRACE("(%s)\n", debugstr_w(name));
if (strchrW(name, '\\'))
return TRUE;
/* Check the existence of the variable, not value */
if (!GetEnvironmentVariableW( env_name, &env_val, 1 ))
return TRUE;
return FALSE;
}
/***********************************************************************
* NeedCurrentDirectoryForExePathA (KERNEL32.@)
*/
BOOL WINAPI NeedCurrentDirectoryForExePathA( LPCSTR name )
{
WCHAR *nameW;
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return TRUE;
return NeedCurrentDirectoryForExePathW( nameW );
}
/***********************************************************************
* wine_get_unix_file_name (KERNEL32.@) Not a Windows API
*

View File

@ -614,6 +614,45 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetCompressedFileSizeW( LPCWSTR name, LPDWORD siz
}
/***********************************************************************
* GetCurrentDirectoryA (kernelbase.@)
*/
UINT WINAPI DECLSPEC_HOTPATCH GetCurrentDirectoryA( UINT buflen, LPSTR buf )
{
WCHAR bufferW[MAX_PATH];
DWORD ret;
if (buflen && buf && ((ULONG_PTR)buf >> 16) == 0)
{
/* Win9x catches access violations here, returning zero.
* This behaviour resulted in some people not noticing
* that they got the argument order wrong. So let's be
* nice and fail gracefully if buf is invalid and looks
* more like a buflen. */
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
ret = RtlGetCurrentDirectory_U( sizeof(bufferW), bufferW );
if (!ret) return 0;
if (ret > sizeof(bufferW))
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
return copy_filename_WtoA( bufferW, buf, buflen );
}
/***********************************************************************
* GetCurrentDirectoryW (kernelbase.@)
*/
UINT WINAPI DECLSPEC_HOTPATCH GetCurrentDirectoryW( UINT buflen, LPWSTR buf )
{
return RtlGetCurrentDirectory_U( buflen * sizeof(WCHAR), buf ) / sizeof(WCHAR);
}
/**************************************************************************
* GetFileAttributesA (kernelbase.@)
*/
@ -725,6 +764,308 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetFileAttributesExW( LPCWSTR name, GET_FILEEX_INF
}
/***********************************************************************
* GetFullPathNameA (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetFullPathNameA( LPCSTR name, DWORD len, LPSTR buffer, LPSTR *lastpart )
{
WCHAR *nameW;
WCHAR bufferW[MAX_PATH], *lastpartW = NULL;
DWORD ret;
if (!(nameW = file_name_AtoW( name, FALSE ))) return 0;
ret = GetFullPathNameW( nameW, MAX_PATH, bufferW, &lastpartW );
if (!ret) return 0;
if (ret > MAX_PATH)
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
ret = copy_filename_WtoA( bufferW, buffer, len );
if (ret < len && lastpart)
{
if (lastpartW)
*lastpart = buffer + file_name_WtoA( bufferW, lastpartW - bufferW, NULL, 0 );
else
*lastpart = NULL;
}
return ret;
}
/***********************************************************************
* GetFullPathNameW (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetFullPathNameW( LPCWSTR name, DWORD len, LPWSTR buffer, LPWSTR *lastpart )
{
return RtlGetFullPathName_U( name, len * sizeof(WCHAR), buffer, lastpart ) / sizeof(WCHAR);
}
/***********************************************************************
* GetLongPathNameA (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
{
WCHAR *shortpathW;
WCHAR longpathW[MAX_PATH];
DWORD ret;
TRACE( "%s\n", debugstr_a( shortpath ));
if (!(shortpathW = file_name_AtoW( shortpath, FALSE ))) return 0;
ret = GetLongPathNameW( shortpathW, longpathW, MAX_PATH );
if (!ret) return 0;
if (ret > MAX_PATH)
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
return copy_filename_WtoA( longpathW, longpath, longlen );
}
/***********************************************************************
* GetLongPathNameW (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetLongPathNameW( LPCWSTR shortpath, LPWSTR longpath, DWORD longlen )
{
static const WCHAR wildcardsW[] = {'*','?',0};
WCHAR tmplongpath[1024];
DWORD sp = 0, lp = 0, tmplen;
WIN32_FIND_DATAW wfd;
UNICODE_STRING nameW;
LPCWSTR p;
HANDLE handle;
TRACE("%s,%p,%u\n", debugstr_w(shortpath), longpath, longlen);
if (!shortpath)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (!shortpath[0])
{
SetLastError( ERROR_PATH_NOT_FOUND );
return 0;
}
if (shortpath[0] == '\\' && shortpath[1] == '\\')
{
FIXME( "UNC pathname %s\n", debugstr_w(shortpath) );
tmplen = lstrlenW( shortpath );
if (tmplen < longlen)
{
if (longpath != shortpath) lstrcpyW( longpath, shortpath );
return tmplen;
}
return tmplen + 1;
}
/* check for drive letter */
if (shortpath[0] != '/' && shortpath[1] == ':' )
{
tmplongpath[0] = shortpath[0];
tmplongpath[1] = ':';
lp = sp = 2;
}
if (wcspbrk( shortpath + sp, wildcardsW ))
{
SetLastError( ERROR_INVALID_NAME );
return 0;
}
while (shortpath[sp])
{
/* check for path delimiters and reproduce them */
if (shortpath[sp] == '\\' || shortpath[sp] == '/')
{
tmplongpath[lp++] = shortpath[sp++];
tmplongpath[lp] = 0; /* terminate string */
continue;
}
for (p = shortpath + sp; *p && *p != '/' && *p != '\\'; p++);
tmplen = p - (shortpath + sp);
lstrcpynW( tmplongpath + lp, shortpath + sp, tmplen + 1 );
if (tmplongpath[lp] == '.')
{
if (tmplen == 1 || (tmplen == 2 && tmplongpath[lp + 1] == '.'))
{
lp += tmplen;
sp += tmplen;
continue;
}
}
/* Check if the file exists */
handle = FindFirstFileW( tmplongpath, &wfd );
if (handle == INVALID_HANDLE_VALUE)
{
TRACE( "not found %s\n", debugstr_w( tmplongpath ));
SetLastError ( ERROR_FILE_NOT_FOUND );
return 0;
}
FindClose( handle );
/* Use the existing file name if it's a short name */
RtlInitUnicodeString( &nameW, tmplongpath + lp );
if (RtlIsNameLegalDOS8Dot3( &nameW, NULL, NULL )) lstrcpyW( tmplongpath + lp, wfd.cFileName );
lp += lstrlenW( tmplongpath + lp );
sp += tmplen;
}
tmplen = lstrlenW( shortpath ) - 1;
if ((shortpath[tmplen] == '/' || shortpath[tmplen] == '\\') &&
(tmplongpath[lp - 1] != '/' && tmplongpath[lp - 1] != '\\'))
tmplongpath[lp++] = shortpath[tmplen];
tmplongpath[lp] = 0;
tmplen = lstrlenW( tmplongpath ) + 1;
if (tmplen <= longlen)
{
lstrcpyW( longpath, tmplongpath );
TRACE("returning %s\n", debugstr_w( longpath ));
tmplen--; /* length without 0 */
}
return tmplen;
}
/***********************************************************************
* GetShortPathNameW (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortlen )
{
static const WCHAR wildcardsW[] = {'*','?',0};
WIN32_FIND_DATAW wfd;
WCHAR *tmpshortpath;
HANDLE handle;
LPCWSTR p;
DWORD sp = 0, lp = 0, tmplen, buf_len;
TRACE( "%s,%p,%u\n", debugstr_w(longpath), shortpath, shortlen );
if (!longpath)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (!longpath[0])
{
SetLastError( ERROR_BAD_PATHNAME );
return 0;
}
/* code below only removes characters from string, never adds, so this is
* the largest buffer that tmpshortpath will need to have */
buf_len = lstrlenW(longpath) + 1;
tmpshortpath = HeapAlloc( GetProcessHeap(), 0, buf_len * sizeof(WCHAR) );
if (!tmpshortpath)
{
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
if (longpath[0] == '\\' && longpath[1] == '\\' && longpath[2] == '?' && longpath[3] == '\\')
{
memcpy( tmpshortpath, longpath, 4 * sizeof(WCHAR) );
sp = lp = 4;
}
if (wcspbrk( longpath + lp, wildcardsW ))
{
HeapFree( GetProcessHeap(), 0, tmpshortpath );
SetLastError( ERROR_INVALID_NAME );
return 0;
}
/* check for drive letter */
if (longpath[lp] != '/' && longpath[lp + 1] == ':' )
{
tmpshortpath[sp] = longpath[lp];
tmpshortpath[sp + 1] = ':';
sp += 2;
lp += 2;
}
while (longpath[lp])
{
/* check for path delimiters and reproduce them */
if (longpath[lp] == '\\' || longpath[lp] == '/')
{
tmpshortpath[sp++] = longpath[lp++];
tmpshortpath[sp] = 0; /* terminate string */
continue;
}
p = longpath + lp;
for (; *p && *p != '/' && *p != '\\'; p++);
tmplen = p - (longpath + lp);
lstrcpynW( tmpshortpath + sp, longpath + lp, tmplen + 1 );
if (tmpshortpath[sp] == '.')
{
if (tmplen == 1 || (tmplen == 2 && tmpshortpath[sp + 1] == '.'))
{
sp += tmplen;
lp += tmplen;
continue;
}
}
/* Check if the file exists and use the existing short file name */
handle = FindFirstFileW( tmpshortpath, &wfd );
if (handle == INVALID_HANDLE_VALUE) goto notfound;
FindClose( handle );
/* In rare cases (like "a.abcd") short path may be longer than original path.
* Make sure we have enough space in temp buffer. */
if (wfd.cAlternateFileName[0] && tmplen < lstrlenW(wfd.cAlternateFileName))
{
WCHAR *new_buf;
buf_len += lstrlenW( wfd.cAlternateFileName ) - tmplen;
new_buf = HeapReAlloc( GetProcessHeap(), 0, tmpshortpath, buf_len * sizeof(WCHAR) );
if(!new_buf)
{
HeapFree( GetProcessHeap(), 0, tmpshortpath );
SetLastError( ERROR_OUTOFMEMORY );
return 0;
}
tmpshortpath = new_buf;
}
lstrcpyW( tmpshortpath + sp, wfd.cAlternateFileName[0] ? wfd.cAlternateFileName : wfd.cFileName );
sp += lstrlenW( tmpshortpath + sp );
lp += tmplen;
}
tmpshortpath[sp] = 0;
tmplen = lstrlenW( tmpshortpath ) + 1;
if (tmplen <= shortlen)
{
lstrcpyW( shortpath, tmpshortpath );
TRACE( "returning %s\n", debugstr_w( shortpath ));
tmplen--; /* length without 0 */
}
HeapFree( GetProcessHeap(), 0, tmpshortpath );
return tmplen;
notfound:
HeapFree( GetProcessHeap(), 0, tmpshortpath );
TRACE( "not found\n" );
SetLastError( ERROR_FILE_NOT_FOUND );
return 0;
}
/***********************************************************************
* GetSystemDirectoryA (kernelbase.@)
*/
@ -767,6 +1108,166 @@ UINT WINAPI DECLSPEC_HOTPATCH GetSystemWindowsDirectoryW( LPWSTR path, UINT coun
}
/***********************************************************************
* GetTempFileNameA (kernelbase.@)
*/
UINT WINAPI DECLSPEC_HOTPATCH GetTempFileNameA( LPCSTR path, LPCSTR prefix, UINT unique, LPSTR buffer )
{
WCHAR *pathW, *prefixW = NULL;
WCHAR bufferW[MAX_PATH];
UINT ret;
if (!(pathW = file_name_AtoW( path, FALSE ))) return 0;
if (prefix && !(prefixW = file_name_AtoW( prefix, TRUE ))) return 0;
ret = GetTempFileNameW( pathW, prefixW, unique, bufferW );
if (ret) file_name_WtoA( bufferW, -1, buffer, MAX_PATH );
HeapFree( GetProcessHeap(), 0, prefixW );
return ret;
}
/***********************************************************************
* GetTempFileNameW (kernelbase.@)
*/
UINT WINAPI DECLSPEC_HOTPATCH GetTempFileNameW( LPCWSTR path, LPCWSTR prefix, UINT unique, LPWSTR buffer )
{
static const WCHAR formatW[] = {'%','x','.','t','m','p',0};
int i;
LPWSTR p;
DWORD attr;
if (!path || !buffer)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
/* 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;
}
lstrcpyW( buffer, path );
p = buffer + lstrlenW(buffer);
/* add a \, if there isn't one */
if ((p == buffer) || (p[-1] != '\\')) *p++ = '\\';
if (prefix) for (i = 3; (i > 0) && (*prefix); i--) *p++ = *prefix++;
unique &= 0xffff;
if (unique) swprintf( p, MAX_PATH - (p - buffer), formatW, unique );
else
{
/* get a "random" unique number and try to create the file */
HANDLE handle;
UINT num = NtGetTickCount() & 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
{
swprintf( p, MAX_PATH - (p - buffer), formatW, unique );
handle = CreateFileW( buffer, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
if (handle != INVALID_HANDLE_VALUE)
{ /* We created it */
CloseHandle( handle );
last = unique;
break;
}
if (GetLastError() != ERROR_FILE_EXISTS && GetLastError() != ERROR_SHARING_VIOLATION)
break; /* No need to go on */
if (!(++unique & 0xffff)) unique = 1;
} while (unique != num);
}
TRACE( "returning %s\n", debugstr_w( buffer ));
return unique;
}
/***********************************************************************
* GetTempPathA (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetTempPathA( DWORD count, LPSTR path )
{
WCHAR pathW[MAX_PATH];
UINT ret;
if (!(ret = GetTempPathW( MAX_PATH, pathW ))) return 0;
if (ret > MAX_PATH)
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
return copy_filename_WtoA( pathW, path, count );
}
/***********************************************************************
* GetTempPathW (kernelbase.@)
*/
DWORD WINAPI DECLSPEC_HOTPATCH GetTempPathW( DWORD count, LPWSTR path )
{
static const WCHAR tmp[] = { 'T','M','P',0 };
static const WCHAR temp[] = { 'T','E','M','P',0 };
static const WCHAR userprofile[] = { 'U','S','E','R','P','R','O','F','I','L','E',0 };
WCHAR tmp_path[MAX_PATH];
UINT ret;
if (!(ret = GetEnvironmentVariableW( tmp, tmp_path, MAX_PATH )) &&
!(ret = GetEnvironmentVariableW( temp, tmp_path, MAX_PATH )) &&
!(ret = GetEnvironmentVariableW( userprofile, tmp_path, MAX_PATH )) &&
!(ret = GetWindowsDirectoryW( tmp_path, MAX_PATH )))
return 0;
if (ret > MAX_PATH)
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
ret = GetFullPathNameW( tmp_path, MAX_PATH, tmp_path, NULL );
if (!ret) return 0;
if (ret > MAX_PATH - 2)
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return 0;
}
if (tmp_path[ret-1] != '\\')
{
tmp_path[ret++] = '\\';
tmp_path[ret] = '\0';
}
ret++; /* add space for terminating 0 */
if (count >= ret)
{
lstrcpynW( path, tmp_path, count );
/* the remaining buffer must be zeroed up to 32766 bytes in XP or 32767
* bytes after it, we will assume the > XP behavior for now */
memset( path + ret, 0, (min(count, 32767) - ret) * sizeof(WCHAR) );
ret--; /* return length without 0 */
}
else if (count)
{
/* the buffer must be cleared if contents will not fit */
memset( path, 0, count * sizeof(WCHAR) );
}
TRACE( "returning %u, %s\n", ret, debugstr_w( path ));
return ret;
}
/***********************************************************************
* GetWindowsDirectoryA (kernelbase.@)
*/
@ -791,6 +1292,61 @@ UINT WINAPI DECLSPEC_HOTPATCH GetWindowsDirectoryW( LPWSTR path, UINT count )
}
/***********************************************************************
* NeedCurrentDirectoryForExePathA (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH NeedCurrentDirectoryForExePathA( LPCSTR name )
{
WCHAR *nameW;
if (!(nameW = file_name_AtoW( name, FALSE ))) return TRUE;
return NeedCurrentDirectoryForExePathW( nameW );
}
/***********************************************************************
* NeedCurrentDirectoryForExePathW (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH NeedCurrentDirectoryForExePathW( LPCWSTR name )
{
static const WCHAR env_name[] = {'N','o','D','e','f','a','u','l','t',
'C','u','r','r','e','n','t',
'D','i','r','e','c','t','o','r','y',
'I','n','E','x','e','P','a','t','h',0};
WCHAR env_val;
if (wcschr( name, '\\' )) return TRUE;
/* check the existence of the variable, not value */
return !GetEnvironmentVariableW( env_name, &env_val, 1 );
}
/***********************************************************************
* SetCurrentDirectoryA (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetCurrentDirectoryA( LPCSTR dir )
{
WCHAR *dirW;
UNICODE_STRING strW;
if (!(dirW = file_name_AtoW( dir, FALSE ))) return FALSE;
RtlInitUnicodeString( &strW, dirW );
return set_ntstatus( RtlSetCurrentDirectory_U( &strW ));
}
/***********************************************************************
* SetCurrentDirectoryW (kernelbase.@)
*/
BOOL WINAPI DECLSPEC_HOTPATCH SetCurrentDirectoryW( LPCWSTR dir )
{
UNICODE_STRING dirW;
RtlInitUnicodeString( &dirW, dir );
return set_ntstatus( RtlSetCurrentDirectory_U( &dirW ));
}
/**************************************************************************
* SetFileApisToANSI (kernelbase.@)
*/

View File

@ -452,8 +452,8 @@
@ stdcall GetCurrencyFormatW(long long wstr ptr ptr long) kernel32.GetCurrencyFormatW
@ stdcall GetCurrentActCtx(ptr)
# @ stub GetCurrentApplicationUserModelId
@ stdcall GetCurrentDirectoryA(long ptr) kernel32.GetCurrentDirectoryA
@ stdcall GetCurrentDirectoryW(long ptr) kernel32.GetCurrentDirectoryW
@ stdcall GetCurrentDirectoryA(long ptr)
@ stdcall GetCurrentDirectoryW(long ptr)
# @ stub GetCurrentPackageApplicationContext
# @ stub GetCurrentPackageApplicationResourcesContext
# @ stub GetCurrentPackageContext
@ -526,8 +526,8 @@
@ stdcall GetFileVersionInfoW(wstr long long ptr)
@ stdcall GetFinalPathNameByHandleA(long ptr long long) kernel32.GetFinalPathNameByHandleA
@ stdcall GetFinalPathNameByHandleW(long ptr long long) kernel32.GetFinalPathNameByHandleW
@ stdcall GetFullPathNameA(str long ptr ptr) kernel32.GetFullPathNameA
@ stdcall GetFullPathNameW(wstr long ptr ptr) kernel32.GetFullPathNameW
@ stdcall GetFullPathNameA(str long ptr ptr)
@ stdcall GetFullPathNameW(wstr long ptr ptr)
# @ stub GetGPOListInternalA
# @ stub GetGPOListInternalW
@ stdcall GetGeoInfoW(long long ptr long long) kernel32.GetGeoInfoW
@ -549,8 +549,8 @@
@ stdcall GetLogicalDrives() kernel32.GetLogicalDrives
@ stdcall GetLogicalProcessorInformation(ptr ptr) kernel32.GetLogicalProcessorInformation
@ stdcall GetLogicalProcessorInformationEx(long ptr ptr) kernel32.GetLogicalProcessorInformationEx
@ stdcall GetLongPathNameA(str long long) kernel32.GetLongPathNameA
@ stdcall GetLongPathNameW(wstr long long) kernel32.GetLongPathNameW
@ stdcall GetLongPathNameA(str long long)
@ stdcall GetLongPathNameW(wstr long long)
# @ stub GetMappedFileNameA
# @ stub GetMappedFileNameW
# @ stub GetMemoryErrorHandlingCapabilities
@ -658,7 +658,7 @@
@ stdcall GetSecurityDescriptorSacl(ptr ptr ptr ptr)
# @ stub GetSerializedAtomBytes
# @ stub GetSharedLocalFolder
@ stdcall GetShortPathNameW(wstr ptr long) kernel32.GetShortPathNameW
@ stdcall GetShortPathNameW(wstr ptr long)
@ stdcall GetSidIdentifierAuthority(ptr)
@ stdcall GetSidLengthRequired(long)
@ stdcall GetSidSubAuthority(ptr long)
@ -707,10 +707,10 @@
@ stdcall GetSystemWow64DirectoryA(ptr long) kernel32.GetSystemWow64DirectoryA
@ stdcall GetSystemWow64DirectoryW(ptr long) kernel32.GetSystemWow64DirectoryW
# @ stub GetTargetPlatformContext
@ stdcall GetTempFileNameA(str str long ptr) kernel32.GetTempFileNameA
@ stdcall GetTempFileNameW(wstr wstr long ptr) kernel32.GetTempFileNameW
@ stdcall GetTempPathA(long ptr) kernel32.GetTempPathA
@ stdcall GetTempPathW(long ptr) kernel32.GetTempPathW
@ stdcall GetTempFileNameA(str str long ptr)
@ stdcall GetTempFileNameW(wstr wstr long ptr)
@ stdcall GetTempPathA(long ptr)
@ stdcall GetTempPathW(long ptr)
@ stdcall GetThreadContext(long ptr)
# @ stub GetThreadDescription
@ stdcall GetThreadErrorMode()
@ -961,8 +961,8 @@
@ stdcall MultiByteToWideChar(long long str long ptr long) kernel32.MultiByteToWideChar
# @ stub NamedPipeEventEnum
# @ stub NamedPipeEventSelect
@ stdcall NeedCurrentDirectoryForExePathA(str) kernel32.NeedCurrentDirectoryForExePathA
@ stdcall NeedCurrentDirectoryForExePathW(wstr) kernel32.NeedCurrentDirectoryForExePathW
@ stdcall NeedCurrentDirectoryForExePathA(str)
@ stdcall NeedCurrentDirectoryForExePathW(wstr)
@ stub NlsCheckPolicy
@ stub NlsDispatchAnsiEnumProc
@ stub NlsEventDataDescCreate
@ -1418,8 +1418,8 @@
@ stdcall SetConsoleTitleW(wstr)
@ stdcall SetConsoleWindowInfo(long long ptr)
@ stdcall SetCriticalSectionSpinCount(ptr long) ntdll.RtlSetCriticalSectionSpinCount
@ stdcall SetCurrentDirectoryA(str) kernel32.SetCurrentDirectoryA
@ stdcall SetCurrentDirectoryW(wstr) kernel32.SetCurrentDirectoryW
@ stdcall SetCurrentDirectoryA(str)
@ stdcall SetCurrentDirectoryW(wstr)
@ stdcall SetDefaultDllDirectories(long) kernel32.SetDefaultDllDirectories
# @ stub SetDynamicTimeZoneInformation
@ stdcall SetEndOfFile(long)