mirror of
https://github.com/obarthel/amiga-smbfs.git
synced 2025-12-08 14:58:35 +00:00
Updated to version 1.139
Please keep in mind that this is still a development version and might surprise you (not necessarily in a good way). Do not let me discourage you to build and test this version, although there will be some risks involved such as data corruption or loss of data.
This commit is contained in:
@@ -1665,8 +1665,8 @@ smbfs 1.136 (22.5.2018)
|
||||
smbfs 1.137 (24.5.2018)
|
||||
|
||||
- Updated the table of error codes which eventually get translated
|
||||
into AmigaDOS error codes. Quite a number of error codes were
|
||||
still not properly covered.
|
||||
into AmigaDOS error codes. Quite a number of error codes were not
|
||||
properly covered.
|
||||
|
||||
- We now show how much memory smbfs has used (in debug mode), and
|
||||
how much memory has not been released yet.
|
||||
@@ -1703,3 +1703,79 @@ smbfs 1.137 (24.5.2018)
|
||||
- Added further tests to figure out if a directory could not be deleted
|
||||
because it was not empty. However, it's difficult to tell all three
|
||||
cases apart which share the same error code. We'll try anyway...
|
||||
|
||||
|
||||
smbfs 1.138 (25.5.2018)
|
||||
|
||||
- The name translation performed by the directory scanning code is now
|
||||
a bit more paranoid than before. They will check if the names can
|
||||
be translated into something suitable for use on the Amiga. This rules
|
||||
out control characters, for example. If a name is unsuitable, an
|
||||
explanation why it is unsuitable will be printed in the debug output.
|
||||
|
||||
- The SBM directory scanning code which uses the TRANSACT2_FINDFIRST2
|
||||
and TRANSACT2_FINDNEXT2 commands now uses the correct flag codes instead
|
||||
of naked numeric constants.
|
||||
|
||||
- Removed support for the "write raw" and "read raw" commands, which extends
|
||||
to the command line parameters and tool types which could be used to
|
||||
disable them or adjust how they would be used.
|
||||
|
||||
|
||||
smbfs 1.139 (26.5.2018)
|
||||
|
||||
- Added more const qualifiers to pointers, so that unintended changes
|
||||
are more easily detected.
|
||||
|
||||
- Text that uses 8 bit characters now uses type TEXT rather than UBYTE,
|
||||
and TEXT * replaces STRPTR where it makes sense.
|
||||
|
||||
- Text buffer size and maximum size (without terminating NUL byte) of
|
||||
the string that may be stored in there are now distinct.
|
||||
|
||||
- Building the error message list for display in an error requester
|
||||
is now more efficient, as it no longer resorts to strcat().
|
||||
|
||||
- Removed the last traces of the SMB "system" file attribute and its
|
||||
mapping to the "pure" protection bit on the Amiga.
|
||||
|
||||
- File sizes returned (through the Examine(), ExNext() and ExAll()
|
||||
functions) now refer to the original SMB file size information
|
||||
which may be a 64 bit integer. Same goes for the file sizes
|
||||
referenced by Seek() and SetFileSize(). Note that for now the
|
||||
sizes returned will be truncated, which means that if they
|
||||
exceed what an unsigned 32 bit integer may represent, then
|
||||
the number 4294967295 will be used instead. There could be
|
||||
hilarious consequences: watch out!
|
||||
|
||||
- When scanning directory contents, names which end up containing
|
||||
unprintable names (not "#$@&%*!") after conversion to Amiga format
|
||||
are now ignored.
|
||||
|
||||
- Reading/writing files updates the internal seek position of the
|
||||
respective file, which is now a 64 bit integer. You can actually
|
||||
read from files > 4 Gigabytes (and write to them, too) as long
|
||||
as you do not use Seek(file, ..., OFFSET_BEGINNING) because that
|
||||
will box you into the first 4 Gigabytes of the file. Note that the
|
||||
result of Seek() and SetFileSize() will be a truncated position
|
||||
(4294967295) if the position happens to be beyond what can be
|
||||
represented by an unsigned 32 bit integer. Because "4294967295"
|
||||
is also known as the signed 32 bit integer "-1" you probably
|
||||
won't be able to tell it apart from a seek error (unless you
|
||||
check the IoErr() value, of course, but who does?). This
|
||||
used to be a problem with "normal" Amiga file systems, and now
|
||||
it's a problem again :-(
|
||||
|
||||
- When decoding directory entry data, we no longer replace the
|
||||
"last change" time with the "last write access" time, and then
|
||||
swap both time records again (who ordered that?). The
|
||||
"last change" time now stays the last change time, and this
|
||||
is what goes into the Amiga FileInfoBlock/ExAllData records.
|
||||
|
||||
- The debug output for the directory scanner now prints the original
|
||||
untranslated name in 'C' style escaped form, in case this might
|
||||
reveal further insights into why the directory entry names look
|
||||
like they do. Note that all file, directory and path names used
|
||||
by the SMB file system layer now appear only in escaped form, which
|
||||
means for example that all backslash characters which serve as
|
||||
path delimiters show up twice as much.
|
||||
|
||||
@@ -68,13 +68,13 @@ $(PROJECT): $(OBJS)
|
||||
assert.o : assert.c
|
||||
cp437.o : cp437.c
|
||||
cp850.o : cp850.c
|
||||
crypt.o : crypt.c system_headers.h assert.h smbfs.h
|
||||
dump_smb.o : dump_smb.c system_headers.h assert.h smbfs.h dump_smb.h quad_math.h
|
||||
main.o : main.c system_headers.h assert.h smbfs.h smb_abstraction.h utf-8-iso-8859-1-conversion.h cp437.h cp850.h errors.h dump_smb.h smbfs_rev.h
|
||||
proc.o : proc.c system_headers.h assert.h smbfs.h quad_math.h errors.h smbfs_rev.h
|
||||
crypt.o : crypt.c system_headers.h assert.h quad_math.h smbfs.h
|
||||
dump_smb.o : dump_smb.c system_headers.h assert.h quad_math.h smbfs.h dump_smb.h
|
||||
main.o : main.c system_headers.h assert.h quad_math.h smbfs.h smb_abstraction.h utf-8-iso-8859-1-conversion.h cp437.h cp850.h errors.h dump_smb.h smbfs_rev.h
|
||||
proc.o : proc.c system_headers.h assert.h quad_math.h smbfs.h errors.h smbfs_rev.h
|
||||
quad_math.o : quad_math.c quad_math.h
|
||||
smb_abstraction.o : smb_abstraction.c system_headers.h assert.h smbfs.h smb_abstraction.h
|
||||
sock.o : sock.c system_headers.h assert.h smbfs.h smb_abstraction.h dump_smb.h errors.h
|
||||
smb_abstraction.o : smb_abstraction.c system_headers.h assert.h quad_math.h smbfs.h errors.h smb_abstraction.h
|
||||
sock.o : sock.c system_headers.h assert.h quad_math.h smbfs.h smb_abstraction.h dump_smb.h errors.h
|
||||
utf-8-iso-8859-1-conversion.o : utf-8-iso-8859-1-conversion.c utf-8-iso-8859-1-conversion.h
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -73,13 +73,13 @@ $(PROJECT): $(OBJS)
|
||||
assert.o : assert.c
|
||||
cp437.o : cp437.c
|
||||
cp850.o : cp850.c
|
||||
crypt.o : crypt.c system_headers.h assert.h smbfs.h
|
||||
dump_smb.o : dump_smb.c system_headers.h assert.h smbfs.h dump_smb.h quad_math.h
|
||||
main.o : main.c system_headers.h assert.h smbfs.h smb_abstraction.h utf-8-iso-8859-1-conversion.h cp437.h cp850.h errors.h dump_smb.h smbfs_rev.h
|
||||
proc.o : proc.c system_headers.h assert.h smbfs.h quad_math.h errors.h smbfs_rev.h
|
||||
crypt.o : crypt.c system_headers.h assert.h quad_math.h smbfs.h
|
||||
dump_smb.o : dump_smb.c system_headers.h assert.h quad_math.h smbfs.h dump_smb.h
|
||||
main.o : main.c system_headers.h assert.h quad_math.h smbfs.h smb_abstraction.h utf-8-iso-8859-1-conversion.h cp437.h cp850.h errors.h dump_smb.h smbfs_rev.h
|
||||
proc.o : proc.c system_headers.h assert.h quad_math.h smbfs.h errors.h smbfs_rev.h
|
||||
quad_math.o : quad_math.c quad_math.h
|
||||
smb_abstraction.o : smb_abstraction.c system_headers.h assert.h smbfs.h smb_abstraction.h
|
||||
sock.o : sock.c system_headers.h assert.h smbfs.h smb_abstraction.h dump_smb.h errors.h
|
||||
smb_abstraction.o : smb_abstraction.c system_headers.h assert.h quad_math.h smbfs.h errors.h smb_abstraction.h
|
||||
sock.o : sock.c system_headers.h assert.h quad_math.h smbfs.h smb_abstraction.h dump_smb.h errors.h
|
||||
utf-8-iso-8859-1-conversion.o : utf-8-iso-8859-1-conversion.c utf-8-iso-8859-1-conversion.h
|
||||
|
||||
###########################################################################
|
||||
|
||||
@@ -40,10 +40,6 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
extern VOID VARARGS68K SPrintf(STRPTR buffer, STRPTR formatString,...);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* This can be used to enable or disable the SMB packet dump output. */
|
||||
static int dump_smb_enabled;
|
||||
|
||||
|
||||
@@ -71,11 +71,13 @@ struct smb_dirent
|
||||
/* to UTC. The ugly conversion happens in */
|
||||
/* proc.c */
|
||||
|
||||
unsigned long size; /* File size. */
|
||||
dword size_low; /* File size (least significant 32 bits). */
|
||||
dword size_high; /* File size (most significant 32 bits). */
|
||||
|
||||
char * complete_path; /* Complete path, MS-DOS notation, with '\' */
|
||||
size_t complete_path_size; /* Number of bytes allocated for name */
|
||||
int len; /* Namelength. */
|
||||
|
||||
int len; /* Name length. */
|
||||
|
||||
unsigned opened:1; /* is it open on the fileserver? */
|
||||
unsigned writable:1; /* was opened for read/write access? */
|
||||
|
||||
@@ -18,6 +18,10 @@
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifndef _QUAD_MATH_H
|
||||
#include "quad_math.h"
|
||||
#endif /* _QUAD_MATH_H */
|
||||
|
||||
/* This structure is used to pass the arguments to smb_proc_lockingX
|
||||
*/
|
||||
struct smb_lkrng
|
||||
@@ -50,11 +54,9 @@ int smb_payload_size(const struct smb_server *server, int wct, int bcc);
|
||||
int smb_proc_open(struct smb_server *server, const char *pathname, int len, int writable, int truncate, struct smb_dirent *entry, int * error_ptr);
|
||||
int smb_proc_close(struct smb_server *server, word fileid, dword mtime, int * error_ptr);
|
||||
int smb_proc_read(struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, char *data, int * error_ptr);
|
||||
int smb_proc_read_raw(struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, char *data, int * error_ptr);
|
||||
int smb_proc_write (struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, const char *data, int * error_ptr);
|
||||
int smb_proc_write_raw(struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, const char *data, int * error_ptr);
|
||||
int smb_proc_writex (struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, const char *data, int * error_ptr);
|
||||
int smb_proc_readx (struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, char *data, int * error_ptr);
|
||||
int smb_proc_writex (struct smb_server *server, struct smb_dirent *finfo, const QUAD * const offset, long count, const char *data, int * error_ptr);
|
||||
int smb_proc_readx (struct smb_server *server, struct smb_dirent *finfo, const QUAD * const offset, long count, char *data, int * error_ptr);
|
||||
int smb_proc_lockingX (struct smb_server *server, struct smb_dirent *finfo, struct smb_lkrng *locks, int num_entries, int mode, long timeout, int * error_ptr);
|
||||
int smb_proc_create(struct smb_server *server, const char *path, int len, struct smb_dirent *entry, int * error_ptr);
|
||||
int smb_proc_mv(struct smb_server *server, const char *opath, const int olen, const char *npath, const int nlen, int * error_ptr);
|
||||
@@ -66,7 +68,7 @@ int smb_proc_readdir(struct smb_server *server, char *path, int fpos, int cache_
|
||||
int smb_proc_getattr_core(struct smb_server *server, const char *path, int len, struct smb_dirent *entry, int * error_ptr);
|
||||
int smb_proc_getattrE(struct smb_server *server, struct smb_dirent *entry, int * error_ptr);
|
||||
int smb_query_path_information(struct smb_server *server, const char *path, int len, int fid, struct smb_dirent *entry, int * error_ptr);
|
||||
int smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, const dword * size_ptr, int * error_ptr);
|
||||
int smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, const QUAD * const size, int * error_ptr);
|
||||
int smb_proc_setattr_core(struct smb_server *server, const char *path, int len, struct smb_dirent *new_finfo, int * error_ptr);
|
||||
int smb_proc_setattrE(struct smb_server *server, word fid, struct smb_dirent *new_entry, int * error_ptr);
|
||||
int smb_proc_dskattr (struct smb_server *server, struct smb_dskattr *attr, int * error_ptr);
|
||||
@@ -78,7 +80,5 @@ void smb_release(struct smb_server *server);
|
||||
int smb_connect(struct smb_server *server, int * error_ptr);
|
||||
int smb_request(struct smb_server *server, int command, void * input_payload,const void * output_payload,int payload_size, int * error_ptr);
|
||||
int smb_trans2_request(struct smb_server *server, int command, int *data_len, int *param_len, char **data, char **param, int * error_ptr);
|
||||
int smb_request_read_raw(struct smb_server *server, unsigned char *target, int max_len, int * error_ptr);
|
||||
int smb_request_write_raw(struct smb_server *server, unsigned const char *source, int length, int * error_ptr);
|
||||
|
||||
#endif /* _LINUX_SMB_FS_H */
|
||||
|
||||
@@ -51,18 +51,6 @@ struct smb_server
|
||||
/* olsen (2012-12-10): raw SMB over TCP instead of NBT transport? */
|
||||
int raw_smb;
|
||||
|
||||
/* olsen (2016-04-20): Use write-behind with SMB_COM_WRITE_RAW? */
|
||||
int write_behind;
|
||||
|
||||
/* olsen (2016-04-20): Prefer SMB_COM_WRITE_RAW to SMB_COM_WRITE? */
|
||||
int prefer_write_raw;
|
||||
|
||||
/* olsen (2018-05-08): Always use SMB_COM_WRITE, even if SMB_COM_WRITE_RAW were possible. */
|
||||
int disable_write_raw;
|
||||
|
||||
/* olsen (2018-05-08): Always use SMB_COM_READ, even if SMB_COM_READ_RAW were possible. */
|
||||
int disable_read_raw;
|
||||
|
||||
/* olsen (2018-05-09): Timeout for send/receive operations in seconds. */
|
||||
int timeout;
|
||||
|
||||
|
||||
@@ -365,6 +365,13 @@
|
||||
#define SMB_INFO_STANDARD 0x0001 /* LAN Manager 2.0 */
|
||||
#define SMB_FILE_BOTH_DIRECTORY_INFO 0x0104 /* NT LAN Manager */
|
||||
|
||||
/* Flags used by TRANSACT2_FINDFIRST */
|
||||
#define SMB_FIND_CLOSE_AFTER_REQUEST 0x0001 /* Close the request after this search */
|
||||
#define SMB_FIND_CLOSE_AT_EOS 0x0002 /* Close search when end of search is reached */
|
||||
#define SMB_FIND_RETURN_RESUME_KEYS 0x0004 /* Return resume keys for each entry found */
|
||||
#define SMB_FIND_CONTINUE_FROM_LAST 0x0008 /* Continue search from previous ending place */
|
||||
#define SMB_FIND_WITH_BACKUP_INTENT 0x0010 /* Find with backup intent */
|
||||
|
||||
/* File system information formats supported by TRANSACT2_QFSINFO (actually,
|
||||
* we only need this one).
|
||||
*/
|
||||
|
||||
+838
-392
File diff suppressed because it is too large
Load Diff
+125
-341
@@ -801,7 +801,7 @@ smb_request_ok_with_payload (
|
||||
else if ((error = smb_valid_packet (server->transmit_buffer)) != 0)
|
||||
{
|
||||
LOG (("not a valid packet!\n"));
|
||||
|
||||
|
||||
(*error_ptr) = error;
|
||||
result = -1;
|
||||
}
|
||||
@@ -854,7 +854,7 @@ reopen_entry(struct smb_server *server, struct smb_dirent *entry,int * error_ptr
|
||||
{
|
||||
int ignored_error;
|
||||
|
||||
LOG (("trying to reopen file %s\n", entry->complete_path));
|
||||
LOG (("trying to reopen file '%s'\n", escape_name(entry->complete_path)));
|
||||
|
||||
result = smb_proc_open (server, entry->complete_path, entry->len, entry->writable, FALSE, entry, error_ptr != NULL ? error_ptr : &ignored_error);
|
||||
}
|
||||
@@ -1001,7 +1001,7 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
|
||||
|
||||
ENTER();
|
||||
|
||||
SHOWSTRING(pathname);
|
||||
D(("pathname = '%s'", escape_name(pathname)));
|
||||
|
||||
if (server->protocol >= PROTOCOL_NT1)
|
||||
{
|
||||
@@ -1115,7 +1115,8 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
|
||||
params = smb_decode_dword(params, &end_of_file_low);
|
||||
(void) smb_decode_dword(params, &end_of_file_high);
|
||||
|
||||
entry->size = end_of_file_low;
|
||||
entry->size_low = end_of_file_low;
|
||||
entry->size_high = end_of_file_high;
|
||||
|
||||
entry->opened = TRUE;
|
||||
entry->writable = writable;
|
||||
@@ -1174,7 +1175,8 @@ smb_proc_open (struct smb_server *server, const char *pathname, int len, int wri
|
||||
entry->fileid = WVAL (buf, smb_vwv0);
|
||||
entry->attr = WVAL (buf, smb_vwv1);
|
||||
entry->ctime = entry->atime = entry->mtime = entry->wtime = local2utc (DVAL (buf, smb_vwv2));
|
||||
entry->size = DVAL (buf, smb_vwv4);
|
||||
entry->size_low = DVAL (buf, smb_vwv4);
|
||||
entry->size_high = 0;
|
||||
entry->opened = TRUE;
|
||||
entry->writable = writable;
|
||||
|
||||
@@ -1269,43 +1271,6 @@ smb_proc_read (struct smb_server *server, struct smb_dirent *finfo, off_t offset
|
||||
return result;
|
||||
}
|
||||
|
||||
/* count must be <= 65535. No error number is returned. A result of 0
|
||||
indicates an error, which has to be investigated by a normal read
|
||||
call. */
|
||||
int
|
||||
smb_proc_read_raw (struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, char *data, int * error_ptr)
|
||||
{
|
||||
char *buf = server->transmit_buffer;
|
||||
int result;
|
||||
|
||||
ASSERT( count <= 65535 );
|
||||
|
||||
retry:
|
||||
|
||||
smb_setup_header (server, SMBreadbraw, 8, 0);
|
||||
|
||||
WSET (buf, smb_vwv0, finfo->fileid);
|
||||
DSET (buf, smb_vwv1, offset);
|
||||
WSET (buf, smb_vwv3, count); /* maxcnt */
|
||||
WSET (buf, smb_vwv4, 0); /* mincnt */
|
||||
DSET (buf, smb_vwv5, 0); /* timeout */
|
||||
WSET (buf, smb_vwv7, 0); /* reserved */
|
||||
|
||||
result = smb_request_read_raw (server, data, count, error_ptr);
|
||||
if (result < 0)
|
||||
{
|
||||
if (smb_retry (server))
|
||||
{
|
||||
if(reopen_entry(server,finfo,NULL) < 0)
|
||||
LOG(("that didn't work.\n"));
|
||||
else
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
smb_proc_write (struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, const char *data, int * error_ptr)
|
||||
{
|
||||
@@ -1346,201 +1311,7 @@ smb_proc_write (struct smb_server *server, struct smb_dirent *finfo, off_t offse
|
||||
}
|
||||
|
||||
int
|
||||
smb_proc_write_raw (struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, const char *data, int * error_ptr)
|
||||
{
|
||||
char *buf = server->transmit_buffer;
|
||||
int num_bytes_written = 0;
|
||||
int result;
|
||||
long max_len;
|
||||
long len;
|
||||
byte *p;
|
||||
|
||||
ASSERT( count <= 65535 );
|
||||
|
||||
LOG (("number of bytes to send = %ld\n", count));
|
||||
|
||||
/* Calculate maximum number of bytes that could be transferred with
|
||||
* a single SMB_COM_WRITE_RAW packet...
|
||||
*
|
||||
* 'max_buffer_size' is the maximum size of a complete SMB message
|
||||
* including the message header, the parameter and data blocks.
|
||||
*
|
||||
* The message header accounts for
|
||||
* 4(protocol)+1(command)+4(status)+1(flags)+2(flags2)+2(pidhigh)+
|
||||
* 8(securityfeatures)+2(reserved)+2(tid)+2(pidlow)+2(uid)+2(mid)
|
||||
* = 32 bytes
|
||||
*
|
||||
* The parameters of a SMB_COM_WRITE_RAW command account for
|
||||
* 1(wordcount)+2(fid)+2(countofbytes)+2(reserved1)+4(offset)+
|
||||
* 4(timeout)+2(writemode)+4(reserved2)+2(datalength)+2(dataoffset)
|
||||
* = 25 bytes
|
||||
*
|
||||
* The data part of a SMB_COM_WRITE_RAW command account for
|
||||
* 2(bytecount)+0(pad) = 2 bytes, not including
|
||||
* the actual payload
|
||||
*
|
||||
* This leaves 'max_buffer_size' - 59 for the payload.
|
||||
*/
|
||||
max_len = server->max_buffer_size;
|
||||
if(max_len > 65535)
|
||||
max_len = 65535;
|
||||
|
||||
max_len -= 59;
|
||||
|
||||
LOG(("maximum length for payload = %ld bytes\n", max_len));
|
||||
|
||||
/* Number of bytes to write is smaller than the maximum
|
||||
* number of bytes which may be sent in a single SMB
|
||||
* message, including parameter and data fields?
|
||||
*/
|
||||
if (count <= max_len)
|
||||
{
|
||||
LOG(("count (%ld) <= max_len (%ld) -- send no data with the message.\n",count,max_len));
|
||||
|
||||
len = 0; /* Send a zero length SMB_COM_WRITE_RAW message, followed by the raw data. */
|
||||
}
|
||||
else
|
||||
{
|
||||
len = count - max_len; /* Send some of the data as part of the SMB_COM_WRITE_RAW message, followed by the remaining raw data. */
|
||||
|
||||
LOG(("count (%ld) > max_len (%ld) -- send %ld bytes with the message.\n",count,max_len,len));
|
||||
}
|
||||
|
||||
retry:
|
||||
|
||||
p = smb_setup_header (server, SMBwritebraw, server->protocol > PROTOCOL_COREPLUS ? 12 : 11, len);
|
||||
|
||||
WSET (buf, smb_vwv0, finfo->fileid);
|
||||
DSET (buf, smb_vwv1, count);
|
||||
DSET (buf, smb_vwv3, offset);
|
||||
DSET (buf, smb_vwv5, 0); /* timeout */
|
||||
|
||||
if(server->write_behind)
|
||||
WSET (buf, smb_vwv7, 0); /* do not send a final result response. */
|
||||
else
|
||||
WSET (buf, smb_vwv7, 1); /* send final result response */
|
||||
|
||||
DSET (buf, smb_vwv8, 0); /* reserved */
|
||||
|
||||
if (server->protocol > PROTOCOL_COREPLUS)
|
||||
{
|
||||
WSET (buf, smb_vwv10, len);
|
||||
WSET (buf, smb_vwv11, p - smb_base(buf));
|
||||
}
|
||||
else
|
||||
{
|
||||
WSET (buf, smb_vwv10, 0);
|
||||
}
|
||||
|
||||
LOG(("requesting SMBwritebraw\n"));
|
||||
|
||||
result = smb_request_ok_with_payload (server, SMBwritebraw, 1, 0, NULL, data, len, error_ptr);
|
||||
if (result < 0)
|
||||
{
|
||||
if (smb_retry (server))
|
||||
{
|
||||
if(reopen_entry(server,finfo,NULL) < 0)
|
||||
{
|
||||
LOG(("that didn't work.\n"));
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
num_bytes_written += len;
|
||||
|
||||
data += len;
|
||||
count -= len;
|
||||
|
||||
LOG (("bytes sent so far = %ld\n", num_bytes_written));
|
||||
|
||||
if(count > 0)
|
||||
{
|
||||
LOG(("sending %ld bytes of data (raw)\n",count));
|
||||
|
||||
ASSERT( count <= 65535 );
|
||||
|
||||
result = smb_request_write_raw (server, data, count, error_ptr);
|
||||
if (result < 0)
|
||||
{
|
||||
/* Roll back the counters */
|
||||
num_bytes_written -= len;
|
||||
|
||||
data -= len;
|
||||
count += len;
|
||||
|
||||
if (smb_retry (server))
|
||||
{
|
||||
if(reopen_entry(server,finfo,NULL) < 0)
|
||||
{
|
||||
LOG(("that didn't work.\n"));
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if(server->write_behind)
|
||||
{
|
||||
/* We just assume success; the next file operation to follow
|
||||
* will set an error status if something went wrong.
|
||||
*/
|
||||
result = num_bytes_written + count;
|
||||
}
|
||||
else
|
||||
{
|
||||
int error;
|
||||
|
||||
/* We have to do the checks of smb_request_ok here as well */
|
||||
if ((error = smb_valid_packet (server->transmit_buffer)) != 0)
|
||||
{
|
||||
LOG (("not a valid packet!\n"));
|
||||
|
||||
(*error_ptr) = error;
|
||||
result = -1;
|
||||
|
||||
goto out;
|
||||
}
|
||||
else if (server->rcls != 0)
|
||||
{
|
||||
LOG (("server error %ld/%ld\n", server->rcls, server->err));
|
||||
|
||||
smb_printerr (server->rcls, server->err);
|
||||
|
||||
(*error_ptr) = error_check_smb_error;
|
||||
result = -1;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
result = num_bytes_written + count;
|
||||
}
|
||||
|
||||
LOG (("bytes sent so far = %ld\n", result));
|
||||
}
|
||||
|
||||
out:
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
smb_proc_writex (struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, const char *data, int * error_ptr)
|
||||
smb_proc_writex (struct smb_server *server, struct smb_dirent *finfo, const QUAD * const offset_quad, long count, const char *data, int * error_ptr)
|
||||
{
|
||||
char *buf = server->transmit_buffer;
|
||||
int result;
|
||||
@@ -1557,17 +1328,17 @@ smb_proc_writex (struct smb_server *server, struct smb_dirent *finfo, off_t offs
|
||||
BSET (buf, smb_vwv0, 0xFF); /* AndXCommand/AndXReserved - no additional SMB commands provided */
|
||||
WSET (buf, smb_vwv1, 0); /* AndXOffset */
|
||||
WSET (buf, smb_vwv2, finfo->fileid); /* fid */
|
||||
DSET (buf, smb_vwv3, offset); /* offset */
|
||||
DSET (buf, smb_vwv3, offset_quad->Low); /* offset */
|
||||
DSET (buf, smb_vwv5, 0); /* timeout */
|
||||
WSET (buf, smb_vwv7, 0); /* write mode */
|
||||
WSET (buf, smb_vwv8, 0); /* remaining */
|
||||
WSET (buf, smb_vwv9, 0); /* reserved */
|
||||
WSET (buf, smb_vwv10, count); /* data length */
|
||||
|
||||
|
||||
if(server->protocol >= PROTOCOL_NT1)
|
||||
{
|
||||
WSET (buf, smb_vwv11, 64+2); /* data offset */
|
||||
DSET (buf, smb_vwv12, 0); /* high offset */
|
||||
DSET (buf, smb_vwv12, offset_quad->High); /* high offset */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1579,7 +1350,8 @@ smb_proc_writex (struct smb_server *server, struct smb_dirent *finfo, off_t offs
|
||||
WSET (p, 0, 1+count); p += 2; /* Byte count (1 pad byte + data bytes) */
|
||||
(*p) = 0; /* Padding byte that must be ignored */
|
||||
|
||||
LOG(("requesting SMBwriteX\n"));
|
||||
|
||||
LOG(("requesting SMBwriteX: offset=%s, count=%ld\n", convert_quad_to_string(offset_quad), count));
|
||||
|
||||
result = smb_request_ok_with_payload (server, SMBwriteX, 6, 0, NULL, data, count, error_ptr);
|
||||
if (result < 0)
|
||||
@@ -1608,7 +1380,7 @@ smb_proc_writex (struct smb_server *server, struct smb_dirent *finfo, off_t offs
|
||||
}
|
||||
|
||||
int
|
||||
smb_proc_readx (struct smb_server *server, struct smb_dirent *finfo, off_t offset, long count, char *data, int * error_ptr)
|
||||
smb_proc_readx (struct smb_server *server, struct smb_dirent *finfo, const QUAD * const offset_quad, long count, char *data, int * error_ptr)
|
||||
{
|
||||
char *buf = server->transmit_buffer;
|
||||
int result;
|
||||
@@ -1625,20 +1397,20 @@ smb_proc_readx (struct smb_server *server, struct smb_dirent *finfo, off_t offse
|
||||
BSET (buf, smb_vwv0, 0xFF); /* AndXCommand/AndXReserved - no additional SMB commands provided */
|
||||
WSET (buf, smb_vwv1, 0); /* AndXOffset */
|
||||
WSET (buf, smb_vwv2, finfo->fileid); /* fid */
|
||||
DSET (buf, smb_vwv3, offset); /* offset */
|
||||
DSET (buf, smb_vwv3, offset_quad->Low); /* offset */
|
||||
WSET (buf, smb_vwv5, count); /* MaxCountOfBytesToReturn */
|
||||
WSET (buf, smb_vwv6, 0); /* MinCountOfBytesToReturn */
|
||||
DSET (buf, smb_vwv7, 0); /* timeout */
|
||||
WSET (buf, smb_vwv9, 0); /* remaining */
|
||||
|
||||
if(server->protocol >= PROTOCOL_NT1)
|
||||
DSET (buf, smb_vwv10, 0); /* OffsetHigh */
|
||||
DSET (buf, smb_vwv10, offset_quad->High); /* OffsetHigh */
|
||||
|
||||
/* Now for the data portion of the message */
|
||||
|
||||
WSET (p, 0, 0); /* Byte count */
|
||||
|
||||
LOG(("requesting SMBreadX: offset=%ld, count=%ld\n", offset, count));
|
||||
LOG(("requesting SMBreadX: offset=%s, count=%ld\n", convert_quad_to_string(offset_quad), count));
|
||||
|
||||
result = smb_request_ok_with_payload (server, SMBreadX, 7, 0, data, NULL, count, error_ptr);
|
||||
if (result < 0)
|
||||
@@ -1654,12 +1426,12 @@ smb_proc_readx (struct smb_server *server, struct smb_dirent *finfo, off_t offse
|
||||
else
|
||||
{
|
||||
word data_length;
|
||||
|
||||
|
||||
p = SMB_VWV (server->transmit_buffer);
|
||||
smb_decode_word (p + 10, &data_length);
|
||||
|
||||
|
||||
LOG(("number of bytes read = %ld\n", data_length));
|
||||
|
||||
|
||||
result = data_length;
|
||||
}
|
||||
|
||||
@@ -1820,7 +1592,7 @@ smb_proc_mkdir (struct smb_server *server, const char *path, const int len, int
|
||||
WSET (outbuf, smb_msrcnt, 0); /* MaxSetupCount+Reserved1 */
|
||||
WSET (outbuf, smb_flags, 0); /* Flags */
|
||||
DSET (outbuf, smb_timeout, 0); /* Timeout */
|
||||
/* Reserved2 */
|
||||
/* Reserved2 */
|
||||
WSET (outbuf, smb_pscnt, WVAL (outbuf, smb_tpscnt)); /* ParameterCount */
|
||||
WSET (outbuf, smb_psoff, ((SMB_BUF (outbuf) + 3) - outbuf) - NETBIOS_HEADER_SIZE); /* ParameterOffset */
|
||||
WSET (outbuf, smb_dscnt, 0); /* DataCount */
|
||||
@@ -1975,7 +1747,8 @@ smb_decode_dirent (char *p, struct smb_dirent *entry)
|
||||
|
||||
entry->attr = BVAL (p, 0);
|
||||
entry->mtime = entry->atime = entry->ctime = entry->wtime = date_dos2unix (WVAL (p, 1), WVAL (p, 3));
|
||||
entry->size = DVAL (p, 5);
|
||||
entry->size_low = DVAL (p, 5);
|
||||
entry->size_high = 0;
|
||||
|
||||
name_size = 13;
|
||||
|
||||
@@ -1986,7 +1759,7 @@ smb_decode_dirent (char *p, struct smb_dirent *entry)
|
||||
|
||||
entry->complete_path[name_size] = '\0';
|
||||
|
||||
LOG (("path = %s\n", entry->complete_path));
|
||||
LOG (("path = '%s'\n", escape_name(entry->complete_path)));
|
||||
|
||||
#if DEBUG
|
||||
{
|
||||
@@ -2031,7 +1804,7 @@ smb_proc_readdir_short (struct smb_server *server, char *path, int fpos, int cac
|
||||
strcat (mask, "\\*.*");
|
||||
|
||||
LOG (("SMB call readdir %ld @ %ld\n", cache_size, fpos));
|
||||
LOG ((" mask = %s\n", mask));
|
||||
LOG ((" mask = '%s'\n", escape_name(mask)));
|
||||
|
||||
buf = server->transmit_buffer;
|
||||
|
||||
@@ -2265,8 +2038,10 @@ smb_decode_long_dirent (char *p, struct smb_dirent *finfo, int level, int * entr
|
||||
|
||||
if (finfo != NULL)
|
||||
{
|
||||
const char * name;
|
||||
int name_len;
|
||||
|
||||
|
||||
name = &p[27];
|
||||
name_len = BVAL (p, 26);
|
||||
|
||||
SHOWVALUE(name_len);
|
||||
@@ -2280,24 +2055,24 @@ smb_decode_long_dirent (char *p, struct smb_dirent *finfo, int level, int * entr
|
||||
break;
|
||||
}
|
||||
|
||||
finfo->ctime = date_dos2unix (WVAL (p, 6), WVAL (p, 4));
|
||||
finfo->atime = date_dos2unix (WVAL (p, 10), WVAL (p, 8));
|
||||
finfo->mtime = date_dos2unix (WVAL (p, 14), WVAL (p, 12));
|
||||
finfo->wtime = finfo->mtime;
|
||||
finfo->size = DVAL (p, 16);
|
||||
finfo->attr = WVAL (p, 24);
|
||||
finfo->len = name_len;
|
||||
|
||||
/* Don't return names with NUL bytes. */
|
||||
if(memchr(&p[27], '\0', name_len) != NULL)
|
||||
if(name_len == 0)
|
||||
{
|
||||
SHOWMSG("name contains NUL bytes (skipping it)");
|
||||
D(("name length == 0 (skipping it)"));
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(finfo->complete_path, &p[27], name_len);
|
||||
finfo->ctime = date_dos2unix (WVAL (p, 6), WVAL (p, 4));
|
||||
finfo->atime = date_dos2unix (WVAL (p, 10), WVAL (p, 8));
|
||||
finfo->mtime = date_dos2unix (WVAL (p, 14), WVAL (p, 12));
|
||||
finfo->wtime = finfo->mtime;
|
||||
finfo->size_low = DVAL (p, 16);
|
||||
finfo->size_high = DVAL (p, 16);
|
||||
finfo->attr = WVAL (p, 24);
|
||||
finfo->len = name_len;
|
||||
|
||||
memcpy(finfo->complete_path, name, name_len);
|
||||
finfo->complete_path[name_len] = '\0';
|
||||
}
|
||||
|
||||
@@ -2311,51 +2086,51 @@ smb_decode_long_dirent (char *p, struct smb_dirent *finfo, int level, int * entr
|
||||
|
||||
if (finfo != NULL)
|
||||
{
|
||||
dword size_low,size_high;
|
||||
int name_len;
|
||||
time_t swap;
|
||||
|
||||
p += 4; /* next entry offset */
|
||||
|
||||
|
||||
p += 4; /* fileindex */
|
||||
|
||||
|
||||
finfo->ctime = convert_long_date_to_time_t(p);
|
||||
p += 8;
|
||||
|
||||
|
||||
finfo->atime = convert_long_date_to_time_t(p);
|
||||
p += 8;
|
||||
|
||||
|
||||
finfo->wtime = convert_long_date_to_time_t(p);
|
||||
p += 8;
|
||||
|
||||
|
||||
finfo->mtime = convert_long_date_to_time_t(p);
|
||||
p += 8;
|
||||
|
||||
|
||||
/* If the modification time is not set, try to
|
||||
* substitute the write time for it.
|
||||
*/
|
||||
if(finfo->mtime == 0)
|
||||
finfo->mtime = finfo->wtime;
|
||||
|
||||
/* Swap last modification time and last write time. */
|
||||
swap = finfo->mtime;
|
||||
finfo->mtime = finfo->wtime;
|
||||
finfo->wtime = swap;
|
||||
|
||||
/* Note: size is a 64 bit integer, we only use the least significant 32 bits. */
|
||||
finfo->size = DVAL (p, 0);
|
||||
size_low = DVAL (p, 0);
|
||||
size_high = DVAL (p, 4);
|
||||
p += 8;
|
||||
|
||||
|
||||
finfo->size_low = size_low;
|
||||
finfo->size_high = size_high;
|
||||
|
||||
p += 8; /* alloc size */
|
||||
|
||||
|
||||
finfo->attr = DVAL (p, 0);
|
||||
p += 4;
|
||||
|
||||
|
||||
name_len = DVAL (p, 0);
|
||||
p += 4;
|
||||
|
||||
/* Skip directory entries whose names we cannot store. */
|
||||
if(name_len == 0)
|
||||
{
|
||||
SHOWMSG("name is empty");
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -2363,21 +2138,32 @@ smb_decode_long_dirent (char *p, struct smb_dirent *finfo, int level, int * entr
|
||||
SHOWVALUE(name_len);
|
||||
|
||||
p += 4; /* EA size */
|
||||
|
||||
|
||||
p += 1; /* short name length */
|
||||
p += 1; /* reserved */
|
||||
|
||||
|
||||
p += 12*2; /* short name (12 WCHAR characters) */
|
||||
|
||||
/* Skip directory entries whose names we cannot store. */
|
||||
if(name_len == 0)
|
||||
/* Just in case, try to remove any trailing NUL bytes from the name. */
|
||||
if(p[name_len - 1] == '\0')
|
||||
{
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
SHOWMSG("removing trailing NUL bytes from name");
|
||||
|
||||
if(p[name_len-1] == '\0')
|
||||
name_len--;
|
||||
do
|
||||
{
|
||||
name_len--;
|
||||
}
|
||||
while(name_len > 0 && p[name_len - 1] == '\0');
|
||||
|
||||
/* This shouldn't become an empty name. */
|
||||
if(name_len == 0)
|
||||
{
|
||||
SHOWMSG("name is empty");
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip directory entries whose names we cannot store. */
|
||||
if(name_len >= (int)finfo->complete_path_size)
|
||||
@@ -2388,15 +2174,6 @@ smb_decode_long_dirent (char *p, struct smb_dirent *finfo, int level, int * entr
|
||||
break;
|
||||
}
|
||||
|
||||
/* Don't return names with NUL bytes. */
|
||||
if(memchr(p, '\0', name_len) != NULL)
|
||||
{
|
||||
SHOWMSG("name contains NUL bytes (skipping it)");
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy (finfo->complete_path, p, name_len);
|
||||
finfo->complete_path[name_len] = '\0';
|
||||
finfo->len = name_len;
|
||||
@@ -2408,7 +2185,7 @@ smb_decode_long_dirent (char *p, struct smb_dirent *finfo, int level, int * entr
|
||||
default:
|
||||
|
||||
(*entry_length_ptr) = 0;
|
||||
|
||||
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
@@ -2441,7 +2218,7 @@ smb_proc_readdir_long (struct smb_server *server, char *path, int fpos, int cach
|
||||
int result = 0;
|
||||
|
||||
int ff_searchcount;
|
||||
int ff_eos = 0;
|
||||
int ff_end_of_search = 0;
|
||||
int ff_dir_handle = 0;
|
||||
int ff_resume_key = 0;
|
||||
int loop_count = 0;
|
||||
@@ -2451,9 +2228,9 @@ smb_proc_readdir_long (struct smb_server *server, char *path, int fpos, int cach
|
||||
int dirlen = strlen (path) + 2 + 1;
|
||||
char *mask;
|
||||
int masklen;
|
||||
|
||||
|
||||
int entry_length;
|
||||
|
||||
|
||||
ENTER();
|
||||
|
||||
/* ZZZ experimental 'max_matches' adjustment */
|
||||
@@ -2483,7 +2260,7 @@ smb_proc_readdir_long (struct smb_server *server, char *path, int fpos, int cach
|
||||
masklen = strlen (mask);
|
||||
|
||||
LOG (("SMB call lreaddir %ld @ %ld\n", cache_size, fpos));
|
||||
LOG ((" mask = %s\n", mask));
|
||||
LOG ((" mask = '%s'\n", escape_name(mask)));
|
||||
|
||||
resp_param = NULL;
|
||||
resp_data = NULL;
|
||||
@@ -2494,7 +2271,7 @@ smb_proc_readdir_long (struct smb_server *server, char *path, int fpos, int cach
|
||||
total_count = 0;
|
||||
current_entry = entry;
|
||||
|
||||
while (ff_eos == 0)
|
||||
while (ff_end_of_search == 0)
|
||||
{
|
||||
loop_count++;
|
||||
if (loop_count > 200)
|
||||
@@ -2520,7 +2297,7 @@ smb_proc_readdir_long (struct smb_server *server, char *path, int fpos, int cach
|
||||
WSET (outbuf, smb_msrcnt, 0); /* MaxSetupCount+Reserved1 */
|
||||
WSET (outbuf, smb_flags, 0); /* Flags */
|
||||
DSET (outbuf, smb_timeout, 0); /* Timeout */
|
||||
/* Reserved2 */
|
||||
/* Reserved2 */
|
||||
WSET (outbuf, smb_pscnt, WVAL (outbuf, smb_tpscnt)); /* ParameterCount */
|
||||
WSET (outbuf, smb_psoff, ((SMB_BUF (outbuf) + 3) - outbuf) - NETBIOS_HEADER_SIZE); /* ParameterOffset */
|
||||
WSET (outbuf, smb_dscnt, 0); /* DataCount */
|
||||
@@ -2540,18 +2317,18 @@ smb_proc_readdir_long (struct smb_server *server, char *path, int fpos, int cach
|
||||
LOG (("first match\n"));
|
||||
WSET (p, 0, attribute); /* attribute */
|
||||
WSET (p, 2, max_matches); /* max count */
|
||||
WSET (p, 4, 8 + 4 + 2); /* resume required + close on end + continue */
|
||||
WSET (p, 4, SMB_FIND_CLOSE_AT_EOS|SMB_FIND_RETURN_RESUME_KEYS|SMB_FIND_CONTINUE_FROM_LAST);
|
||||
WSET (p, 6, info_level);
|
||||
DSET (p, 8, 0);
|
||||
DSET (p, 8, 0); /* return every entry there is */
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG (("next match; ff_dir_handle=0x%lx ff_resume_key=%ld mask='%s'\n", ff_dir_handle, ff_resume_key, mask));
|
||||
LOG (("next match; ff_dir_handle=0x%lx ff_resume_key=%ld mask='%s'\n", ff_dir_handle, ff_resume_key, escape_name(mask)));
|
||||
WSET (p, 0, ff_dir_handle);
|
||||
WSET (p, 2, max_matches); /* max count */
|
||||
WSET (p, 4, info_level);
|
||||
DSET (p, 6, ff_resume_key);
|
||||
WSET (p, 10, 8 + 4 + 2); /* resume required + close on end + continue */
|
||||
WSET (p, 10, SMB_FIND_CLOSE_AT_EOS|SMB_FIND_RETURN_RESUME_KEYS|SMB_FIND_CONTINUE_FROM_LAST);
|
||||
}
|
||||
|
||||
p += 12;
|
||||
@@ -2615,15 +2392,15 @@ smb_proc_readdir_long (struct smb_server *server, char *path, int fpos, int cach
|
||||
ff_dir_handle = WVAL (p, 0);
|
||||
|
||||
ff_searchcount = WVAL (p, 2);
|
||||
ff_eos = WVAL (p, 4);
|
||||
ff_end_of_search = WVAL (p, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
ff_searchcount = WVAL (p, 0);
|
||||
ff_eos = WVAL (p, 2);
|
||||
ff_end_of_search = WVAL (p, 2);
|
||||
}
|
||||
|
||||
LOG (("received %ld entries (eos=%ld)\n",ff_searchcount, ff_eos));
|
||||
LOG (("received %ld entries (end_of_search=%ld)\n",ff_searchcount, ff_end_of_search));
|
||||
if (ff_searchcount == 0)
|
||||
break;
|
||||
|
||||
@@ -2785,7 +2562,7 @@ smb_proc_getattr_core (struct smb_server *server, const char *path, int len, str
|
||||
char *p;
|
||||
char *buf = server->transmit_buffer;
|
||||
|
||||
LOG (("path=%s\n", path));
|
||||
LOG (("path='%s'\n", escape_name(path)));
|
||||
|
||||
ASSERT( smb_payload_size(server, 0, 2 + len) >= 0 );
|
||||
|
||||
@@ -2808,7 +2585,8 @@ smb_proc_getattr_core (struct smb_server *server, const char *path, int len, str
|
||||
/* The server only tells us 1 time */
|
||||
entry->ctime = entry->atime = entry->mtime = entry->wtime = local2utc (DVAL (buf, smb_vwv1));
|
||||
|
||||
entry->size = DVAL (buf, smb_vwv3);
|
||||
entry->size_low = DVAL (buf, smb_vwv3);
|
||||
entry->size_high = 0;
|
||||
|
||||
#if DEBUG
|
||||
{
|
||||
@@ -2855,7 +2633,7 @@ smb_query_path_information(struct smb_server *server, const char *path, int len,
|
||||
WSET (outbuf, smb_msrcnt, 0); /* MaxSetupCount+Reserved1 */
|
||||
WSET (outbuf, smb_flags, 0); /* Flags */
|
||||
DSET (outbuf, smb_timeout, 0); /* Timeout */
|
||||
/* Reserved2 */
|
||||
/* Reserved2 */
|
||||
WSET (outbuf, smb_pscnt, WVAL (outbuf, smb_tpscnt)); /* ParameterCount */
|
||||
WSET (outbuf, smb_psoff, ((SMB_BUF (outbuf) + 3) - outbuf) - NETBIOS_HEADER_SIZE); /* ParameterOffset */
|
||||
WSET (outbuf, smb_dscnt, 0); /* DataCount */
|
||||
@@ -2927,15 +2705,20 @@ smb_query_path_information(struct smb_server *server, const char *path, int len,
|
||||
p = smb_decode_dword(p, &end_of_file_low);
|
||||
(void) smb_decode_dword(p, &end_of_file_high);
|
||||
|
||||
entry->size = end_of_file_low;
|
||||
entry->size_low = end_of_file_low;
|
||||
entry->size_high = end_of_file_high;
|
||||
|
||||
#if DEBUG
|
||||
{
|
||||
struct tm tm;
|
||||
QUAD entry_size_quad;
|
||||
|
||||
entry_size_quad.Low = entry->size_low;
|
||||
entry_size_quad.High = entry->size_high;
|
||||
|
||||
GMTime(entry->mtime,&tm);
|
||||
LOG(("mtime = %ld-%02ld-%02ld %ld:%02ld:%02ld\n",tm.tm_year + 1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec));
|
||||
LOG(("size = %lu (0x%08lx)\n",entry->size,entry->size));
|
||||
LOG(("size = %s (0x%08lx:0x%08lx)\n",convert_quad_to_string(&entry_size_quad),entry->size_high,entry->size_low));
|
||||
LOG(("attr = 0x%08lx\n",entry->attr));
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
@@ -2969,12 +2752,13 @@ smb_proc_getattrE (struct smb_server *server, struct smb_dirent *entry, int * er
|
||||
goto out;
|
||||
}
|
||||
|
||||
entry->ctime = date_dos2unix (WVAL (buf, smb_vwv1), WVAL (buf, smb_vwv0));
|
||||
entry->atime = date_dos2unix (WVAL (buf, smb_vwv3), WVAL (buf, smb_vwv2));
|
||||
entry->mtime = date_dos2unix (WVAL (buf, smb_vwv5), WVAL (buf, smb_vwv4));
|
||||
entry->wtime = entry->mtime;
|
||||
entry->size = DVAL (buf, smb_vwv6);
|
||||
entry->attr = WVAL (buf, smb_vwv10);
|
||||
entry->ctime = date_dos2unix (WVAL (buf, smb_vwv1), WVAL (buf, smb_vwv0));
|
||||
entry->atime = date_dos2unix (WVAL (buf, smb_vwv3), WVAL (buf, smb_vwv2));
|
||||
entry->mtime = date_dos2unix (WVAL (buf, smb_vwv5), WVAL (buf, smb_vwv4));
|
||||
entry->wtime = entry->mtime;
|
||||
entry->size_low = DVAL (buf, smb_vwv6);
|
||||
entry->size_high = 0;
|
||||
entry->attr = WVAL (buf, smb_vwv10);
|
||||
|
||||
#if DEBUG
|
||||
{
|
||||
@@ -3000,17 +2784,17 @@ smb_proc_getattrE (struct smb_server *server, struct smb_dirent *entry, int * er
|
||||
}
|
||||
|
||||
int
|
||||
smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, const dword * size_ptr, int * error_ptr)
|
||||
smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, const QUAD * const size_quad, int * error_ptr)
|
||||
{
|
||||
unsigned char *outbuf = server->transmit_buffer;
|
||||
int data_size;
|
||||
char * p;
|
||||
int result;
|
||||
QUAD change_time;
|
||||
QUAD change_time_quad;
|
||||
|
||||
retry:
|
||||
|
||||
data_size = (size_ptr == NULL) ? 40 : 8;
|
||||
data_size = (size_quad == NULL) ? 40 : 8;
|
||||
|
||||
ASSERT( smb_payload_size(server, 15, 3 + 6 + 2 + data_size) >= 0 );
|
||||
|
||||
@@ -3023,7 +2807,7 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co
|
||||
WSET (outbuf, smb_msrcnt, 0); /* MaxSetupCount+Reserved1 */
|
||||
WSET (outbuf, smb_flags, 0); /* Flags */
|
||||
DSET (outbuf, smb_timeout, 0); /* Timeout */
|
||||
/* Reserved2 */
|
||||
/* Reserved2 */
|
||||
WSET (outbuf, smb_pscnt, WVAL (outbuf, smb_tpscnt)); /* ParameterCount */
|
||||
WSET (outbuf, smb_psoff, ((SMB_BUF (outbuf) + 3) - outbuf) - NETBIOS_HEADER_SIZE); /* ParameterOffset */
|
||||
WSET (outbuf, smb_dscnt, WVAL (outbuf, smb_tdscnt)); /* DataCount */
|
||||
@@ -3039,7 +2823,7 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co
|
||||
(*p++) = '\0';
|
||||
|
||||
WSET (p, 0, entry->fileid);
|
||||
WSET (p, 2, size_ptr == NULL ? SMB_SET_FILE_BASIC_INFO : SMB_SET_FILE_END_OF_FILE_INFO);
|
||||
WSET (p, 2, size_quad == NULL ? SMB_SET_FILE_BASIC_INFO : SMB_SET_FILE_END_OF_FILE_INFO);
|
||||
WSET (p, 4, 0);
|
||||
|
||||
p += 6;
|
||||
@@ -3048,7 +2832,7 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co
|
||||
(*p++) = '\0';
|
||||
(*p++) = '\0';
|
||||
|
||||
if(size_ptr == NULL)
|
||||
if(size_quad == NULL)
|
||||
{
|
||||
/* Creation time (no change) */
|
||||
DSET(p, 0, 0);
|
||||
@@ -3058,15 +2842,15 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co
|
||||
DSET(p, 8, 0);
|
||||
DSET(p, 12, 0);
|
||||
|
||||
convert_time_t_to_long_date(entry->mtime,&change_time);
|
||||
convert_time_t_to_long_date(entry->mtime,&change_time_quad);
|
||||
|
||||
/* Last write time */
|
||||
DSET(p, 16, change_time.Low);
|
||||
DSET(p, 20, change_time.High);
|
||||
DSET(p, 16, change_time_quad.Low);
|
||||
DSET(p, 20, change_time_quad.High);
|
||||
|
||||
/* Change time */
|
||||
DSET(p, 24, change_time.Low);
|
||||
DSET(p, 28, change_time.High);
|
||||
DSET(p, 24, change_time_quad.Low);
|
||||
DSET(p, 28, change_time_quad.High);
|
||||
|
||||
/* Extended file attributes */
|
||||
DSET(p, 32, entry->attr);
|
||||
@@ -3077,8 +2861,8 @@ smb_set_file_information(struct smb_server *server, struct smb_dirent *entry, co
|
||||
else
|
||||
{
|
||||
/* End of file */
|
||||
DSET(p, 0, (*size_ptr));
|
||||
DSET(p, 4, 0);
|
||||
DSET(p, 0, size_quad->Low);
|
||||
DSET(p, 4, size_quad->High);
|
||||
}
|
||||
|
||||
result = smb_trans2_request (server, SMBtrans2, NULL, NULL, NULL, NULL, error_ptr);
|
||||
@@ -3220,7 +3004,7 @@ smb_proc_dskattr (struct smb_server *server, struct smb_dskattr *attr, int * err
|
||||
WSET (outbuf, smb_msrcnt, 0); /* MaxSetupCount+Reserved1 */
|
||||
WSET (outbuf, smb_flags, 0); /* Flags */
|
||||
DSET (outbuf, smb_timeout, 0); /* Timeout */
|
||||
/* Reserved2 */
|
||||
/* Reserved2 */
|
||||
WSET (outbuf, smb_pscnt, WVAL (outbuf, smb_tpscnt)); /* ParameterCount */
|
||||
WSET (outbuf, smb_psoff, ((SMB_BUF (outbuf) + 3) - outbuf) - NETBIOS_HEADER_SIZE); /* ParameterOffset */
|
||||
WSET (outbuf, smb_dscnt, 0); /* DataCount */
|
||||
@@ -3686,7 +3470,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
|
||||
|
||||
smb_setup_header (server, SMBsesssetupX, 13, user_len + password_len + nt_password_len + strlen (server->mount_data.workgroup_name)+1 + strlen (native_os)+1 + strlen (native_lanman)+1);
|
||||
|
||||
capabilities = CAP_RAW_MODE|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_NT_FIND|CAP_LARGE_FILES;
|
||||
capabilities = CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_NT_FIND|CAP_LARGE_FILES;
|
||||
|
||||
WSET (packet, smb_vwv0, 0xff); /* AndXCommand+AndXReserved */
|
||||
WSET (packet, smb_vwv1, 0); /* AndXOffset */
|
||||
@@ -3797,7 +3581,7 @@ smb_proc_reconnect (struct smb_server *server, int * error_ptr)
|
||||
|
||||
StringToUpper(full_share);
|
||||
|
||||
SHOWSTRING(full_share);
|
||||
D(("full_share = '%s'", escape_name(full_share)));
|
||||
|
||||
ASSERT( smb_payload_size(server, 4, password_len + full_share_len+1 + strlen(dev)+1) >= 0 );
|
||||
|
||||
|
||||
+46
-1
@@ -119,7 +119,7 @@ divide_64_by_32(const QUAD * const dividend,ULONG divisor,QUAD * quotient)
|
||||
{
|
||||
QUAD dividend_cdef = (*dividend);
|
||||
ULONG dividend_ab = 0;
|
||||
LONG i;
|
||||
int i;
|
||||
|
||||
quotient->High = quotient->Low = 0;
|
||||
|
||||
@@ -169,6 +169,22 @@ divide_64_by_32(const QUAD * const dividend,ULONG divisor,QUAD * quotient)
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Add an unsigned 32 bit quantity to a 64 bit quantity, yielding a
|
||||
* 64 bit sum.
|
||||
*/
|
||||
ULONG
|
||||
add_64_plus_32_to_64(const QUAD * const a,ULONG b,QUAD * ab)
|
||||
{
|
||||
QUAD b_quad;
|
||||
|
||||
b_quad.Low = b;
|
||||
b_quad.High = 0;
|
||||
|
||||
return(add_64_plus_64_to_64(a,&b_quad,ab));
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Add an unsigned 64 bit quantity to a 64 bit quantity, yielding a
|
||||
* 64 bit sum.
|
||||
*/
|
||||
@@ -243,3 +259,32 @@ subtract_64_from_64_to_64(const QUAD * const minuend,const QUAD * const subtrahe
|
||||
/* Return the underflow, if any. */
|
||||
return(extended_minuend.High);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Compare two unsigned 64 bit integers in the manner of strcmp(). */
|
||||
int
|
||||
compare_64_to_64(const QUAD * const a,const QUAD * const b)
|
||||
{
|
||||
int result;
|
||||
|
||||
if(a->High < b->High)
|
||||
{
|
||||
result = -1;
|
||||
}
|
||||
else if (a->High == b->High)
|
||||
{
|
||||
if (a->Low < b->Low)
|
||||
result = -1;
|
||||
else if (a->Low == b->Low)
|
||||
result = 0;
|
||||
else
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
@@ -42,8 +42,10 @@ typedef struct
|
||||
VOID multiply_32_by_32_to_64(ULONG ab,ULONG cd,QUAD * product);
|
||||
ULONG multiply_64_by_32_to_64(const QUAD * const abcd,ULONG ef,QUAD * abcdef);
|
||||
ULONG divide_64_by_32(const QUAD * const dividend,ULONG divisor,QUAD * quotient);
|
||||
ULONG add_64_plus_32_to_64(const QUAD * const a,ULONG b,QUAD * ab);
|
||||
ULONG add_64_plus_64_to_64(const QUAD * const a,const QUAD * const b,QUAD * ab);
|
||||
ULONG subtract_64_from_64_to_64(const QUAD * const minuend,const QUAD * const subtrahend,QUAD * difference);
|
||||
int compare_64_to_64(const QUAD * const a,const QUAD * const b);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
@@ -104,13 +104,13 @@ system_headers.gst: system_headers.h system_headers.c
|
||||
assert.o : assert.c
|
||||
cp437.o : cp437.c
|
||||
cp850.o : cp850.c
|
||||
crypt.o : crypt.c system_headers.h assert.h smbfs.h
|
||||
dump_smb.o : dump_smb.c system_headers.h assert.h smbfs.h dump_smb.h quad_math.h
|
||||
main.o : main.c system_headers.h assert.h smbfs.h smb_abstraction.h utf-8-iso-8859-1-conversion.h cp437.h cp850.h errors.h dump_smb.h smbfs_rev.h
|
||||
proc.o : proc.c system_headers.h assert.h smbfs.h quad_math.h errors.h smbfs_rev.h
|
||||
crypt.o : crypt.c system_headers.h assert.h quad_math.h smbfs.h
|
||||
dump_smb.o : dump_smb.c system_headers.h assert.h quad_math.h smbfs.h dump_smb.h
|
||||
main.o : main.c system_headers.h assert.h quad_math.h smbfs.h smb_abstraction.h utf-8-iso-8859-1-conversion.h cp437.h cp850.h errors.h dump_smb.h smbfs_rev.h
|
||||
proc.o : proc.c system_headers.h assert.h quad_math.h smbfs.h errors.h smbfs_rev.h
|
||||
quad_math.o : quad_math.c quad_math.h
|
||||
smb_abstraction.o : smb_abstraction.c system_headers.h assert.h smbfs.h smb_abstraction.h
|
||||
sock.o : sock.c system_headers.h assert.h smbfs.h smb_abstraction.h dump_smb.h errors.h
|
||||
smb_abstraction.o : smb_abstraction.c system_headers.h assert.h quad_math.h smbfs.h errors.h smb_abstraction.h
|
||||
sock.o : sock.c system_headers.h assert.h quad_math.h smbfs.h smb_abstraction.h dump_smb.h errors.h
|
||||
swap_stack_and_call.o : swap_stack_and_call.asm
|
||||
utf-8-iso-8859-1-conversion.o : utf-8-iso-8859-1-conversion.c utf-8-iso-8859-1-conversion.h
|
||||
|
||||
|
||||
+59
-171
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "smbfs.h"
|
||||
#include "errors.h"
|
||||
#include "quad_math.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@@ -82,10 +83,6 @@ smba_connect (
|
||||
int max_transmit,
|
||||
int timeout,
|
||||
int opt_raw_smb,
|
||||
int opt_write_behind,
|
||||
int opt_prefer_write_raw,
|
||||
int opt_disable_write_raw,
|
||||
int opt_disable_read_raw,
|
||||
char * opt_native_os,
|
||||
int * error_ptr,
|
||||
int * smb_error_class_ptr,
|
||||
@@ -117,26 +114,6 @@ smba_connect (
|
||||
if(opt_raw_smb)
|
||||
res->server.raw_smb = TRUE;
|
||||
|
||||
/* olsen (2016-04-20): Use write-behind with SMB_COM_WRITE_RAW. */
|
||||
if(opt_write_behind)
|
||||
res->server.write_behind = TRUE;
|
||||
|
||||
/* olsen (2018-05-08): Always use SMB_COM_WRITE, even if SMB_COM_WRITE_RAW were possible. */
|
||||
if(opt_disable_write_raw)
|
||||
{
|
||||
res->server.disable_write_raw = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* olsen (2016-04-20): Prefer the use of SMB_COM_WRITE_RAW over SMB_COM_WRITE. */
|
||||
if(opt_prefer_write_raw)
|
||||
res->server.prefer_write_raw = TRUE;
|
||||
}
|
||||
|
||||
/* olsen (2018-05-08): Always use SMB_COM_READ, even if SMB_COM_READ_RAW were possible. */
|
||||
if(opt_disable_read_raw)
|
||||
res->server.disable_read_raw = TRUE;
|
||||
|
||||
/* olsen (2018-05-09): Timeout for send/receive operations in seconds. */
|
||||
res->server.timeout = timeout;
|
||||
|
||||
@@ -301,7 +278,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate, int * erro
|
||||
{
|
||||
if(!f->dirent.opened)
|
||||
{
|
||||
LOG (("opening file %s\n", f->dirent.complete_path));
|
||||
LOG (("opening file '%s'\n", escape_name(f->dirent.complete_path)));
|
||||
|
||||
result = smb_proc_open (&s->server, f->dirent.complete_path, f->dirent.len, writable, truncate, &f->dirent, error_ptr);
|
||||
if (result < 0)
|
||||
@@ -309,7 +286,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate, int * erro
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG (("file %s is already open\n", f->dirent.complete_path));
|
||||
LOG (("file '%s' is already open\n", escape_name(f->dirent.complete_path)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -317,7 +294,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate, int * erro
|
||||
{
|
||||
if(!f->dirent.opened)
|
||||
{
|
||||
LOG (("opening file %s\n", f->dirent.complete_path));
|
||||
LOG (("opening file '%s'\n", escape_name(f->dirent.complete_path)));
|
||||
|
||||
result = smb_proc_open (&s->server, f->dirent.complete_path, f->dirent.len, writable, truncate, &f->dirent, error_ptr);
|
||||
if (result < 0)
|
||||
@@ -325,7 +302,7 @@ make_open (smba_file_t * f, int need_fid, int writable, int truncate, int * erro
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG (("file %s is already open\n", f->dirent.complete_path));
|
||||
LOG (("file '%s' is already open\n", escape_name(f->dirent.complete_path)));
|
||||
}
|
||||
|
||||
if (s->supports_E || !s->supports_E_known)
|
||||
@@ -394,7 +371,7 @@ smba_open (smba_server_t * s, char *name, size_t name_size, int writable, int tr
|
||||
f->dirent.len = strlen (name);
|
||||
f->server = s;
|
||||
|
||||
LOG(("open '%s' (writable=%s, truncate=%s)\n", name, writable ? "yes" : "no", truncate ? "yes" : "no"));
|
||||
LOG(("open '%s' (writable=%s, truncate=%s)\n", escape_name(name), writable ? "yes" : "no", truncate ? "yes" : "no"));
|
||||
|
||||
result = make_open (f, open_dont_need_fid, writable, truncate, error_ptr);
|
||||
if (result < 0)
|
||||
@@ -426,7 +403,7 @@ write_attr (smba_file_t * f, int * error_ptr)
|
||||
{
|
||||
int result;
|
||||
|
||||
LOG (("file %s\n", f->dirent.complete_path));
|
||||
LOG (("file '%s'\n", escape_name(f->dirent.complete_path)));
|
||||
|
||||
if(f->server->server.protocol >= PROTOCOL_LANMAN2)
|
||||
{
|
||||
@@ -468,7 +445,7 @@ smba_close (smba_file_t * f, int * error_ptr)
|
||||
{
|
||||
if(f != NULL)
|
||||
{
|
||||
LOG (("closing file '%s'\n", f->dirent.complete_path));
|
||||
LOG (("closing file '%s'\n", escape_name(f->dirent.complete_path)));
|
||||
|
||||
if(f->node.mln_Succ != NULL || f->node.mln_Pred != NULL)
|
||||
Remove((struct Node *)f);
|
||||
@@ -500,7 +477,7 @@ smba_close (smba_file_t * f, int * error_ptr)
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
smba_read (smba_file_t * f, char *data, long len, long offset, int * error_ptr)
|
||||
smba_read (smba_file_t * f, char *data, long len, const QUAD * const offset, int * error_ptr)
|
||||
{
|
||||
int max_receive = f->server->server.max_recv;
|
||||
int num_bytes_read = 0;
|
||||
@@ -514,6 +491,7 @@ smba_read (smba_file_t * f, char *data, long len, long offset, int * error_ptr)
|
||||
|
||||
if (f->server->server.protocol >= PROTOCOL_LANMAN1)
|
||||
{
|
||||
QUAD position_quad = (*offset);
|
||||
int max_readx_size;
|
||||
int count;
|
||||
|
||||
@@ -556,13 +534,13 @@ smba_read (smba_file_t * f, char *data, long len, long offset, int * error_ptr)
|
||||
{
|
||||
count = min(len, max_readx_size);
|
||||
|
||||
result = smb_proc_readx (&f->server->server, &f->dirent, offset, count, data, error_ptr);
|
||||
result = smb_proc_readx (&f->server->server, &f->dirent, &position_quad, count, data, error_ptr);
|
||||
if (result < 0)
|
||||
goto out;
|
||||
|
||||
num_bytes_read += result;
|
||||
len -= result;
|
||||
offset += result;
|
||||
add_64_plus_32_to_64(&position_quad,result,&position_quad);
|
||||
data += result;
|
||||
|
||||
if(result < count)
|
||||
@@ -573,50 +551,10 @@ smba_read (smba_file_t * f, char *data, long len, long offset, int * error_ptr)
|
||||
}
|
||||
while (len > 0);
|
||||
}
|
||||
/* SMB_COM_READ_RAW and SMB_COM_WRITE_RAW supported? */
|
||||
else if ((f->server->server.capabilities & CAP_RAW_MODE) != 0 && !f->server->server.disable_read_raw)
|
||||
{
|
||||
int max_raw_size = f->server->server.max_raw_size;
|
||||
int n;
|
||||
|
||||
do
|
||||
{
|
||||
/* SMB_COM_READ_RAW can only read up to 65535 bytes. */
|
||||
n = min(len, 65535);
|
||||
|
||||
/* The maximum number of bytes to be read in raw
|
||||
* mode may be limited, too.
|
||||
*/
|
||||
if(n > max_raw_size)
|
||||
n = max_raw_size;
|
||||
|
||||
/* Limit how much data we are prepared to receive? */
|
||||
if(n > max_receive)
|
||||
n = max_receive;
|
||||
|
||||
result = smb_proc_read_raw (&f->server->server, &f->dirent, offset, n, data, error_ptr);
|
||||
if(result <= 0)
|
||||
{
|
||||
D(("!!! wanted to read %ld bytes, got %ld",n,result));
|
||||
break;
|
||||
}
|
||||
|
||||
num_bytes_read += result;
|
||||
len -= result;
|
||||
offset += result;
|
||||
data += result;
|
||||
|
||||
if(result < n)
|
||||
{
|
||||
D(("read returned fewer characters than expected (%ld < %ld)",result,n));
|
||||
break;
|
||||
}
|
||||
}
|
||||
while(len > 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int max_size_smb_com_read;
|
||||
off_t position = offset->Low;
|
||||
int count;
|
||||
|
||||
/* Calculate maximum number of bytes that could be transferred with
|
||||
@@ -664,13 +602,13 @@ smba_read (smba_file_t * f, char *data, long len, long offset, int * error_ptr)
|
||||
if(count > max_receive)
|
||||
count = max_receive;
|
||||
|
||||
result = smb_proc_read (&f->server->server, &f->dirent, offset, count, data, error_ptr);
|
||||
result = smb_proc_read (&f->server->server, &f->dirent, position, count, data, error_ptr);
|
||||
if (result < 0)
|
||||
goto out;
|
||||
|
||||
num_bytes_read += result;
|
||||
len -= result;
|
||||
offset += result;
|
||||
position += result;
|
||||
data += result;
|
||||
|
||||
if(result < count)
|
||||
@@ -692,7 +630,7 @@ smba_read (smba_file_t * f, char *data, long len, long offset, int * error_ptr)
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
smba_write (smba_file_t * f, const char *data, long len, long offset, int * error_ptr)
|
||||
smba_write (smba_file_t * f, const char *data, long len, const QUAD * const offset, int * error_ptr)
|
||||
{
|
||||
int num_bytes_written = 0;
|
||||
int max_buffer_size;
|
||||
@@ -709,6 +647,7 @@ smba_write (smba_file_t * f, const char *data, long len, long offset, int * erro
|
||||
/* SMB_COM_WRITE_ANDX supported? */
|
||||
if (f->server->server.protocol >= PROTOCOL_LANMAN1)
|
||||
{
|
||||
QUAD position_quad = (*offset);
|
||||
int max_writex_size;
|
||||
int n;
|
||||
|
||||
@@ -754,69 +693,14 @@ smba_write (smba_file_t * f, const char *data, long len, long offset, int * erro
|
||||
|
||||
LOG(("writing %ld bytes; offset=%lu, len=%ld\n", n, offset, len));
|
||||
|
||||
result = smb_proc_writex(&f->server->server, &f->dirent, offset, n, data, error_ptr);
|
||||
result = smb_proc_writex(&f->server->server, &f->dirent, &position_quad, n, data, error_ptr);
|
||||
if(result < 0)
|
||||
goto out;
|
||||
|
||||
LOG(("number of bytes written = %ld\n", result));
|
||||
|
||||
data += result;
|
||||
offset += result;
|
||||
len -= result;
|
||||
num_bytes_written += result;
|
||||
}
|
||||
while(len > 0);
|
||||
}
|
||||
else if ((f->server->server.capabilities & CAP_RAW_MODE) != 0 && !f->server->server.disable_write_raw)
|
||||
{
|
||||
int max_raw_size = f->server->server.max_raw_size;
|
||||
int max_size_smb_com_write_raw;
|
||||
int n;
|
||||
|
||||
/* Try to send the maximum number of bytes with the two SMBwritebraw packets.
|
||||
* This is how it breaks down:
|
||||
*
|
||||
* The message header accounts for
|
||||
* 4(protocol)+1(command)+4(status)+1(flags)+2(flags2)+2(pidhigh)+
|
||||
* 8(securityfeatures)+2(reserved)+2(tid)+2(pidlow)+2(uid)+2(mid)
|
||||
* = 32 bytes
|
||||
*
|
||||
* The parameters of a SMB_COM_WRITE_RAW command account for
|
||||
* 1(wordcount)+2(fid)+2(countofbytes)+2(reserved1)+4(offset)+
|
||||
* 4(timeout)+2(writemode)+4(reserved2)+2(datalength)+
|
||||
* 2(dataoffset) = 25 bytes
|
||||
*
|
||||
* The data part of a SMB_COM_WRITE_RAW command accounts for
|
||||
* 2(bytecount) = 2 bytes
|
||||
*
|
||||
* This leaves 'max_buffer_size' - 59 for the payload.
|
||||
*/
|
||||
/*max_size_smb_com_write_raw = 2 * f->server->server.max_buffer_size - (SMB_HEADER_LEN + 12 * sizeof (word) + 4) - 8;*/
|
||||
max_size_smb_com_write_raw = max(max_buffer_size, max_raw_size) - 59;
|
||||
|
||||
/* SMB_COM_WRITE_RAW cannot transmit more than 65535 bytes. */
|
||||
if(max_size_smb_com_write_raw > 65535)
|
||||
max_size_smb_com_write_raw = 65535;
|
||||
|
||||
LOG (("len = %ld, max_size_smb_com_write_raw = %ld\n", len, max_size_smb_com_write_raw));
|
||||
|
||||
do
|
||||
{
|
||||
n = min(len, max_size_smb_com_write_raw);
|
||||
|
||||
ASSERT( n > 0 );
|
||||
|
||||
if(n > max_raw_size)
|
||||
n = max_raw_size;
|
||||
|
||||
ASSERT( n <= 65535 );
|
||||
|
||||
result = smb_proc_write_raw (&f->server->server, &f->dirent, offset, n, data, error_ptr);
|
||||
if(result < 0)
|
||||
goto out;
|
||||
|
||||
data += result;
|
||||
offset += result;
|
||||
add_64_plus_32_to_64(&position_quad,result,&position_quad);
|
||||
len -= result;
|
||||
num_bytes_written += result;
|
||||
}
|
||||
@@ -825,6 +709,7 @@ smba_write (smba_file_t * f, const char *data, long len, long offset, int * erro
|
||||
else
|
||||
{
|
||||
int max_size_smb_com_write, count;
|
||||
off_t position = offset->Low;
|
||||
|
||||
/* Calculate maximum number of bytes that could be transferred with
|
||||
* a single SMBwrite packet...
|
||||
@@ -864,12 +749,12 @@ smba_write (smba_file_t * f, const char *data, long len, long offset, int * erro
|
||||
|
||||
ASSERT( count <= 65535 );
|
||||
|
||||
result = smb_proc_write (&f->server->server, &f->dirent, offset, count, data, error_ptr);
|
||||
result = smb_proc_write (&f->server->server, &f->dirent, position, count, data, error_ptr);
|
||||
if (result < 0)
|
||||
goto out;
|
||||
|
||||
len -= result;
|
||||
offset += result;
|
||||
position += result;
|
||||
data += result;
|
||||
num_bytes_written += result;
|
||||
}
|
||||
@@ -891,8 +776,22 @@ smba_write (smba_file_t * f, const char *data, long len, long offset, int * erro
|
||||
* at writing some data. Hence we update the cached file
|
||||
* size here.
|
||||
*/
|
||||
if (offset + num_bytes_written > (int)f->dirent.size) /* ZZZ overflow check needed? */
|
||||
f->dirent.size = offset + num_bytes_written;
|
||||
if(num_bytes_written > 0)
|
||||
{
|
||||
QUAD size_quad;
|
||||
QUAD new_position_quad;
|
||||
|
||||
size_quad.Low = f->dirent.size_low;
|
||||
size_quad.High = f->dirent.size_high;
|
||||
|
||||
add_64_plus_32_to_64(offset,num_bytes_written,&new_position_quad);
|
||||
|
||||
if(compare_64_to_64(&new_position_quad,&size_quad) > 0)
|
||||
{
|
||||
f->dirent.size_low = new_position_quad.Low;
|
||||
f->dirent.size_high = new_position_quad.High;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -951,7 +850,7 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
|
||||
|
||||
if (f->attr_time == 0 || (now > f->attr_time && now - f->attr_time > ATTR_CACHE_TIME))
|
||||
{
|
||||
LOG (("file %s\n", f->dirent.complete_path));
|
||||
LOG (("file '%s'\n", escape_name(f->dirent.complete_path)));
|
||||
|
||||
if (f->server->server.protocol >= PROTOCOL_LANMAN2)
|
||||
{
|
||||
@@ -980,7 +879,9 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
|
||||
data->is_system = (f->dirent.attr & aSYSTEM) != 0;
|
||||
data->is_changed_since_last_archive = (f->dirent.attr & aARCH) != 0;
|
||||
|
||||
data->size = f->dirent.size;
|
||||
data->size_low = f->dirent.size_low;
|
||||
data->size_high = f->dirent.size_high;
|
||||
|
||||
data->atime = f->dirent.atime;
|
||||
data->ctime = f->dirent.ctime;
|
||||
data->mtime = f->dirent.mtime;
|
||||
@@ -993,7 +894,7 @@ smba_getattr (smba_file_t * f, smba_stat_t * data, int * error_ptr)
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
smba_setattr (smba_file_t * f, const smba_stat_t * data, const dword * size_ptr, int * error_ptr)
|
||||
smba_setattr (smba_file_t * f, const smba_stat_t * data, const QUAD * const size, int * error_ptr)
|
||||
{
|
||||
BOOL times_changed = FALSE;
|
||||
int result = 0;
|
||||
@@ -1001,19 +902,19 @@ smba_setattr (smba_file_t * f, const smba_stat_t * data, const dword * size_ptr,
|
||||
|
||||
if (data != NULL)
|
||||
{
|
||||
if (data->atime != -1 && f->dirent.atime != data->atime)
|
||||
if (data->atime != (time_t)-1 && f->dirent.atime != data->atime)
|
||||
{
|
||||
f->dirent.atime = data->atime;
|
||||
times_changed = TRUE;
|
||||
}
|
||||
|
||||
if (data->ctime != -1 && f->dirent.ctime != data->ctime)
|
||||
if (data->ctime != (time_t)-1 && f->dirent.ctime != data->ctime)
|
||||
{
|
||||
f->dirent.ctime = data->ctime;
|
||||
times_changed = TRUE;
|
||||
}
|
||||
|
||||
if (data->mtime != -1 && f->dirent.mtime != data->mtime)
|
||||
if (data->mtime != (time_t)-1 && f->dirent.mtime != data->mtime)
|
||||
{
|
||||
f->dirent.mtime = data->mtime;
|
||||
times_changed = TRUE;
|
||||
@@ -1031,13 +932,6 @@ smba_setattr (smba_file_t * f, const smba_stat_t * data, const dword * size_ptr,
|
||||
else
|
||||
attrs &= ~aARCH;
|
||||
|
||||
/*
|
||||
if (data->is_system)
|
||||
attrs |= aSYSTEM;
|
||||
else
|
||||
attrs &= ~aSYSTEM;
|
||||
*/
|
||||
|
||||
if(f->dirent.attr != attrs)
|
||||
{
|
||||
f->dirent.attr = attrs;
|
||||
@@ -1052,21 +946,22 @@ smba_setattr (smba_file_t * f, const smba_stat_t * data, const dword * size_ptr,
|
||||
}
|
||||
}
|
||||
|
||||
if (size_ptr != NULL && (*size_ptr) != f->dirent.size)
|
||||
if (size != NULL && (size->Low != f->dirent.size_low || size->High != f->dirent.size_high))
|
||||
{
|
||||
result = make_open (f, open_need_fid, open_writable, open_dont_truncate, error_ptr);
|
||||
if(result < 0)
|
||||
goto out;
|
||||
|
||||
if(f->server->server.protocol >= PROTOCOL_LANMAN2)
|
||||
result = smb_set_file_information (&f->server->server, &f->dirent, size_ptr, error_ptr);
|
||||
result = smb_set_file_information (&f->server->server, &f->dirent, size, error_ptr);
|
||||
else
|
||||
result = smb_proc_trunc (&f->server->server, f->dirent.fileid, (*size_ptr), error_ptr);
|
||||
result = smb_proc_trunc (&f->server->server, f->dirent.fileid, size->Low, error_ptr);
|
||||
|
||||
if(result < 0)
|
||||
goto out;
|
||||
|
||||
f->dirent.size = (*size_ptr);
|
||||
f->dirent.size_low = size->Low;
|
||||
f->dirent.size_high = size->High;
|
||||
}
|
||||
|
||||
out:
|
||||
@@ -1123,7 +1018,7 @@ smba_readdir (smba_file_t * f, long offs, void *d, smba_callback_t callback, int
|
||||
if (cache_index >= f->dircache->base + f->dircache->len && f->dircache->eof)
|
||||
break; /* nothing more to read */
|
||||
|
||||
LOG (("cachefill for %s\n", f->dirent.complete_path));
|
||||
LOG (("cachefill for '%s'\n", escape_name(f->dirent.complete_path)));
|
||||
LOG (("\tbase was: %ld, len was: %ld, newbase=%ld\n", f->dircache->base, f->dircache->len, cache_index));
|
||||
|
||||
f->dircache->len = 0;
|
||||
@@ -1162,14 +1057,15 @@ smba_readdir (smba_file_t * f, long offs, void *d, smba_callback_t callback, int
|
||||
eof = (o >= (f->dircache->len - 1) && f->dircache->eof);
|
||||
count++;
|
||||
|
||||
LOG (("delivering '%s', cache_index=%ld, eof=%ld\n", f->dircache->cache[o].complete_path, cache_index, eof));
|
||||
LOG (("delivering '%s', cache_index=%ld, eof=%ld\n", escape_name(f->dircache->cache[o].complete_path), cache_index, eof));
|
||||
|
||||
data.is_dir = (f->dircache->cache[o].attr & aDIR) != 0;
|
||||
data.is_read_only = (f->dircache->cache[o].attr & aRONLY) != 0;
|
||||
data.is_hidden = (f->dircache->cache[o].attr & aHIDDEN) != 0;
|
||||
data.is_system = (f->dircache->cache[o].attr & aSYSTEM) != 0;
|
||||
data.is_changed_since_last_archive = (f->dircache->cache[o].attr & aARCH) != 0;
|
||||
data.size = f->dircache->cache[o].size;
|
||||
data.size_low = f->dircache->cache[o].size_low;
|
||||
data.size_high = f->dircache->cache[o].size_high;
|
||||
data.atime = f->dircache->cache[o].atime;
|
||||
data.ctime = f->dircache->cache[o].ctime;
|
||||
data.mtime = f->dircache->cache[o].mtime;
|
||||
@@ -1221,10 +1117,10 @@ invalidate_dircache (struct smba_server * server, char * path)
|
||||
other_path[0] = '\0';
|
||||
}
|
||||
|
||||
SHOWSTRING(other_path);
|
||||
D(("other_path = '%s'", escape_name(other_path)));
|
||||
|
||||
if(dircache->cache_for != NULL)
|
||||
SHOWSTRING(dircache->cache_for->dirent.complete_path);
|
||||
D(("dircache->cache_for->dirent.complete_path = '%s'", escape_name(dircache->cache_for->dirent.complete_path)));
|
||||
else
|
||||
SHOWMSG("-- directory cache is empty --");
|
||||
|
||||
@@ -1246,7 +1142,7 @@ invalidate_dircache (struct smba_server * server, char * path)
|
||||
/*****************************************************************************/
|
||||
|
||||
int
|
||||
smba_create (smba_file_t * dir, const char *name, smba_stat_t * attr, int * error_ptr)
|
||||
smba_create (smba_file_t * dir, const char *name, int * error_ptr)
|
||||
{
|
||||
struct smb_dirent entry;
|
||||
char *path = NULL;
|
||||
@@ -1362,7 +1258,7 @@ close_path (smba_server_t * s, char *path, int * error_ptr)
|
||||
result = smb_proc_close (&s->server, p->dirent.fileid, p->dirent.mtime, error_ptr);
|
||||
if(result < 0)
|
||||
{
|
||||
LOG(("closing %s with file id %ld failed\n", path, p->dirent.fileid));
|
||||
LOG(("closing '%s' with file id %ld failed\n", escape_name(path), p->dirent.fileid));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1638,10 +1534,6 @@ smba_start(
|
||||
int opt_max_transmit,
|
||||
int opt_timeout,
|
||||
int opt_raw_smb,
|
||||
int opt_write_behind,
|
||||
int opt_prefer_write_raw,
|
||||
int opt_disable_write_raw,
|
||||
int opt_disable_read_raw,
|
||||
char * opt_native_os,
|
||||
int * error_ptr,
|
||||
int * smb_error_class_ptr,
|
||||
@@ -1813,10 +1705,6 @@ smba_start(
|
||||
opt_max_transmit,
|
||||
opt_timeout,
|
||||
opt_raw_smb,
|
||||
opt_write_behind,
|
||||
opt_prefer_write_raw,
|
||||
opt_disable_write_raw,
|
||||
opt_disable_read_raw,
|
||||
opt_native_os,
|
||||
error_ptr,
|
||||
smb_error_class_ptr,
|
||||
|
||||
@@ -16,6 +16,16 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#ifndef _QUAD_MATH_H
|
||||
#include "quad_math.h"
|
||||
#endif /* _QUAD_MATH_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Forward declaration to keep the compiler happy. */
|
||||
#ifndef _SMB_FS_SB
|
||||
struct smb_server;
|
||||
@@ -55,10 +65,13 @@ typedef struct smba_stat
|
||||
unsigned is_hidden:1;
|
||||
unsigned is_system:1;
|
||||
unsigned is_changed_since_last_archive:1;
|
||||
int size;
|
||||
long atime;
|
||||
long ctime;
|
||||
long mtime;
|
||||
|
||||
unsigned long size_low;
|
||||
unsigned long size_high;
|
||||
|
||||
time_t atime;
|
||||
time_t ctime;
|
||||
time_t mtime;
|
||||
} smba_stat_t;
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -74,20 +87,20 @@ typedef int (*smba_callback_t) (void *d, int fpos, int nextpos, char *name, int
|
||||
|
||||
int smba_open(smba_server_t *s, char *name, size_t name_size, int writable, int truncate, smba_file_t **file, int * error_ptr);
|
||||
void smba_close(smba_file_t *f, int * error_ptr);
|
||||
int smba_read(smba_file_t *f, char *data, long len, long offset, int * error_ptr);
|
||||
int smba_write(smba_file_t *f, const char *data, long len, long offset, int * error_ptr);
|
||||
int smba_read(smba_file_t *f, char *data, long len, const QUAD * const offset, int * error_ptr);
|
||||
int smba_write(smba_file_t *f, const char *data, long len, const QUAD * const offset, int * error_ptr);
|
||||
int smba_lockrec (smba_file_t *f, long offset, long len, long mode, int unlocked, long timeout, int * error_ptr);
|
||||
int smba_getattr(smba_file_t *f, smba_stat_t *data, int * error_ptr);
|
||||
int smba_setattr(smba_file_t *f, const smba_stat_t *data, const unsigned long * size_ptr, int * error_ptr);
|
||||
int smba_setattr(smba_file_t *f, const smba_stat_t *data, const QUAD * const size, int * error_ptr);
|
||||
int smba_readdir(smba_file_t *f, long offs, void *d, smba_callback_t callback, int * error_ptr);
|
||||
int smba_create(smba_file_t *dir, const char *name, smba_stat_t *attr, int * error_ptr);
|
||||
int smba_create(smba_file_t *dir, const char *name, int * error_ptr);
|
||||
int smba_mkdir(smba_file_t *dir, const char *name, int * error_ptr);
|
||||
int smba_remove(smba_server_t *s, char *path, int * error_ptr);
|
||||
int smba_rmdir(smba_server_t *s, char *path, int * error_ptr);
|
||||
int smba_rename(smba_server_t *s, char *from, char *to, int * error_ptr);
|
||||
int smba_statfs(smba_server_t *s, long *bsize, long *blocks, long *bfree, int * error_ptr);
|
||||
void smb_invalidate_all_inodes(struct smb_server *server);
|
||||
int smba_start(char *service, char *opt_workgroup, char *opt_username, char *opt_password, char *opt_clientname, char *opt_servername, int opt_cachesize, int opt_max_transmit, int opt_timeout, int opt_raw_smb, int opt_write_behind, int opt_prefer_write_raw, int opt_disable_write_raw, int opt_disable_read_raw, char * opt_native_os, int * error_ptr, int * smb_error_class_ptr, int * smb_error_ptr, smba_server_t **result);
|
||||
int smba_start(char *service, char *opt_workgroup, char *opt_username, char *opt_password, char *opt_clientname, char *opt_servername, int opt_cachesize, int opt_max_transmit, int opt_timeout, int opt_raw_smb, char * opt_native_os, int * error_ptr, int * smb_error_class_ptr, int * smb_error_ptr, smba_server_t **result);
|
||||
void smba_disconnect(smba_server_t *server);
|
||||
int smba_get_dircache_size(struct smba_server * server);
|
||||
int smba_change_dircache_size(struct smba_server * server,int cache_size);
|
||||
|
||||
+9
-3
@@ -33,6 +33,10 @@
|
||||
#include "assert.h"
|
||||
#endif /* _ASSERT_H */
|
||||
|
||||
#ifndef _QUAD_MATH_H
|
||||
#include "quad_math.h"
|
||||
#endif /* _QUAD_MATH_H */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#define SAME (0)
|
||||
@@ -131,16 +135,18 @@ extern int h_errno;
|
||||
/****************************************************************************/
|
||||
|
||||
extern int BroadcastNameQuery(const char *name, const char *scope, UBYTE *address);
|
||||
extern LONG CompareNames(STRPTR a,STRPTR b);
|
||||
extern LONG CompareNames(const TEXT * a,const TEXT * b);
|
||||
extern LONG GetTimeZoneDelta(VOID);
|
||||
extern STRPTR posix_strerror(int error);
|
||||
extern STRPTR host_strerror(int error);
|
||||
extern time_t MakeTime(const struct tm * const tm);
|
||||
extern ULONG GetCurrentTime(VOID);
|
||||
extern VOID GMTime(time_t seconds,struct tm * tm);
|
||||
extern VOID VARARGS68K ReportError(STRPTR fmt,...);
|
||||
extern VOID VARARGS68K ReportError(const TEXT * fmt,...);
|
||||
extern VOID StringToUpper(STRPTR s);
|
||||
extern VOID VARARGS68K SPrintf(STRPTR buffer, STRPTR formatString,...);
|
||||
extern VOID VARARGS68K SPrintf(STRPTR buffer, const TEXT * formatString,...);
|
||||
extern TEXT * escape_name(const TEXT * name);
|
||||
extern const char * convert_quad_to_string(const QUAD * const number);
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#define VERSION 1
|
||||
#define REVISION 137
|
||||
#define DATE "24.5.2018"
|
||||
#define VERS "smbfs 1.137"
|
||||
#define VSTRING "smbfs 1.137 (24.5.2018)\r\n"
|
||||
#define VERSTAG "\0$VER: smbfs 1.137 (24.5.2018)"
|
||||
#define REVISION 139
|
||||
#define DATE "26.5.2018"
|
||||
#define VERS "smbfs 1.139"
|
||||
#define VSTRING "smbfs 1.139 (26.5.2018)\r\n"
|
||||
#define VERSTAG "\0$VER: smbfs 1.139 (26.5.2018)"
|
||||
|
||||
@@ -1 +1 @@
|
||||
137
|
||||
139
|
||||
|
||||
+3
-135
@@ -994,6 +994,9 @@ smb_connect (struct smb_server *server, int * error_ptr)
|
||||
/* If there was a network error, or data was left unread,
|
||||
* the best option is to the close server connection and
|
||||
* reopen it again.
|
||||
*
|
||||
* Here's where we decide whether closing the connection
|
||||
* makes sense, and then close it if necessary.
|
||||
*/
|
||||
void
|
||||
smb_check_server_connection(struct smb_server *server, int error)
|
||||
@@ -1185,138 +1188,3 @@ smb_trans2_request (struct smb_server *server, int command, int *data_len, int *
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
smb_request_read_raw (struct smb_server *server, unsigned char *target, int max_len, int * error_ptr)
|
||||
{
|
||||
unsigned char *buffer = server->transmit_buffer;
|
||||
int sock_fd = server->mount_data.fd;
|
||||
int len, result;
|
||||
|
||||
ASSERT( error_ptr != NULL );
|
||||
|
||||
if (server->state != CONN_VALID)
|
||||
{
|
||||
LOG (("Connection state is invalid\n"));
|
||||
|
||||
(*error_ptr) = error_server_connection_invalid;
|
||||
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Length includes the NetBIOS session header (4 bytes), which
|
||||
* is prepended to the packet to be sent.
|
||||
*/
|
||||
len = NETBIOS_HEADER_SIZE + smb_len (buffer);
|
||||
|
||||
LOG (("len = %ld cmd = 0x%02lx\n", len, buffer[8]));
|
||||
LOG (("target=%lx, max_len=%ld\n", (unsigned int) target, max_len));
|
||||
LOG (("buffer=%lx, sock=%lx\n", (unsigned int) buffer, (unsigned int) sock_fd));
|
||||
|
||||
#if defined(DUMP_SMB)
|
||||
dump_netbios_header(__FILE__,__LINE__,buffer,NULL,0);
|
||||
dump_smb(__FILE__,__LINE__,0,buffer+NETBIOS_HEADER_SIZE,len-NETBIOS_HEADER_SIZE,smb_packet_from_consumer,server->max_recv);
|
||||
#endif /* defined(DUMP_SMB) */
|
||||
|
||||
/* Request that data should be read in raw mode. */
|
||||
result = send (sock_fd, (void *) buffer, len, 0);
|
||||
if (result < 0)
|
||||
{
|
||||
LOG(("send() for %ld bytes failed (errno=%ld)\n", len, errno));
|
||||
|
||||
(*error_ptr) = errno;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Wait for the raw data to be sent by the server. */
|
||||
result = smb_receive_raw (server, SMBreadbraw, sock_fd, target, max_len, NULL, 0, FALSE, error_ptr);
|
||||
|
||||
out:
|
||||
|
||||
if (result < 0)
|
||||
smb_check_server_connection(server,(*error_ptr));
|
||||
|
||||
LOG (("result = %ld\n", result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* smb_request_write_raw assumes that the request SMBwriteBraw has been
|
||||
* completed successfully, so that we can send the raw data now.
|
||||
*/
|
||||
int
|
||||
smb_request_write_raw (struct smb_server *server, unsigned const char *source, int length, int * error_ptr)
|
||||
{
|
||||
byte nb_header[NETBIOS_HEADER_SIZE];
|
||||
int sock_fd = server->mount_data.fd;
|
||||
int result;
|
||||
|
||||
if (server->state != CONN_VALID)
|
||||
{
|
||||
LOG (("Connection state is invalid\n"));
|
||||
|
||||
(*error_ptr) = error_server_connection_invalid;
|
||||
|
||||
result = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ASSERT( length <= 65535 );
|
||||
|
||||
/* Send the NetBIOS header. */
|
||||
smb_encode_smb_length (nb_header, length);
|
||||
|
||||
#if defined(DUMP_SMB)
|
||||
dump_netbios_header(__FILE__,__LINE__,nb_header,NULL,0);
|
||||
#endif /* defined(DUMP_SMB) */
|
||||
|
||||
result = send (sock_fd, nb_header, NETBIOS_HEADER_SIZE, 0);
|
||||
if(result < 0)
|
||||
{
|
||||
LOG(("send() for %ld bytes failed (errno=%ld)\n", NETBIOS_HEADER_SIZE, errno));
|
||||
|
||||
(*error_ptr) = errno;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if defined(DUMP_SMB)
|
||||
dump_smb(__FILE__,__LINE__,0,source,length,smb_packet_from_consumer,server->max_recv);
|
||||
#endif /* defined(DUMP_SMB) */
|
||||
|
||||
/* Now send the data to be written. */
|
||||
result = send (sock_fd, (void *)source, length, 0);
|
||||
if(result < 0)
|
||||
{
|
||||
LOG(("send() for %ld bytes failed (errno=%ld)\n", length, errno));
|
||||
|
||||
(*error_ptr) = errno;
|
||||
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Wait for the server to respond. */
|
||||
if(!server->write_behind)
|
||||
{
|
||||
result = smb_receive (server, SMBwritebraw, sock_fd, NULL, 0, error_ptr);
|
||||
if(result < 0)
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(("not waiting for server to respond\n"));
|
||||
}
|
||||
|
||||
result = length;
|
||||
|
||||
out:
|
||||
|
||||
if (result < 0)
|
||||
smb_check_server_connection(server,(*error_ptr));
|
||||
|
||||
LOG (("result = %ld\n", result));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user