add-server-streams-support [plain text]
Index: samba/source/smbd/trans2.c
===================================================================
--- samba/source/smbd/trans2.c.orig
+++ samba/source/smbd/trans2.c
@@ -7,6 +7,8 @@
Copyright (C) Steve French 2005
Copyright (C) James Peach 2007
+ Copyright (C) 2006-2007 Apple Inc. All right reserved.
+
Extensively modified by Andrew Tridgell, 1995
This program is free software; you can redistribute it and/or modify
@@ -2274,7 +2276,7 @@ static int call_trans2qfsinfo(connection
const char *vname = volume_label(SNUM(conn));
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
- int quota_flag = 0;
+ int fs_attribute_flags = 0;
if (total_params < 2) {
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
@@ -2358,15 +2360,25 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAva
case SMB_QUERY_FS_ATTRIBUTE_INFO:
case SMB_FS_ATTRIBUTE_INFORMATION:
+ fs_attribute_flags =
+ FILE_CASE_SENSITIVE_SEARCH |
+ FILE_CASE_PRESERVED_NAMES |
+ FILE_UNICODE_ON_DISK;
#if defined(HAVE_SYS_QUOTAS)
- quota_flag = FILE_VOLUME_QUOTAS;
+ fs_attribute_flags |= FILE_VOLUME_QUOTAS;
#endif
- SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
- (lp_nt_acl_support(SNUM(conn)) ? FILE_PERSISTENT_ACLS : 0)|
- FILE_UNICODE_ON_DISK|
- quota_flag); /* FS ATTRIBUTES */
+ if (lp_stream_support(SNUM(conn)) &&
+ (conn->fs_capabilities & FILE_NAMED_STREAMS)) {
+ fs_attribute_flags |= FILE_NAMED_STREAMS;
+ }
+
+ if (lp_nt_acl_support(SNUM(conn)) ) {
+ fs_attribute_flags |= FILE_PERSISTENT_ACLS;
+ }
+
+ SIVAL(pdata, 0, fs_attribute_flags); /* FS ATTRIBUTES */
SIVAL(pdata,4,255); /* Max filename component length */
/* NOTE! the fstype must *not* be null terminated or win98 won't recognise it
@@ -2727,7 +2739,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAva
* Thursby MAC extension... ONLY on NTFS filesystems
* once we do streams then we don't need this
*/
- if (strequal(lp_fstype(SNUM(conn)),"NTFS")) {
+ if (!lp_stream_support(SNUM(conn)) &&
+ strequal(lp_fstype(SNUM(conn)),"NTFS")) {
data_len = 88;
SIVAL(pdata,84,0x100); /* Don't support mac... */
break;
@@ -3191,6 +3204,104 @@ static char *store_file_unix_basic_info2
return pdata;
}
+static unsigned int marshall_stream_info(connection_struct *conn,
+ files_struct *fsp,
+ const char *fname,
+ int dosmode,
+ SMB_BIG_UINT file_data_size,
+ SMB_BIG_UINT file_data_allocation,
+ char *pdata)
+{
+ unsigned int data_size = 0;
+ unsigned nextOffset = 0;
+ int count = 0;
+ int curr = 0;
+ char * namelist = NULL;
+ size_t * sizelist = NULL;
+
+ char * name;
+
+ size_t byte_len = 0;
+
+ if (!(dosmode & aDIR)) {
+ /* Don't show ::$DATA for directories. If we do, the XP copy engine
+ * tries to copy it, which results in all sorts of interesting
+ * phenomena.
+ */
+ byte_len += dos_PutUniCode(pdata + 24,"::$DATA",
+ (size_t)0xE, False);
+ SIVAL(pdata, nextOffset, 0); /* might overwrite this if
+ more streams */
+ SIVAL(pdata, 4, byte_len); /* Byte length of unicode
+ string ::$DATA */
+ SOFF_T(pdata, 8, file_data_size);
+ SIVAL(pdata, 16, file_data_allocation);
+ SIVAL(pdata, 20, 0); /* ??? */
+ data_size = 24 + byte_len;
+ }
+
+ count = SMB_VFS_STREAMINFO(conn, fsp, fname,
+ &namelist, &sizelist);
+ if (count <= 0) {
+ return data_size;
+ }
+
+ DEBUG(4, ("streaminfo on %s gave %d streams\n",
+ fsp ? fsp->fsp_name : fname, count));
+
+ for (name = namelist, curr = 0; curr < count; ++curr ) {
+ size_t nlen = strlen(name);
+
+/* TDB_ALIGN, renamed to avoid clashes. */
+#define STREAMINFO_ALIGN(x, a) (((x) + (a)-1) & ~((a)-1))
+
+ /* update the previous record's next
+ * record offset ...
+ */
+ data_size = STREAMINFO_ALIGN(data_size, 8);
+ SIVAL(pdata, nextOffset, data_size - nextOffset);
+
+#undef STREAMINFO_ALIGN
+
+ DEBUG(4, ("pushing name=%s size=%u\n",
+ name, (unsigned)sizelist[curr]));
+
+ /* remember where the next record offset
+ * field is for this record ...
+ */
+ nextOffset = data_size;
+ /* make sure it's clear ... */
+ SIVAL(pdata, nextOffset, 0);
+
+ /* now insert the new record .. */
+
+ byte_len = dos_PutUniCode(pdata + data_size + 24,
+ name, nlen * 2, False);
+
+ /* add stream name length ... */
+ SIVAL(pdata, 4 + data_size, byte_len);
+
+ /* add stream size ... */
+ SOFF_T(pdata, 8 + data_size, (SMB_OFF_T)sizelist[curr]);
+
+ /* allocation size is the same as the
+ * stream size ...
+ */
+ SOFF_T(pdata,16 + data_size, (SMB_OFF_T)sizelist[curr]);
+ SIVAL(pdata, 20 + data_size, 0); /*??*/
+
+ data_size += 24 + byte_len;
+
+ /* Skip to next name. */
+ name += (nlen + 1);
+ }
+
+ SAFE_FREE(namelist);
+ SAFE_FREE(sizelist);
+
+ return data_size;
+}
+
/****************************************************************************
Reply to a TRANS2_QFILEPATHINFO or TRANSACT2_QFILEINFO (query file info by
file name or file id).
@@ -3749,26 +3860,20 @@ total_data=%u (should be %u)\n", (unsign
data_size = 4;
break;
-#if 0
/*
- * NT4 server just returns "invalid query" to this - if we try to answer
- * it then NTws gets a BSOD! (tridge).
+ * NT4 server just returns "invalid query" to this - if we
+ * try to answer it then NTws gets a BSOD! (tridge).
* W2K seems to want this. JRA.
*/
+ /* The first statement above is false - verified using Thursby
+ * client against NT4 -- gcolley.
+ */
case SMB_QUERY_FILE_STREAM_INFO:
-#endif
case SMB_FILE_STREAM_INFORMATION:
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_STREAM_INFORMATION\n"));
- if (mode & aDIR) {
- data_size = 0;
- } else {
- size_t byte_len = dos_PutUniCode(pdata+24,"::$DATA", (size_t)0xE, False);
- SIVAL(pdata,0,0); /* ??? */
- SIVAL(pdata,4,byte_len); /* Byte length of unicode string ::$DATA */
- SOFF_T(pdata,8,file_size);
- SOFF_T(pdata,16,allocation_size);
- data_size = 24 + byte_len;
- }
+ data_size = marshall_stream_info(conn, fsp,
+ fname, mode, file_size,
+ allocation_size, pdata);
break;
case SMB_QUERY_COMPRESSION_INFO: