Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e3e1bede
Commit
e3e1bede
authored
Sep 17, 2019
by
Alexandre Julliard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Move some path functions to kernelbase.
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
5f10545b
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
586 additions
and
649 deletions
+586
-649
kernel32.spec
dlls/kernel32/kernel32.spec
+15
-15
path.c
dlls/kernel32/path.c
+0
-619
file.c
dlls/kernelbase/file.c
+556
-0
kernelbase.spec
dlls/kernelbase/kernelbase.spec
+15
-15
No files found.
dlls/kernel32/kernel32.spec
View file @
e3e1bede
...
...
@@ -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)
...
...
dlls/kernel32/path.c
View file @
e3e1bede
...
...
@@ -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
*/
...
...
@@ -1687,77 +1175,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.@)
*
* See comment for GetWindowsDirectoryA.
...
...
@@ -1839,42 +1256,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
*
* Return the full Unix file name for a given path.
...
...
dlls/kernelbase/file.c
View file @
e3e1bede
...
...
@@ -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.@)
*/
...
...
@@ -726,6 +765,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.@)
*/
UINT
WINAPI
DECLSPEC_HOTPATCH
GetSystemDirectoryA
(
LPSTR
path
,
UINT
count
)
...
...
@@ -768,6 +1109,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.@)
*/
UINT
WINAPI
DECLSPEC_HOTPATCH
GetWindowsDirectoryA
(
LPSTR
path
,
UINT
count
)
...
...
@@ -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.@)
*/
...
...
dlls/kernelbase/kernelbase.spec
View file @
e3e1bede
...
...
@@ -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)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment