Author: dchapyshev
Date: Fri Jul 17 15:24:07 2009
New Revision: 42003
URL:
http://svn.reactos.org/svn/reactos?rev=42003&view=rev
Log:
- Rewrite SearchPathW (based on Wine code). It fixes regression in mysql
Modified:
trunk/reactos/dll/win32/kernel32/file/dir.c
trunk/reactos/dll/win32/kernel32/include/kernel32.h
trunk/reactos/dll/win32/kernel32/misc/ldr.c
Modified: trunk/reactos/dll/win32/kernel32/file/dir.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/file/di…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/file/dir.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/file/dir.c [iso-8859-1] Fri Jul 17 15:24:07 2009
@@ -954,183 +954,102 @@
}
+/***********************************************************************
+ * 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
*/
DWORD
WINAPI
-SearchPathW (
- LPCWSTR lpPath,
- LPCWSTR lpFileName,
- LPCWSTR lpExtension,
- DWORD nBufferLength,
- LPWSTR lpBuffer,
- 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;
- ULONG pos, len;
- PWCHAR EnvironmentBufferW = NULL;
- PWCHAR AppPathW = NULL;
- WCHAR Buffer;
- BOOL HasExtension = FALSE, IsAbsolute = FALSE;
- LPCWSTR p;
- PWCHAR Name;
-
- TRACE("SearchPath\n");
-
- p = lpFileName + wcslen(lpFileName);
- while (lpFileName < p &&
- L'\\' != *(p - 1) &&
- L'/' != *(p - 1))
- {
- HasExtension = HasExtension || L'.' == *(p - 1);
- if (p >= lpFileName && L'\\' == *(p-1))
- {
- if (':' == *p)
- IsAbsolute = TRUE;
- }
- p--;
- }
- if (IsAbsolute)
- {
- if (HasExtension || NULL == lpExtension)
- {
- Name = (PWCHAR) lpFileName;
- }
- else
- {
- Name = RtlAllocateHeap(RtlGetProcessHeap(),
- HEAP_GENERATE_EXCEPTIONS,
- (wcslen(lpFileName) + wcslen(lpExtension)
+ 1)
- * sizeof(WCHAR));
- if (NULL == Name)
- {
- SetLastError(ERROR_OUTOFMEMORY);
- return 0;
- }
- wcscat(wcscpy(Name, lpFileName), lpExtension);
- }
- if (RtlDoesFileExists_U(Name))
- {
- retCode = RtlGetFullPathName_U (Name,
- nBufferLength * sizeof(WCHAR),
- lpBuffer,
- lpFilePart);
- }
- if (Name != lpFileName)
- {
- RtlFreeHeap(GetProcessHeap(), 0, Name);
- }
+SearchPathW(LPCWSTR lpPath,
+ LPCWSTR lpFileName,
+ LPCWSTR lpExtension,
+ DWORD nBufferLength,
+ LPWSTR lpBuffer,
+ LPWSTR *lpFilePart)
+{
+ DWORD ret = 0;
+
+ /* 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);
+
+ if (lpExtension)
+ {
+ LPCWSTR p = wcsrchr(lpFileName, '.');
+ if (p && !strchr((const char *)p, '/') && !wcschr( p,
'\\' ))
+ lpExtension = NULL; /* Ignore the specified extension */
+ }
+
+ /* Allocate a buffer for the file name and extension */
+ if (lpExtension)
+ {
+ LPWSTR tmp;
+ DWORD len = wcslen(lpFileName) + wcslen(lpExtension);
+
+ if (!(tmp = RtlAllocateHeap(RtlGetProcessHeap(), 0, (len + 1) *
sizeof(WCHAR))))
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return 0;
+ }
+ wcscpy(tmp, lpFileName);
+ wcscat(tmp, lpExtension);
+ if (RtlDoesFileExists_U(tmp))
+ ret = GetFullPathNameW(tmp, nBufferLength, lpBuffer, lpFilePart);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, tmp);
+ }
+ }
+ else if (lpPath && lpPath[0]) /* search in the specified path */
+ {
+ ret = RtlDosSearchPath_U(lpPath,
+ lpFileName,
+ lpExtension,
+ nBufferLength * sizeof(WCHAR),
+ lpBuffer,
+ lpFilePart) / sizeof(WCHAR);
+ }
+ else /* search in the default path */
+ {
+ WCHAR *DllPath = GetDllLoadPath(NULL);
+
+ if (DllPath)
+ {
+ ret = RtlDosSearchPath_U(DllPath,
+ lpFileName,
+ lpExtension,
+ nBufferLength * sizeof(WCHAR),
+ lpBuffer,
+ lpFilePart) / sizeof(WCHAR);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath);
}
else
{
- if (lpPath == NULL)
- {
-
- 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);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return 0;
+ }
+ }
+
+ if (!ret) SetLastError(ERROR_FILE_NOT_FOUND);
+
+ return ret;
}
/*
Modified: trunk/reactos/dll/win32/kernel32/include/kernel32.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/include…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/include/kernel32.h [iso-8859-1] Fri Jul 17 15:24:07
2009
@@ -189,5 +189,8 @@
PCODEPAGE_ENTRY FASTCALL
IntGetCodePageEntry(UINT CodePage);
+LPWSTR
+GetDllLoadPath(LPCWSTR lpModule);
+
#endif /* ndef _KERNEL32_INCLUDE_KERNEL32_H */
Modified: trunk/reactos/dll/win32/kernel32/misc/ldr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/ld…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/ldr.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/misc/ldr.c [iso-8859-1] Fri Jul 17 15:24:07 2009
@@ -31,7 +31,7 @@
* @remarks Returned pointer must be freed by caller.
*/
-LPWSTR WINAPI
+LPWSTR
GetDllLoadPath(LPCWSTR lpModule)
{
ULONG Pos = 0, Length = 0;