kernel32: Move SearchPath functions to kernelbase.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
15bf3eee2c
commit
8d25965e12
|
@ -1324,8 +1324,8 @@
|
|||
@ stdcall -i386 -private -norelay SUnMapLS_IP_EBP_8() krnl386.exe16.SUnMapLS_IP_EBP_8
|
||||
@ stdcall -import ScrollConsoleScreenBufferA(long ptr ptr ptr ptr)
|
||||
@ stdcall -import ScrollConsoleScreenBufferW(long ptr ptr ptr ptr)
|
||||
@ stdcall SearchPathA(str str str long ptr ptr)
|
||||
@ stdcall SearchPathW(wstr wstr wstr long ptr ptr)
|
||||
@ stdcall -import SearchPathA(str str str long ptr ptr)
|
||||
@ stdcall -import SearchPathW(wstr wstr wstr long ptr ptr)
|
||||
@ stdcall SetCPGlobal(long)
|
||||
@ stdcall SetCalendarInfoA(long long long str)
|
||||
@ stdcall SetCalendarInfoW(long long long wstr)
|
||||
|
|
|
@ -254,300 +254,6 @@ DWORD WINAPI GetShortPathNameA( LPCSTR longpath, LPSTR shortpath, DWORD shortlen
|
|||
return copy_filename_WtoA( shortpathW, shortpath, shortlen );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* 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 inline BOOL contains_pathW (LPCWSTR name)
|
||||
{
|
||||
if (RtlDetermineDosPathNameType_U( name ) != RELATIVE_PATH) return TRUE;
|
||||
if (name[0] != '.') return FALSE;
|
||||
if (name[1] == '/' || name[1] == '\\') return TRUE;
|
||||
return (name[1] == '.' && (name[2] == '/' || name[2] == '\\'));
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* find_actctx_dllpath
|
||||
*
|
||||
* Find the path (if any) of the dll from the activation context.
|
||||
* Returned path doesn't include a name.
|
||||
*/
|
||||
static NTSTATUS find_actctx_dllpath(const WCHAR *libname, WCHAR **path)
|
||||
{
|
||||
static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\'};
|
||||
static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0};
|
||||
|
||||
ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info;
|
||||
ACTCTX_SECTION_KEYED_DATA data;
|
||||
UNICODE_STRING nameW;
|
||||
NTSTATUS status;
|
||||
SIZE_T needed, size = 1024;
|
||||
WCHAR *p;
|
||||
|
||||
RtlInitUnicodeString( &nameW, libname );
|
||||
data.cbSize = sizeof(data);
|
||||
status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
|
||||
ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||
&nameW, &data );
|
||||
if (status != STATUS_SUCCESS) return status;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!(info = HeapAlloc( GetProcessHeap(), 0, size )))
|
||||
{
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
status = RtlQueryInformationActivationContext( 0, data.hActCtx, &data.ulAssemblyRosterIndex,
|
||||
AssemblyDetailedInformationInActivationContext,
|
||||
info, size, &needed );
|
||||
if (status == STATUS_SUCCESS) break;
|
||||
if (status != STATUS_BUFFER_TOO_SMALL) goto done;
|
||||
HeapFree( GetProcessHeap(), 0, info );
|
||||
size = needed;
|
||||
/* restart with larger buffer */
|
||||
}
|
||||
|
||||
if (!info->lpAssemblyManifestPath || !info->lpAssemblyDirectoryName)
|
||||
{
|
||||
status = STATUS_SXS_KEY_NOT_FOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((p = strrchrW( info->lpAssemblyManifestPath, '\\' )))
|
||||
{
|
||||
DWORD dirlen = info->ulAssemblyDirectoryNameLength / sizeof(WCHAR);
|
||||
|
||||
p++;
|
||||
if (strncmpiW( p, info->lpAssemblyDirectoryName, dirlen ) || strcmpiW( p + dirlen, dotManifestW ))
|
||||
{
|
||||
/* manifest name does not match directory name, so it's not a global
|
||||
* windows/winsxs manifest; use the manifest directory name instead */
|
||||
dirlen = p - info->lpAssemblyManifestPath;
|
||||
needed = (dirlen + 1) * sizeof(WCHAR);
|
||||
if (!(*path = p = HeapAlloc( GetProcessHeap(), 0, needed )))
|
||||
{
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
memcpy( p, info->lpAssemblyManifestPath, dirlen * sizeof(WCHAR) );
|
||||
*(p + dirlen) = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
needed = (strlenW( DIR_Windows ) * sizeof(WCHAR) +
|
||||
sizeof(winsxsW) + info->ulAssemblyDirectoryNameLength + 2*sizeof(WCHAR));
|
||||
|
||||
if (!(*path = p = HeapAlloc( GetProcessHeap(), 0, needed )))
|
||||
{
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
strcpyW( p, DIR_Windows );
|
||||
p += strlenW(p);
|
||||
memcpy( p, winsxsW, sizeof(winsxsW) );
|
||||
p += ARRAY_SIZE( winsxsW );
|
||||
memcpy( p, info->lpAssemblyDirectoryName, info->ulAssemblyDirectoryNameLength );
|
||||
p += info->ulAssemblyDirectoryNameLength / sizeof(WCHAR);
|
||||
*p++ = '\\';
|
||||
*p = 0;
|
||||
done:
|
||||
HeapFree( GetProcessHeap(), 0, info );
|
||||
RtlReleaseActivationContext( data.hActCtx );
|
||||
return status;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* SearchPathW [KERNEL32.@]
|
||||
*
|
||||
* Searches for a specified file in the search path.
|
||||
*
|
||||
* PARAMS
|
||||
* path [I] Path to search (NULL means default)
|
||||
* name [I] Filename to search for.
|
||||
* ext [I] File extension to append to file name. The first
|
||||
* character must be a period. This parameter is
|
||||
* specified only if the filename given does not
|
||||
* contain an extension.
|
||||
* buflen [I] size of buffer, in characters
|
||||
* buffer [O] buffer for found filename
|
||||
* lastpart [O] address of pointer to last used character in
|
||||
* buffer (the final '\')
|
||||
*
|
||||
* RETURNS
|
||||
* Success: length of string copied into buffer, not including
|
||||
* terminating null character. If the filename found is
|
||||
* longer than the length of the buffer, the length of the
|
||||
* filename is returned.
|
||||
* Failure: Zero
|
||||
*
|
||||
* NOTES
|
||||
* If the file is not found, calls SetLastError(ERROR_FILE_NOT_FOUND)
|
||||
* (tested on NT 4.0)
|
||||
*/
|
||||
DWORD WINAPI SearchPathW( LPCWSTR path, LPCWSTR name, LPCWSTR ext, DWORD buflen,
|
||||
LPWSTR buffer, LPWSTR *lastpart )
|
||||
{
|
||||
DWORD ret = 0;
|
||||
|
||||
if (!name || !name[0])
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the name contains an explicit path, ignore the path */
|
||||
|
||||
if (contains_pathW(name))
|
||||
{
|
||||
/* try first without extension */
|
||||
if (RtlDoesFileExists_U( name ))
|
||||
return GetFullPathNameW( name, buflen, buffer, lastpart );
|
||||
|
||||
if (ext)
|
||||
{
|
||||
LPCWSTR p = strrchrW( name, '.' );
|
||||
if (p && !strchrW( p, '/' ) && !strchrW( p, '\\' ))
|
||||
ext = NULL; /* Ignore the specified extension */
|
||||
}
|
||||
|
||||
/* Allocate a buffer for the file name and extension */
|
||||
if (ext)
|
||||
{
|
||||
LPWSTR tmp;
|
||||
DWORD len = strlenW(name) + strlenW(ext);
|
||||
|
||||
if (!(tmp = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
SetLastError( ERROR_OUTOFMEMORY );
|
||||
return 0;
|
||||
}
|
||||
strcpyW( tmp, name );
|
||||
strcatW( tmp, ext );
|
||||
if (RtlDoesFileExists_U( tmp ))
|
||||
ret = GetFullPathNameW( tmp, buflen, buffer, lastpart );
|
||||
HeapFree( GetProcessHeap(), 0, tmp );
|
||||
}
|
||||
}
|
||||
else if (path && path[0]) /* search in the specified path */
|
||||
{
|
||||
ret = RtlDosSearchPath_U( path, name, ext, buflen * sizeof(WCHAR),
|
||||
buffer, lastpart ) / sizeof(WCHAR);
|
||||
}
|
||||
else /* search in active context and default path */
|
||||
{
|
||||
WCHAR *dll_path = NULL, *search = NULL;
|
||||
DWORD req_len, name_len;
|
||||
|
||||
req_len = name_len = strlenW(name);
|
||||
|
||||
if (strchrW( name, '.' )) ext = NULL;
|
||||
if (ext)
|
||||
{
|
||||
DWORD ext_len = strlenW(ext);
|
||||
|
||||
req_len += ext_len;
|
||||
name_len += ext_len;
|
||||
|
||||
search = HeapAlloc( GetProcessHeap(), 0, (name_len + ext_len + 1) * sizeof(WCHAR) );
|
||||
if (!search)
|
||||
{
|
||||
SetLastError( ERROR_OUTOFMEMORY );
|
||||
return 0;
|
||||
}
|
||||
strcpyW( search, name );
|
||||
strcatW( search, ext );
|
||||
name = search;
|
||||
|
||||
/* now that we have combined name we don't need extension any more */
|
||||
}
|
||||
|
||||
/* When file is found with activation context no attempt is made
|
||||
to check if it's really exist, path is returned only basing on context info. */
|
||||
if (find_actctx_dllpath( name, &dll_path ) == STATUS_SUCCESS)
|
||||
{
|
||||
DWORD path_len;
|
||||
|
||||
path_len = strlenW(dll_path);
|
||||
req_len += path_len;
|
||||
|
||||
if (lastpart) *lastpart = NULL;
|
||||
|
||||
/* count null termination char too */
|
||||
if (req_len + 1 <= buflen)
|
||||
{
|
||||
memcpy( buffer, dll_path, path_len * sizeof(WCHAR) );
|
||||
memcpy( &buffer[path_len], name, name_len * sizeof(WCHAR) );
|
||||
buffer[req_len] = 0;
|
||||
if (lastpart) *lastpart = buffer + path_len;
|
||||
ret = req_len;
|
||||
}
|
||||
else
|
||||
ret = req_len + 1;
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, dll_path );
|
||||
}
|
||||
else if (!RtlGetSearchPath( &dll_path ))
|
||||
{
|
||||
ret = RtlDosSearchPath_U( dll_path, name, NULL, buflen * sizeof(WCHAR),
|
||||
buffer, lastpart ) / sizeof(WCHAR);
|
||||
RtlReleasePath( dll_path );
|
||||
}
|
||||
HeapFree( GetProcessHeap(), 0, search );
|
||||
}
|
||||
|
||||
if (!ret) SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
else TRACE( "found %s\n", debugstr_w(buffer) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SearchPathA (KERNEL32.@)
|
||||
*
|
||||
* See SearchPathW.
|
||||
*/
|
||||
DWORD WINAPI SearchPathA( LPCSTR path, LPCSTR name, LPCSTR ext,
|
||||
DWORD buflen, LPSTR buffer, LPSTR *lastpart )
|
||||
{
|
||||
WCHAR *pathW = NULL, *nameW, *extW = NULL;
|
||||
WCHAR bufferW[MAX_PATH];
|
||||
DWORD ret;
|
||||
|
||||
if (!name)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(nameW = FILE_name_AtoW( name, FALSE ))) return 0;
|
||||
if (path && !(pathW = FILE_name_AtoW( path, TRUE ))) return 0;
|
||||
|
||||
if (ext && !(extW = FILE_name_AtoW( ext, TRUE )))
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, pathW );
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = SearchPathW(pathW, nameW, extW, MAX_PATH, bufferW, NULL);
|
||||
|
||||
HeapFree( GetProcessHeap(), 0, pathW );
|
||||
HeapFree( GetProcessHeap(), 0, extW );
|
||||
|
||||
if (!ret) return 0;
|
||||
if (ret > MAX_PATH)
|
||||
{
|
||||
SetLastError(ERROR_FILENAME_EXCED_RANGE);
|
||||
return 0;
|
||||
}
|
||||
ret = copy_filename_WtoA( bufferW, buffer, buflen );
|
||||
if (buflen > ret && lastpart)
|
||||
*lastpart = strrchr(buffer, '\\') + 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL is_same_file(HANDLE h1, HANDLE h2)
|
||||
{
|
||||
|
|
|
@ -63,6 +63,137 @@ static void WINAPI read_write_apc( void *apc_user, PIO_STATUS_BLOCK io, ULONG re
|
|||
***********************************************************************/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* contains_path
|
||||
*
|
||||
* 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 inline BOOL contains_path( const WCHAR *name )
|
||||
{
|
||||
if (RtlDetermineDosPathNameType_U( name ) != RELATIVE_PATH) return TRUE;
|
||||
if (name[0] != '.') return FALSE;
|
||||
if (name[1] == '/' || name[1] == '\\') return TRUE;
|
||||
return (name[1] == '.' && (name[2] == '/' || name[2] == '\\'));
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* append_ext
|
||||
*/
|
||||
static WCHAR *append_ext( const WCHAR *name, const WCHAR *ext )
|
||||
{
|
||||
const WCHAR *p;
|
||||
WCHAR *ret;
|
||||
DWORD len;
|
||||
|
||||
if (!ext) return NULL;
|
||||
p = wcsrchr( name, '.' );
|
||||
if (p && !wcschr( p, '/' ) && !wcschr( p, '\\' )) return NULL;
|
||||
|
||||
len = lstrlenW( name ) + lstrlenW( ext );
|
||||
if ((ret = RtlAllocateHeap( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) )))
|
||||
{
|
||||
lstrcpyW( ret, name );
|
||||
lstrcatW( ret, ext );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* find_actctx_dllpath
|
||||
*
|
||||
* Find the path (if any) of the dll from the activation context.
|
||||
* Returned path doesn't include a name.
|
||||
*/
|
||||
static NTSTATUS find_actctx_dllpath( const WCHAR *name, WCHAR **path )
|
||||
{
|
||||
static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\'};
|
||||
static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0};
|
||||
|
||||
ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info;
|
||||
ACTCTX_SECTION_KEYED_DATA data;
|
||||
UNICODE_STRING nameW;
|
||||
NTSTATUS status;
|
||||
SIZE_T needed, size = 1024;
|
||||
WCHAR *p;
|
||||
|
||||
RtlInitUnicodeString( &nameW, name );
|
||||
data.cbSize = sizeof(data);
|
||||
status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
|
||||
ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION,
|
||||
&nameW, &data );
|
||||
if (status != STATUS_SUCCESS) return status;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (!(info = RtlAllocateHeap( GetProcessHeap(), 0, size )))
|
||||
{
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
status = RtlQueryInformationActivationContext( 0, data.hActCtx, &data.ulAssemblyRosterIndex,
|
||||
AssemblyDetailedInformationInActivationContext,
|
||||
info, size, &needed );
|
||||
if (status == STATUS_SUCCESS) break;
|
||||
if (status != STATUS_BUFFER_TOO_SMALL) goto done;
|
||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
||||
size = needed;
|
||||
/* restart with larger buffer */
|
||||
}
|
||||
|
||||
if (!info->lpAssemblyManifestPath || !info->lpAssemblyDirectoryName)
|
||||
{
|
||||
status = STATUS_SXS_KEY_NOT_FOUND;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ((p = wcsrchr( info->lpAssemblyManifestPath, '\\' )))
|
||||
{
|
||||
DWORD dirlen = info->ulAssemblyDirectoryNameLength / sizeof(WCHAR);
|
||||
|
||||
p++;
|
||||
if (wcsnicmp( p, info->lpAssemblyDirectoryName, dirlen ) || wcsicmp( p + dirlen, dotManifestW ))
|
||||
{
|
||||
/* manifest name does not match directory name, so it's not a global
|
||||
* windows/winsxs manifest; use the manifest directory name instead */
|
||||
dirlen = p - info->lpAssemblyManifestPath;
|
||||
needed = (dirlen + 1) * sizeof(WCHAR);
|
||||
if (!(*path = p = HeapAlloc( GetProcessHeap(), 0, needed )))
|
||||
{
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
memcpy( p, info->lpAssemblyManifestPath, dirlen * sizeof(WCHAR) );
|
||||
*(p + dirlen) = 0;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
needed = (lstrlenW( windows_dir ) * sizeof(WCHAR) +
|
||||
sizeof(winsxsW) + info->ulAssemblyDirectoryNameLength + 2*sizeof(WCHAR));
|
||||
|
||||
if (!(*path = p = RtlAllocateHeap( GetProcessHeap(), 0, needed )))
|
||||
{
|
||||
status = STATUS_NO_MEMORY;
|
||||
goto done;
|
||||
}
|
||||
lstrcpyW( p, windows_dir );
|
||||
p += lstrlenW(p);
|
||||
memcpy( p, winsxsW, sizeof(winsxsW) );
|
||||
p += ARRAY_SIZE( winsxsW );
|
||||
memcpy( p, info->lpAssemblyDirectoryName, info->ulAssemblyDirectoryNameLength );
|
||||
p += info->ulAssemblyDirectoryNameLength / sizeof(WCHAR);
|
||||
*p++ = '\\';
|
||||
*p = 0;
|
||||
done:
|
||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
||||
RtlReleaseActivationContext( data.hActCtx );
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* copy_filename_WtoA
|
||||
*
|
||||
|
@ -1321,6 +1452,119 @@ BOOL WINAPI DECLSPEC_HOTPATCH NeedCurrentDirectoryForExePathW( LPCWSTR name )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SearchPathA (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH SearchPathA( LPCSTR path, LPCSTR name, LPCSTR ext,
|
||||
DWORD buflen, LPSTR buffer, LPSTR *lastpart )
|
||||
{
|
||||
WCHAR *pathW = NULL, *nameW, *extW = NULL;
|
||||
WCHAR bufferW[MAX_PATH];
|
||||
DWORD ret;
|
||||
|
||||
if (!name)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(nameW = file_name_AtoW( name, FALSE ))) return 0;
|
||||
if (path && !(pathW = file_name_AtoW( path, TRUE ))) return 0;
|
||||
if (ext && !(extW = file_name_AtoW( ext, TRUE )))
|
||||
{
|
||||
RtlFreeHeap( GetProcessHeap(), 0, pathW );
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = SearchPathW( pathW, nameW, extW, MAX_PATH, bufferW, NULL );
|
||||
|
||||
RtlFreeHeap( GetProcessHeap(), 0, pathW );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, extW );
|
||||
|
||||
if (!ret) return 0;
|
||||
if (ret > MAX_PATH)
|
||||
{
|
||||
SetLastError( ERROR_FILENAME_EXCED_RANGE );
|
||||
return 0;
|
||||
}
|
||||
ret = copy_filename_WtoA( bufferW, buffer, buflen );
|
||||
if (buflen > ret && lastpart) *lastpart = strrchr(buffer, '\\') + 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SearchPathW (kernelbase.@)
|
||||
*/
|
||||
DWORD WINAPI DECLSPEC_HOTPATCH SearchPathW( LPCWSTR path, LPCWSTR name, LPCWSTR ext, DWORD buflen,
|
||||
LPWSTR buffer, LPWSTR *lastpart )
|
||||
{
|
||||
DWORD ret = 0;
|
||||
WCHAR *name_ext;
|
||||
|
||||
if (!name || !name[0])
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the name contains an explicit path, ignore the path */
|
||||
|
||||
if (contains_path( name ))
|
||||
{
|
||||
/* try first without extension */
|
||||
if (RtlDoesFileExists_U( name )) return GetFullPathNameW( name, buflen, buffer, lastpart );
|
||||
|
||||
if ((name_ext = append_ext( name, ext )))
|
||||
{
|
||||
if (RtlDoesFileExists_U( name_ext ))
|
||||
ret = GetFullPathNameW( name_ext, buflen, buffer, lastpart );
|
||||
RtlFreeHeap( GetProcessHeap(), 0, name_ext );
|
||||
}
|
||||
}
|
||||
else if (path && path[0]) /* search in the specified path */
|
||||
{
|
||||
ret = RtlDosSearchPath_U( path, name, ext, buflen * sizeof(WCHAR),
|
||||
buffer, lastpart ) / sizeof(WCHAR);
|
||||
}
|
||||
else /* search in active context and default path */
|
||||
{
|
||||
WCHAR *dll_path = NULL, *name_ext = append_ext( name, ext );
|
||||
|
||||
if (name_ext) name = name_ext;
|
||||
|
||||
/* When file is found with activation context no attempt is made
|
||||
to check if it's really exist, path is returned only basing on context info. */
|
||||
if (find_actctx_dllpath( name, &dll_path ) == STATUS_SUCCESS)
|
||||
{
|
||||
ret = lstrlenW( dll_path ) + lstrlenW( name ) + 1;
|
||||
|
||||
/* count null termination char too */
|
||||
if (ret <= buflen)
|
||||
{
|
||||
lstrcpyW( buffer, dll_path );
|
||||
lstrcatW( buffer, name );
|
||||
if (lastpart) *lastpart = buffer + lstrlenW( dll_path );
|
||||
ret--;
|
||||
}
|
||||
else if (lastpart) *lastpart = NULL;
|
||||
RtlFreeHeap( GetProcessHeap(), 0, dll_path );
|
||||
}
|
||||
else if (!RtlGetSearchPath( &dll_path ))
|
||||
{
|
||||
ret = RtlDosSearchPath_U( dll_path, name, NULL, buflen * sizeof(WCHAR),
|
||||
buffer, lastpart ) / sizeof(WCHAR);
|
||||
RtlReleasePath( dll_path );
|
||||
}
|
||||
RtlFreeHeap( GetProcessHeap(), 0, name_ext );
|
||||
}
|
||||
|
||||
if (!ret) SetLastError( ERROR_FILE_NOT_FOUND );
|
||||
else TRACE( "found %s\n", debugstr_w(buffer) );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetCurrentDirectoryA (kernelbase.@)
|
||||
*/
|
||||
|
|
|
@ -1385,8 +1385,8 @@
|
|||
# @ stub SaveStateRootFolderPath
|
||||
@ stdcall ScrollConsoleScreenBufferA(long ptr ptr ptr ptr)
|
||||
@ stdcall ScrollConsoleScreenBufferW(long ptr ptr ptr ptr)
|
||||
@ stdcall SearchPathA(str str str long ptr ptr) kernel32.SearchPathA
|
||||
@ stdcall SearchPathW(wstr wstr wstr long ptr ptr) kernel32.SearchPathW
|
||||
@ stdcall SearchPathA(str str str long ptr ptr)
|
||||
@ stdcall SearchPathW(wstr wstr wstr long ptr ptr)
|
||||
@ stdcall SetAclInformation(ptr ptr long long)
|
||||
# @ stub SetCachedSigningLevel
|
||||
@ stdcall SetCalendarInfoW(long long long wstr) kernel32.SetCalendarInfoW
|
||||
|
|
|
@ -92,7 +92,7 @@ static BOOL load_library_as_datafile( LPCWSTR load_path, DWORD flags, LPCWSTR na
|
|||
|
||||
if (flags & LOAD_LIBRARY_AS_IMAGE_RESOURCE) protect |= SEC_IMAGE;
|
||||
|
||||
if (SearchPathW( load_path, name, dotDLL, ARRAY_SIZE( filenameW ), filenameW, NULL ))
|
||||
if (SearchPathW( NULL, name, dotDLL, ARRAY_SIZE( filenameW ), filenameW, NULL ))
|
||||
{
|
||||
file = CreateFileW( filenameW, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE,
|
||||
NULL, OPEN_EXISTING, 0, 0 );
|
||||
|
|
Loading…
Reference in New Issue