Skip to content
Snippets Groups Projects
Commit 963985b3 authored by Michael McCormack's avatar Michael McCormack Committed by Alexandre Julliard
Browse files

First go at reading directories on public SMB shares.

parent 044b5c41
No related branches found
No related tags found
No related merge requests found
......@@ -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 );
......
This diff is collapsed.
......@@ -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__ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment