kernel32: Implemented FindFirstVolume/FindNextVolume using the mount point manager.

This commit is contained in:
Alexandre Julliard 2008-01-04 14:31:40 +01:00
parent 838f12539b
commit 7f508df25b
2 changed files with 107 additions and 18 deletions

View File

@ -378,10 +378,10 @@
@ stdcall FindNextChangeNotification(long)
@ stdcall FindNextFileA(long ptr)
@ stdcall FindNextFileW(long ptr)
@ stub FindNextVolumeA
@ stdcall FindNextVolumeA(long ptr long)
@ stub FindNextVolumeMountPointA
@ stub FindNextVolumeMountPointW
@ stub FindNextVolumeW
@ stdcall FindNextVolumeW(long ptr long)
@ stdcall FindResourceA(long str str)
@ stdcall FindResourceExA(long str str long)
@ stdcall FindResourceExW(long wstr wstr long)

View File

@ -37,6 +37,7 @@
#include "winternl.h"
#include "winioctl.h"
#include "ntddcdrm.h"
#include "ddk/mountmgr.h"
#include "kernel_private.h"
#include "wine/library.h"
#include "wine/unicode.h"
@ -1403,21 +1404,119 @@ BOOL WINAPI GetVolumePathNameW(LPCWSTR filename, LPWSTR volumepathname, DWORD bu
*/
HANDLE WINAPI FindFirstVolumeA(LPSTR volume, DWORD len)
{
FIXME("(%p, %d), stub!\n", volume, len);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return INVALID_HANDLE_VALUE;
WCHAR *buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
HANDLE handle = FindFirstVolumeW( buffer, len );
if (handle != INVALID_HANDLE_VALUE)
{
if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, volume, len, NULL, NULL ))
{
FindVolumeClose( handle );
handle = INVALID_HANDLE_VALUE;
}
}
HeapFree( GetProcessHeap(), 0, buffer );
return handle;
}
/***********************************************************************
* FindFirstVolumeW (KERNEL32.@)
*/
HANDLE WINAPI FindFirstVolumeW(LPWSTR volume, DWORD len)
HANDLE WINAPI FindFirstVolumeW( LPWSTR volume, DWORD len )
{
FIXME("(%p, %d), stub!\n", volume, len);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
DWORD size = 1024;
HANDLE mgr = CreateFileW( MOUNTMGR_DOS_DEVICE_NAME, 0, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, 0 );
if (mgr == INVALID_HANDLE_VALUE) return INVALID_HANDLE_VALUE;
for (;;)
{
MOUNTMGR_MOUNT_POINT input;
MOUNTMGR_MOUNT_POINTS *output;
if (!(output = HeapAlloc( GetProcessHeap(), 0, size )))
{
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
break;
}
memset( &input, 0, sizeof(input) );
if (!DeviceIoControl( mgr, IOCTL_MOUNTMGR_QUERY_POINTS, &input, sizeof(input),
output, size, NULL, NULL ))
{
if (GetLastError() != ERROR_MORE_DATA) break;
size = output->Size;
HeapFree( GetProcessHeap(), 0, output );
continue;
}
CloseHandle( mgr );
/* abuse the Size field to store the current index */
output->Size = 0;
if (!FindNextVolumeW( output, volume, len ))
{
HeapFree( GetProcessHeap(), 0, output );
return INVALID_HANDLE_VALUE;
}
return (HANDLE)output;
}
CloseHandle( mgr );
return INVALID_HANDLE_VALUE;
}
/***********************************************************************
* FindNextVolumeA (KERNEL32.@)
*/
BOOL WINAPI FindNextVolumeA( HANDLE handle, LPSTR volume, DWORD len )
{
WCHAR *buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
BOOL ret;
if ((ret = FindNextVolumeW( handle, buffer, len )))
{
if (!WideCharToMultiByte( CP_ACP, 0, buffer, -1, volume, len, NULL, NULL )) ret = FALSE;
}
return ret;
}
/***********************************************************************
* FindNextVolumeW (KERNEL32.@)
*/
BOOL WINAPI FindNextVolumeW( HANDLE handle, LPWSTR volume, DWORD len )
{
MOUNTMGR_MOUNT_POINTS *data = handle;
while (data->Size < data->NumberOfMountPoints)
{
static const WCHAR volumeW[] = {'\\','?','?','\\','V','o','l','u','m','e','{',};
WCHAR *link = (WCHAR *)((char *)data + data->MountPoints[data->Size].SymbolicLinkNameOffset);
DWORD size = data->MountPoints[data->Size].SymbolicLinkNameLength;
data->Size++;
/* skip non-volumes */
if (size < sizeof(volumeW) || memcmp( link, volumeW, sizeof(volumeW) )) continue;
if (size + sizeof(WCHAR) >= len * sizeof(WCHAR))
{
SetLastError( ERROR_FILENAME_EXCED_RANGE );
return FALSE;
}
memcpy( volume, link, size );
volume[1] = '\\'; /* map \??\ to \\?\ */
volume[size / sizeof(WCHAR)] = '\\'; /* Windows appends a backslash */
volume[size / sizeof(WCHAR) + 1] = 0;
TRACE( "returning entry %u %s\n", data->Size - 1, debugstr_w(volume) );
return TRUE;
}
SetLastError( ERROR_NO_MORE_FILES );
return FALSE;
}
/***********************************************************************
* FindVolumeClose (KERNEL32.@)
*/
BOOL WINAPI FindVolumeClose(HANDLE handle)
{
return HeapFree( GetProcessHeap(), 0, handle );
}
/***********************************************************************
* FindFirstVolumeMountPointA (KERNEL32.@)
*/
@ -1438,16 +1537,6 @@ HANDLE WINAPI FindFirstVolumeMountPointW(LPCWSTR root, LPWSTR mount_point, DWORD
return INVALID_HANDLE_VALUE;
}
/***********************************************************************
* FindVolumeClose (KERNEL32.@)
*/
BOOL WINAPI FindVolumeClose(HANDLE handle)
{
FIXME("(%p), stub!\n", handle);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* FindVolumeMountPointClose (KERNEL32.@)
*/