kernel32: Move some path functions to kernelbase.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5f10545b19
commit
e3e1bede1b
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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.@)
|
||||
*/
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue