mirror of
https://github.com/reactos/reactos.git
synced 2024-08-30 15:18:33 +00:00
- Rewrite SearchPathW (based on Wine code). It fixes regression in mysql
svn path=/trunk/; revision=42003
This commit is contained in:
parent
6324272e80
commit
f86de98c40
|
@ -954,183 +954,102 @@ Cleanup:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* ContainsPath (Wine name: contains_pathW)
|
||||||
|
*
|
||||||
|
* Check if the file name contains a path; helper for SearchPathW.
|
||||||
|
* A relative path is not considered a path unless it starts with ./ or ../
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
BOOL
|
||||||
|
ContainsPath(LPCWSTR name)
|
||||||
|
{
|
||||||
|
if (RtlDetermineDosPathNameType_U(name) != RtlPathTypeRelative) return TRUE;
|
||||||
|
if (name[0] != '.') return FALSE;
|
||||||
|
if (name[1] == '/' || name[1] == '\\') return TRUE;
|
||||||
|
return (name[1] == '.' && (name[2] == '/' || name[2] == '\\'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
DWORD
|
DWORD
|
||||||
WINAPI
|
WINAPI
|
||||||
SearchPathW (
|
SearchPathW(LPCWSTR lpPath,
|
||||||
LPCWSTR lpPath,
|
LPCWSTR lpFileName,
|
||||||
LPCWSTR lpFileName,
|
LPCWSTR lpExtension,
|
||||||
LPCWSTR lpExtension,
|
DWORD nBufferLength,
|
||||||
DWORD nBufferLength,
|
LPWSTR lpBuffer,
|
||||||
LPWSTR lpBuffer,
|
LPWSTR *lpFilePart)
|
||||||
LPWSTR *lpFilePart
|
|
||||||
)
|
|
||||||
/*
|
|
||||||
* FUNCTION: Searches for the specified file
|
|
||||||
* ARGUMENTS:
|
|
||||||
* lpPath = Points to a null-terminated string that specified the
|
|
||||||
* path to be searched. If this parameters is NULL then
|
|
||||||
* the following directories are searched
|
|
||||||
* The directory from which the application loaded
|
|
||||||
* The current directory
|
|
||||||
* The system directory
|
|
||||||
* The 16-bit system directory
|
|
||||||
* The windows directory
|
|
||||||
* The directories listed in the PATH environment
|
|
||||||
* variable
|
|
||||||
* lpFileName = Specifies the filename to search for
|
|
||||||
* lpExtension = Points to the null-terminated string that specifies
|
|
||||||
* an extension to be added to the filename when
|
|
||||||
* searching for the file. The first character of the
|
|
||||||
* filename extension must be a period (.). The
|
|
||||||
* extension is only added if the specified filename
|
|
||||||
* doesn't end with an extension
|
|
||||||
*
|
|
||||||
* If the filename extension is not required or if the
|
|
||||||
* filename contains an extension, this parameters can be
|
|
||||||
* NULL
|
|
||||||
* nBufferLength = The length in characters of the buffer for output
|
|
||||||
* lpBuffer = Points to the buffer for the valid path and filename of
|
|
||||||
* file found
|
|
||||||
* lpFilePart = Points to the last component of the valid path and
|
|
||||||
* filename
|
|
||||||
* RETURNS: On success, the length, in characters, of the string copied to the
|
|
||||||
* buffer
|
|
||||||
* On failure, zero.
|
|
||||||
*/
|
|
||||||
{
|
{
|
||||||
DWORD retCode = 0;
|
DWORD ret = 0;
|
||||||
ULONG pos, len;
|
|
||||||
PWCHAR EnvironmentBufferW = NULL;
|
|
||||||
PWCHAR AppPathW = NULL;
|
|
||||||
WCHAR Buffer;
|
|
||||||
BOOL HasExtension = FALSE, IsAbsolute = FALSE;
|
|
||||||
LPCWSTR p;
|
|
||||||
PWCHAR Name;
|
|
||||||
|
|
||||||
TRACE("SearchPath\n");
|
/* If the name contains an explicit path, ignore the path */
|
||||||
|
if (ContainsPath(lpFileName))
|
||||||
|
{
|
||||||
|
/* try first without extension */
|
||||||
|
if (RtlDoesFileExists_U(lpFileName))
|
||||||
|
return GetFullPathNameW(lpFileName, nBufferLength, lpBuffer, lpFilePart);
|
||||||
|
|
||||||
p = lpFileName + wcslen(lpFileName);
|
if (lpExtension)
|
||||||
while (lpFileName < p &&
|
|
||||||
L'\\' != *(p - 1) &&
|
|
||||||
L'/' != *(p - 1))
|
|
||||||
{
|
{
|
||||||
HasExtension = HasExtension || L'.' == *(p - 1);
|
LPCWSTR p = wcsrchr(lpFileName, '.');
|
||||||
if (p >= lpFileName && L'\\' == *(p-1))
|
if (p && !strchr((const char *)p, '/') && !wcschr( p, '\\' ))
|
||||||
{
|
lpExtension = NULL; /* Ignore the specified extension */
|
||||||
if (':' == *p)
|
|
||||||
IsAbsolute = TRUE;
|
|
||||||
}
|
|
||||||
p--;
|
|
||||||
}
|
}
|
||||||
if (IsAbsolute)
|
|
||||||
|
/* Allocate a buffer for the file name and extension */
|
||||||
|
if (lpExtension)
|
||||||
{
|
{
|
||||||
if (HasExtension || NULL == lpExtension)
|
LPWSTR tmp;
|
||||||
{
|
DWORD len = wcslen(lpFileName) + wcslen(lpExtension);
|
||||||
Name = (PWCHAR) lpFileName;
|
|
||||||
}
|
if (!(tmp = RtlAllocateHeap(RtlGetProcessHeap(), 0, (len + 1) * sizeof(WCHAR))))
|
||||||
else
|
{
|
||||||
{
|
SetLastError(ERROR_OUTOFMEMORY);
|
||||||
Name = RtlAllocateHeap(RtlGetProcessHeap(),
|
return 0;
|
||||||
HEAP_GENERATE_EXCEPTIONS,
|
}
|
||||||
(wcslen(lpFileName) + wcslen(lpExtension) + 1)
|
wcscpy(tmp, lpFileName);
|
||||||
* sizeof(WCHAR));
|
wcscat(tmp, lpExtension);
|
||||||
if (NULL == Name)
|
if (RtlDoesFileExists_U(tmp))
|
||||||
{
|
ret = GetFullPathNameW(tmp, nBufferLength, lpBuffer, lpFilePart);
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, tmp);
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
wcscat(wcscpy(Name, lpFileName), lpExtension);
|
else if (lpPath && lpPath[0]) /* search in the specified path */
|
||||||
}
|
{
|
||||||
if (RtlDoesFileExists_U(Name))
|
ret = RtlDosSearchPath_U(lpPath,
|
||||||
{
|
lpFileName,
|
||||||
retCode = RtlGetFullPathName_U (Name,
|
lpExtension,
|
||||||
nBufferLength * sizeof(WCHAR),
|
nBufferLength * sizeof(WCHAR),
|
||||||
lpBuffer,
|
lpBuffer,
|
||||||
lpFilePart);
|
lpFilePart) / sizeof(WCHAR);
|
||||||
}
|
}
|
||||||
if (Name != lpFileName)
|
else /* search in the default path */
|
||||||
{
|
{
|
||||||
RtlFreeHeap(GetProcessHeap(), 0, Name);
|
WCHAR *DllPath = GetDllLoadPath(NULL);
|
||||||
}
|
|
||||||
|
if (DllPath)
|
||||||
|
{
|
||||||
|
ret = RtlDosSearchPath_U(DllPath,
|
||||||
|
lpFileName,
|
||||||
|
lpExtension,
|
||||||
|
nBufferLength * sizeof(WCHAR),
|
||||||
|
lpBuffer,
|
||||||
|
lpFilePart) / sizeof(WCHAR);
|
||||||
|
RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (lpPath == NULL)
|
SetLastError(ERROR_OUTOFMEMORY);
|
||||||
{
|
return 0;
|
||||||
|
|
||||||
AppPathW = (PWCHAR) RtlAllocateHeap(RtlGetProcessHeap(),
|
|
||||||
HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
|
|
||||||
MAX_PATH * sizeof(WCHAR));
|
|
||||||
if (AppPathW == NULL)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
wcscat (AppPathW, NtCurrentPeb()->ProcessParameters->ImagePathName.Buffer);
|
|
||||||
|
|
||||||
len = wcslen (AppPathW);
|
|
||||||
|
|
||||||
while (len && AppPathW[len - 1] != L'\\')
|
|
||||||
len--;
|
|
||||||
|
|
||||||
if (len) AppPathW[len-1] = L'\0';
|
|
||||||
|
|
||||||
len = GetEnvironmentVariableW(L"PATH", &Buffer, 0);
|
|
||||||
len += 1 + GetCurrentDirectoryW(0, &Buffer);
|
|
||||||
len += 1 + GetSystemDirectoryW(&Buffer, 0);
|
|
||||||
len += 1 + GetWindowsDirectoryW(&Buffer, 0);
|
|
||||||
len += 1 + wcslen(AppPathW) * sizeof(WCHAR);
|
|
||||||
|
|
||||||
EnvironmentBufferW = (PWCHAR) RtlAllocateHeap(RtlGetProcessHeap(),
|
|
||||||
HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY,
|
|
||||||
len * sizeof(WCHAR));
|
|
||||||
if (EnvironmentBufferW == NULL)
|
|
||||||
{
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, AppPathW);
|
|
||||||
SetLastError(ERROR_OUTOFMEMORY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pos = GetCurrentDirectoryW(len, EnvironmentBufferW);
|
|
||||||
EnvironmentBufferW[pos++] = L';';
|
|
||||||
EnvironmentBufferW[pos] = 0;
|
|
||||||
pos += GetSystemDirectoryW(&EnvironmentBufferW[pos], len - pos);
|
|
||||||
EnvironmentBufferW[pos++] = L';';
|
|
||||||
EnvironmentBufferW[pos] = 0;
|
|
||||||
pos += GetWindowsDirectoryW(&EnvironmentBufferW[pos], len - pos);
|
|
||||||
EnvironmentBufferW[pos++] = L';';
|
|
||||||
EnvironmentBufferW[pos] = 0;
|
|
||||||
pos += GetEnvironmentVariableW(L"PATH", &EnvironmentBufferW[pos], len - pos);
|
|
||||||
EnvironmentBufferW[pos++] = L';';
|
|
||||||
EnvironmentBufferW[pos] = 0;
|
|
||||||
wcscat (EnvironmentBufferW, AppPathW);
|
|
||||||
|
|
||||||
RtlFreeHeap (RtlGetProcessHeap (),
|
|
||||||
0,
|
|
||||||
AppPathW);
|
|
||||||
|
|
||||||
lpPath = EnvironmentBufferW;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
retCode = RtlDosSearchPath_U ((PWCHAR)lpPath, (PWCHAR)lpFileName, (PWCHAR)lpExtension,
|
|
||||||
nBufferLength * sizeof(WCHAR), lpBuffer, lpFilePart);
|
|
||||||
|
|
||||||
if (EnvironmentBufferW != NULL)
|
|
||||||
{
|
|
||||||
RtlFreeHeap(GetProcessHeap(), 0, EnvironmentBufferW);
|
|
||||||
}
|
|
||||||
if (retCode == 0)
|
|
||||||
{
|
|
||||||
SetLastError(ERROR_FILE_NOT_FOUND);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return retCode / sizeof(WCHAR);
|
}
|
||||||
|
|
||||||
|
if (!ret) SetLastError(ERROR_FILE_NOT_FOUND);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -189,5 +189,8 @@ BasepMapFile(IN LPCWSTR lpApplicationName,
|
||||||
PCODEPAGE_ENTRY FASTCALL
|
PCODEPAGE_ENTRY FASTCALL
|
||||||
IntGetCodePageEntry(UINT CodePage);
|
IntGetCodePageEntry(UINT CodePage);
|
||||||
|
|
||||||
|
LPWSTR
|
||||||
|
GetDllLoadPath(LPCWSTR lpModule);
|
||||||
|
|
||||||
#endif /* ndef _KERNEL32_INCLUDE_KERNEL32_H */
|
#endif /* ndef _KERNEL32_INCLUDE_KERNEL32_H */
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ extern BOOLEAN InWindows;
|
||||||
* @remarks Returned pointer must be freed by caller.
|
* @remarks Returned pointer must be freed by caller.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
LPWSTR WINAPI
|
LPWSTR
|
||||||
GetDllLoadPath(LPCWSTR lpModule)
|
GetDllLoadPath(LPCWSTR lpModule)
|
||||||
{
|
{
|
||||||
ULONG Pos = 0, Length = 0;
|
ULONG Pos = 0, Length = 0;
|
||||||
|
|
Loading…
Reference in a new issue