Commit 963985b3 authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

First go at reading directories on public SMB shares.

parent 044b5c41
......@@ -52,6 +52,8 @@
#include "wine/server.h"
#include "msvcrt/excpt.h"
#include "smb.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dosfs);
......@@ -121,7 +123,11 @@ typedef struct
BYTE attr;
int drive;
int cur_pos;
DOS_DIR *dir;
union
{
DOS_DIR *dos_dir;
SMB_DIR *smb_dir;
} u;
} FIND_FIRST_INFO;
......@@ -1154,6 +1160,13 @@ DWORD WINAPI GetLongPathNameA( LPCSTR shortpath, LPSTR longpath,
return 0;
}
if(shortpath[0]=='\\' && shortpath[1]=='\\')
{
ERR("UNC pathname %s\n",debugstr_a(shortpath));
lstrcpynA( longpath, full_name.short_name, longlen );
return lstrlenA(longpath);
}
if (!DOSFS_GetFullName( shortpath, TRUE, &full_name )) return 0;
lstrcpynA( longpath, full_name.short_name, longlen );
......@@ -1485,7 +1498,7 @@ static int DOSFS_FindNextEx( FIND_FIRST_INFO *info, WIN32_FIND_DATAA *entry )
strcat( buffer, "/" );
p = buffer + strlen(buffer);
while (DOSFS_ReadDir( info->dir, &long_name, &short_name ))
while (DOSFS_ReadDir( info->u.dos_dir, &long_name, &short_name ))
{
info->cur_pos++;
......@@ -1583,12 +1596,12 @@ int DOSFS_FindNext( const char *path, const char *short_mask,
_EnterWin16Lock();
/* Check the cached directory */
if (!(info.dir && info.path == path && info.short_mask == short_mask
if (!(info.u.dos_dir && info.path == path && info.short_mask == short_mask
&& info.long_mask == long_mask && info.drive == drive
&& info.attr == attr && info.cur_pos <= skip))
{
/* Not in the cache, open it anew */
if (info.dir) DOSFS_CloseDir( info.dir );
if (info.u.dos_dir) DOSFS_CloseDir( info.u.dos_dir );
info.path = (LPSTR)path;
info.long_mask = (LPSTR)long_mask;
......@@ -1596,24 +1609,24 @@ int DOSFS_FindNext( const char *path, const char *short_mask,
info.attr = attr;
info.drive = drive;
info.cur_pos = 0;
info.dir = DOSFS_OpenDir( info.path );
info.u.dos_dir = DOSFS_OpenDir( info.path );
}
/* Skip to desired position */
while (info.cur_pos < skip)
if (info.dir && DOSFS_ReadDir( info.dir, &long_name, &short_name ))
if (info.u.dos_dir && DOSFS_ReadDir( info.u.dos_dir, &long_name, &short_name ))
info.cur_pos++;
else
break;
if (info.dir && info.cur_pos == skip && DOSFS_FindNextEx( &info, entry ))
if (info.u.dos_dir && info.cur_pos == skip && DOSFS_FindNextEx( &info, entry ))
count = info.cur_pos - skip;
else
count = 0;
if (!count)
{
if (info.dir) DOSFS_CloseDir( info.dir );
if (info.u.dos_dir) DOSFS_CloseDir( info.u.dos_dir );
memset( &info, '\0', sizeof(info) );
}
......@@ -1633,7 +1646,6 @@ HANDLE WINAPI FindFirstFileExA(
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags)
{
DOS_FULL_NAME full_name;
HGLOBAL handle;
FIND_FIRST_INFO *info;
......@@ -1650,6 +1662,28 @@ HANDLE WINAPI FindFirstFileExA(
WIN32_FIND_DATAA * data = (WIN32_FIND_DATAA *) lpFindFileData;
data->dwReserved0 = data->dwReserved1 = 0x0;
if (!lpFileName) return 0;
if (lpFileName[0] == '\\' && lpFileName[1] == '\\')
{
ERR("UNC path name\n");
if (!(handle = GlobalAlloc(GMEM_MOVEABLE, sizeof(FIND_FIRST_INFO)))) break;
info = (FIND_FIRST_INFO *)GlobalLock( handle );
info->u.smb_dir = SMB_FindFirst(lpFileName);
if(info->u.smb_dir < 0)
{
GlobalUnlock( handle );
GlobalFree(handle);
break;
}
info->drive = -1;
GlobalUnlock( handle );
}
else
{
DOS_FULL_NAME full_name;
if (!DOSFS_GetFullName( lpFileName, FALSE, &full_name )) break;
if (!(handle = GlobalAlloc(GMEM_MOVEABLE, sizeof(FIND_FIRST_INFO)))) break;
info = (FIND_FIRST_INFO *)GlobalLock( handle );
......@@ -1664,9 +1698,10 @@ HANDLE WINAPI FindFirstFileExA(
else info->drive = DRIVE_GetCurrentDrive();
info->cur_pos = 0;
info->dir = DOSFS_OpenDir( info->path );
info->u.dos_dir = DOSFS_OpenDir( info->path );
GlobalUnlock( handle );
}
if (!FindNextFileA( handle, data ))
{
FindClose( handle );
......@@ -1766,28 +1801,41 @@ HANDLE WINAPI FindFirstFileW( LPCWSTR lpFileName, WIN32_FIND_DATAW *lpFindData )
BOOL WINAPI FindNextFileA( HANDLE handle, WIN32_FIND_DATAA *data )
{
FIND_FIRST_INFO *info;
BOOL ret = FALSE;
if ((handle == INVALID_HANDLE_VALUE) ||
!(info = (FIND_FIRST_INFO *)GlobalLock( handle )))
{
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
return ret;
}
GlobalUnlock( handle );
if (!info->path || !info->dir)
if (info->drive == -1)
{
ret = SMB_FindNext( info->u.smb_dir, data );
if(!ret)
{
SMB_CloseDir( info->u.smb_dir );
HeapFree( GetProcessHeap(), 0, info->path );
SetLastError( ERROR_NO_MORE_FILES );
}
goto done;
}
else if (!info->path || !info->u.dos_dir)
{
SetLastError( ERROR_NO_MORE_FILES );
return FALSE;
}
if (!DOSFS_FindNextEx( info, data ))
else if (!DOSFS_FindNextEx( info, data ))
{
DOSFS_CloseDir( info->dir ); info->dir = NULL;
DOSFS_CloseDir( info->u.dos_dir ); info->u.dos_dir = NULL;
HeapFree( GetProcessHeap(), 0, info->path );
info->path = info->long_mask = NULL;
SetLastError( ERROR_NO_MORE_FILES );
return FALSE;
}
return TRUE;
else
ret = TRUE;
done:
GlobalUnlock( handle );
return ret;
}
......@@ -1825,7 +1873,7 @@ BOOL WINAPI FindClose( HANDLE handle )
{
if ((info = (FIND_FIRST_INFO *)GlobalLock( handle )))
{
if (info->dir) DOSFS_CloseDir( info->dir );
if (info->u.dos_dir) DOSFS_CloseDir( info->u.dos_dir );
if (info->path) HeapFree( GetProcessHeap(), 0, info->path );
}
}
......@@ -2368,7 +2416,7 @@ HANDLE16 WINAPI FindFirstFile16( LPCSTR path, WIN32_FIND_DATAA *data )
else info->drive = DRIVE_GetCurrentDrive();
info->cur_pos = 0;
info->dir = DOSFS_OpenDir( info->path );
info->u.dos_dir = DOSFS_OpenDir( info->path );
GlobalUnlock16( handle );
if (!FindNextFile16( handle, data ))
......@@ -2394,14 +2442,14 @@ BOOL16 WINAPI FindNextFile16( HANDLE16 handle, WIN32_FIND_DATAA *data )
return FALSE;
}
GlobalUnlock16( handle );
if (!info->path || !info->dir)
if (!info->path || !info->u.dos_dir)
{
SetLastError( ERROR_NO_MORE_FILES );
return FALSE;
}
if (!DOSFS_FindNextEx( info, data ))
{
DOSFS_CloseDir( info->dir ); info->dir = NULL;
DOSFS_CloseDir( info->u.dos_dir ); info->u.dos_dir = NULL;
HeapFree( GetProcessHeap(), 0, info->path );
info->path = info->long_mask = NULL;
SetLastError( ERROR_NO_MORE_FILES );
......@@ -2423,7 +2471,7 @@ BOOL16 WINAPI FindClose16( HANDLE16 handle )
SetLastError( ERROR_INVALID_HANDLE );
return FALSE;
}
if (info->dir) DOSFS_CloseDir( info->dir );
if (info->u.dos_dir) DOSFS_CloseDir( info->u.dos_dir );
if (info->path) HeapFree( GetProcessHeap(), 0, info->path );
GlobalUnlock16( handle );
GlobalFree16( handle );
......
......@@ -25,6 +25,7 @@
#define SMB_ADDWORD(p,word) { (p)[0] = (word & 0xff); (p)[1] = ((word)>>8)&0xff; }
#define SMB_GETWORD(p) ( (((p)[1])<<8) | ((p)[0]) )
#define SMB_ADDDWORD(p,w) { (p)[3]=((w)>>24)&0xff; (p)[2]=((w)>>16)&0xff; (p)[1]=((w)>>8)&0xff; (p)[0]=(w)&0xff; }
#define SMB_GETDWORD(p) ( (((p)[3])<<24) | (((p)[2])<<16) | (((p)[1])<<8) | ((p)[0]) )
#define SMB_COM_CREATE_DIRECTORY 0x00
#define SMB_COM_DELETE_DIRECTORY 0x01
......@@ -91,10 +92,24 @@
#define SMB_COM_CLOSE_PRINT_FILE 0xC2
#define SMB_COM_GET_PRINT_QUEUE 0xC3
#define TRANS2_FIND_FIRST2 0x01
#define TRANS2_FIND_NEXT2 0x02
extern BOOL WINAPI SMB_ReadFile(HANDLE hFile, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead, LPOVERLAPPED lpOverlapped);
extern HANDLE WINAPI SMB_CreateFileA( LPCSTR filename, DWORD access, DWORD sharing,
LPSECURITY_ATTRIBUTES sa, DWORD creation,
DWORD attributes, HANDLE template );
#endif /* __INC_SMB__ */
typedef struct tagSMB_DIR
{
int current;
int num_entries;
unsigned char **entries;
unsigned char *buffer;
} SMB_DIR;
extern SMB_DIR* WINAPI SMB_FindFirst(LPCSTR filename);
extern BOOL WINAPI SMB_FindNext(SMB_DIR *dir, WIN32_FIND_DATAA *data );
extern BOOL WINAPI SMB_CloseDir(SMB_DIR *dir);
#endif /* __INC_SMB__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment