summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Rothwell <sfr@canb.auug.org.au>2011-03-11 11:09:51 +1100
committerStephen Rothwell <sfr@canb.auug.org.au>2011-03-11 11:09:51 +1100
commitc7a86e49a919531443922ff34a39208bc0494fe5 (patch)
tree94aa8f936ab8ff4451ad5fe3bdae1a0b4db33dd1
parent0b438f2064272c96287c723c2b0575f0a399a037 (diff)
parent12fa0cfa9d78384c97b0b6276c280c9d861946bd (diff)
Merge remote-tracking branch 'cifs/master'
-rw-r--r--fs/cifs/Kconfig35
-rw-r--r--fs/cifs/Makefile4
-rw-r--r--fs/cifs/README28
-rw-r--r--fs/cifs/TODO2
-rw-r--r--fs/cifs/cache.c6
-rw-r--r--fs/cifs/cifs_debug.c215
-rw-r--r--fs/cifs/cifs_debug.h12
-rw-r--r--fs/cifs/cifs_dfs_ref.c2
-rw-r--r--fs/cifs/cifs_fs_sb.h4
-rw-r--r--fs/cifs/cifs_spnego.c6
-rw-r--r--fs/cifs/cifs_spnego.h2
-rw-r--r--fs/cifs/cifs_unicode.c61
-rw-r--r--fs/cifs/cifs_unicode.h7
-rw-r--r--fs/cifs/cifsacl.c6
-rw-r--r--fs/cifs/cifsacl.h2
-rw-r--r--fs/cifs/cifsencrypt.c30
-rw-r--r--fs/cifs/cifsfs.c25
-rw-r--r--fs/cifs/cifsfs.h6
-rw-r--r--fs/cifs/cifsglob.h133
-rw-r--r--fs/cifs/cifsproto.h178
-rw-r--r--fs/cifs/cifssmb.c395
-rw-r--r--fs/cifs/connect.c150
-rw-r--r--fs/cifs/dir.c8
-rw-r--r--fs/cifs/export.c4
-rw-r--r--fs/cifs/file.c38
-rw-r--r--fs/cifs/fscache.c6
-rw-r--r--fs/cifs/fscache.h8
-rw-r--r--fs/cifs/inode.c42
-rw-r--r--fs/cifs/ioctl.c2
-rw-r--r--fs/cifs/link.c12
-rw-r--r--fs/cifs/misc.c35
-rw-r--r--fs/cifs/ntlmssp.h10
-rw-r--r--fs/cifs/readdir.c8
-rw-r--r--fs/cifs/sess.c69
-rw-r--r--fs/cifs/smb2glob.h252
-rw-r--r--fs/cifs/smb2misc.c336
-rw-r--r--fs/cifs/smb2pdu.c2506
-rw-r--r--fs/cifs/smb2pdu.h996
-rw-r--r--fs/cifs/smb2proto.h203
-rw-r--r--fs/cifs/smb2sess.c80
-rw-r--r--fs/cifs/smb2status.h1782
-rw-r--r--fs/cifs/smb2transport.c140
-rw-r--r--fs/cifs/smbdes.c418
-rw-r--r--fs/cifs/smbencrypt.c124
-rw-r--r--fs/cifs/transport.c24
-rw-r--r--fs/cifs/xattr.c28
46 files changed, 7297 insertions, 1143 deletions
diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 7cb0f7f847e4..75c47cd8d086 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -7,6 +7,7 @@ config CIFS
select CRYPTO_MD5
select CRYPTO_HMAC
select CRYPTO_ARC4
+ select CRYPTO_DES
help
This is the client VFS module for the Common Internet File System
(CIFS) protocol which is the successor to the Server Message Block
@@ -152,16 +153,28 @@ config CIFS_ACL
Allows to fetch CIFS/NTFS ACL from the server. The DACL blob
is handed over to the application/caller.
-config CIFS_EXPERIMENTAL
- bool "CIFS Experimental Features (EXPERIMENTAL)"
+config CIFS_SMB2
+ bool "SMB2 network file system support (EXPERIMENTAL)"
+ depends on EXPERIMENTAL && INET && BROKEN
+ select NLS
+ select KEYS
+ select FSCACHE
+ select DNS_RESOLVER
+
+ help
+ This enables experimental support for the SMB2 (Server Message Block
+ version 2) protocol. The SMB2 protocol is the successor to the
+ popular CIFS and SMB network file sharing protocols. SMB2 is the
+ native file sharing mechanism for recent versions of Windows
+ operating systems (since Vista). SMB2 enablement will eventually
+ allow users better performance, security and features, than would be
+ possible with cifs. Note that smb2 mount options also are simpler
+ (compared to cifs) due to protocol improvements.
+
+ Unless you are a developer or tester, say N.
+
+config CIFS_NFSD_EXPORT
+ bool "Allow nfsd to export CIFS file system (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL
help
- Enables cifs features under testing. These features are
- experimental and currently include DFS support and directory
- change notification ie fcntl(F_DNOTIFY), as well as the upcall
- mechanism which will be used for Kerberos session negotiation
- and uid remapping. Some of these features also may depend on
- setting a value of 1 to the pseudo-file /proc/fs/cifs/Experimental
- (which is disabled by default). See the file fs/cifs/README
- for more details. If unsure, say N.
-
+ Allows NFS server to export a CIFS mounted share (nfsd over cifs)
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index d87558448e3d..c7a14914c9dc 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -4,7 +4,7 @@
obj-$(CONFIG_CIFS) += cifs.o
cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \
- link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \
+ link.o misc.o netmisc.o smbencrypt.o transport.o asn1.o \
cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
readdir.o ioctl.o sess.o export.o
@@ -15,3 +15,5 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
+
+cifs-$(CONFIG_CIFS_SMB2) += smb2pdu.o smb2misc.o smb2sess.o smb2transport.o
diff --git a/fs/cifs/README b/fs/cifs/README
index fe1683590828..4a3ca0e5ca24 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -685,22 +685,6 @@ LinuxExtensionsEnabled If set to one then the client will attempt to
support and want to map the uid and gid fields
to values supplied at mount (rather than the
actual values, then set this to zero. (default 1)
-Experimental When set to 1 used to enable certain experimental
- features (currently enables multipage writes
- when signing is enabled, the multipage write
- performance enhancement was disabled when
- signing turned on in case buffer was modified
- just before it was sent, also this flag will
- be used to use the new experimental directory change
- notification code). When set to 2 enables
- an additional experimental feature, "raw ntlmssp"
- session establishment support (which allows
- specifying "sec=ntlmssp" on mount). The Linux cifs
- module will use ntlmv2 authentication encapsulated
- in "raw ntlmssp" (not using SPNEGO) when
- "sec=ntlmssp" is specified on mount.
- This support also requires building cifs with
- the CONFIG_CIFS_EXPERIMENTAL configuration flag.
These experimental features and tracing can be enabled by changing flags in
/proc/fs/cifs (after the cifs module has been installed or built into the
@@ -720,18 +704,6 @@ the start of smb requests and responses can be enabled via:
echo 1 > /proc/fs/cifs/traceSMB
-Two other experimental features are under development. To test these
-requires enabling CONFIG_CIFS_EXPERIMENTAL
-
- cifsacl support needed to retrieve approximated mode bits based on
- the contents on the CIFS ACL.
-
- lease support: cifs will check the oplock state before calling into
- the vfs to see if we can grant a lease on a file.
-
- DNOTIFY fcntl: needed for support of directory change
- notification and perhaps later for file leases)
-
Per share (per client mount) statistics are available in /proc/fs/cifs/Stats
if the kernel was configured with cifs statistics enabled. The statistics
represent the number of successful (ie non-zero return code from the server)
diff --git a/fs/cifs/TODO b/fs/cifs/TODO
index 355abcdcda98..2c68abc58d6f 100644
--- a/fs/cifs/TODO
+++ b/fs/cifs/TODO
@@ -1,5 +1,7 @@
Version 1.53 May 20, 2008
+PUT IN WARNING FOR NTLMV2 becoming default
+
A Partial List of Missing Features
==================================
diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index e654dfd092c3..29b20ae945db 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -146,7 +146,7 @@ static char *extract_sharename(const char *treename)
static uint16_t cifs_super_get_key(const void *cookie_netfs_data, void *buffer,
uint16_t maxbuf)
{
- const struct cifsTconInfo *tcon = cookie_netfs_data;
+ const struct cifs_tcon *tcon = cookie_netfs_data;
char *sharename;
uint16_t len;
@@ -173,7 +173,7 @@ cifs_fscache_super_get_aux(const void *cookie_netfs_data, void *buffer,
uint16_t maxbuf)
{
struct cifs_fscache_super_auxdata auxdata;
- const struct cifsTconInfo *tcon = cookie_netfs_data;
+ const struct cifs_tcon *tcon = cookie_netfs_data;
memset(&auxdata, 0, sizeof(auxdata));
auxdata.resource_id = tcon->resource_id;
@@ -192,7 +192,7 @@ fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
uint16_t datalen)
{
struct cifs_fscache_super_auxdata auxdata;
- const struct cifsTconInfo *tcon = cookie_netfs_data;
+ const struct cifs_tcon *tcon = cookie_netfs_data;
if (datalen != sizeof(auxdata))
return FSCACHE_CHECKAUX_OBSOLETE;
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 65829d32128c..d925cf67723f 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -110,8 +110,8 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
struct list_head *tmp1, *tmp2, *tmp3;
struct mid_q_entry *mid_entry;
struct TCP_Server_Info *server;
- struct cifsSesInfo *ses;
- struct cifsTconInfo *tcon;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
int i, j;
__u32 dev_type;
@@ -152,7 +152,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
tcp_ses_list);
i++;
list_for_each(tmp2, &server->smb_ses_list) {
- ses = list_entry(tmp2, struct cifsSesInfo,
+ ses = list_entry(tmp2, struct cifs_ses,
smb_ses_list);
if ((ses->serverDomain == NULL) ||
(ses->serverOS == NULL) ||
@@ -171,7 +171,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
seq_printf(m, "TCP status: %d\n\tLocal Users To "
"Server: %d SecMode: 0x%x Req On Wire: %d",
server->tcpStatus, server->srv_count,
- server->secMode,
+ server->sec_mode,
atomic_read(&server->inFlight));
#ifdef CONFIG_CIFS_STATS2
@@ -183,7 +183,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
seq_puts(m, "\n\tShares:");
j = 0;
list_for_each(tmp3, &ses->tcon_list) {
- tcon = list_entry(tmp3, struct cifsTconInfo,
+ tcon = list_entry(tmp3, struct cifs_tcon,
tcon_list);
++j;
dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType);
@@ -249,6 +249,55 @@ static const struct file_operations cifs_debug_data_proc_fops = {
};
#ifdef CONFIG_CIFS_STATS
+
+#ifdef CONFIG_CIFS_SMB2
+static void smb2_clear_stats(struct cifs_tcon *tcon)
+{
+ int i;
+
+ atomic_set(&tcon->num_smbs_sent, 0);
+ for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
+ atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
+ atomic_set(&tcon->stats.smb2_stats.smb2_com_fail[i], 0);
+ }
+}
+#endif /* CONFIG_CIFS_SMB2 */
+
+static void clear_cifs_stats(struct cifs_tcon *tcon)
+{
+ atomic_set(&tcon->num_smbs_sent, 0);
+
+#ifdef CONFIG_CIFS_SMB2
+ if (tcon->ses->server->is_smb2) {
+ smb2_clear_stats(tcon);
+ return;
+ }
+#endif /* CONFIG_CIFS_SMB2 */
+
+ /* cifs specific statistics, not applicable to smb2 sessions */
+ atomic_set(&tcon->stats.cifs_stats.num_writes, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_reads, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_flushes, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_oplock_brks, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_opens, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_posixopens, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_posixmkdirs, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_closes, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_deletes, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_mkdirs, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_rmdirs, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_renames, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_t2renames, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_ffirst, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_fnext, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_fclose, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_hardlinks, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_symlinks, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_locks, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_acl_get, 0);
+ atomic_set(&tcon->stats.cifs_stats.num_acl_set, 0);
+}
+
static ssize_t cifs_stats_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
{
@@ -256,8 +305,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
int rc;
struct list_head *tmp1, *tmp2, *tmp3;
struct TCP_Server_Info *server;
- struct cifsSesInfo *ses;
- struct cifsTconInfo *tcon;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
rc = get_user(c, buffer);
if (rc)
@@ -273,31 +322,13 @@ static ssize_t cifs_stats_proc_write(struct file *file,
server = list_entry(tmp1, struct TCP_Server_Info,
tcp_ses_list);
list_for_each(tmp2, &server->smb_ses_list) {
- ses = list_entry(tmp2, struct cifsSesInfo,
+ ses = list_entry(tmp2, struct cifs_ses,
smb_ses_list);
list_for_each(tmp3, &ses->tcon_list) {
tcon = list_entry(tmp3,
- struct cifsTconInfo,
+ struct cifs_tcon,
tcon_list);
- atomic_set(&tcon->num_smbs_sent, 0);
- atomic_set(&tcon->num_writes, 0);
- atomic_set(&tcon->num_reads, 0);
- atomic_set(&tcon->num_oplock_brks, 0);
- atomic_set(&tcon->num_opens, 0);
- atomic_set(&tcon->num_posixopens, 0);
- atomic_set(&tcon->num_posixmkdirs, 0);
- atomic_set(&tcon->num_closes, 0);
- atomic_set(&tcon->num_deletes, 0);
- atomic_set(&tcon->num_mkdirs, 0);
- atomic_set(&tcon->num_rmdirs, 0);
- atomic_set(&tcon->num_renames, 0);
- atomic_set(&tcon->num_t2renames, 0);
- atomic_set(&tcon->num_ffirst, 0);
- atomic_set(&tcon->num_fnext, 0);
- atomic_set(&tcon->num_fclose, 0);
- atomic_set(&tcon->num_hardlinks, 0);
- atomic_set(&tcon->num_symlinks, 0);
- atomic_set(&tcon->num_locks, 0);
+ clear_cifs_stats(tcon);
}
}
}
@@ -307,13 +338,51 @@ static ssize_t cifs_stats_proc_write(struct file *file,
return count;
}
+static void cifs_stats_print(struct seq_file *m, struct cifs_tcon *tcon)
+{
+ if (tcon->need_reconnect)
+ seq_puts(m, "\tDISCONNECTED ");
+ seq_printf(m, "\nSMBs: %d Oplock Breaks: %d",
+ atomic_read(&tcon->num_smbs_sent),
+ atomic_read(&tcon->stats.cifs_stats.num_oplock_brks));
+ seq_printf(m, "\nReads: %d Bytes: %lld",
+ atomic_read(&tcon->stats.cifs_stats.num_reads),
+ (long long)(tcon->bytes_read));
+ seq_printf(m, "\nWrites: %d Bytes: %lld",
+ atomic_read(&tcon->stats.cifs_stats.num_writes),
+ (long long)(tcon->bytes_written));
+ seq_printf(m, "\nFlushes: %d",
+ atomic_read(&tcon->stats.cifs_stats.num_flushes));
+ seq_printf(m, "\nLocks: %d HardLinks: %d Symlinks: %d",
+ atomic_read(&tcon->stats.cifs_stats.num_locks),
+ atomic_read(&tcon->stats.cifs_stats.num_hardlinks),
+ atomic_read(&tcon->stats.cifs_stats.num_symlinks));
+ seq_printf(m, "\nOpens: %d Closes: %d Deletes: %d",
+ atomic_read(&tcon->stats.cifs_stats.num_opens),
+ atomic_read(&tcon->stats.cifs_stats.num_closes),
+ atomic_read(&tcon->stats.cifs_stats.num_deletes));
+ seq_printf(m, "\nPosix Opens: %d Posix Mkdirs: %d",
+ atomic_read(&tcon->stats.cifs_stats.num_posixopens),
+ atomic_read(&tcon->stats.cifs_stats.num_posixmkdirs));
+ seq_printf(m, "\nMkdirs: %d Rmdirs: %d",
+ atomic_read(&tcon->stats.cifs_stats.num_mkdirs),
+ atomic_read(&tcon->stats.cifs_stats.num_rmdirs));
+ seq_printf(m, "\nRenames: %d T2 Renames %d",
+ atomic_read(&tcon->stats.cifs_stats.num_renames),
+ atomic_read(&tcon->stats.cifs_stats.num_t2renames));
+ seq_printf(m, "\nFindFirst: %d FNext %d FClose %d",
+ atomic_read(&tcon->stats.cifs_stats.num_ffirst),
+ atomic_read(&tcon->stats.cifs_stats.num_fnext),
+ atomic_read(&tcon->stats.cifs_stats.num_fclose));
+}
+
static int cifs_stats_proc_show(struct seq_file *m, void *v)
{
int i;
struct list_head *tmp1, *tmp2, *tmp3;
struct TCP_Server_Info *server;
- struct cifsSesInfo *ses;
- struct cifsTconInfo *tcon;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
seq_printf(m,
"Resources in use\nCIFS Session: %d\n",
@@ -346,52 +415,15 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
server = list_entry(tmp1, struct TCP_Server_Info,
tcp_ses_list);
list_for_each(tmp2, &server->smb_ses_list) {
- ses = list_entry(tmp2, struct cifsSesInfo,
+ ses = list_entry(tmp2, struct cifs_ses,
smb_ses_list);
list_for_each(tmp3, &ses->tcon_list) {
tcon = list_entry(tmp3,
- struct cifsTconInfo,
+ struct cifs_tcon,
tcon_list);
i++;
seq_printf(m, "\n%d) %s", i, tcon->treeName);
- if (tcon->need_reconnect)
- seq_puts(m, "\tDISCONNECTED ");
- seq_printf(m, "\nSMBs: %d Oplock Breaks: %d",
- atomic_read(&tcon->num_smbs_sent),
- atomic_read(&tcon->num_oplock_brks));
- seq_printf(m, "\nReads: %d Bytes: %lld",
- atomic_read(&tcon->num_reads),
- (long long)(tcon->bytes_read));
- seq_printf(m, "\nWrites: %d Bytes: %lld",
- atomic_read(&tcon->num_writes),
- (long long)(tcon->bytes_written));
- seq_printf(m, "\nFlushes: %d",
- atomic_read(&tcon->num_flushes));
- seq_printf(m, "\nLocks: %d HardLinks: %d "
- "Symlinks: %d",
- atomic_read(&tcon->num_locks),
- atomic_read(&tcon->num_hardlinks),
- atomic_read(&tcon->num_symlinks));
- seq_printf(m, "\nOpens: %d Closes: %d "
- "Deletes: %d",
- atomic_read(&tcon->num_opens),
- atomic_read(&tcon->num_closes),
- atomic_read(&tcon->num_deletes));
- seq_printf(m, "\nPosix Opens: %d "
- "Posix Mkdirs: %d",
- atomic_read(&tcon->num_posixopens),
- atomic_read(&tcon->num_posixmkdirs));
- seq_printf(m, "\nMkdirs: %d Rmdirs: %d",
- atomic_read(&tcon->num_mkdirs),
- atomic_read(&tcon->num_rmdirs));
- seq_printf(m, "\nRenames: %d T2 Renames %d",
- atomic_read(&tcon->num_renames),
- atomic_read(&tcon->num_t2renames));
- seq_printf(m, "\nFindFirst: %d FNext %d "
- "FClose %d",
- atomic_read(&tcon->num_ffirst),
- atomic_read(&tcon->num_fnext),
- atomic_read(&tcon->num_fclose));
+ cifs_stats_print(m, tcon);
}
}
}
@@ -423,7 +455,6 @@ static const struct file_operations cifs_lookup_cache_proc_fops;
static const struct file_operations traceSMB_proc_fops;
static const struct file_operations cifs_multiuser_mount_proc_fops;
static const struct file_operations cifs_security_flags_proc_fops;
-static const struct file_operations cifs_experimental_proc_fops;
static const struct file_operations cifs_linux_ext_proc_fops;
void
@@ -441,8 +472,6 @@ cifs_proc_init(void)
proc_create("cifsFYI", 0, proc_fs_cifs, &cifsFYI_proc_fops);
proc_create("traceSMB", 0, proc_fs_cifs, &traceSMB_proc_fops);
proc_create("OplockEnabled", 0, proc_fs_cifs, &cifs_oplock_proc_fops);
- proc_create("Experimental", 0, proc_fs_cifs,
- &cifs_experimental_proc_fops);
proc_create("LinuxExtensionsEnabled", 0, proc_fs_cifs,
&cifs_linux_ext_proc_fops);
proc_create("MultiuserMount", 0, proc_fs_cifs,
@@ -469,7 +498,6 @@ cifs_proc_clean(void)
remove_proc_entry("OplockEnabled", proc_fs_cifs);
remove_proc_entry("SecurityFlags", proc_fs_cifs);
remove_proc_entry("LinuxExtensionsEnabled", proc_fs_cifs);
- remove_proc_entry("Experimental", proc_fs_cifs);
remove_proc_entry("LookupCacheEnabled", proc_fs_cifs);
remove_proc_entry("fs/cifs", NULL);
}
@@ -550,45 +578,6 @@ static const struct file_operations cifs_oplock_proc_fops = {
.write = cifs_oplock_proc_write,
};
-static int cifs_experimental_proc_show(struct seq_file *m, void *v)
-{
- seq_printf(m, "%d\n", experimEnabled);
- return 0;
-}
-
-static int cifs_experimental_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, cifs_experimental_proc_show, NULL);
-}
-
-static ssize_t cifs_experimental_proc_write(struct file *file,
- const char __user *buffer, size_t count, loff_t *ppos)
-{
- char c;
- int rc;
-
- rc = get_user(c, buffer);
- if (rc)
- return rc;
- if (c == '0' || c == 'n' || c == 'N')
- experimEnabled = 0;
- else if (c == '1' || c == 'y' || c == 'Y')
- experimEnabled = 1;
- else if (c == '2')
- experimEnabled = 2;
-
- return count;
-}
-
-static const struct file_operations cifs_experimental_proc_fops = {
- .owner = THIS_MODULE,
- .open = cifs_experimental_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
- .write = cifs_experimental_proc_write,
-};
-
static int cifs_linux_ext_proc_show(struct seq_file *m, void *v)
{
seq_printf(m, "%d\n", linuxExtEnabled);
diff --git a/fs/cifs/cifs_debug.h b/fs/cifs/cifs_debug.h
index 8942b28cf807..fec074389c11 100644
--- a/fs/cifs/cifs_debug.h
+++ b/fs/cifs/cifs_debug.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright (c) International Business Machines Corp., 2000,2002
+ * Copyright (c) International Business Machines Corp., 2000,2011
* Modified by Steve French (sfrench@us.ibm.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
-#define CIFS_DEBUG /* BB temporary */
+#define CIFS_DEBUG /* remove to disable cifserror logging */
#ifndef _H_CIFS_DEBUG
#define _H_CIFS_DEBUG
@@ -28,6 +28,9 @@ void cifs_dump_mem(char *label, void *data, int length);
#define DBG2 2
void cifs_dump_detail(struct smb_hdr *);
void cifs_dump_mids(struct TCP_Server_Info *);
+#ifdef CONFIG_CIFS_SMB2
+void smb2_dump_detail(struct smb2_hdr *);
+#endif /* CONFIG_CIFS_SMB2 */
#else
#define DBG2 0
#endif
@@ -37,12 +40,15 @@ void dump_smb(struct smb_hdr *, int);
#define CIFS_RC 0x02
#define CIFS_TIMER 0x04
+#ifdef CONFIG_CIFS_SMB2
+void dump_smb2(struct smb2_hdr *, int);
+#endif /* CONFIG_CIFS_SMB2 */
+
/*
* debug ON
* --------
*/
#ifdef CIFS_DEBUG
-
/* information message: e.g., configuration, major event */
extern int cifsFYI;
#define cifsfyi(fmt, arg...) \
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 0a265ad9e426..e5826f867728 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -272,7 +272,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
struct dfs_info3_param *referrals = NULL;
unsigned int num_referrals = 0;
struct cifs_sb_info *cifs_sb;
- struct cifsSesInfo *ses;
+ struct cifs_ses *ses;
char *full_path;
int xid, i;
int rc;
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index ac51cd2d33ae..1ef54abd0714 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifs_fs_sb.h
*
- * Copyright (c) International Business Machines Corp., 2002,2004
+ * Copyright (c) International Business Machines Corp., 2002,2010
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -24,10 +24,12 @@
#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */
+/* SERVER_INUM is always set for SMB2 */
#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
#define CIFS_MOUNT_DIRECT_IO 8 /* do not write nor read through page cache */
#define CIFS_MOUNT_NO_XATTR 0x10 /* if set - disable xattr support */
#define CIFS_MOUNT_MAP_SPECIAL_CHR 0x20 /* remap illegal chars in filenames */
+/* The following two are not supported for SMB2 */
#define CIFS_MOUNT_POSIX_PATHS 0x40 /* Negotiate posix pathnames if possible*/
#define CIFS_MOUNT_UNX_EMUL 0x80 /* Network compat with SFUnix emulation */
#define CIFS_MOUNT_NO_BRL 0x100 /* No sending byte range locks to srv */
diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c
index 4dfba8283165..2272fd5fe5b7 100644
--- a/fs/cifs/cifs_spnego.c
+++ b/fs/cifs/cifs_spnego.c
@@ -95,7 +95,7 @@ struct key_type cifs_spnego_key_type = {
/* get a key struct with a SPNEGO security blob, suitable for session setup */
struct key *
-cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
+cifs_get_spnego_key(struct cifs_ses *sesInfo)
{
struct TCP_Server_Info *server = sesInfo->server;
struct sockaddr_in *sa = (struct sockaddr_in *) &server->dstaddr;
@@ -113,7 +113,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
MAX_MECH_STR_LEN +
UID_KEY_LEN + (sizeof(uid_t) * 2) +
CREDUID_KEY_LEN + (sizeof(uid_t) * 2) +
- USER_KEY_LEN + strlen(sesInfo->userName) +
+ USER_KEY_LEN + strlen(sesInfo->user_name) +
PID_KEY_LEN + (sizeof(pid_t) * 2) + 1;
spnego_key = ERR_PTR(-ENOMEM);
@@ -153,7 +153,7 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
sprintf(dp, ";creduid=0x%x", sesInfo->cred_uid);
dp = description + strlen(description);
- sprintf(dp, ";user=%s", sesInfo->userName);
+ sprintf(dp, ";user=%s", sesInfo->user_name);
dp = description + strlen(description);
sprintf(dp, ";pid=0x%x", current->pid);
diff --git a/fs/cifs/cifs_spnego.h b/fs/cifs/cifs_spnego.h
index e4041ec4d712..31bef9ee078b 100644
--- a/fs/cifs/cifs_spnego.h
+++ b/fs/cifs/cifs_spnego.h
@@ -41,7 +41,7 @@ struct cifs_spnego_msg {
#ifdef __KERNEL__
extern struct key_type cifs_spnego_key_type;
-extern struct key *cifs_get_spnego_key(struct cifsSesInfo *sesInfo);
+extern struct key *cifs_get_spnego_key(struct cifs_ses *sesInfo);
#endif /* KERNEL */
#endif /* _CIFS_SPNEGO_H */
diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
index fc0fd4fde306..9dd2682c0a87 100644
--- a/fs/cifs/cifs_unicode.c
+++ b/fs/cifs/cifs_unicode.c
@@ -333,3 +333,64 @@ ctoUCS_out:
return i;
}
+#ifdef CONFIG_CIFS_SMB2
+/*
+ * smb2_local_to_ucs2_bytes - how long will a string be after conversion?
+ * @from - pointer to input string
+ * @maxbytes - don't go past this many bytes of input string
+ * @codepage - source codepage
+ *
+ * Walk a string and return the number of bytes that the string will
+ * be after being converted to the given charset, not including any null
+ * termination required. Don't walk past maxbytes in the source buffer.
+ */
+
+int
+smb2_local_to_ucs2_bytes(const char *from, int len,
+ const struct nls_table *codepage)
+{
+ int charlen;
+ int i;
+ wchar_t wchar_to;
+
+ if (from == NULL)
+ return 0;
+ for (i = 0; len && *from; i++, from += charlen, len -= charlen) {
+ charlen = codepage->char2uni(from, len, &wchar_to);
+ /* Failed conversion defaults to a question mark */
+ if (charlen < 1)
+ charlen = 1;
+ }
+ return 2 * i; /* UCS characters are two bytes */
+}
+
+/*
+ * smb2_strndup_to_ucs - copy a string to wire format from the local codepage
+ * @src - source string
+ * @maxlen - don't walk past this many bytes in the source string
+ * @ucslen - the length of the allocated string in bytes (including null)
+ * @codepage - source codepage
+ *
+ * Take a string convert it from the local codepage to UCS2 and
+ * put it in a new buffer. Returns a pointer to the new string or NULL on
+ * error.
+ */
+__le16 *
+smb2_strndup_to_ucs(const char *src, const int maxlen, int *ucs_len,
+ const struct nls_table *codepage)
+{
+ int len;
+ __le16 *dst;
+
+ len = smb2_local_to_ucs2_bytes(src, maxlen, codepage);
+ len += 2; /* NULL */
+ dst = kmalloc(len, GFP_KERNEL);
+ if (!dst) {
+ *ucs_len = 0;
+ return NULL;
+ }
+ cifs_strtoUCS(dst, src, maxlen, codepage);
+ *ucs_len = len;
+ return dst;
+}
+#endif /* CONFIG_CIFS_SMB2 */
diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
index 7fe6b52df507..a56dfbce25b3 100644
--- a/fs/cifs/cifs_unicode.h
+++ b/fs/cifs/cifs_unicode.h
@@ -377,4 +377,11 @@ UniStrlwr(register wchar_t *upin)
#endif
+#ifdef CONFIG_CIFS_SMB2
+extern int smb2_local_to_ucs2_bytes(const char *from, int len,
+ const struct nls_table *codepage);
+extern __le16 *smb2_strndup_to_ucs(const char *src, const int maxlen,
+ int *ucs_len, const struct nls_table *cp);
+#endif /* CONFIG_CIFS_SMB2 */
+
#endif /* _CIFS_UNICODE_H */
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index beeebf194234..a14e45d8d25e 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -592,7 +592,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
int oplock = 0;
int xid, rc;
__u16 fid;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
@@ -660,7 +660,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
int oplock = 0;
int xid, rc;
__u16 fid;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
@@ -688,7 +688,7 @@ out:
}
/* Set an ACL on the server */
-static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
+int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
struct inode *inode, const char *path)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h
index c4ae7d036563..025e9438ce97 100644
--- a/fs/cifs/cifsacl.h
+++ b/fs/cifs/cifsacl.h
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifsacl.h
*
- * Copyright (c) International Business Machines Corp., 2007
+ * Copyright (c) International Business Machines Corp., 2007,2010
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index a51585f9852b..5e71531bcd87 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu,
}
/* first calculate 24 bytes ntlm response and then 16 byte session key */
-int setup_ntlm_response(struct cifsSesInfo *ses)
+int setup_ntlm_response(struct cifs_ses *ses)
{
int rc = 0;
unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;
@@ -265,10 +265,11 @@ int setup_ntlm_response(struct cifsSesInfo *ses)
}
#ifdef CONFIG_CIFS_WEAK_PW_HASH
-void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
+int calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
char *lnm_session_key)
{
int i;
+ int rc;
char password_with_pad[CIFS_ENCPWD_SIZE];
memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
@@ -279,7 +280,7 @@ void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
memset(lnm_session_key, 0, CIFS_SESS_KEY_SIZE);
memcpy(lnm_session_key, password_with_pad,
CIFS_ENCPWD_SIZE);
- return;
+ return 0;
}
/* calculate old style session key */
@@ -296,10 +297,9 @@ void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
for (i = 0; i < CIFS_ENCPWD_SIZE; i++)
password_with_pad[i] = toupper(password_with_pad[i]);
- SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
+ rc = SMBencrypt(password_with_pad, cryptkey, lnm_session_key);
- /* clear password before we return/free memory */
- memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
+ return rc;
}
#endif /* CIFS_WEAK_PW_HASH */
@@ -309,7 +309,7 @@ void calc_lanman_hash(const char *password, const char *cryptkey, bool encrypt,
* Allocate domain name which gets freed when session struct is deallocated.
*/
static int
-build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
+build_avpair_blob(struct cifs_ses *ses, const struct nls_table *nls_cp)
{
unsigned int dlen;
unsigned int wlen;
@@ -397,7 +397,7 @@ build_avpair_blob(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
* about target string i.e. for some, just user name might suffice.
*/
static int
-find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
+find_domain_name(struct cifs_ses *ses, const struct nls_table *nls_cp)
{
unsigned int attrsize;
unsigned int type;
@@ -442,7 +442,7 @@ find_domain_name(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
return 0;
}
-static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash,
+static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash,
const struct nls_table *nls_cp)
{
int rc = 0;
@@ -469,15 +469,15 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, char *ntlmv2_hash,
return rc;
}
- /* convert ses->userName to unicode and uppercase */
- len = strlen(ses->userName);
+ /* convert ses->user_name to unicode and uppercase */
+ len = strlen(ses->user_name);
user = kmalloc(2 + (len * 2), GFP_KERNEL);
if (user == NULL) {
cERROR(1, "calc_ntlmv2_hash: user mem alloc failure\n");
rc = -ENOMEM;
goto calc_exit_2;
}
- len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp);
+ len = cifs_strtoUCS((__le16 *)user, ses->user_name, len, nls_cp);
UniStrupr(user);
crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
@@ -524,7 +524,7 @@ calc_exit_2:
}
static int
-CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
+CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
{
int rc;
unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
@@ -560,7 +560,7 @@ CalcNTLMv2_response(const struct cifsSesInfo *ses, char *ntlmv2_hash)
int
-setup_ntlmv2_rsp(struct cifsSesInfo *ses, const struct nls_table *nls_cp)
+setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
{
int rc;
int baselen;
@@ -646,7 +646,7 @@ setup_ntlmv2_rsp_ret:
}
int
-calc_seckey(struct cifsSesInfo *ses)
+calc_seckey(struct cifs_ses *ses)
{
int rc;
struct crypto_blkcipher *tfm_arc4;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index f2970136d17d..120a9cf37275 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -53,7 +53,6 @@ int cifsFYI = 0;
int cifsERROR = 1;
int traceSMB = 0;
unsigned int oplockEnabled = 1;
-unsigned int experimEnabled = 0;
unsigned int linuxExtEnabled = 1;
unsigned int lookupCacheEnabled = 1;
unsigned int multiuser_mount = 0;
@@ -82,6 +81,10 @@ module_param(echo_retries, ushort, 0644);
MODULE_PARM_DESC(echo_retries, "Number of echo attempts before giving up and "
"reconnecting server. Default: 5. 0 means "
"never reconnect.");
+bool sign_zero_copy; /* globals init to false automatically */
+module_param(sign_zero_copy, bool, 0644);
+MODULE_PARM_DESC(sign_zero_copy, "Don't copy pages on write with signing "
+ "enabled. Default: N");
extern mempool_t *cifs_sm_req_poolp;
extern mempool_t *cifs_req_poolp;
extern mempool_t *cifs_mid_poolp;
@@ -163,7 +166,7 @@ cifs_read_super(struct super_block *sb, void *data,
sb->s_bdi = &cifs_sb->bdi;
sb->s_blocksize = CIFS_MAX_MSGSIZE;
sb->s_blocksize_bits = 14; /* default 2**14 = CIFS_MAX_MSGSIZE */
- inode = cifs_root_iget(sb, ROOT_I);
+ inode = cifs_root_iget(sb);
if (IS_ERR(inode)) {
rc = PTR_ERR(inode);
@@ -184,12 +187,12 @@ cifs_read_super(struct super_block *sb, void *data,
else
sb->s_d_op = &cifs_dentry_ops;
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CIFS_NFSD_EXPORT
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
cFYI(1, "export ops supported");
sb->s_export_op = &cifs_export_ops;
}
-#endif /* EXPERIMENTAL */
+#endif /* CIFS_NFSD_EXPORT */
return 0;
@@ -248,7 +251,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
struct super_block *sb = dentry->d_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
int rc = -EOPNOTSUPP;
int xid;
@@ -401,7 +404,7 @@ static int
cifs_show_options(struct seq_file *s, struct vfsmount *m)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(m->mnt_sb);
- struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
struct sockaddr *srcaddr;
srcaddr = (struct sockaddr *)&tcon->ses->server->srcaddr;
@@ -409,8 +412,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
seq_printf(s, ",multiuser");
- else if (tcon->ses->userName)
- seq_printf(s, ",username=%s", tcon->ses->userName);
+ else if (tcon->ses->user_name)
+ seq_printf(s, ",username=%s", tcon->ses->user_name);
if (tcon->ses->domainName)
seq_printf(s, ",domain=%s", tcon->ses->domainName);
@@ -495,7 +498,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
static void cifs_umount_begin(struct super_block *sb)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
if (cifs_sb == NULL)
return;
@@ -981,10 +984,10 @@ init_cifs(void)
int rc = 0;
cifs_proc_init();
INIT_LIST_HEAD(&cifs_tcp_ses_list);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
INIT_LIST_HEAD(&GlobalDnotifyReqList);
INIT_LIST_HEAD(&GlobalDnotifyRsp_Q);
-#endif
+#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
/*
* Initialize Global counters
*/
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index a9371b6578c0..371d021815b1 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -47,7 +47,7 @@ extern void cifs_sb_deactive(struct super_block *sb);
/* Functions related to inodes */
extern const struct inode_operations cifs_dir_inode_ops;
-extern struct inode *cifs_root_iget(struct super_block *, unsigned long);
+extern struct inode *cifs_root_iget(struct super_block *);
extern int cifs_create(struct inode *, struct dentry *, int,
struct nameidata *);
extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
@@ -123,9 +123,9 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CIFS_NFSD_EXPORT
extern const struct export_operations cifs_export_ops;
-#endif /* EXPERIMENTAL */
+#endif /* CIFS_NFSD_EXPORT */
#define CIFS_VERSION "1.71"
#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 17afb0fbcaed..d69e1e697768 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1,7 +1,7 @@
/*
* fs/cifs/cifsglob.h
*
- * Copyright (C) International Business Machines Corp., 2002,2008
+ * Copyright (C) International Business Machines Corp., 2002,2011
* Author(s): Steve French (sfrench@us.ibm.com)
* Jeremy Allison (jra@samba.org)
*
@@ -27,6 +27,9 @@
#include "cifsacl.h"
#include <crypto/internal/hash.h>
#include <linux/scatterlist.h>
+#ifdef CONFIG_CIFS_SMB2
+#include "smb2glob.h"
+#endif /* CONFIG_CIFS_SMB2 */
/*
* The sizes of various internal tables and strings
@@ -37,10 +40,9 @@
#define MAX_TREE_SIZE (2 + MAX_SERVER_SIZE + 1 + MAX_SHARE_SIZE + 1)
#define MAX_SERVER_SIZE 15
-#define MAX_SHARE_SIZE 64 /* used to be 20, this should still be enough */
-#define MAX_USERNAME_SIZE 32 /* 32 is to allow for 15 char names + null
- termination then *2 for unicode versions */
-#define MAX_PASSWORD_SIZE 512 /* max for windows seems to be 256 wide chars */
+#define MAX_SHARE_SIZE 80
+#define MAX_USERNAME_SIZE 256 /* reasonable maximum for current servers */
+#define MAX_PASSWORD_SIZE 512 /* max for windows seems to be 256 wide chars */
#define CIFS_MIN_RCV_POOL 4
@@ -179,7 +181,7 @@ struct TCP_Server_Info {
struct mutex srv_mutex;
struct task_struct *tsk;
char server_GUID[16];
- char secMode;
+ __u16 sec_mode;
bool session_estab; /* mark when very first sess is established */
u16 dialect; /* dialect index that server chose */
enum securityEnum secType;
@@ -211,6 +213,7 @@ struct TCP_Server_Info {
bool sec_kerberosu2u; /* supports U2U Kerberos */
bool sec_kerberos; /* supports plain Kerberos */
bool sec_mskerberos; /* supports legacy MS Kerberos */
+ bool is_smb2; /* smb2 not cifs protocol negotiated */
struct delayed_work echo; /* echo ping workqueue job */
#ifdef CONFIG_CIFS_FSCACHE
struct fscache_cookie *fscache; /* client index cache cookie */
@@ -219,6 +222,19 @@ struct TCP_Server_Info {
atomic_t inSend; /* requests trying to send */
atomic_t num_waiters; /* blocked waiting to get in sendrecv */
#endif
+#ifdef CONFIG_CIFS_SMB2
+ wait_queue_head_t read_q; /* used by readpages */
+ atomic_t active_readpage_req; /* used by readpages */
+ atomic_t resp_rdy; /* used by readpages and demultiplex */
+ atomic_t credits; /* send no more simultaneous requests than this */
+ __le16 smb2_dialect_revision; /* SMB2.0 implemented, 2.1 recognized */
+ struct task_struct *observe;
+/* char smb2_crypt_key[SMB2_CRYPTO_KEY_SIZE]; BB can we use cifs key? */
+ __u64 current_smb2_mid; /* multiplex id - rotating counter */
+ __u8 speed; /* helps us identify if this is a slow link */
+ unsigned int max_read;
+ unsigned int max_write;
+#endif /* CONFIG_CIFS_SMB2 */
};
/*
@@ -254,7 +270,7 @@ static inline void cifs_set_net_ns(struct TCP_Server_Info *srv, struct net *net)
/*
* Session structure. One of these for each uid session with a particular host
*/
-struct cifsSesInfo {
+struct cifs_ses {
struct list_head smb_ses_list;
struct list_head tcon_list;
struct mutex session_mutex;
@@ -274,12 +290,16 @@ struct cifsSesInfo {
int capabilities;
char serverName[SERVER_NAME_LEN_WITH_NULL * 2]; /* BB make bigger for
TCP names - will ipv6 and sctp addresses fit? */
- char userName[MAX_USERNAME_SIZE + 1];
+ char *user_name; /* must not be null except during init of sess
+ and after mount option parsing we fill it */
char *domainName;
char *password;
struct session_key auth_key;
struct ntlmssp_auth *ntlmssp; /* ciphertext, flags, server challenge */
bool need_reconnect:1; /* connection reset, uid now invalid */
+#ifdef CONFIG_CIFS_SMB2
+ __u16 session_flags;
+#endif /* CONFIG_CIFS_SMB2 */
};
/* no more than one of the following three session flags may be set */
#define CIFS_SES_NT4 1
@@ -289,15 +309,16 @@ struct cifsSesInfo {
which do not negotiate NTLM or POSIX dialects, but instead
negotiate one of the older LANMAN dialects */
#define CIFS_SES_LANMAN 8
+#define CIFS_SES_SMB2 16
/*
* there is one of these for each connection to a resource on a particular
* session
*/
-struct cifsTconInfo {
+struct cifs_tcon {
struct list_head tcon_list;
int tc_count;
struct list_head openFileList;
- struct cifsSesInfo *ses; /* pointer to session associated with */
+ struct cifs_ses *ses; /* pointer to session associated with */
char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
char *nativeFileSystem;
char *password; /* for share-level security */
@@ -306,27 +327,37 @@ struct cifsTconInfo {
enum statusEnum tidStatus;
#ifdef CONFIG_CIFS_STATS
atomic_t num_smbs_sent;
- atomic_t num_writes;
- atomic_t num_reads;
- atomic_t num_flushes;
- atomic_t num_oplock_brks;
- atomic_t num_opens;
- atomic_t num_closes;
- atomic_t num_deletes;
- atomic_t num_mkdirs;
- atomic_t num_posixopens;
- atomic_t num_posixmkdirs;
- atomic_t num_rmdirs;
- atomic_t num_renames;
- atomic_t num_t2renames;
- atomic_t num_ffirst;
- atomic_t num_fnext;
- atomic_t num_fclose;
- atomic_t num_hardlinks;
- atomic_t num_symlinks;
- atomic_t num_locks;
- atomic_t num_acl_get;
- atomic_t num_acl_set;
+ union {
+ struct {
+ atomic_t num_writes;
+ atomic_t num_reads;
+ atomic_t num_flushes;
+ atomic_t num_oplock_brks;
+ atomic_t num_opens;
+ atomic_t num_closes;
+ atomic_t num_deletes;
+ atomic_t num_mkdirs;
+ atomic_t num_posixopens;
+ atomic_t num_posixmkdirs;
+ atomic_t num_rmdirs;
+ atomic_t num_renames;
+ atomic_t num_t2renames;
+ atomic_t num_ffirst;
+ atomic_t num_fnext;
+ atomic_t num_fclose;
+ atomic_t num_hardlinks;
+ atomic_t num_symlinks;
+ atomic_t num_locks;
+ atomic_t num_acl_get;
+ atomic_t num_acl_set;
+ } cifs_stats;
+#ifdef CONFIG_CIFS_SMB2
+ struct {
+ atomic_t smb2_com_sent[NUMBER_OF_SMB2_COMMANDS];
+ atomic_t smb2_com_fail[NUMBER_OF_SMB2_COMMANDS];
+ } smb2_stats;
+#endif /* CONFIG CIFS_SMB2 */
+ } stats;
#ifdef CONFIG_CIFS_STATS2
unsigned long long time_writes;
unsigned long long time_reads;
@@ -349,6 +380,7 @@ struct cifsTconInfo {
FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
FILE_SYSTEM_UNIX_INFO fsUnixInfo;
bool ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */
+ bool print:1; /* set if connection to printer share */
bool retry:1;
bool nocase:1;
bool seal:1; /* transport encryption for this mounted share */
@@ -357,6 +389,14 @@ struct cifsTconInfo {
bool local_lease:1; /* check leases (only) on local system not remote */
bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */
bool need_reconnect:1; /* connection reset, tid now invalid */
+ bool bad_network_name:1;
+#ifdef CONFIG_CIFS_SMB2
+ __u32 capabilities;
+ __u32 share_flags;
+ __u32 maximal_access;
+ __u32 vol_serial_number;
+ __le64 vol_create_time;
+#endif /* CONFIG_CIFS_SMB2 */
#ifdef CONFIG_CIFS_FSCACHE
u64 resource_id; /* server resource id */
struct fscache_cookie *fscache; /* cookie for share */
@@ -379,12 +419,12 @@ struct tcon_link {
#define TCON_LINK_IN_TREE 2
unsigned long tl_time;
atomic_t tl_count;
- struct cifsTconInfo *tl_tcon;
+ struct cifs_tcon *tl_tcon;
};
extern struct tcon_link *cifs_sb_tlink(struct cifs_sb_info *cifs_sb);
-static inline struct cifsTconInfo *
+static inline struct cifs_tcon *
tlink_tcon(struct tcon_link *tlink)
{
return tlink->tl_tcon;
@@ -401,7 +441,7 @@ cifs_get_tlink(struct tcon_link *tlink)
}
/* This function is always expected to succeed */
-extern struct cifsTconInfo *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
+extern struct cifs_tcon *cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb);
/*
* This info hangs off the cifsFileInfo structure, pointed to by llist.
@@ -511,7 +551,7 @@ static inline char CIFS_DIR_SEP(const struct cifs_sb_info *cifs_sb)
#ifdef CONFIG_CIFS_STATS
#define cifs_stats_inc atomic_inc
-static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon,
+static inline void cifs_stats_bytes_written(struct cifs_tcon *tcon,
unsigned int bytes)
{
if (bytes) {
@@ -521,7 +561,7 @@ static inline void cifs_stats_bytes_written(struct cifsTconInfo *tcon,
}
}
-static inline void cifs_stats_bytes_read(struct cifsTconInfo *tcon,
+static inline void cifs_stats_bytes_read(struct cifs_tcon *tcon,
unsigned int bytes)
{
spin_lock(&tcon->stat_lock);
@@ -569,13 +609,6 @@ struct mid_q_entry {
bool multiEnd:1; /* both received */
};
-struct oplock_q_entry {
- struct list_head qhead;
- struct inode *pinode;
- struct cifsTconInfo *tcon;
- __u16 netfid;
-};
-
/* for pending dnotify requests */
struct dir_notify_req {
struct list_head lhead;
@@ -625,6 +658,7 @@ struct cifs_fattr {
struct timespec cf_atime;
struct timespec cf_mtime;
struct timespec cf_ctime;
+ u32 ea_size;
};
static inline void free_dfs_info_param(struct dfs_info3_param *param)
@@ -655,6 +689,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
#define MID_RESPONSE_RECEIVED 4
#define MID_RETRY_NEEDED 8 /* session closed while this request out */
#define MID_RESPONSE_MALFORMED 0x10
+#define MID_NO_RESPONSE_NEEDED 0x20
/* Types of response buffer returned from SendReceive2 */
#define CIFS_NO_BUFFER 0 /* Response buffer not returned */
@@ -663,6 +698,7 @@ static inline void free_dfs_info_array(struct dfs_info3_param *param,
#define CIFS_IOVEC 4 /* array of response buffers */
/* Type of Request to SendReceive2 */
+#define CIFS_STD_OP 0
#define CIFS_BLOCKING_OP 1 /* operation can block */
#define CIFS_ASYNC_OP 2 /* do not wait for response */
#define CIFS_TIMEOUT_MASK 0x003 /* only one of above set in req */
@@ -713,13 +749,6 @@ require use of the stronger protocol */
#define CIFSSEC_DEF (CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2)
#define CIFSSEC_MAX (CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2)
#define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5 | CIFSSEC_MAY_NTLMSSP)
-/*
- *****************************************************************
- * All constants go here
- *****************************************************************
- */
-
-#define UID_HASH (16)
/*
* Note that ONE module should define _DECLARE_GLOBALS_HERE to cause the
@@ -780,10 +809,12 @@ GLOBAL_EXTERN spinlock_t cifs_tcp_ses_lock;
*/
GLOBAL_EXTERN spinlock_t cifs_file_list_lock;
+#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
/* Outstanding dir notify requests */
GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
/* DirNotify response queue */
GLOBAL_EXTERN struct list_head GlobalDnotifyRsp_Q;
+#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
/*
* Global transaction id (XID) information
@@ -817,7 +848,6 @@ GLOBAL_EXTERN unsigned int multiuser_mount; /* if enabled allows new sessions
have the uid/password or Kerberos credential
or equivalent for current user */
GLOBAL_EXTERN unsigned int oplockEnabled;
-GLOBAL_EXTERN unsigned int experimEnabled;
GLOBAL_EXTERN unsigned int lookupCacheEnabled;
GLOBAL_EXTERN unsigned int global_secflags; /* if on, session setup sent
with more secure ntlmssp2 challenge/resp */
@@ -827,6 +857,7 @@ GLOBAL_EXTERN unsigned int CIFSMaxBufSize; /* max size not including hdr */
GLOBAL_EXTERN unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */
GLOBAL_EXTERN unsigned int cifs_min_small; /* min size of small buf pool */
GLOBAL_EXTERN unsigned int cifs_max_pending; /* MAX requests at once to server*/
+GLOBAL_EXTERN bool sign_zero_copy; /* don't copy written pages with signing */
/* reconnect after this many failed echo attempts */
GLOBAL_EXTERN unsigned short echo_retries;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 8096f27ad9a8..095cec7354d0 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -55,7 +55,7 @@ do { \
} while (0)
extern char *build_path_from_dentry(struct dentry *);
extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
- struct cifsTconInfo *tcon);
+ struct cifs_tcon *tcon);
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
extern char *cifs_compose_mount_options(const char *sb_mountdata,
const char *fullpath, const struct dfs_info3_param *ref,
@@ -67,17 +67,17 @@ extern void DeleteMidQEntry(struct mid_q_entry *midEntry);
extern int cifs_call_async(struct TCP_Server_Info *server,
struct smb_hdr *in_buf, mid_callback_t *callback,
void *cbdata);
-extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *,
+extern int SendReceive(const unsigned int /* xid */ , struct cifs_ses *,
struct smb_hdr * /* input */ ,
struct smb_hdr * /* out */ ,
int * /* bytes returned */ , const int long_op);
-extern int SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
+extern int SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
struct smb_hdr *in_buf, int flags);
-extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *,
+extern int SendReceive2(const unsigned int /* xid */ , struct cifs_ses *,
struct kvec *, int /* nvec to send */,
int * /* type of buf returned */ , const int flags);
extern int SendReceiveBlockingLock(const unsigned int xid,
- struct cifsTconInfo *ptcon,
+ struct cifs_tcon *ptcon,
struct smb_hdr *in_buf ,
struct smb_hdr *out_buf,
int *bytes_returned);
@@ -99,12 +99,12 @@ extern int cifs_fill_sockaddr(struct sockaddr *dst, const char *src, int len,
const unsigned short int port);
extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
extern void header_assemble(struct smb_hdr *, char /* command */ ,
- const struct cifsTconInfo *, int /* length of
+ const struct cifs_tcon *, int /* length of
fixed section (word count) in two byte units */);
extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
- struct cifsSesInfo *ses,
+ struct cifs_ses *ses,
void **request_buf);
-extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
+extern int CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
const struct nls_table *nls_cp);
extern __u16 GetNextMid(struct TCP_Server_Info *server);
extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
@@ -143,6 +143,8 @@ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
extern int mode_to_cifs_acl(struct inode *inode, const char *path, __u64);
extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
const char *, u32 *);
+extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
+ const char *);
extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
const char *);
@@ -152,94 +154,94 @@ void cifs_proc_init(void);
void cifs_proc_clean(void);
extern int cifs_negotiate_protocol(unsigned int xid,
- struct cifsSesInfo *ses);
-extern int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
+ struct cifs_ses *ses);
+extern int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
struct nls_table *nls_info);
-extern int CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses);
+extern int CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses);
-extern int CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
- const char *tree, struct cifsTconInfo *tcon,
+extern int CIFSTCon(unsigned int xid, struct cifs_ses *ses,
+ const char *tree, struct cifs_tcon *tcon,
const struct nls_table *);
-extern int CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
const char *searchName, const struct nls_table *nls_codepage,
__u16 *searchHandle, struct cifs_search_info *psrch_inf,
int map, const char dirsep);
-extern int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
__u16 searchHandle, struct cifs_search_info *psrch_inf);
-extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
+extern int CIFSFindClose(const int, struct cifs_tcon *tcon,
const __u16 search_handle);
-extern int CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
u16 netfid, FILE_ALL_INFO *pFindData);
-extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
FILE_ALL_INFO *findData,
int legacy /* whether to use old info level */,
const struct nls_table *nls_codepage, int remap);
-extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
+extern int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
FILE_ALL_INFO *findData,
const struct nls_table *nls_codepage, int remap);
-extern int CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
u16 netfid, FILE_UNIX_BASIC_INFO *pFindData);
extern int CIFSSMBUnixQPathInfo(const int xid,
- struct cifsTconInfo *tcon,
+ struct cifs_tcon *tcon,
const unsigned char *searchName,
FILE_UNIX_BASIC_INFO *pFindData,
const struct nls_table *nls_codepage, int remap);
-extern int CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
+extern int CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
const unsigned char *searchName,
struct dfs_info3_param **target_nodes,
unsigned int *number_of_nodes_in_array,
const struct nls_table *nls_codepage, int remap);
-extern int get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
+extern int get_dfs_path(int xid, struct cifs_ses *pSesInfo,
const char *old_path,
const struct nls_table *nls_codepage,
unsigned int *pnum_referrals,
struct dfs_info3_param **preferrals,
int remap);
-extern void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
+extern void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
struct super_block *sb, struct smb_vol *vol);
-extern int CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon,
struct kstatfs *FSData);
-extern int SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon,
+extern int SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon,
struct kstatfs *FSData);
-extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon,
__u64 cap);
extern int CIFSSMBQFSAttributeInfo(const int xid,
- struct cifsTconInfo *tcon);
-extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon);
-extern int CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon);
-extern int CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
+ struct cifs_tcon *tcon);
+extern int CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon);
+extern int CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon);
+extern int CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
struct kstatfs *FSData);
-extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
const FILE_BASIC_INFO *data, __u16 fid,
__u32 pid_of_opener);
-extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
bool delete_file, __u16 fid, __u32 pid_of_opener);
#if 0
-extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon,
char *fileName, __u16 dos_attributes,
const struct nls_table *nls_codepage);
#endif /* possibly unneeded function */
-extern int CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon,
const char *fileName, __u64 size,
bool setAllocationSizeFlag,
const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon,
__u64 size, __u16 fileHandle, __u32 opener_pid,
bool AllocSizeFlag);
@@ -253,121 +255,122 @@ struct cifs_unix_set_info_args {
dev_t device;
};
-extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
const struct cifs_unix_set_info_args *args,
u16 fid, u32 pid_of_opener);
-extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *pTcon,
+extern int CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *pTcon,
char *fileName,
const struct cifs_unix_set_info_args *args,
const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
const char *newName,
const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon,
const char *name, const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon,
const char *name, __u16 type,
const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon,
const char *name,
const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
+extern int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
int netfid, const char *target_name,
const struct nls_table *nls_codepage,
int remap_special_chars);
extern int CIFSCreateHardLink(const int xid,
- struct cifsTconInfo *tcon,
+ struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage,
int remap_special_chars);
extern int CIFSUnixCreateHardLink(const int xid,
- struct cifsTconInfo *tcon,
+ struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage,
int remap_special_chars);
extern int CIFSUnixCreateSymLink(const int xid,
- struct cifsTconInfo *tcon,
+ struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage);
extern int CIFSSMBUnixQuerySymLink(const int xid,
- struct cifsTconInfo *tcon,
+ struct cifs_tcon *tcon,
const unsigned char *searchName, char **syminfo,
const struct nls_table *nls_codepage);
+#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
extern int CIFSSMBQueryReparseLinkInfo(const int xid,
- struct cifsTconInfo *tcon,
+ struct cifs_tcon *tcon,
const unsigned char *searchName,
char *symlinkinfo, const int buflen, __u16 fid,
const struct nls_table *nls_codepage);
-
-extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
+#endif /* temporarily unused until cifs_symlink fixed */
+extern int CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
const char *fileName, const int disposition,
const int access_flags, const int omode,
__u16 *netfid, int *pOplock, FILE_ALL_INFO *,
const struct nls_table *nls_codepage, int remap);
-extern int SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
+extern int SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
const char *fileName, const int disposition,
const int access_flags, const int omode,
__u16 *netfid, int *pOplock, FILE_ALL_INFO *,
const struct nls_table *nls_codepage, int remap);
-extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon,
u32 posix_flags, __u64 mode, __u16 *netfid,
FILE_UNIX_BASIC_INFO *pRetData,
__u32 *pOplock, const char *name,
const struct nls_table *nls_codepage, int remap);
-extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBClose(const int xid, struct cifs_tcon *tcon,
const int smb_file_id);
-extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBFlush(const int xid, struct cifs_tcon *tcon,
const int smb_file_id);
-extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBRead(const int xid, struct cifs_tcon *tcon,
const int netfid, unsigned int count,
const __u64 lseek, unsigned int *nbytes, char **buf,
int *return_buf_type);
-extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBWrite(const int xid, struct cifs_tcon *tcon,
const int netfid, const unsigned int count,
const __u64 lseek, unsigned int *nbytes,
const char *buf, const char __user *ubuf,
const int long_op);
-extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBWrite2(const int xid, struct cifs_tcon *tcon,
const int netfid, const unsigned int count,
const __u64 offset, unsigned int *nbytes,
struct kvec *iov, const int nvec, const int long_op);
-extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, __u64 *inode_number,
const struct nls_table *nls_codepage,
int remap_special_chars);
extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
const struct nls_table *cp, int mapChars);
-extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
const __u16 netfid, const __u64 len,
const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType,
const bool waitFlag, const __u8 oplock_level);
-extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
const __u16 smb_file_id, const int get_flag,
const __u64 len, struct file_lock *,
const __u16 lock_type, const bool waitFlag);
-extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
+extern int CIFSSMBTDis(const int xid, struct cifs_tcon *tcon);
extern int CIFSSMBEcho(struct TCP_Server_Info *server);
-extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
+extern int CIFSSMBLogoff(const int xid, struct cifs_ses *ses);
-extern struct cifsSesInfo *sesInfoAlloc(void);
-extern void sesInfoFree(struct cifsSesInfo *);
-extern struct cifsTconInfo *tconInfoAlloc(void);
-extern void tconInfoFree(struct cifsTconInfo *);
+extern struct cifs_ses *sesInfoAlloc(void);
+extern void sesInfoFree(struct cifs_ses *);
+extern struct cifs_tcon *tconInfoAlloc(void);
+extern void tconInfoFree(struct cifs_tcon *);
extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
@@ -376,49 +379,51 @@ extern int cifs_verify_signature(struct smb_hdr *,
struct TCP_Server_Info *server,
__u32 expected_sequence_number);
extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *);
-extern int setup_ntlm_response(struct cifsSesInfo *);
-extern int setup_ntlmv2_rsp(struct cifsSesInfo *, const struct nls_table *);
+extern int setup_ntlm_response(struct cifs_ses *);
+extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *);
extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *);
extern void cifs_crypto_shash_release(struct TCP_Server_Info *);
-extern int calc_seckey(struct cifsSesInfo *);
+extern int calc_seckey(struct cifs_ses *);
#ifdef CONFIG_CIFS_WEAK_PW_HASH
-extern void calc_lanman_hash(const char *password, const char *cryptkey,
+extern int calc_lanman_hash(const char *password, const char *cryptkey,
bool encrypt, char *lnm_session_key);
#endif /* CIFS_WEAK_PW_HASH */
+#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
+extern int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
+ const int notify_subdirs, const __u16 netfid,
+ __u32 filter, struct file *file, int multishot,
+ const struct nls_table *nls_codepage);
+#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
extern int CIFSSMBCopy(int xid,
- struct cifsTconInfo *source_tcon,
+ struct cifs_tcon *source_tcon,
const char *fromName,
const __u16 target_tid,
const char *toName, const int flags,
const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
- const int notify_subdirs, const __u16 netfid,
- __u32 filter, struct file *file, int multishot,
- const struct nls_table *nls_codepage);
-extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
+extern ssize_t CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
const unsigned char *ea_name, char *EAData,
size_t bufsize, const struct nls_table *nls_codepage,
int remap_special_chars);
-extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon,
const char *fileName, const char *ea_name,
const void *ea_value, const __u16 ea_value_len,
const struct nls_table *nls_codepage, int remap_special_chars);
-extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon,
__u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
-extern int CIFSSMBSetCIFSACL(const int, struct cifsTconInfo *, __u16,
+extern int CIFSSMBSetCIFSACL(const int, struct cifs_tcon *, __u16,
struct cifs_ntsd *, __u32);
-extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
char *acl_inf, const int buflen, const int acl_type,
const struct nls_table *nls_codepage, int remap_special_chars);
-extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
const unsigned char *fileName,
const char *local_acl, const int buflen, const int acl_type,
const struct nls_table *nls_codepage, int remap_special_chars);
-extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
+extern int CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
extern bool CIFSCouldBeMFSymlink(const struct cifs_fattr *fattr);
@@ -427,9 +432,6 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,
struct cifs_sb_info *cifs_sb, int xid);
extern int mdfour(unsigned char *, unsigned char *, int);
extern int E_md4hash(const unsigned char *passwd, unsigned char *p16);
-extern void SMBencrypt(unsigned char *passwd, const unsigned char *c8,
- unsigned char *p24);
-extern void E_P16(unsigned char *p14, unsigned char *p16);
-extern void E_P24(unsigned char *p21, const unsigned char *c8,
+extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
unsigned char *p24);
#endif /* _CIFSPROTO_H */
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 904aa47e3515..6488a521cada 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -84,7 +84,7 @@ static struct {
/* Mark as invalid, all open files on tree connections since they
were closed when session to server was lost */
-static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
+static void mark_open_files_invalid(struct cifs_tcon *pTcon)
{
struct cifsFileInfo *open_file = NULL;
struct list_head *tmp;
@@ -104,10 +104,10 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon)
/* reconnect the socket, tcon, and smb session if needed */
static int
-cifs_reconnect_tcon(struct cifsTconInfo *tcon, int smb_command)
+cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
{
int rc = 0;
- struct cifsSesInfo *ses;
+ struct cifs_ses *ses;
struct TCP_Server_Info *server;
struct nls_table *nls_codepage;
@@ -226,7 +226,7 @@ out:
SMB information in the SMB header. If the return code is zero, this
function must have filled in request_buf pointer */
static int
-small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+small_smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
void **request_buf)
{
int rc;
@@ -252,7 +252,7 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
int
small_smb_init_no_tc(const int smb_command, const int wct,
- struct cifsSesInfo *ses, void **request_buf)
+ struct cifs_ses *ses, void **request_buf)
{
int rc;
struct smb_hdr *buffer;
@@ -278,7 +278,7 @@ small_smb_init_no_tc(const int smb_command, const int wct,
/* If the return code is zero, this function must fill in request_buf pointer */
static int
-__smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+__smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
void **request_buf, void **response_buf)
{
*request_buf = cifs_buf_get();
@@ -304,7 +304,7 @@ __smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
/* If the return code is zero, this function must fill in request_buf pointer */
static int
-smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
+smb_init(int smb_command, int wct, struct cifs_tcon *tcon,
void **request_buf, void **response_buf)
{
int rc;
@@ -317,7 +317,7 @@ smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
}
static int
-smb_init_no_reconnect(int smb_command, int wct, struct cifsTconInfo *tcon,
+smb_init_no_reconnect(int smb_command, int wct, struct cifs_tcon *tcon,
void **request_buf, void **response_buf)
{
if (tcon->ses->need_reconnect || tcon->need_reconnect)
@@ -358,7 +358,7 @@ vt2_err:
}
int
-CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
+CIFSSMBNegotiate(unsigned int xid, struct cifs_ses *ses)
{
NEGOTIATE_REQ *pSMB;
NEGOTIATE_RSP *pSMBr;
@@ -442,7 +442,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
rc = -EOPNOTSUPP;
goto neg_err_exit;
}
- server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode);
+ server->sec_mode = le16_to_cpu(rsp->SecurityMode);
server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
(__u32)CIFSMaxBufSize + MAX_CIFS_HDR_SIZE);
@@ -496,7 +496,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
cpu_to_le16(CIFS_CRYPTO_KEY_SIZE)) {
memcpy(ses->server->cryptkey, rsp->EncryptionKey,
CIFS_CRYPTO_KEY_SIZE);
- } else if (server->secMode & SECMODE_PW_ENCRYPT) {
+ } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
rc = -EIO; /* need cryptkey unless plain text */
goto neg_err_exit;
}
@@ -518,11 +518,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
goto neg_err_exit;
}
/* else wct == 17 NTLM */
- server->secMode = pSMBr->SecurityMode;
- if ((server->secMode & SECMODE_USER) == 0)
+ server->sec_mode = pSMBr->SecurityMode;
+ if ((server->sec_mode & SECMODE_USER) == 0)
cFYI(1, "share mode security");
- if ((server->secMode & SECMODE_PW_ENCRYPT) == 0)
+ if ((server->sec_mode & SECMODE_PW_ENCRYPT) == 0)
#ifdef CONFIG_CIFS_WEAK_PW_HASH
if ((secFlags & CIFSSEC_MAY_PLNTXT) == 0)
#endif /* CIFS_WEAK_PW_HASH */
@@ -541,10 +541,6 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
server->secType = RawNTLMSSP;
else if (secFlags & CIFSSEC_MAY_LANMAN)
server->secType = LANMAN;
-/* #ifdef CONFIG_CIFS_EXPERIMENTAL
- else if (secFlags & CIFSSEC_MAY_PLNTXT)
- server->secType = ??
-#endif */
else {
rc = -EOPNOTSUPP;
cERROR(1, "Invalid security type");
@@ -569,7 +565,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
} else if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC)
&& (pSMBr->EncryptionKeyLength == 0)) {
/* decode security blob */
- } else if (server->secMode & SECMODE_PW_ENCRYPT) {
+ } else if (server->sec_mode & SECMODE_PW_ENCRYPT) {
rc = -EIO; /* no crypt key only if plain text pwd */
goto neg_err_exit;
}
@@ -630,27 +626,27 @@ signing_check:
/* MUST_SIGN already includes the MAY_SIGN FLAG
so if this is zero it means that signing is disabled */
cFYI(1, "Signing disabled");
- if (server->secMode & SECMODE_SIGN_REQUIRED) {
+ if (server->sec_mode & SECMODE_SIGN_REQUIRED) {
cERROR(1, "Server requires "
"packet signing to be enabled in "
"/proc/fs/cifs/SecurityFlags.");
rc = -EOPNOTSUPP;
}
- server->secMode &=
+ server->sec_mode &=
~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
} else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) {
/* signing required */
cFYI(1, "Must sign - secFlags 0x%x", secFlags);
- if ((server->secMode &
+ if ((server->sec_mode &
(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED)) == 0) {
cERROR(1, "signing required but server lacks support");
rc = -EOPNOTSUPP;
} else
- server->secMode |= SECMODE_SIGN_REQUIRED;
+ server->sec_mode |= SECMODE_SIGN_REQUIRED;
} else {
/* signing optional ie CIFSSEC_MAY_SIGN */
- if ((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
- server->secMode &=
+ if ((server->sec_mode & SECMODE_SIGN_REQUIRED) == 0)
+ server->sec_mode &=
~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
}
@@ -662,7 +658,7 @@ neg_err_exit:
}
int
-CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon)
+CIFSSMBTDis(const int xid, struct cifs_tcon *tcon)
{
struct smb_hdr *smb_buffer;
int rc = 0;
@@ -747,7 +743,7 @@ CIFSSMBEcho(struct TCP_Server_Info *server)
}
int
-CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
+CIFSSMBLogoff(const int xid, struct cifs_ses *ses)
{
LOGOFF_ANDX_REQ *pSMB;
int rc = 0;
@@ -774,7 +770,7 @@ CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses)
pSMB->hdr.Mid = GetNextMid(ses->server);
- if (ses->server->secMode &
+ if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
@@ -794,7 +790,7 @@ session_already_dead:
}
int
-CIFSPOSIXDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
+CIFSPOSIXDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
__u16 type, const struct nls_table *nls_codepage, int remap)
{
TRANSACTION2_SPI_REQ *pSMB = NULL;
@@ -860,7 +856,7 @@ PsxDelete:
cFYI(1, "Posix delete returned %d", rc);
cifs_buf_release(pSMB);
- cifs_stats_inc(&tcon->num_deletes);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
if (rc == -EAGAIN)
goto PsxDelete;
@@ -869,7 +865,7 @@ PsxDelete:
}
int
-CIFSSMBDelFile(const int xid, struct cifsTconInfo *tcon, const char *fileName,
+CIFSSMBDelFile(const int xid, struct cifs_tcon *tcon, const char *fileName,
const struct nls_table *nls_codepage, int remap)
{
DELETE_FILE_REQ *pSMB = NULL;
@@ -902,7 +898,7 @@ DelFileRetry:
pSMB->ByteCount = cpu_to_le16(name_len + 1);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_deletes);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_deletes);
if (rc)
cFYI(1, "Error in RMFile = %d", rc);
@@ -914,7 +910,7 @@ DelFileRetry:
}
int
-CIFSSMBRmDir(const int xid, struct cifsTconInfo *tcon, const char *dirName,
+CIFSSMBRmDir(const int xid, struct cifs_tcon *tcon, const char *dirName,
const struct nls_table *nls_codepage, int remap)
{
DELETE_DIRECTORY_REQ *pSMB = NULL;
@@ -946,7 +942,7 @@ RmDirRetry:
pSMB->ByteCount = cpu_to_le16(name_len + 1);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_rmdirs);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_rmdirs);
if (rc)
cFYI(1, "Error in RMDir = %d", rc);
@@ -957,7 +953,7 @@ RmDirRetry:
}
int
-CIFSSMBMkDir(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBMkDir(const int xid, struct cifs_tcon *tcon,
const char *name, const struct nls_table *nls_codepage, int remap)
{
int rc = 0;
@@ -989,7 +985,7 @@ MkDirRetry:
pSMB->ByteCount = cpu_to_le16(name_len + 1);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_mkdirs);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_mkdirs);
if (rc)
cFYI(1, "Error in Mkdir = %d", rc);
@@ -1000,7 +996,7 @@ MkDirRetry:
}
int
-CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, __u32 posix_flags,
+CIFSPOSIXCreate(const int xid, struct cifs_tcon *tcon, __u32 posix_flags,
__u64 mode, __u16 *netfid, FILE_UNIX_BASIC_INFO *pRetData,
__u32 *pOplock, const char *name,
const struct nls_table *nls_codepage, int remap)
@@ -1111,9 +1107,9 @@ psx_create_err:
cifs_buf_release(pSMB);
if (posix_flags & SMB_O_DIRECTORY)
- cifs_stats_inc(&tcon->num_posixmkdirs);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_posixmkdirs);
else
- cifs_stats_inc(&tcon->num_posixopens);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_posixopens);
if (rc == -EAGAIN)
goto PsxCreat;
@@ -1166,7 +1162,7 @@ access_flags_to_smbopen_mode(const int access_flags)
}
int
-SMBLegacyOpen(const int xid, struct cifsTconInfo *tcon,
+SMBLegacyOpen(const int xid, struct cifs_tcon *tcon,
const char *fileName, const int openDisposition,
const int access_flags, const int create_options, __u16 *netfid,
int *pOplock, FILE_ALL_INFO *pfile_info,
@@ -1234,7 +1230,7 @@ OldOpenRetry:
/* long_op set to 1 to allow for oplock break timeouts */
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *)pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_opens);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
if (rc) {
cFYI(1, "Error in Open = %d", rc);
} else {
@@ -1273,7 +1269,7 @@ OldOpenRetry:
}
int
-CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBOpen(const int xid, struct cifs_tcon *tcon,
const char *fileName, const int openDisposition,
const int access_flags, const int create_options, __u16 *netfid,
int *pOplock, FILE_ALL_INFO *pfile_info,
@@ -1347,7 +1343,7 @@ openRetry:
/* long_op set to 1 to allow for oplock break timeouts */
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *)pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_opens);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_opens);
if (rc) {
cFYI(1, "Error in Open = %d", rc);
} else {
@@ -1375,7 +1371,7 @@ openRetry:
}
int
-CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
+CIFSSMBRead(const int xid, struct cifs_tcon *tcon, const int netfid,
const unsigned int count, const __u64 lseek, unsigned int *nbytes,
char **buf, int *pbuf_type)
{
@@ -1429,7 +1425,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
iov[0].iov_len = pSMB->hdr.smb_buf_length + 4;
rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */,
&resp_buf_type, CIFS_LOG_ERROR);
- cifs_stats_inc(&tcon->num_reads);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
pSMBr = (READ_RSP *)iov[0].iov_base;
if (rc) {
cERROR(1, "Send error in read = %d", rc);
@@ -1480,7 +1476,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
int
-CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBWrite(const int xid, struct cifs_tcon *tcon,
const int netfid, const unsigned int count,
const __u64 offset, unsigned int *nbytes, const char *buf,
const char __user *ubuf, const int long_op)
@@ -1573,7 +1569,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, long_op);
- cifs_stats_inc(&tcon->num_writes);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
if (rc) {
cFYI(1, "Send error in write = %d", rc);
} else {
@@ -1599,7 +1595,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
}
int
-CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBWrite2(const int xid, struct cifs_tcon *tcon,
const int netfid, const unsigned int count,
const __u64 offset, unsigned int *nbytes, struct kvec *iov,
int n_vec, const int long_op)
@@ -1665,7 +1661,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type,
long_op);
- cifs_stats_inc(&tcon->num_writes);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
if (rc) {
cFYI(1, "Send error Write2 = %d", rc);
} else if (resp_buf_type == 0) {
@@ -1700,7 +1696,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
int
-CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBLock(const int xid, struct cifs_tcon *tcon,
const __u16 smb_file_id, const __u64 len,
const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType,
@@ -1760,7 +1756,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
timeout);
/* SMB buffer freed by function above */
}
- cifs_stats_inc(&tcon->num_locks);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_locks);
if (rc)
cFYI(1, "Send error in Lock = %d", rc);
@@ -1770,7 +1766,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
}
int
-CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBPosixLock(const int xid, struct cifs_tcon *tcon,
const __u16 smb_file_id, const int get_flag, const __u64 len,
struct file_lock *pLockData, const __u16 lock_type,
const bool waitFlag)
@@ -1908,7 +1904,7 @@ plk_err_exit:
int
-CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
+CIFSSMBClose(const int xid, struct cifs_tcon *tcon, int smb_file_id)
{
int rc = 0;
CLOSE_REQ *pSMB = NULL;
@@ -1925,7 +1921,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
pSMB->LastWriteTime = 0xFFFFFFFF;
pSMB->ByteCount = 0;
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
- cifs_stats_inc(&tcon->num_closes);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_closes);
if (rc) {
if (rc != -EINTR) {
/* EINTR is expected when user ctl-c to kill app */
@@ -1941,7 +1937,7 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
}
int
-CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
+CIFSSMBFlush(const int xid, struct cifs_tcon *tcon, int smb_file_id)
{
int rc = 0;
FLUSH_REQ *pSMB = NULL;
@@ -1954,7 +1950,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
pSMB->FileID = (__u16) smb_file_id;
pSMB->ByteCount = 0;
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
- cifs_stats_inc(&tcon->num_flushes);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_flushes);
if (rc)
cERROR(1, "Send error in Flush = %d", rc);
@@ -1962,7 +1958,7 @@ CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
}
int
-CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBRename(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap)
{
@@ -2017,7 +2013,7 @@ renameRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_renames);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_renames);
if (rc)
cFYI(1, "Send error in rename = %d", rc);
@@ -2029,7 +2025,7 @@ renameRetry:
return rc;
}
-int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
+int CIFSSMBRenameOpenFile(const int xid, struct cifs_tcon *pTcon,
int netfid, const char *target_name,
const struct nls_table *nls_codepage, int remap)
{
@@ -2096,7 +2092,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, pTcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&pTcon->num_t2renames);
+ cifs_stats_inc(&pTcon->stats.cifs_stats.num_t2renames);
if (rc)
cFYI(1, "Send error in Rename (by file handle) = %d", rc);
@@ -2109,7 +2105,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
}
int
-CIFSSMBCopy(const int xid, struct cifsTconInfo *tcon, const char *fromName,
+CIFSSMBCopy(const int xid, struct cifs_tcon *tcon, const char *fromName,
const __u16 target_tid, const char *toName, const int flags,
const struct nls_table *nls_codepage, int remap)
{
@@ -2177,7 +2173,7 @@ copyRetry:
}
int
-CIFSUnixCreateSymLink(const int xid, struct cifsTconInfo *tcon,
+CIFSUnixCreateSymLink(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage)
{
@@ -2253,7 +2249,7 @@ createSymLinkRetry:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_symlinks);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_symlinks);
if (rc)
cFYI(1, "Send error in SetPathInfo create symlink = %d", rc);
@@ -2266,7 +2262,7 @@ createSymLinkRetry:
}
int
-CIFSUnixCreateHardLink(const int xid, struct cifsTconInfo *tcon,
+CIFSUnixCreateHardLink(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap)
{
@@ -2339,7 +2335,7 @@ createHardLinkRetry:
pSMB->ByteCount = cpu_to_le16(byte_count);
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_hardlinks);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
if (rc)
cFYI(1, "Send error in SetPathInfo (hard link) = %d", rc);
@@ -2351,7 +2347,7 @@ createHardLinkRetry:
}
int
-CIFSCreateHardLink(const int xid, struct cifsTconInfo *tcon,
+CIFSCreateHardLink(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap)
{
@@ -2411,7 +2407,7 @@ winCreateHardLinkRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_hardlinks);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_hardlinks);
if (rc)
cFYI(1, "Send error in hard link (NT rename) = %d", rc);
@@ -2423,7 +2419,7 @@ winCreateHardLinkRetry:
}
int
-CIFSSMBUnixQuerySymLink(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBUnixQuerySymLink(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, char **symlinkinfo,
const struct nls_table *nls_codepage)
{
@@ -2516,9 +2512,19 @@ querySymLinkRetry:
return rc;
}
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CONFIG_CIFS_SYMLINK_EXPERIMENTAL
+/*
+ * Recent Windows versions now create symlinks more frequently
+ * and they use the "reparse point" mechanism below. We can of course
+ * do symlinks nicely to Samba and other servers which support the
+ * CIFS Unix Extensions and we can also do SFU symlinks and "client only"
+ * "MF" symlinks optionally, but for recent Windows we really need to
+ * reenable the code below and fix the cifs_symlink callers to handle this.
+ * In the interim this code has been moved to its own config option so
+ * it is not compiled in by default until callers fixed up and more tested.
+ */
int
-CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBQueryReparseLinkInfo(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
char *symlinkinfo, const int buflen, __u16 fid,
const struct nls_table *nls_codepage)
@@ -2618,7 +2624,7 @@ qreparse_out:
return rc;
}
-#endif /* CIFS_EXPERIMENTAL */
+#endif /* CIFS_SYMLINK_EXPERIMENTAL */ /* BB temporarily unused */
#ifdef CONFIG_CIFS_POSIX
@@ -2756,7 +2762,7 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
}
int
-CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBGetPosixACL(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
char *acl_inf, const int buflen, const int acl_type,
const struct nls_table *nls_codepage, int remap)
@@ -2819,7 +2825,7 @@ queryAclRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_acl_get);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
if (rc) {
cFYI(1, "Send error in Query POSIX ACL = %d", rc);
} else {
@@ -2844,7 +2850,7 @@ queryAclRetry:
}
int
-CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBSetPosixACL(const int xid, struct cifs_tcon *tcon,
const unsigned char *fileName,
const char *local_acl, const int buflen,
const int acl_type,
@@ -2924,7 +2930,7 @@ setACLerrorExit:
/* BB fix tabs in this function FIXME BB */
int
-CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
+CIFSGetExtAttr(const int xid, struct cifs_tcon *tcon,
const int netfid, __u64 *pExtAttrBits, __u64 *pMask)
{
int rc = 0;
@@ -3017,7 +3023,7 @@ GetExtAttrOut:
*/
static int
smb_init_nttransact(const __u16 sub_command, const int setup_count,
- const int parm_len, struct cifsTconInfo *tcon,
+ const int parm_len, struct cifs_tcon *tcon,
void **ret_buf)
{
int rc;
@@ -3099,7 +3105,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
/* Get Security Descriptor (by handle) from remote server for a file or dir */
int
-CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
+CIFSSMBGetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
struct cifs_ntsd **acl_inf, __u32 *pbuflen)
{
int rc = 0;
@@ -3130,7 +3136,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type,
0);
- cifs_stats_inc(&tcon->num_acl_get);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_acl_get);
if (rc) {
cFYI(1, "Send error in QuerySecDesc = %d", rc);
} else { /* decode response */
@@ -3191,7 +3197,7 @@ qsec_out:
}
int
-CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
+CIFSSMBSetCIFSACL(const int xid, struct cifs_tcon *tcon, __u16 fid,
struct cifs_ntsd *pntsd, __u32 acllen)
{
__u16 byte_count, param_count, data_count, param_offset, data_offset;
@@ -3258,7 +3264,7 @@ setCifsAclRetry:
/* Legacy Query Path Information call for lookup to old servers such
as Win9x/WinME */
-int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
+int SMBQueryInformation(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
FILE_ALL_INFO *pFinfo,
const struct nls_table *nls_codepage, int remap)
@@ -3326,7 +3332,7 @@ QInfRetry:
}
int
-CIFSSMBQFileInfo(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBQFileInfo(const int xid, struct cifs_tcon *tcon,
u16 netfid, FILE_ALL_INFO *pFindData)
{
struct smb_t2_qfi_req *pSMB = NULL;
@@ -3393,7 +3399,7 @@ QFileInfoRetry:
}
int
-CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBQPathInfo(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
FILE_ALL_INFO *pFindData,
int legacy /* old style infolevel */,
@@ -3494,7 +3500,7 @@ QPathInfoRetry:
}
int
-CIFSSMBUnixQFileInfo(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBUnixQFileInfo(const int xid, struct cifs_tcon *tcon,
u16 netfid, FILE_UNIX_BASIC_INFO *pFindData)
{
struct smb_t2_qfi_req *pSMB = NULL;
@@ -3563,7 +3569,7 @@ UnixQFileInfoRetry:
}
int
-CIFSSMBUnixQPathInfo(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBUnixQPathInfo(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
FILE_UNIX_BASIC_INFO *pFindData,
const struct nls_table *nls_codepage, int remap)
@@ -3649,7 +3655,7 @@ UnixQPathInfoRetry:
/* xid, tcon, searchName and codepage are input parms, rest are returned */
int
-CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
+CIFSFindFirst(const int xid, struct cifs_tcon *tcon,
const char *searchName,
const struct nls_table *nls_codepage,
__u16 *pnetfid,
@@ -3736,7 +3742,7 @@ findFirstRetry:
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_ffirst);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_ffirst);
if (rc) {/* BB add logic to retry regular search if Unix search
rejected unexpectedly by server */
@@ -3797,7 +3803,7 @@ findFirstRetry:
return rc;
}
-int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
+int CIFSFindNext(const int xid, struct cifs_tcon *tcon,
__u16 searchHandle, struct cifs_search_info *psrch_inf)
{
TRANSACTION2_FNEXT_REQ *pSMB = NULL;
@@ -3865,7 +3871,7 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
- cifs_stats_inc(&tcon->num_fnext);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_fnext);
if (rc) {
if (rc == -EBADF) {
psrch_inf->endOfSearch = true;
@@ -3935,7 +3941,7 @@ FNext2_err_exit:
}
int
-CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
+CIFSFindClose(const int xid, struct cifs_tcon *tcon,
const __u16 searchHandle)
{
int rc = 0;
@@ -3957,7 +3963,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
if (rc)
cERROR(1, "Send error in FindClose = %d", rc);
- cifs_stats_inc(&tcon->num_fclose);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_fclose);
/* Since session is dead, search handle closed on server already */
if (rc == -EAGAIN)
@@ -3967,7 +3973,7 @@ CIFSFindClose(const int xid, struct cifsTconInfo *tcon,
}
int
-CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
+CIFSGetSrvInodeNumber(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName,
__u64 *inode_number,
const struct nls_table *nls_codepage, int remap)
@@ -4169,7 +4175,7 @@ parse_DFS_referrals_exit:
}
int
-CIFSGetDFSRefer(const int xid, struct cifsSesInfo *ses,
+CIFSGetDFSRefer(const int xid, struct cifs_ses *ses,
const unsigned char *searchName,
struct dfs_info3_param **target_nodes,
unsigned int *num_of_nodes,
@@ -4218,7 +4224,7 @@ getDFSRetry:
}
if (ses->server) {
- if (ses->server->secMode &
+ if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
}
@@ -4283,7 +4289,7 @@ GetDFSRefExit:
/* Query File System Info such as free space to old servers such as Win 9x */
int
-SMBOldQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
+SMBOldQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
{
/* level 0x01 SMB_QUERY_FILE_SYSTEM_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4362,7 +4368,7 @@ oldQFSInfoRetry:
}
int
-CIFSSMBQFSInfo(const int xid, struct cifsTconInfo *tcon, struct kstatfs *FSData)
+CIFSSMBQFSInfo(const int xid, struct cifs_tcon *tcon, struct kstatfs *FSData)
{
/* level 0x103 SMB_QUERY_FILE_SYSTEM_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4441,7 +4447,7 @@ QFSInfoRetry:
}
int
-CIFSSMBQFSAttributeInfo(const int xid, struct cifsTconInfo *tcon)
+CIFSSMBQFSAttributeInfo(const int xid, struct cifs_tcon *tcon)
{
/* level 0x105 SMB_QUERY_FILE_SYSTEM_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4511,7 +4517,7 @@ QFSAttributeRetry:
}
int
-CIFSSMBQFSDeviceInfo(const int xid, struct cifsTconInfo *tcon)
+CIFSSMBQFSDeviceInfo(const int xid, struct cifs_tcon *tcon)
{
/* level 0x104 SMB_QUERY_FILE_SYSTEM_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4581,7 +4587,7 @@ QFSDeviceRetry:
}
int
-CIFSSMBQFSUnixInfo(const int xid, struct cifsTconInfo *tcon)
+CIFSSMBQFSUnixInfo(const int xid, struct cifs_tcon *tcon)
{
/* level 0x200 SMB_QUERY_CIFS_UNIX_INFO */
TRANSACTION2_QFSI_REQ *pSMB = NULL;
@@ -4651,7 +4657,7 @@ QFSUnixRetry:
}
int
-CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
+CIFSSMBSetFSUnixInfo(const int xid, struct cifs_tcon *tcon, __u64 cap)
{
/* level 0x200 SMB_SET_CIFS_UNIX_INFO */
TRANSACTION2_SETFSI_REQ *pSMB = NULL;
@@ -4725,7 +4731,7 @@ SETFSUnixRetry:
int
-CIFSSMBQFSPosixInfo(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBQFSPosixInfo(const int xid, struct cifs_tcon *tcon,
struct kstatfs *FSData)
{
/* level 0x201 SMB_QUERY_CIFS_POSIX_INFO */
@@ -4818,7 +4824,7 @@ QFSPosixRetry:
in Samba which this routine can run into */
int
-CIFSSMBSetEOF(const int xid, struct cifsTconInfo *tcon, const char *fileName,
+CIFSSMBSetEOF(const int xid, struct cifs_tcon *tcon, const char *fileName,
__u64 size, bool SetAllocation,
const struct nls_table *nls_codepage, int remap)
{
@@ -4907,7 +4913,7 @@ SetEOFRetry:
}
int
-CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
+CIFSSMBSetFileSize(const int xid, struct cifs_tcon *tcon, __u64 size,
__u16 fid, __u32 pid_of_opener, bool SetAllocation)
{
struct smb_com_transaction2_sfi_req *pSMB = NULL;
@@ -4989,7 +4995,7 @@ CIFSSMBSetFileSize(const int xid, struct cifsTconInfo *tcon, __u64 size,
time and resort to the original setpathinfo level which takes the ancient
DOS time format with 2 second granularity */
int
-CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBSetFileInfo(const int xid, struct cifs_tcon *tcon,
const FILE_BASIC_INFO *data, __u16 fid, __u32 pid_of_opener)
{
struct smb_com_transaction2_sfi_req *pSMB = NULL;
@@ -5051,7 +5057,7 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
}
int
-CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBSetFileDisposition(const int xid, struct cifs_tcon *tcon,
bool delete_file, __u16 fid, __u32 pid_of_opener)
{
struct smb_com_transaction2_sfi_req *pSMB = NULL;
@@ -5107,7 +5113,7 @@ CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
}
int
-CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBSetPathInfo(const int xid, struct cifs_tcon *tcon,
const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage, int remap)
{
@@ -5191,7 +5197,7 @@ SetTimesRetry:
handling it anyway and NT4 was what we thought it would be needed for
Do not delete it until we prove whether needed for Win9x though */
int
-CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon, char *fileName,
+CIFSSMBSetAttrLegacy(int xid, struct cifs_tcon *tcon, char *fileName,
__u16 dos_attrs, const struct nls_table *nls_codepage)
{
SETATTR_REQ *pSMB = NULL;
@@ -5279,7 +5285,7 @@ cifs_fill_unix_set_info(FILE_UNIX_BASIC_INFO *data_offset,
}
int
-CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBUnixSetFileInfo(const int xid, struct cifs_tcon *tcon,
const struct cifs_unix_set_info_args *args,
u16 fid, u32 pid_of_opener)
{
@@ -5342,7 +5348,7 @@ CIFSSMBUnixSetFileInfo(const int xid, struct cifsTconInfo *tcon,
}
int
-CIFSSMBUnixSetPathInfo(const int xid, struct cifsTconInfo *tcon, char *fileName,
+CIFSSMBUnixSetPathInfo(const int xid, struct cifs_tcon *tcon, char *fileName,
const struct cifs_unix_set_info_args *args,
const struct nls_table *nls_codepage, int remap)
{
@@ -5418,79 +5424,6 @@ setPermsRetry:
return rc;
}
-int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
- const int notify_subdirs, const __u16 netfid,
- __u32 filter, struct file *pfile, int multishot,
- const struct nls_table *nls_codepage)
-{
- int rc = 0;
- struct smb_com_transaction_change_notify_req *pSMB = NULL;
- struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
- struct dir_notify_req *dnotify_req;
- int bytes_returned;
-
- cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
- rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
- (void **) &pSMBr);
- if (rc)
- return rc;
-
- pSMB->TotalParameterCount = 0 ;
- pSMB->TotalDataCount = 0;
- pSMB->MaxParameterCount = cpu_to_le32(2);
- /* BB find exact data count max from sess structure BB */
- pSMB->MaxDataCount = 0; /* same in little endian or be */
-/* BB VERIFY verify which is correct for above BB */
- pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
- MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
-
- pSMB->MaxSetupCount = 4;
- pSMB->Reserved = 0;
- pSMB->ParameterOffset = 0;
- pSMB->DataCount = 0;
- pSMB->DataOffset = 0;
- pSMB->SetupCount = 4; /* single byte does not need le conversion */
- pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
- pSMB->ParameterCount = pSMB->TotalParameterCount;
- if (notify_subdirs)
- pSMB->WatchTree = 1; /* one byte - no le conversion needed */
- pSMB->Reserved2 = 0;
- pSMB->CompletionFilter = cpu_to_le32(filter);
- pSMB->Fid = netfid; /* file handle always le */
- pSMB->ByteCount = 0;
-
- rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
- (struct smb_hdr *)pSMBr, &bytes_returned,
- CIFS_ASYNC_OP);
- if (rc) {
- cFYI(1, "Error in Notify = %d", rc);
- } else {
- /* Add file to outstanding requests */
- /* BB change to kmem cache alloc */
- dnotify_req = kmalloc(
- sizeof(struct dir_notify_req),
- GFP_KERNEL);
- if (dnotify_req) {
- dnotify_req->Pid = pSMB->hdr.Pid;
- dnotify_req->PidHigh = pSMB->hdr.PidHigh;
- dnotify_req->Mid = pSMB->hdr.Mid;
- dnotify_req->Tid = pSMB->hdr.Tid;
- dnotify_req->Uid = pSMB->hdr.Uid;
- dnotify_req->netfid = netfid;
- dnotify_req->pfile = pfile;
- dnotify_req->filter = filter;
- dnotify_req->multishot = multishot;
- spin_lock(&GlobalMid_Lock);
- list_add_tail(&dnotify_req->lhead,
- &GlobalDnotifyReqList);
- spin_unlock(&GlobalMid_Lock);
- } else
- rc = -ENOMEM;
- }
- cifs_buf_release(pSMB);
- return rc;
-}
-
#ifdef CONFIG_CIFS_XATTR
/*
* Do a path-based QUERY_ALL_EAS call and parse the result. This is a common
@@ -5502,7 +5435,7 @@ int CIFSSMBNotify(const int xid, struct cifsTconInfo *tcon,
* the data isn't copied to it, but the length is returned.
*/
ssize_t
-CIFSSMBQAllEAs(const int xid, struct cifsTconInfo *tcon,
+CIFSSMBQAllEAs(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, const unsigned char *ea_name,
char *EAData, size_t buf_size,
const struct nls_table *nls_codepage, int remap)
@@ -5683,7 +5616,7 @@ QAllEAsOut:
}
int
-CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon, const char *fileName,
+CIFSSMBSetEA(const int xid, struct cifs_tcon *tcon, const char *fileName,
const char *ea_name, const void *ea_value,
const __u16 ea_value_len, const struct nls_table *nls_codepage,
int remap)
@@ -5787,5 +5720,99 @@ SetEARetry:
return rc;
}
-
#endif
+
+#ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* BB unused temporarily */
+/*
+ * Years ago the kernel added a "dnotify" function for Samba server,
+ * to allow network clients (such as Windows) to display updated
+ * lists of files in directory listings automatically when
+ * files are added by one user when another user has the
+ * same directory open on their desktop. The Linux cifs kernel
+ * client hooked into the kernel side of this interface for
+ * the same reason, but ironically when the VFS moved from
+ * "dnotify" to "inotify" it became harder to plug in Linux
+ * network file system clients (the most obvious use case
+ * for notify interfaces is when multiple users can update
+ * the contents of the same directory - exactly what network
+ * file systems can do) although the server (Samba) could
+ * still use it. For the short term we leave the worker
+ * function ifdeffed out (below) until inotify is fixed
+ * in the VFS to make it easier to plug in network file
+ * system clients. If inotify turns out to be permanently
+ * incompatible for network fs clients, we could instead simply
+ * expose this config flag by adding a future cifs (and smb2) notify ioctl.
+ */
+int CIFSSMBNotify(const int xid, struct cifs_tcon *tcon,
+ const int notify_subdirs, const __u16 netfid,
+ __u32 filter, struct file *pfile, int multishot,
+ const struct nls_table *nls_codepage)
+{
+ int rc = 0;
+ struct smb_com_transaction_change_notify_req *pSMB = NULL;
+ struct smb_com_ntransaction_change_notify_rsp *pSMBr = NULL;
+ struct dir_notify_req *dnotify_req;
+ int bytes_returned;
+
+ cFYI(1, "In CIFSSMBNotify for file handle %d", (int)netfid);
+ rc = smb_init(SMB_COM_NT_TRANSACT, 23, tcon, (void **) &pSMB,
+ (void **) &pSMBr);
+ if (rc)
+ return rc;
+
+ pSMB->TotalParameterCount = 0 ;
+ pSMB->TotalDataCount = 0;
+ pSMB->MaxParameterCount = cpu_to_le32(2);
+ /* BB find exact data count max from sess structure BB */
+ pSMB->MaxDataCount = 0; /* same in little endian or be */
+/* BB VERIFY verify which is correct for above BB */
+ pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf -
+ MAX_CIFS_HDR_SIZE) & 0xFFFFFF00);
+
+ pSMB->MaxSetupCount = 4;
+ pSMB->Reserved = 0;
+ pSMB->ParameterOffset = 0;
+ pSMB->DataCount = 0;
+ pSMB->DataOffset = 0;
+ pSMB->SetupCount = 4; /* single byte does not need le conversion */
+ pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_NOTIFY_CHANGE);
+ pSMB->ParameterCount = pSMB->TotalParameterCount;
+ if (notify_subdirs)
+ pSMB->WatchTree = 1; /* one byte - no le conversion needed */
+ pSMB->Reserved2 = 0;
+ pSMB->CompletionFilter = cpu_to_le32(filter);
+ pSMB->Fid = netfid; /* file handle always le */
+ pSMB->ByteCount = 0;
+
+ rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
+ (struct smb_hdr *)pSMBr, &bytes_returned,
+ CIFS_ASYNC_OP);
+ if (rc) {
+ cFYI(1, "Error in Notify = %d", rc);
+ } else {
+ /* Add file to outstanding requests */
+ /* BB change to kmem cache alloc */
+ dnotify_req = kmalloc(
+ sizeof(struct dir_notify_req),
+ GFP_KERNEL);
+ if (dnotify_req) {
+ dnotify_req->Pid = pSMB->hdr.Pid;
+ dnotify_req->PidHigh = pSMB->hdr.PidHigh;
+ dnotify_req->Mid = pSMB->hdr.Mid;
+ dnotify_req->Tid = pSMB->hdr.Tid;
+ dnotify_req->Uid = pSMB->hdr.Uid;
+ dnotify_req->netfid = netfid;
+ dnotify_req->pfile = pfile;
+ dnotify_req->filter = filter;
+ dnotify_req->multishot = multishot;
+ spin_lock(&GlobalMid_Lock);
+ list_add_tail(&dnotify_req->lhead,
+ &GlobalDnotifyReqList);
+ spin_unlock(&GlobalMid_Lock);
+ } else
+ rc = -ENOMEM;
+ }
+ cifs_buf_release(pSMB);
+ return rc;
+}
+#endif /* was needed for dnotify, and will be needed for inotify when VFS fix */
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 8d6c17ab593d..63ec77c8cb09 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
/*
* fs/cifs/connect.c
*
- * Copyright (C) International Business Machines Corp., 2002,2009
+ * Copyright (C) International Business Machines Corp., 2002,2011
* Author(s): Steve French (sfrench@us.ibm.com)
*
* This library is free software; you can redistribute it and/or modify
@@ -48,6 +48,9 @@
#include "nterr.h"
#include "rfc1002pdu.h"
#include "fscache.h"
+#ifdef CONFIG_CIFS_SMB2
+#include "smb2proto.h"
+#endif /* CONFIG_CIFS_SMB2 */
#define CIFS_PORT 445
#define RFC1001_PORT 139
@@ -102,6 +105,7 @@ struct smb_vol {
bool fsc:1; /* enable fscache */
bool mfsymlinks:1; /* use Minshall+French Symlinks */
bool multiuser:1;
+ bool use_smb2:1; /* force smb2 use on mount instead of cifs */
unsigned int rsize;
unsigned int wsize;
bool sockopt_tcp_nodelay:1;
@@ -134,8 +138,8 @@ cifs_reconnect(struct TCP_Server_Info *server)
{
int rc = 0;
struct list_head *tmp, *tmp2;
- struct cifsSesInfo *ses;
- struct cifsTconInfo *tcon;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
struct mid_q_entry *mid_entry;
spin_lock(&GlobalMid_Lock);
@@ -156,11 +160,11 @@ cifs_reconnect(struct TCP_Server_Info *server)
cFYI(1, "%s: marking sessions and tcons for reconnect", __func__);
spin_lock(&cifs_tcp_ses_lock);
list_for_each(tmp, &server->smb_ses_list) {
- ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
+ ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
ses->need_reconnect = true;
ses->ipc_tid = 0;
list_for_each(tmp2, &ses->tcon_list) {
- tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
+ tcon = list_entry(tmp2, struct cifs_tcon, tcon_list);
tcon->need_reconnect = true;
}
}
@@ -722,7 +726,7 @@ multi_t2_fnd:
sock_release(csocket);
server->ssocket = NULL;
}
- /* buffer usuallly freed in free_mid - need to free it here on exit */
+ /* buffer usually freed in free_mid - need to free it here on exit */
cifs_buf_release(bigbuf);
if (smallbuf) /* no sense logging a debug message if NULL */
cifs_small_buf_release(smallbuf);
@@ -881,7 +885,8 @@ cifs_parse_mount_options(char *options, const char *devname,
/* null user, ie anonymous, authentication */
vol->nullauth = 1;
}
- if (strnlen(value, 200) < 200) {
+ if (strnlen(value, MAX_USERNAME_SIZE) <
+ MAX_USERNAME_SIZE) {
vol->username = value;
} else {
printk(KERN_WARNING "CIFS: username too long\n");
@@ -1023,6 +1028,22 @@ cifs_parse_mount_options(char *options, const char *devname,
cERROR(1, "bad security option: %s", value);
return 1;
}
+ } else if (strnicmp(data, "vers", 3) == 0) {
+ if (!value || !*value) {
+ cERROR(1, "no protocol version specified"
+ " after vers= mount option");
+ } else if ((strnicmp(value, "cifs", 4) == 0) ||
+ (strnicmp(value, "1", 1) == 0)) {
+ /* this is the default */
+ continue;
+ } else if ((strnicmp(value, "smb2", 4) == 0) ||
+ (strnicmp(value, "2", 1) == 0)) {
+#ifdef CONFIG_CIFS_SMB2
+ vol->use_smb2 = true;
+#else
+ cERROR(1, "smb2 support not enabled");
+#endif /* CONFIG_CIFS_SMB2 */
+ }
} else if ((strnicmp(data, "unc", 3) == 0)
|| (strnicmp(data, "target", 6) == 0)
|| (strnicmp(data, "path", 4) == 0)) {
@@ -1574,10 +1595,10 @@ match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
/* now check if signing mode is acceptible */
if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
- (server->secMode & SECMODE_SIGN_REQUIRED))
+ (server->sec_mode & SECMODE_SIGN_REQUIRED))
return false;
else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
- (server->secMode &
+ (server->sec_mode &
(SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
return false;
@@ -1598,6 +1619,14 @@ cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
(struct sockaddr *)&vol->srcaddr))
continue;
+#ifdef CONFIG_CIFS_SMB2
+ if ((server->is_smb2 == true) && (vol->use_smb2 == false))
+ continue;
+
+ if ((server->is_smb2 == false) && (vol->use_smb2 == true))
+ continue;
+#endif /* CONFIG_CIFS_SMB2 */
+
if (!match_port(server, addr))
continue;
@@ -1709,6 +1738,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
tcp_ses->noblocksnd = volume_info->noblocksnd;
tcp_ses->noautotune = volume_info->noautotune;
+ /* BB should we set this unconditionally now, especially for SMB2 */
tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
atomic_set(&tcp_ses->inFlight, 0);
init_waitqueue_head(&tcp_ses->response_q);
@@ -1752,6 +1782,11 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
goto out_err_crypto_release;
}
+#ifdef CONFIG_CIFS_SMB2
+ if (volume_info->use_smb2)
+ tcp_ses->is_smb2 = true;
+#endif /* CONFIG_CIFS_SMB2 */
+
/*
* since we're in a cifs function already, we know that
* this will succeed. No need for try_module_get().
@@ -1794,10 +1829,10 @@ out_err:
return ERR_PTR(rc);
}
-static struct cifsSesInfo *
+static struct cifs_ses *
cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
{
- struct cifsSesInfo *ses;
+ struct cifs_ses *ses;
spin_lock(&cifs_tcp_ses_lock);
list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
@@ -1808,7 +1843,9 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
break;
default:
/* anything else takes username/password */
- if (strncmp(ses->userName, vol->username,
+ if (ses->user_name == NULL)
+ continue;
+ if (strncmp(ses->user_name, vol->username,
MAX_USERNAME_SIZE))
continue;
if (strlen(vol->username) != 0 &&
@@ -1827,7 +1864,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
}
static void
-cifs_put_smb_ses(struct cifsSesInfo *ses)
+cifs_put_smb_ses(struct cifs_ses *ses)
{
int xid;
struct TCP_Server_Info *server = ses->server;
@@ -1851,11 +1888,11 @@ cifs_put_smb_ses(struct cifsSesInfo *ses)
cifs_put_tcp_session(server);
}
-static struct cifsSesInfo *
+static struct cifs_ses *
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
{
int rc = -ENOMEM, xid;
- struct cifsSesInfo *ses;
+ struct cifs_ses *ses;
struct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;
@@ -1906,9 +1943,11 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
else
sprintf(ses->serverName, "%pI4", &addr->sin_addr);
- if (volume_info->username)
- strncpy(ses->userName, volume_info->username,
- MAX_USERNAME_SIZE);
+ if (volume_info->username) {
+ ses->user_name = kstrdup(volume_info->username, GFP_KERNEL);
+ if (!ses->user_name)
+ goto get_ses_fail;
+ }
/* volume_info->password freed at unmount */
if (volume_info->password) {
@@ -1947,15 +1986,15 @@ get_ses_fail:
return ERR_PTR(rc);
}
-static struct cifsTconInfo *
-cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
+static struct cifs_tcon *
+cifs_find_tcon(struct cifs_ses *ses, const char *unc)
{
struct list_head *tmp;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
spin_lock(&cifs_tcp_ses_lock);
list_for_each(tmp, &ses->tcon_list) {
- tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
+ tcon = list_entry(tmp, struct cifs_tcon, tcon_list);
if (tcon->tidStatus == CifsExiting)
continue;
if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
@@ -1970,10 +2009,10 @@ cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
}
static void
-cifs_put_tcon(struct cifsTconInfo *tcon)
+cifs_put_tcon(struct cifs_tcon *tcon)
{
int xid;
- struct cifsSesInfo *ses = tcon->ses;
+ struct cifs_ses *ses = tcon->ses;
cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
spin_lock(&cifs_tcp_ses_lock);
@@ -1994,11 +2033,11 @@ cifs_put_tcon(struct cifsTconInfo *tcon)
cifs_put_smb_ses(ses);
}
-static struct cifsTconInfo *
-cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
+static struct cifs_tcon *
+cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info)
{
int rc, xid;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
tcon = cifs_find_tcon(ses, volume_info->UNC);
if (tcon) {
@@ -2088,7 +2127,7 @@ cifs_put_tlink(struct tcon_link *tlink)
}
int
-get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
+get_dfs_path(int xid, struct cifs_ses *pSesInfo, const char *old_path,
const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
struct dfs_info3_param **preferrals, int remap)
{
@@ -2387,7 +2426,7 @@ ip_connect(struct TCP_Server_Info *server)
return generic_ip_connect(server);
}
-void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
+void reset_cifs_unix_caps(int xid, struct cifs_tcon *tcon,
struct super_block *sb, struct smb_vol *vol_info)
{
/* if we are reconnecting then should we check to see if
@@ -2628,7 +2667,7 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
}
static int
-is_path_accessible(int xid, struct cifsTconInfo *tcon,
+is_path_accessible(int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb, const char *full_path)
{
int rc;
@@ -2702,8 +2741,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
int rc;
int xid;
struct smb_vol *volume_info;
- struct cifsSesInfo *pSesInfo;
- struct cifsTconInfo *tcon;
+ struct cifs_ses *pSesInfo;
+ struct cifs_tcon *tcon;
struct TCP_Server_Info *srvTcp;
char *full_path;
char *mount_data = mount_data_global;
@@ -2955,8 +2994,8 @@ out:
}
int
-CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
- const char *tree, struct cifsTconInfo *tcon,
+CIFSTCon(unsigned int xid, struct cifs_ses *ses,
+ const char *tree, struct cifs_tcon *tcon,
const struct nls_table *nls_codepage)
{
struct smb_hdr *smb_buffer;
@@ -2988,7 +3027,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
pSMB->AndXCommand = 0xFF;
pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
bcc_ptr = &pSMB->Password[0];
- if ((ses->server->secMode) & SECMODE_USER) {
+ if ((ses->server->sec_mode) & SECMODE_USER) {
pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
*bcc_ptr = 0; /* password is null byte */
bcc_ptr++; /* skip password */
@@ -3005,7 +3044,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
(ses->server->secType == LANMAN))
calc_lanman_hash(tcon->password, ses->server->cryptkey,
- ses->server->secMode &
+ ses->server->sec_mode &
SECMODE_PW_ENCRYPT ? true : false,
bcc_ptr);
else
@@ -3021,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
}
}
- if (ses->server->secMode &
+ if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
@@ -3141,7 +3180,7 @@ cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
return 0;
}
-int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
+int cifs_negotiate_protocol(unsigned int xid, struct cifs_ses *ses)
{
int rc = 0;
struct TCP_Server_Info *server = ses->server;
@@ -3150,6 +3189,17 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
if (server->maxBuf != 0)
return 0;
+#ifdef CONFIG_CIFS_SMB2
+ if (ses->server->is_smb2) {
+ rc = SMB2_negotiate(xid, ses);
+ /* BB we probably don't need to retry with modern servers */
+ if (rc == -EAGAIN)
+ rc = -EHOSTDOWN;
+
+ goto neg_prot_exit;
+ }
+#endif /* CONFIG_CIFS_SMB2 */
+
rc = CIFSSMBNegotiate(xid, ses);
if (rc == -EAGAIN) {
/* retry only once on 1st time connection */
@@ -3157,6 +3207,10 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
if (rc == -EAGAIN)
rc = -EHOSTDOWN;
}
+
+#ifdef CONFIG_CIFS_SMB2
+neg_prot_exit:
+#endif /* CONFIG_CIFS_SMB2 */
if (rc == 0) {
spin_lock(&GlobalMid_Lock);
if (server->tcpStatus != CifsExiting)
@@ -3171,7 +3225,7 @@ int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
}
-int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
+int cifs_setup_session(unsigned int xid, struct cifs_ses *ses,
struct nls_table *nls_info)
{
int rc = 0;
@@ -3183,7 +3237,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
ses->capabilities &= (~CAP_UNIX);
cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
- server->secMode, server->capabilities, server->timeAdj);
+ server->sec_mode, server->capabilities, server->timeAdj);
rc = CIFS_SessSetup(xid, ses, nls_info);
if (rc) {
@@ -3215,14 +3269,16 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
return rc;
}
-static struct cifsTconInfo *
+static struct cifs_tcon *
cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
{
- struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb);
- struct cifsSesInfo *ses;
- struct cifsTconInfo *tcon = NULL;
+ struct cifs_tcon *master_tcon = cifs_sb_master_tcon(cifs_sb);
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon = NULL;
struct smb_vol *vol_info;
- char username[MAX_USERNAME_SIZE + 1];
+ char username[28]; /* big enough for "krb50x" + hex of ULONG_MAX 6+16 */
+ /* We used to have this as MAX_USERNAME which is */
+ /* way too big now (256 instead of 32) */
vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
if (vol_info == NULL) {
@@ -3251,7 +3307,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
if (IS_ERR(ses)) {
- tcon = (struct cifsTconInfo *)ses;
+ tcon = (struct cifs_tcon *)ses;
cifs_put_tcp_session(master_tcon->ses->server);
goto out;
}
@@ -3276,7 +3332,7 @@ cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
return cifs_sb->master_tlink;
}
-struct cifsTconInfo *
+struct cifs_tcon *
cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
{
return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index dd5f22918c33..ab74179681c9 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -55,7 +55,7 @@ build_path_from_dentry(struct dentry *direntry)
char *full_path;
char dirsep;
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
- struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
if (direntry == NULL)
return NULL; /* not much we can do if dentry is freed and
@@ -152,7 +152,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
__u16 fileHandle;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
char *full_path = NULL;
FILE_ALL_INFO *buf = NULL;
struct inode *newinode = NULL;
@@ -356,7 +356,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
int oplock = 0;
@@ -486,7 +486,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
bool posix_open = false;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct cifsFileInfo *cfile;
struct inode *newInode = NULL;
char *full_path = NULL;
diff --git a/fs/cifs/export.c b/fs/cifs/export.c
index 993f82045bf6..55d87ac52000 100644
--- a/fs/cifs/export.c
+++ b/fs/cifs/export.c
@@ -45,7 +45,7 @@
#include "cifs_debug.h"
#include "cifsfs.h"
-#ifdef CONFIG_CIFS_EXPERIMENTAL
+#ifdef CIFS_NFSD_EXPORT
static struct dentry *cifs_get_parent(struct dentry *dentry)
{
/* BB need to add code here eventually to enable export via NFSD */
@@ -63,5 +63,5 @@ const struct export_operations cifs_export_ops = {
.encode_fs = */
};
-#endif /* EXPERIMENTAL */
+#endif /* CIFS_NFSD_EXPORT */
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e964b1cd5dd0..9293ff2e7590 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -114,7 +114,7 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_fattr fattr;
struct tcon_link *tlink;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
cFYI(1, "posix open %s", full_path);
@@ -168,7 +168,7 @@ posix_open_ret:
static int
cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
- struct cifsTconInfo *tcon, unsigned int f_flags, __u32 *poplock,
+ struct cifs_tcon *tcon, unsigned int f_flags, __u32 *poplock,
__u16 *pnetfid, int xid)
{
int rc;
@@ -285,7 +285,7 @@ cifs_new_fileinfo(__u16 fileHandle, struct file *file,
void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
{
struct inode *inode = cifs_file->dentry->d_inode;
- struct cifsTconInfo *tcon = tlink_tcon(cifs_file->tlink);
+ struct cifs_tcon *tcon = tlink_tcon(cifs_file->tlink);
struct cifsInodeInfo *cifsi = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsLockInfo *li, *tmp;
@@ -343,7 +343,7 @@ int cifs_open(struct inode *inode, struct file *file)
int xid;
__u32 oplock;
struct cifs_sb_info *cifs_sb;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
struct tcon_link *tlink;
struct cifsFileInfo *pCifsFile = NULL;
char *full_path = NULL;
@@ -457,7 +457,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
int xid;
__u32 oplock;
struct cifs_sb_info *cifs_sb;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
struct cifsInodeInfo *pCifsInode;
struct inode *inode;
char *full_path = NULL;
@@ -594,7 +594,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
xid = GetXid();
if (pCFileStruct) {
- struct cifsTconInfo *pTcon = tlink_tcon(pCFileStruct->tlink);
+ struct cifs_tcon *pTcon = tlink_tcon(pCFileStruct->tlink);
cFYI(1, "Freeing private data in close dir");
spin_lock(&cifs_file_list_lock);
@@ -651,7 +651,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
__u64 length;
bool wait_flag = false;
struct cifs_sb_info *cifs_sb;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
__u16 netfid;
__u8 lockType = LOCKING_ANDX_LARGE_FILES;
bool posix_locking = 0;
@@ -863,7 +863,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
unsigned int bytes_written = 0;
unsigned int total_written;
struct cifs_sb_info *cifs_sb;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
int xid;
struct cifsFileInfo *open_file;
struct cifsInodeInfo *cifsi = CIFS_I(inode);
@@ -952,7 +952,7 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
unsigned int bytes_written = 0;
unsigned int total_written;
struct cifs_sb_info *cifs_sb;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
int xid;
struct dentry *dentry = open_file->dentry;
struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
@@ -979,8 +979,8 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
if (rc != 0)
break;
}
- if (experimEnabled || (pTcon->ses->server &&
- ((pTcon->ses->server->secMode &
+ if (sign_zero_copy || (pTcon->ses->server &&
+ ((pTcon->ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
== 0))) {
struct kvec iov[2];
@@ -1207,7 +1207,7 @@ static int cifs_writepages(struct address_space *mapping,
int nr_pages;
__u64 offset = 0;
struct cifsFileInfo *open_file;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
struct cifsInodeInfo *cifsi = CIFS_I(mapping->host);
struct page *page;
struct pagevec pvec;
@@ -1240,7 +1240,7 @@ static int cifs_writepages(struct address_space *mapping,
}
tcon = tlink_tcon(open_file->tlink);
- if (!experimEnabled && tcon->ses->server->secMode &
+ if (!sign_zero_copy && tcon->ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
cifsFileInfo_put(open_file);
kfree(iov);
@@ -1527,7 +1527,7 @@ int cifs_strict_fsync(struct file *file, int datasync)
{
int xid;
int rc = 0;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
struct cifsFileInfo *smbfile = file->private_data;
struct inode *inode = file->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
@@ -1552,7 +1552,7 @@ int cifs_fsync(struct file *file, int datasync)
{
int xid;
int rc = 0;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
struct cifsFileInfo *smbfile = file->private_data;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
@@ -1671,7 +1671,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
struct iov_iter it;
struct inode *inode;
struct cifsFileInfo *open_file;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct cifs_sb_info *cifs_sb;
int xid, rc;
@@ -1826,7 +1826,7 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
size_t len, cur_len;
int iov_offset = 0;
struct cifs_sb_info *cifs_sb;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct cifsFileInfo *open_file;
struct smb_com_read_rsp *pSMBr;
char *read_data;
@@ -1947,7 +1947,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
unsigned int total_read;
unsigned int current_read_size;
struct cifs_sb_info *cifs_sb;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
int xid;
char *current_offset;
struct cifsFileInfo *open_file;
@@ -2096,7 +2096,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
loff_t offset;
struct page *page;
struct cifs_sb_info *cifs_sb;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
unsigned int bytes_read = 0;
unsigned int read_size, i;
char *smb_read_data = NULL;
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index 297a43d0ff7f..d368a47ba5eb 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -40,7 +40,7 @@ void cifs_fscache_release_client_cookie(struct TCP_Server_Info *server)
server->fscache = NULL;
}
-void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon)
+void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon)
{
struct TCP_Server_Info *server = tcon->ses->server;
@@ -51,7 +51,7 @@ void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon)
server->fscache, tcon->fscache);
}
-void cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon)
+void cifs_fscache_release_super_cookie(struct cifs_tcon *tcon)
{
cFYI(1, "CIFS: releasing superblock cookie (0x%p)", tcon->fscache);
fscache_relinquish_cookie(tcon->fscache, 0);
@@ -62,7 +62,7 @@ static void cifs_fscache_enable_inode_cookie(struct inode *inode)
{
struct cifsInodeInfo *cifsi = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
if (cifsi->fscache)
return;
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index 31b88ec2341e..63539323e0b9 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -40,8 +40,8 @@ extern void cifs_fscache_unregister(void);
*/
extern void cifs_fscache_get_client_cookie(struct TCP_Server_Info *);
extern void cifs_fscache_release_client_cookie(struct TCP_Server_Info *);
-extern void cifs_fscache_get_super_cookie(struct cifsTconInfo *);
-extern void cifs_fscache_release_super_cookie(struct cifsTconInfo *);
+extern void cifs_fscache_get_super_cookie(struct cifs_tcon *);
+extern void cifs_fscache_release_super_cookie(struct cifs_tcon *);
extern void cifs_fscache_release_inode_cookie(struct inode *);
extern void cifs_fscache_set_inode_cookie(struct inode *, struct file *);
@@ -99,9 +99,9 @@ static inline void
cifs_fscache_get_client_cookie(struct TCP_Server_Info *server) {}
static inline void
cifs_fscache_release_client_cookie(struct TCP_Server_Info *server) {}
-static inline void cifs_fscache_get_super_cookie(struct cifsTconInfo *tcon) {}
+static inline void cifs_fscache_get_super_cookie(struct cifs_tcon *tcon) {}
static inline void
-cifs_fscache_release_super_cookie(struct cifsTconInfo *tcon) {}
+cifs_fscache_release_super_cookie(struct cifs_tcon *tcon) {}
static inline void cifs_fscache_release_inode_cookie(struct inode *inode) {}
static inline void cifs_fscache_set_inode_cookie(struct inode *inode,
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 8852470b4fbb..41e5651b1701 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -295,7 +295,7 @@ int cifs_get_file_info_unix(struct file *filp)
struct inode *inode = filp->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsFileInfo *cfile = filp->private_data;
- struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
+ struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
xid = GetXid();
rc = CIFSSMBUnixQFileInfo(xid, tcon, cfile->netfid, &find_data);
@@ -318,7 +318,7 @@ int cifs_get_inode_info_unix(struct inode **pinode,
int rc;
FILE_UNIX_BASIC_INFO find_data;
struct cifs_fattr fattr;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
struct tcon_link *tlink;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
@@ -373,7 +373,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
int oplock = 0;
__u16 netfid;
struct tcon_link *tlink;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
char buf[24];
unsigned int bytes_read;
char *pbuf;
@@ -468,7 +468,7 @@ static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
char ea_value[4];
__u32 mode;
struct tcon_link *tlink;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
tlink = cifs_sb_tlink(cifs_sb);
if (IS_ERR(tlink))
@@ -502,7 +502,7 @@ static void
cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
struct cifs_sb_info *cifs_sb, bool adjust_tz)
{
- struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
memset(fattr, 0, sizeof(*fattr));
fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
@@ -553,7 +553,7 @@ int cifs_get_file_info(struct file *filp)
struct inode *inode = filp->f_path.dentry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct cifsFileInfo *cfile = filp->private_data;
- struct cifsTconInfo *tcon = tlink_tcon(cfile->tlink);
+ struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
xid = GetXid();
rc = CIFSSMBQFileInfo(xid, tcon, cfile->netfid, &find_data);
@@ -590,7 +590,7 @@ int cifs_get_inode_info(struct inode **pinode,
struct super_block *sb, int xid, const __u16 *pfid)
{
int rc = 0, tmprc;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct tcon_link *tlink;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *buf = NULL;
@@ -736,7 +736,7 @@ static const struct inode_operations cifs_ipc_inode_ops = {
};
char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb,
- struct cifsTconInfo *tcon)
+ struct cifs_tcon *tcon)
{
int pplen = cifs_sb->prepathlen;
int dfsplen;
@@ -878,14 +878,14 @@ retry_iget5_locked:
}
/* gets root inode */
-struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
+struct inode *cifs_root_iget(struct super_block *sb)
{
int xid;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct inode *inode = NULL;
long rc;
char *full_path;
- struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
full_path = cifs_build_path_to_root(cifs_sb, tcon);
if (full_path == NULL)
@@ -943,7 +943,7 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, int xid,
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
FILE_BASIC_INFO info_buf;
if (attrs == NULL)
@@ -1061,7 +1061,7 @@ cifs_rename_pending_delete(char *full_path, struct dentry *dentry, int xid)
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
__u32 dosattr, origattr;
FILE_BASIC_INFO *info_buf = NULL;
@@ -1179,7 +1179,7 @@ int cifs_unlink(struct inode *dir, struct dentry *dentry)
struct super_block *sb = dir->i_sb;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct tcon_link *tlink;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
struct iattr *attrs = NULL;
__u32 dosattr = 0, origattr = 0;
@@ -1277,7 +1277,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
struct cifs_fattr fattr;
@@ -1455,7 +1455,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
char *full_path = NULL;
struct cifsInodeInfo *cifsInode;
@@ -1512,7 +1512,7 @@ cifs_do_rename(int xid, struct dentry *from_dentry, const char *fromPath,
{
struct cifs_sb_info *cifs_sb = CIFS_SB(from_dentry->d_sb);
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
__u16 srcfid;
int oplock, rc;
@@ -1564,7 +1564,7 @@ int cifs_rename(struct inode *source_dir, struct dentry *source_dentry,
char *toName = NULL;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
FILE_UNIX_BASIC_INFO *info_buf_source = NULL;
FILE_UNIX_BASIC_INFO *info_buf_target;
int xid, rc, tmprc;
@@ -1769,7 +1769,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
- struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb);
+ struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
int err = cifs_revalidate_dentry(dentry);
if (!err) {
@@ -1831,7 +1831,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
- struct cifsTconInfo *pTcon = NULL;
+ struct cifs_tcon *pTcon = NULL;
/*
* To avoid spurious oplock breaks from server, in the case of
@@ -1920,7 +1920,7 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs)
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct cifs_unix_set_info_args *args = NULL;
struct cifsFileInfo *open_file;
@@ -2206,7 +2206,7 @@ cifs_setattr(struct dentry *direntry, struct iattr *attrs)
{
struct inode *inode = direntry->d_inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
- struct cifsTconInfo *pTcon = cifs_sb_master_tcon(cifs_sb);
+ struct cifs_tcon *pTcon = cifs_sb_master_tcon(cifs_sb);
if (pTcon->unix_ext)
return cifs_setattr_unix(direntry, attrs);
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c
index 0c98672d0122..4221b5e48a42 100644
--- a/fs/cifs/ioctl.c
+++ b/fs/cifs/ioctl.c
@@ -38,7 +38,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)
struct cifs_sb_info *cifs_sb;
#ifdef CONFIG_CIFS_POSIX
struct cifsFileInfo *pSMBFile = filep->private_data;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
__u64 ExtAttrBits = 0;
__u64 ExtAttrMask = 0;
__u64 caps;
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index e8804d373404..2904baa1ecb2 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -175,7 +175,7 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
}
static int
-CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
+CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap)
{
@@ -219,7 +219,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,
}
static int
-CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,
+CIFSQueryMFSymLink(const int xid, struct cifs_tcon *tcon,
const unsigned char *searchName, char **symlinkinfo,
const struct nls_table *nls_codepage, int remap)
{
@@ -291,7 +291,7 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,
int oplock = 0;
__u16 netfid = 0;
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
u8 *buf;
char *pbuf;
unsigned int bytes_read = 0;
@@ -370,7 +370,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
char *toName = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct cifsInodeInfo *cifsInode;
tlink = cifs_sb_tlink(cifs_sb);
@@ -445,7 +445,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
char *target_path = NULL;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink = NULL;
- struct cifsTconInfo *tcon;
+ struct cifs_tcon *tcon;
xid = GetXid();
@@ -518,7 +518,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
int xid;
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
char *full_path = NULL;
struct inode *newinode = NULL;
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 2a930a752a78..718268fde042 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -67,12 +67,12 @@ _FreeXid(unsigned int xid)
spin_unlock(&GlobalMid_Lock);
}
-struct cifsSesInfo *
+struct cifs_ses *
sesInfoAlloc(void)
{
- struct cifsSesInfo *ret_buf;
+ struct cifs_ses *ret_buf;
- ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);
+ ret_buf = kzalloc(sizeof(struct cifs_ses), GFP_KERNEL);
if (ret_buf) {
atomic_inc(&sesInfoAllocCount);
ret_buf->status = CifsNew;
@@ -85,7 +85,7 @@ sesInfoAlloc(void)
}
void
-sesInfoFree(struct cifsSesInfo *buf_to_free)
+sesInfoFree(struct cifs_ses *buf_to_free)
{
if (buf_to_free == NULL) {
cFYI(1, "Null buffer passed to sesInfoFree");
@@ -100,15 +100,16 @@ sesInfoFree(struct cifsSesInfo *buf_to_free)
memset(buf_to_free->password, 0, strlen(buf_to_free->password));
kfree(buf_to_free->password);
}
+ kfree(buf_to_free->user_name);
kfree(buf_to_free->domainName);
kfree(buf_to_free);
}
-struct cifsTconInfo *
+struct cifs_tcon *
tconInfoAlloc(void)
{
- struct cifsTconInfo *ret_buf;
- ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);
+ struct cifs_tcon *ret_buf;
+ ret_buf = kzalloc(sizeof(struct cifs_tcon), GFP_KERNEL);
if (ret_buf) {
atomic_inc(&tconInfoAllocCount);
ret_buf->tidStatus = CifsNew;
@@ -123,7 +124,7 @@ tconInfoAlloc(void)
}
void
-tconInfoFree(struct cifsTconInfo *buf_to_free)
+tconInfoFree(struct cifs_tcon *buf_to_free)
{
if (buf_to_free == NULL) {
cFYI(1, "Null buffer passed to tconInfoFree");
@@ -294,11 +295,11 @@ __u16 GetNextMid(struct TCP_Server_Info *server)
case it is responsbility of caller to set the mid */
void
header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
- const struct cifsTconInfo *treeCon, int word_count
+ const struct cifs_tcon *treeCon, int word_count
/* length of fixed section (word count) in two byte units */)
{
struct list_head *temp_item;
- struct cifsSesInfo *ses;
+ struct cifs_ses *ses;
char *temp = (char *) buffer;
memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */
@@ -360,7 +361,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
"did not match tcon uid");
spin_lock(&cifs_tcp_ses_lock);
list_for_each(temp_item, &treeCon->ses->server->smb_ses_list) {
- ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);
+ ses = list_entry(temp_item, struct cifs_ses, smb_ses_list);
if (ses->linux_uid == current_fsuid()) {
if (ses->server == treeCon->ses->server) {
cFYI(1, "found matching uid substitute right smb_uid");
@@ -381,7 +382,7 @@ header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,
if (treeCon->nocase)
buffer->Flags |= SMBFLG_CASELESS;
if ((treeCon->ses) && (treeCon->ses->server))
- if (treeCon->ses->server->secMode &
+ if (treeCon->ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
}
@@ -508,8 +509,8 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
{
struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;
struct list_head *tmp, *tmp1, *tmp2;
- struct cifsSesInfo *ses;
- struct cifsTconInfo *tcon;
+ struct cifs_ses *ses;
+ struct cifs_tcon *tcon;
struct cifsInodeInfo *pCifsInode;
struct cifsFileInfo *netfile;
@@ -567,13 +568,13 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
/* look up tcon based on tid & uid */
spin_lock(&cifs_tcp_ses_lock);
list_for_each(tmp, &srv->smb_ses_list) {
- ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
+ ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
list_for_each(tmp1, &ses->tcon_list) {
- tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list);
+ tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
if (tcon->tid != buf->Tid)
continue;
- cifs_stats_inc(&tcon->num_oplock_brks);
+ cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
spin_lock(&cifs_file_list_lock);
list_for_each(tmp2, &tcon->openFileList) {
netfile = list_entry(tmp2, struct cifsFileInfo,
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 5d52e4a3b1ed..848249fa120f 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -126,3 +126,13 @@ typedef struct _AUTHENTICATE_MESSAGE {
do not set the version is present flag */
char UserString[0];
} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
+
+/*
+ * Size of the session key (crypto key encrypted with the password
+ */
+
+int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, struct cifs_ses *ses);
+void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, struct cifs_ses *ses);
+int build_ntlmssp_auth_blob(unsigned char *pbuffer, u16 *buflen,
+ struct cifs_ses *ses,
+ const struct nls_table *nls_cp);
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index f8e4cd2a7912..6751e745bbc6 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -195,7 +195,7 @@ int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,
int len;
int oplock = 0;
int rc;
- struct cifsTconInfo *ptcon = cifs_sb_tcon(cifs_sb);
+ struct cifs_tcon *ptcon = cifs_sb_tcon(cifs_sb);
char *tmpbuffer;
rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,
@@ -223,7 +223,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
struct cifsFileInfo *cifsFile;
struct cifs_sb_info *cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
struct tcon_link *tlink = NULL;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
if (file->private_data == NULL) {
tlink = cifs_sb_tlink(cifs_sb);
@@ -496,7 +496,7 @@ static int cifs_save_resume_key(const char *current_entry,
assume that they are located in the findfirst return buffer.*/
/* We start counting in the buffer with entry 2 and increment for every
entry (do not increment for . or .. entry) */
-static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
+static int find_cifs_entry(const int xid, struct cifs_tcon *pTcon,
struct file *file, char **ppCurrentEntry, int *num_to_ret)
{
int rc = 0;
@@ -764,7 +764,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
{
int rc = 0;
int xid, i;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct cifsFileInfo *cifsFile = NULL;
char *current_entry;
int num_to_fill = 0;
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index 16765703131b..16831c7c099f 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -37,13 +37,13 @@
* the socket has been reestablished (so we know whether to use vc 0).
* Called while holding the cifs_tcp_ses_lock, so do not block
*/
-static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
+static bool is_first_ses_reconnect(struct cifs_ses *ses)
{
struct list_head *tmp;
- struct cifsSesInfo *tmp_ses;
+ struct cifs_ses *tmp_ses;
list_for_each(tmp, &ses->server->smb_ses_list) {
- tmp_ses = list_entry(tmp, struct cifsSesInfo,
+ tmp_ses = list_entry(tmp, struct cifs_ses,
smb_ses_list);
if (tmp_ses->need_reconnect == false)
return false;
@@ -61,11 +61,11 @@ static bool is_first_ses_reconnect(struct cifsSesInfo *ses)
* any vc but zero (some servers reset the connection on vcnum zero)
*
*/
-static __le16 get_next_vcnum(struct cifsSesInfo *ses)
+static __le16 get_next_vcnum(struct cifs_ses *ses)
{
__u16 vcnum = 0;
struct list_head *tmp;
- struct cifsSesInfo *tmp_ses;
+ struct cifs_ses *tmp_ses;
__u16 max_vcs = ses->server->max_vcs;
__u16 i;
int free_vc_found = 0;
@@ -87,7 +87,7 @@ static __le16 get_next_vcnum(struct cifsSesInfo *ses)
free_vc_found = 1;
list_for_each(tmp, &ses->server->smb_ses_list) {
- tmp_ses = list_entry(tmp, struct cifsSesInfo,
+ tmp_ses = list_entry(tmp, struct cifs_ses,
smb_ses_list);
if (tmp_ses->vcnum == i) {
free_vc_found = 0;
@@ -114,7 +114,7 @@ get_vc_num_exit:
return cpu_to_le16(vcnum);
}
-static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
+static __u32 cifs_ssetup_hdr(struct cifs_ses *ses, SESSION_SETUP_ANDX *pSMB)
{
__u32 capabilities = 0;
@@ -136,7 +136,7 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
- if (ses->server->secMode &
+ if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
@@ -181,7 +181,7 @@ unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
*pbcc_area = bcc_ptr;
}
-static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
+static void unicode_domain_string(char **pbcc_area, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
char *bcc_ptr = *pbcc_area;
@@ -204,7 +204,7 @@ static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
}
-static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
+static void unicode_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
char *bcc_ptr = *pbcc_area;
@@ -219,12 +219,12 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
bcc_ptr++;
} */
/* copy user */
- if (ses->userName == NULL) {
+ if (ses->user_name == NULL) {
/* null user mount */
*bcc_ptr = 0;
*(bcc_ptr+1) = 0;
} else {
- bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
+ bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->user_name,
MAX_USERNAME_SIZE, nls_cp);
}
bcc_ptr += 2 * bytes_ret;
@@ -236,7 +236,7 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
*pbcc_area = bcc_ptr;
}
-static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
+static void ascii_ssetup_strings(char **pbcc_area, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
char *bcc_ptr = *pbcc_area;
@@ -244,12 +244,11 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
/* copy user */
/* BB what about null user mounts - check that we do this BB */
/* copy user */
- if (ses->userName == NULL) {
- /* BB what about null user mounts - check that we do this BB */
- } else {
- strncpy(bcc_ptr, ses->userName, MAX_USERNAME_SIZE);
- }
- bcc_ptr += strnlen(ses->userName, MAX_USERNAME_SIZE);
+ if (ses->user_name != NULL)
+ strncpy(bcc_ptr, ses->user_name, MAX_USERNAME_SIZE);
+ /* else null user mount */
+
+ bcc_ptr += strnlen(ses->user_name, MAX_USERNAME_SIZE);
*bcc_ptr = 0;
bcc_ptr++; /* account for null termination */
@@ -277,7 +276,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
}
static void
-decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifsSesInfo *ses,
+decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
int len;
@@ -324,7 +323,7 @@ decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifsSesInfo *ses,
}
static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
- struct cifsSesInfo *ses,
+ struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
int rc = 0;
@@ -377,8 +376,8 @@ static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
return rc;
}
-static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
- struct cifsSesInfo *ses)
+int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
+ struct cifs_ses *ses)
{
unsigned int tioffset; /* challenge message target info area */
unsigned int tilen; /* challenge message target info area length */
@@ -424,8 +423,8 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
/* We do not malloc the blob, it is passed in pbuffer, because
it is fixed size, and small, making this approach cleaner */
-static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
- struct cifsSesInfo *ses)
+void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
+ struct cifs_ses *ses)
{
NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
__u32 flags;
@@ -438,7 +437,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
flags = NTLMSSP_NEGOTIATE_56 | NTLMSSP_REQUEST_TARGET |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
- if (ses->server->secMode &
+ if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
flags |= NTLMSSP_NEGOTIATE_SIGN;
if (!ses->server->session_estab)
@@ -461,9 +460,9 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
/* We do not malloc the blob, it is passed in pbuffer, because its
maximum possible size is fixed and small, making this approach cleaner.
This function returns the length of the data in the blob */
-static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+int build_ntlmssp_auth_blob(unsigned char *pbuffer,
u16 *buflen,
- struct cifsSesInfo *ses,
+ struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
int rc;
@@ -478,10 +477,10 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
- if (ses->server->secMode &
+ if (ses->server->sec_mode &
(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
flags |= NTLMSSP_NEGOTIATE_SIGN;
- if (ses->server->secMode & SECMODE_SIGN_REQUIRED)
+ if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED)
flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
@@ -523,14 +522,14 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
tmp += len;
}
- if (ses->userName == NULL) {
+ if (ses->user_name == NULL) {
sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
sec_blob->UserName.Length = 0;
sec_blob->UserName.MaximumLength = 0;
tmp += 2;
} else {
int len;
- len = cifs_strtoUCS((__le16 *)tmp, ses->userName,
+ len = cifs_strtoUCS((__le16 *)tmp, ses->user_name,
MAX_USERNAME_SIZE, nls_cp);
len *= 2; /* unicode is 2 bytes each */
sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
@@ -565,7 +564,7 @@ setup_ntlmv2_ret:
}
int
-CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
+CIFS_SessSetup(unsigned int xid, struct cifs_ses *ses,
const struct nls_table *nls_cp)
{
int rc = 0;
@@ -670,8 +669,8 @@ ssetup_ntlmssp_authenticate:
* to use challenge/response method (i.e. Password bit is 1).
*/
- calc_lanman_hash(ses->password, ses->server->cryptkey,
- ses->server->secMode & SECMODE_PW_ENCRYPT ?
+ rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
+ ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
true : false, lnm_session_key);
ses->flags |= CIFS_SES_LANMAN;
diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h
new file mode 100644
index 000000000000..66c01db10e59
--- /dev/null
+++ b/fs/cifs/smb2glob.h
@@ -0,0 +1,252 @@
+/*
+ * fs/cifs/smb2glob.h
+ *
+ * Definitions for various global variables and structures
+ *
+ * Copyright (C) International Business Machines Corp., 2002,2011
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ * Jeremy Allison (jra@samba.org)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ */
+#ifndef _SMB2_GLOB_H
+#define _SMB2_GLOB_H
+#include <linux/in.h>
+#include <linux/in6.h>
+#include <linux/workqueue.h>
+#include "smb2pdu.h"
+
+/*
+ * The sizes of various internal tables and strings
+ */
+
+#define SMB2_MIN_RCV_POOL 4
+
+
+/*
+ *****************************************************************
+ * Except the SMB2 PDUs themselves all the
+ * globally interesting structs should go here
+ *****************************************************************
+ */
+
+#define SMB2_OBSERVE_CHECK_TIME 20
+#define SMB2_OBSERVE_DELETE_TIME 45
+
+/* Values for tcon->speed set by echo command */
+#define SMB2_ECHO_FAST 1 /* Less than 3 jiffies, 12ms */
+#define SMB2_ECHO_OK 2 /* Less than 15 jiffies, 60ms */
+#define SMB2_ECHO_SLOW 3 /* Less than 125 jiffies, 1/2 sec */
+#define SMB2_ECHO_VERY_SLOW 4 /* Less than 1000 jiffies, 4 seconds */
+#define SMB2_ECHO_TIMEOUT 5 /* Else Too long, server is sick ... */
+
+/*
+ * This info hangs off the smb2_file structure, pointed to by llist.
+ * This is used to track byte stream locks on the file
+ */
+struct smb2_lock {
+ struct list_head llist; /* pointer to next smb2_lock */
+ __u64 offset;
+ __u64 length;
+ __u32 flags;
+};
+
+/*
+ * One of these for each open instance of a file
+ */
+struct smb2_search {
+ loff_t index_of_last_entry;
+ __u16 entries_in_buf;
+ __u32 resume_key;
+ char *ntwrk_buf_start;
+ char *srch_entries_start;
+ char *last_entry;
+ char *presume_name;
+ unsigned int resume_name_len;
+ bool search_end:1;
+ bool empty_dir:1;
+ bool small_buf:1; /* so we know which buf_release function to call */
+};
+
+struct smb2_file {
+ struct list_head tlist; /* pointer to next fid owned by tcon */
+ struct list_head flist; /* next fid (file instance) for this inode */
+ unsigned int uid; /* allows finding which FileInfo structure */
+ __u32 pid; /* process id who opened file */
+ u64 persist_fid;
+ u64 volatile_fid;
+ /* BB add lock scope info here if needed */ ;
+ /* lock scope id (0 if none) */
+ struct dentry *dentry; /* needed for writepage and oplock break */
+ struct mutex lock_mutex;
+ struct list_head llist; /* list of byte range locks we have. */
+ unsigned int f_flags;
+ bool close_pend:1; /* file is marked to close */
+ bool invalid_handle:1; /* file closed via session abend */
+ bool message_mode:1; /* for pipes: message vs byte mode */
+ bool is_dir:1; /* Open directory rather than file */
+ bool oplock_break_cancelled:1;
+ atomic_t count; /* reference count */
+ atomic_t wrt_pending; /* handle in use - defer close */
+ struct work_struct oplock_break; /* work for oplock breaks */
+ struct mutex fh_mutex; /* prevents reopen race after dead ses*/
+ struct smb2_search srch_inf;
+};
+
+/*
+ * One of these for each file inode
+ */
+
+struct smb2_inode {
+ struct list_head lock_list;
+ /* BB add in lists for dirty pages i.e. write caching info for oplock */
+ struct list_head open_file_list;
+ int write_behind_rc;
+ __u32 dos_attrs; /* e.g. DOS archive bit, sparse, compressed, system */
+ __u32 ea_size;
+ unsigned long time; /* jiffies of last update/check of inode */
+ u64 server_eof; /* current file size on server */
+ bool can_cache_read:1; /* read oplock */
+ bool can_cache_all:1; /* read and writebehind oplock */
+ bool can_defer_close:1; /* batch oplock: as above but can defer close */
+ bool oplock_pending:1;
+ bool delete_pending:1; /* DELETE_ON_CLOSE is set */
+ u64 uniqueid; /* server inode number */
+ struct fscache_cookie *fscache;
+ struct inode vfs_inode;
+};
+
+static inline struct smb2_inode *
+SMB2_I(struct inode *inode)
+{
+ return container_of(inode, struct smb2_inode, vfs_inode);
+}
+
+
+static inline void smb2_file_get(struct smb2_file *smb2_file)
+{
+ atomic_inc(&smb2_file->count);
+}
+
+/* Release a reference on the file private data */
+/* BB see file.c cifsFileInfo_put MUSTFIX BB */
+static inline void smb2_file_put(struct smb2_file *smb2_file)
+{
+ if (atomic_dec_and_test(&smb2_file->count)) {
+ iput(smb2_file->dentry->d_inode);
+ kfree(smb2_file);
+ }
+}
+
+/* Represents a read request in page sized blocks.
+ * Used by smb2_readpages().*/
+struct page_req {
+ struct list_head req_node; /* list of page_req's */
+ struct list_head *page_list_index; /* list of pages */
+ struct address_space *mapping;
+ int num_pages;
+ int read_size;
+ int start_page_index; /* first expected index */
+ int end_page_index; /* last expected index */
+ struct mid_q_entry *midq; /* queue structure for demultiplex */
+};
+
+/* one of these for every pending SMB2 request to the server */
+struct smb2_mid_entry {
+ struct list_head qhead; /* mids waiting on reply from this server */
+ __u64 mid; /* multiplex id(s) */
+ __u16 pid; /* process id */
+ __u32 sequence_number; /* for signing */ /* BB check if needed */
+ unsigned long when_alloc; /* when mid was created */
+#ifdef CONFIG_CIFS_STATS2
+ unsigned long when_sent; /* time when smb send finished */
+ unsigned long when_received; /* when demux complete (taken off wire) */
+#endif
+ struct task_struct *tsk; /* task waiting for response */
+ struct smb2_hdr *resp_buf; /* response buffer */
+ char **pagebuf_list; /* response buffer */
+ int num_pages;
+ int mid_state; /* wish this were enum but can not pass to wait_event */
+ __le16 command; /* smb command code */
+ bool async_resp_rcvd:1; /* if server has responded with interim resp */
+ bool large_buf:1; /* if valid response, is pointer to large buf */
+ bool is_kmap_buf:1;
+/* bool multi_rsp:1; BB do we have to account for something in SMB2 like
+ we saw multiple trans2 responses for one request (possible in CIFS) */
+ /* Async things */
+ __u64 *mid_list; /* multiplex id(s) */
+ int *mid_state_list;
+ short int *large_buf_list;
+ unsigned int num_mid;
+ unsigned int act_num_mid;
+ unsigned int num_received;
+ unsigned int cur_id;
+ struct smb2_hdr **resp_buf_list; /* response buffer */
+ __le16 *command_list;
+ bool async:1;
+ bool complex_mid:1; /* complex entry - consists of several messages */
+ int result;
+ unsigned long last_rsp_time;
+ int (*callback)(struct smb2_mid_entry * , void *);
+ void *callback_data;
+};
+
+
+#define SMB2SEC_DEF (SMB2SEC_MAY_SIGN | SMB2SEC_MAY_NTLM | SMB2SEC_MAY_NTLMV2)
+#define SMB2SEC_MAX (SMB2SEC_MUST_SIGN | SMB2SEC_MUST_NTLMV2)
+#define SMB2SEC_AUTH_MASK (SMB2SEC_MAY_NTLM | SMB2SEC_MAY_NTLMV2 | \
+ SMB2SEC_MAY_PLNTXT | SMB2SEC_MAY_KRB5)
+/*
+ *****************************************************************
+ * Constants go here
+ *****************************************************************
+ */
+
+
+/* BB since num credits could be negotiated higher, override with max_pending */
+#define SMB2_MAX_REQ 256
+
+/* Identifiers for functions that use the open, operation, close pattern
+ * in inode.c:open_op_close() */
+#define SMB2_OP_SET_DELETE 1
+#define SMB2_OP_SET_INFO 2
+#define SMB2_OP_QUERY_INFO 3
+#define SMB2_OP_QUERY_DIR 4
+#define SMB2_OP_MKDIR 5
+#define SMB2_OP_RENAME 6
+
+/* Used when constructing chained read requests. */
+#define CHAINED_REQUEST 1
+#define START_OF_CHAIN 2
+#define END_OF_CHAIN 4
+#define RELATED_REQUEST 8
+
+/*
+ * The externs for various global variables put here. The actual declarations
+ * of these should be mostly placed at the front of smb2fs.c to be easy to spot
+ */
+
+
+/*
+ * Global counters, updated atomically
+ */
+
+/* Various Debug counters */
+extern atomic_t smb2_buf_alloc_count; /* current number allocated */
+#ifdef CONFIG_SMB2_STATS2
+extern atomic_t smb2_total_buf_alloc; /* total allocated over all time */
+extern atomic_t smb2_total_smbuf_alloc;
+#endif
+extern atomic_t smb2_smbuf_alloc_count;
+extern atomic_t smb2_mid_count;
+
+#endif /* _SMB2_GLOB_H */
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
new file mode 100644
index 000000000000..b314f4e2caf7
--- /dev/null
+++ b/fs/cifs/smb2misc.c
@@ -0,0 +1,336 @@
+/*
+ * fs/cifs/smb2misc.c
+ *
+ * Copyright (C) International Business Machines Corp., 2002,2011
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <linux/ctype.h>
+#include "smb2pdu.h"
+#include "cifsglob.h"
+#include "cifsproto.h"
+#include "smb2proto.h"
+#include "cifs_debug.h"
+#include "cifs_unicode.h"
+#include "smb2status.h"
+
+/*
+__u64 get_mid(struct tcp_srv_inf *server)
+{
+ __u64 mid;
+
+ if (server == NULL)
+ return 0;
+
+ spin_lock(&SMB2_mid_lock);
+ mid = server->current_mid++;
+ spin_unlock(&SMB2_mid_lock);
+ return mid;
+} */ /* BB do we eventually need an SMB2 version of this routine? BB */
+
+static int
+check_smb2_hdr(struct smb2_hdr *smb, __u16 mid)
+{
+ /* Make sure that this really is an SMB, that it is a response,
+ and that the message ids match */
+ if ((*(__le32 *) smb->ProtocolId == cpu_to_le32(0x424d53fe)) &&
+ (mid == smb->MessageId)) {
+ if (smb->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
+ return 0;
+ else {
+ /* only one valid case where server sends us request */
+ if (smb->Command == SMB2_OPLOCK_BREAK)
+ return 0;
+ else
+ cERROR(1, "Received Request not response");
+ }
+ } else { /* bad signature or mid */
+ if (*(__le32 *) smb->ProtocolId != cpu_to_le32(0x424d53fe))
+ cERROR(1, "Bad protocol string signature header %x",
+ *(unsigned int *) smb->ProtocolId);
+ if (mid != smb->MessageId)
+ cERROR(1, "Mids do not match");
+ }
+ cERROR(1, "bad smb detected. The Mid=%lld", smb->MessageId);
+ return 1;
+}
+
+/*
+ * The following table defines the expected "StructureSize" of SMB2 responses
+ * in order by SMB2 command. This is similar to "wct" in SMB/CIFS responses.
+ *
+ * Note that commands are defined in smb2pdu.h in le16 but the array below is
+ * indexed by command in host byte order
+ */
+static const int smb2_rsp_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
+ /* SMB2_NEGOTIATE */ 65,
+ /* SMB2_SESSION_SETUP */ 9,
+ /* SMB2_LOGOFF */ 4,
+ /* SMB2_TREE_CONNECT */ 16,
+ /* SMB2_TREE_DISCONNECT */ 4,
+ /* SMB2_CREATE */ 89,
+ /* SMB2_CLOSE */ 60,
+ /* SMB2_FLUSH */ 4,
+ /* SMB2_READ */ 17,
+ /* SMB2_WRITE */ 17,
+ /* SMB2_LOCK */ 4,
+ /* SMB2_IOCTL */ 49,
+ /* SMB2_CANCEL */ 0, /* BB CHECK this ... not listed in documentation */
+ /* SMB2_ECHO */ 4,
+ /* SMB2_QUERY_DIRECTORY */ 9,
+ /* SMB2_CHANGE_NOTIFY */ 9,
+ /* SMB2_QUERY_INFO */ 9,
+ /* SMB2_SET_INFO */ 2,
+ /* SMB2_OPLOCK_BREAK */ 24 /* BB FIXME can also be 44 for lease break */
+};
+
+int
+checkSMB2(struct smb2_hdr *smb, __u64 mid, unsigned int length)
+{
+ struct smb2_pdu * smb2 = (struct smb2_pdu *)smb;
+ __u32 len = be32_to_cpu(smb->smb2_buf_length);
+ __u32 clc_len; /* calculated length */
+ __u16 command;
+
+ /* BB disable following printk later */
+ cFYI(1, "checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len);
+
+ /* Add function to do table lookup of StructureSize by command
+ ie Validate the wct via smb2_struct_sizes table above */
+
+ if (length < 2 + sizeof(struct smb2_hdr)) {
+ if ((length >= sizeof(struct smb2_hdr))
+ && (smb->Status != 0)) {
+ smb2->StructureSize2 = 0;
+ /* As with SMB/CIFS, on some error cases servers may
+ not return wct properly */
+ return 0;
+ } else {
+ cERROR(1, "Length less than smb header size");
+ }
+ return 1;
+ }
+ if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) {
+ cERROR(1, "smb length greater than maximum, mid=%lld",
+ smb->MessageId);
+ return 1;
+ }
+
+ if (check_smb2_hdr(smb, mid))
+ return 1;
+
+ if (le16_to_cpu(smb->StructureSize) != 64) {
+ cERROR(1, "Illegal structure size %d",
+ le16_to_cpu(smb->StructureSize));
+ return 1;
+ }
+
+ command = le16_to_cpu(smb->Command);
+ if (command >= NUMBER_OF_SMB2_COMMANDS) {
+ cERROR(1, "illegal SMB2 command %d", command);
+ return 1;
+ }
+
+ if (smb2_rsp_struct_sizes[command] !=
+ le16_to_cpu(smb2->StructureSize2)) {
+ if ((smb->Status == 0) ||
+ (le16_to_cpu(smb2->StructureSize2) != 9)) {
+ /* error packets have 9 byte structure size */
+ cERROR(1, "Illegal response size %d for command %d",
+ le16_to_cpu(smb2->StructureSize2), command);
+ return 1;
+ }
+ }
+
+ clc_len = smb2_calc_size(smb);
+
+ if (4 + len != length) {
+ cERROR(1, "Length read does not match RFC1001 length %d",
+ len);
+ return 1;
+ }
+
+ if (4 + len != clc_len) {
+ cFYI(1, "Calculated size %d length %d mismatch for mid %lld",
+ clc_len, 4 + len, smb->MessageId);
+ if (clc_len == 4 + len + 1) /* BB FIXME (fix samba) */
+ return 0; /* BB workaround Samba 3 bug SessSetup rsp */
+ return 1;
+ }
+ return 0;
+}
+
+void
+dump_smb2(struct smb2_hdr *smb_buf, int smb_buf_length)
+{
+ dump_smb((struct smb_hdr *)smb_buf, smb_buf_length);
+}
+
+/*
+ * The size of the variable area depends on the offset and length fields
+ * located in different fields for various SMB2 responses. SMB2 responses
+ * with no variable length info, show an offset of zero for the offset field.
+ */
+static const bool has_smb2_data_area[NUMBER_OF_SMB2_COMMANDS] = {
+ /* SMB2_NEGOTIATE */ true,
+ /* SMB2_SESSION_SETUP */ true,
+ /* SMB2_LOGOFF */ false,
+ /* SMB2_TREE_CONNECT */ false,
+ /* SMB2_TREE_DISCONNECT */ false,
+ /* SMB2_CREATE */ true,
+ /* SMB2_CLOSE */ false,
+ /* SMB2_FLUSH */ false,
+ /* SMB2_READ */ true,
+ /* SMB2_WRITE */ false,
+ /* SMB2_LOCK */ false,
+ /* SMB2_IOCTL */ true,
+ /* SMB2_CANCEL */ false, /* BB CHECK this not listed in documentation */
+ /* SMB2_ECHO */ false,
+ /* SMB2_QUERY_DIRECTORY */ true,
+ /* SMB2_CHANGE_NOTIFY */ true,
+ /* SMB2_QUERY_INFO */ true,
+ /* SMB2_SET_INFO */ false,
+ /* SMB2_OPLOCK_BREAK */ false
+};
+
+/* Returns the pointer to the beginning of the data area
+ Length of the data area and the offset to it (from the beginning of the smb
+ are also returned */
+char *smb2_get_data_area_len(int *poff, int *plen, struct smb2_hdr *pSMB2)
+{
+ *poff = 0;
+ *plen = 0;
+
+ /* error responses do not have data area */
+ if (pSMB2->Status &&
+ (le32_to_cpu(pSMB2->Status) != STATUS_MORE_PROCESSING_REQUIRED) &&
+ (le16_to_cpu(((struct smb2_err_rsp *)pSMB2)->StructureSize) == 9))
+ return NULL;
+
+ /* Following commands have data areas so we have to get the location
+ of the data buffer offset and data buffer length for the particular
+ command */
+ switch (pSMB2->Command) {
+ case SMB2_NEGOTIATE:
+ *poff = le16_to_cpu(
+ ((struct smb2_negotiate_rsp *)pSMB2)->SecurityBufferOffset);
+ *plen = le16_to_cpu(
+ ((struct smb2_negotiate_rsp *)pSMB2)->SecurityBufferLength);
+ break;
+ case SMB2_SESSION_SETUP:
+ *poff = le16_to_cpu(
+ ((struct sess_setup_rsp *)pSMB2)->SecurityBufferOffset);
+ *plen = le16_to_cpu(
+ ((struct sess_setup_rsp *)pSMB2)->SecurityBufferLength);
+ break;
+ case SMB2_CREATE:
+ *poff = le32_to_cpu(
+ ((struct create_rsp *)pSMB2)->CreateContextsOffset);
+ *plen = le32_to_cpu(
+ ((struct create_rsp *)pSMB2)->CreateContextsLength);
+ break;
+ case SMB2_READ:
+ *poff = ((struct read_rsp *)pSMB2)->DataOffset;
+ *plen = le32_to_cpu(
+ ((struct read_rsp *)pSMB2)->DataLength);
+ break;
+ case SMB2_QUERY_INFO:
+ *poff = le16_to_cpu(
+ ((struct query_info_rsp *)pSMB2)->OutputBufferOffset);
+ *plen = le32_to_cpu(
+ ((struct query_info_rsp *)pSMB2)->OutputBufferLength);
+ break;
+ case SMB2_QUERY_DIRECTORY:
+ *poff = le16_to_cpu(
+ ((struct query_directory_rsp *)pSMB2)->OutputBufferOffset);
+ *plen = le32_to_cpu(
+ ((struct query_directory_rsp *)pSMB2)->OutputBufferLength);
+ break;
+ case SMB2_IOCTL:
+ case SMB2_CHANGE_NOTIFY:
+ default:
+ /* BB FIXME for unimplemented cases above */
+ cERROR(1, "no length check for command");
+ break;
+ }
+
+ /* Invalid length or offset probably means data area is invalid, but
+ we have little choice but to ignore the data area in this case */
+ if (*poff > 4096) {
+ dump_stack();
+ cERROR(1, "offset %d too large, data area ignored", *poff);
+ *plen = 0;
+ *poff = 0;
+ } else if (*poff < 0) {
+ cERROR(1, "negative offset to data invalid ignore data area");
+ *poff = 0;
+ *plen = 0;
+ } else if (*plen < 0) {
+ cERROR(1, "negative data length invalid, data area ignored");
+ *plen = 0;
+ } else if (*plen > 128 * 1024) {
+ cERROR(1, "data area larger than 128K");
+ *plen = 0;
+ }
+
+ /* return pointer to beginning of data area, ie offset from SMB start */
+ if ((*poff != 0) && (*plen != 0))
+ return pSMB2->ProtocolId + *poff;
+ else
+ return NULL;
+}
+
+/*
+ * calculate the size of the SMB message based on the fixed header
+ * portion, the number of word parameters and the data portion of the message
+ */
+unsigned int
+smb2_calc_size(struct smb2_hdr *pSMB2h)
+{
+ struct smb2_pdu *pSMB2 = (struct smb2_pdu *)pSMB2h;
+ int offset; /* the offset from the beginning of SMB to data area */
+ int data_length; /* the length of the variable length data area */
+ /* Structure Size has already been checked to make sure it is 64 */
+ int len = 4 + le16_to_cpu(pSMB2->hdr.StructureSize);
+
+ /* StructureSize2, ie length of fixed parameter area has already
+ been checked to make sure it is the correct length */
+ len += le16_to_cpu(pSMB2->StructureSize2);
+
+ if (has_smb2_data_area[le16_to_cpu(pSMB2h->Command)] == false)
+ goto calc_size_exit;
+
+ smb2_get_data_area_len(&offset, &data_length, pSMB2h);
+ cFYI(1, "smb2 data length %d offset %d", data_length, offset);
+
+ if (data_length > 0) {
+ /* Check to make sure that data area begins after fixed area,
+ Note that last byte of the fixed area is part of data area
+ for some commands, typically those with odd StructureSize,
+ so we must add one to the calculation (and 4 to account for
+ the size of the RFC1001 hdr */
+ if (offset + 4 + 1 < len) {
+ cERROR(1, "data area overlaps SMB2 header, ignoring");
+ data_length = 0;
+ } else {
+ len = 4 + offset + data_length;
+ }
+ }
+calc_size_exit:
+ cFYI(1, "smb2 len %d", len);
+ return len;
+}
+
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
new file mode 100644
index 000000000000..3d285942906b
--- /dev/null
+++ b/fs/cifs/smb2pdu.c
@@ -0,0 +1,2506 @@
+/*
+ * fs/cifs/smb2pdu.c
+ *
+ * Copyright (C) International Business Machines Corp., 2009,2011
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ * Contains the routines for constructing the SMB2 PDUs themselves
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+ /* SMB2 PDU handling routines here - except for leftovers (eg session setup) */
+ /* Note that there are handle based routines which must be */
+ /* treated slightly differently for reconnection purposes since we never */
+ /* want to reuse a stale file handle and only the caller knows the file info */
+
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/vfs.h>
+#include <linux/uaccess.h>
+#include <linux/xattr.h>
+#include "smb2pdu.h"
+#include "cifsglob.h"
+#include "cifsacl.h"
+#include "cifsproto.h"
+#include "smb2proto.h"
+#include "cifs_unicode.h"
+#include "cifs_debug.h"
+#include "ntlmssp.h"
+#include "smb2status.h"
+
+/* Mark as invalid, all open files on tree connections since they
+ were closed when session to server was lost */
+static void mark_open_files_invalid(struct cifs_tcon *ptcon)
+{
+ struct smb2_file *open_file = NULL;
+ struct list_head *tmp;
+ struct list_head *tmp1;
+
+/* list all files open on tree connection and mark them invalid */
+ spin_lock(&cifs_file_list_lock);
+ list_for_each_safe(tmp, tmp1, &ptcon->openFileList) {
+ open_file = list_entry(tmp, struct smb2_file, tlist);
+ open_file->invalid_handle = true;
+ }
+ spin_unlock(&cifs_file_list_lock);
+ /* BB Add call to invalidate_inodes(sb) for all superblocks mounted
+ to this tcon */
+}
+
+
+/*
+ * The following table defines the expected "StructureSize" of SMB2 requests
+ * in order by SMB2 command. This is similar to "wct" in SMB/CIFS requests.
+ *
+ * Note that commands are defined in smb2pdu.h in le16 but the array below is
+ * indexed by command in host byte order
+ */
+static const int smb2_req_struct_sizes[NUMBER_OF_SMB2_COMMANDS] = {
+ /* SMB2_NEGOTIATE */ 36,
+ /* SMB2_SESSION_SETUP */ 25,
+ /* SMB2_LOGOFF */ 4,
+ /* SMB2_TREE_CONNECT */ 9,
+ /* SMB2_TREE_DISCONNECT */ 4,
+ /* SMB2_CREATE */ 57,
+ /* SMB2_CLOSE */ 24,
+ /* SMB2_FLUSH */ 24,
+ /* SMB2_READ */ 49,
+ /* SMB2_WRITE */ 49,
+ /* SMB2_LOCK */ 48,
+ /* SMB2_IOCTL */ 57,
+ /* SMB2_CANCEL */ 4,
+ /* SMB2_ECHO */ 4,
+ /* SMB2_QUERY_DIRECTORY */ 33,
+ /* SMB2_CHANGE_NOTIFY */ 32,
+ /* SMB2_QUERY_INFO */ 41,
+ /* SMB2_SET_INFO */ 33,
+ /* SMB2_OPLOCK_BREAK */ 24 /* BB this is 36 for LEASE_BREAK variant */
+};
+
+
+/* NB: MID can not be set if tcon not passed in, in that
+ case it is responsbility of caller to set the mid */
+static void
+smb2_hdr_assemble(struct smb2_hdr *buffer, __le16 smb2_cmd /* command */ ,
+ const struct cifs_tcon *tcon)
+{
+ struct list_head *temp_item;
+ struct cifs_ses *ses;
+ struct smb2_pdu *smb = (struct smb2_pdu *)buffer;
+ char *temp = (char *) buffer;
+ /* lookup word count ie StructureSize from table */
+ __u16 parmsize = smb2_req_struct_sizes[le16_to_cpu(smb2_cmd)];
+
+ /* smaller than SMALL_BUFFER_SIZE but bigger than fixed area of
+ largest operations (Create) */
+ memset(temp, 0, 256);
+
+ /* Note this is only network field converted to big endian */
+ buffer->smb2_buf_length = cpu_to_be32(parmsize + sizeof(struct smb2_hdr)
+ - 4 /* RFC 1001 length field itself not counted */);
+
+ buffer->ProtocolId[0] = 0xFE;
+ buffer->ProtocolId[1] = 'S';
+ buffer->ProtocolId[2] = 'M';
+ buffer->ProtocolId[3] = 'B';
+ buffer->StructureSize = cpu_to_le16(64);
+ buffer->Command = smb2_cmd;
+ buffer->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */
+ buffer->ProcessId = cpu_to_le32((__u16)current->tgid);
+ if (tcon) {
+ buffer->TreeId = tcon->tid;
+ /* For the multiuser case, there are few obvious technically */
+ /* possible mechanisms to match the local linux user (uid) */
+ /* to a valid remote smb user (smb_uid): */
+ /* 1) Query Winbind (or other local pam/nss daemon */
+ /* for userid/password/logon_domain or credential */
+ /* 2) Query Winbind for uid to sid to username mapping */
+ /* and see if we have a matching password for existing*/
+ /* session for that user perhas getting password by */
+ /* adding a new pam_smb2 module that stores passwords */
+ /* so that the smb2 vfs can get at that for all logged*/
+ /* on users */
+ /* 3) (Which is the mechanism we have chosen) */
+ /* Search through sessions to the same server for a */
+ /* a match on the uid that was passed in on mount */
+ /* with the current processes uid (or euid?) and use */
+ /* that smb uid. If no existing smb session for */
+ /* that uid found, use the default smb session ie */
+ /* the smb session for the volume mounted which is */
+ /* the same as would be used if the multiuser mount */
+ /* flag were disabled. */
+
+ /* BB Add support for establishing new tcon and SMB Session */
+ /* with userid/password pairs found on the smb session */
+ /* for other target tcp/ip addresses BB */
+ if (tcon->ses) {
+ /* Uid is not converted */
+ buffer->SessionId = tcon->ses->Suid;
+ /* BB check this against related recent cifs changes */
+ if (multiuser_mount != 0) {
+ if (current_fsuid() !=
+ tcon->ses->linux_uid) {
+ cFYI(1, "Multiuser mode and UID "
+ "did not match tcon uid");
+ spin_lock(&cifs_tcp_ses_lock);
+ list_for_each(temp_item,
+ &tcon->ses->server->smb_ses_list) {
+ ses = list_entry(temp_item,
+ struct cifs_ses,
+ smb_ses_list);
+ if (ses->linux_uid == current_fsuid()) {
+ if (ses->server == tcon->ses->server) {
+ buffer->SessionId = ses->Suid;
+ break;
+ } else {
+ /* BB eventually call smb2_setup_session here */
+ cFYI(1, "local UID found but no smb sess with this server exists");
+ }
+ }
+ }
+ spin_unlock(&cifs_tcp_ses_lock);
+ }
+ }
+ }
+ /* BB check following DFS flags BB */
+ /* BB do we have to add check for SHI1005_FLAGS_DFS_ROOT too? */
+ if (tcon->share_flags & SHI1005_FLAGS_DFS)
+ buffer->Flags |= SMB2_FLAGS_DFS_OPERATIONS;
+/* BB how does SMB2 do case sensitive? */
+/* if (tcon->nocase)
+ buffer->Flags |= SMBFLG_CASELESS; */
+ if ((tcon->ses) && (tcon->ses->server))
+ if (tcon->ses->server->sec_mode &
+ SMB2_NEGOTIATE_SIGNING_REQUIRED)
+ buffer->Flags |= SMB2_FLAGS_SIGNED;
+ }
+
+ smb->StructureSize2 = cpu_to_le16(parmsize);
+ return;
+}
+
+/* Allocate and return pointer to an SMB request buffer, and set basic
+ SMB information in the SMB header. If the return code is zero, this
+ function must have filled in request_buf pointer */
+static int
+small_smb2_init(__le16 smb2_command, struct cifs_tcon *tcon,
+ void **request_buf)
+{
+ int rc = 0;
+
+ /* SMBs NegProt, SessSetup, uLogoff do not have tcon yet so
+ check for tcp and smb session status done differently
+ for those three - in the calling routine */
+ if (tcon) {
+ if (tcon->tidStatus == CifsExiting) {
+ /* only tree disconnect, open, and write,
+ (and ulogoff which does not have tcon)
+ are allowed as we start force umount */
+ if ((smb2_command != SMB2_WRITE) &&
+ (smb2_command != SMB2_CREATE) &&
+ (smb2_command != SMB2_TREE_DISCONNECT)) {
+ cFYI(1, "can not send cmd %d while umounting",
+ smb2_command);
+ return -ENODEV;
+ }
+ }
+ if ((tcon->ses) && (tcon->ses->status != CifsExiting) &&
+ (tcon->ses->server)) {
+ struct nls_table *nls_codepage;
+ /* Give Demultiplex thread up to 10 seconds to
+ reconnect, should be greater than smb2 socket
+ timeout which is 7 seconds */
+ while (tcon->ses->server->tcpStatus ==
+ CifsNeedReconnect) {
+ /* Return to caller for TREE_DISCONNECT
+ and LOGOFF and CLOSE here ... since they
+ are implicitly done when session drops */
+ switch (smb2_command) {
+ /* special case next three in caller */
+ /* BB Should we keep oplock break and
+ add flush to the four exceptions? */
+ case SMB2_TREE_DISCONNECT:
+ case SMB2_CANCEL:
+ case SMB2_CLOSE:
+ case SMB2_OPLOCK_BREAK:
+ return -EAGAIN;
+ }
+ wait_event_interruptible_timeout(
+ tcon->ses->server->response_q,
+ (tcon->ses->server->tcpStatus ==
+ CifsGood),
+ 10 * HZ);
+ if (tcon->ses->server->tcpStatus ==
+ CifsNeedReconnect) {
+ /* on "soft" mounts we wait once */
+ if (!tcon->retry ||
+ (tcon->ses->status == CifsExiting)) {
+ cFYI(1, "gave up waiting on "
+ "reconnect in smb_init");
+ return -EHOSTDOWN;
+ } /* else "hard" mount - keep retrying
+ until process is killed or server
+ comes back on-line */
+ } else /* TCP session is reestablished now */
+ break;
+ }
+
+ nls_codepage = load_nls_default();
+ /* need to prevent multiple threads trying to
+ simultaneously reconnect the same SMB session */
+ mutex_lock(&tcon->ses->session_mutex);
+ if (tcon->ses->need_reconnect)
+ rc = smb2_setup_session(0, tcon->ses,
+ nls_codepage);
+
+
+ if (smb2_command == SMB2_TREE_CONNECT) {
+ mutex_unlock(&tcon->ses->session_mutex);
+ goto get_buf;
+ }
+
+ /* we need to prevent multiple threads in this case too */
+ if (!rc && (tcon->need_reconnect)) {
+ mark_open_files_invalid(tcon);
+ rc = SMB2_tcon(0, tcon->ses, tcon->treeName,
+ tcon, nls_codepage);
+ /* BB FIXME add code to check if wsize needs
+ update due to negotiated smb buffer size
+ shrinking */
+ if (rc == 0)
+ atomic_inc(&tconInfoReconnectCount);
+
+ cFYI(1, "reconnect tcon rc = %d", rc);
+ /* Removed call to reopen open files here.
+ It is safer (and faster) to reopen files
+ one at a time as needed in read and write */
+
+ /* Check if handle based operation so we
+ know whether we can continue or not without
+ returning to caller to reset file handle */
+ /* BB Is flush done by server on drop
+ of tcp session? Should we special
+ case it and skip above? */
+ switch (smb2_command) {
+ case SMB2_FLUSH:
+ case SMB2_READ:
+ case SMB2_WRITE:
+ case SMB2_LOCK:
+ case SMB2_IOCTL:
+ case SMB2_QUERY_DIRECTORY:
+ case SMB2_CHANGE_NOTIFY:
+ case SMB2_QUERY_INFO:
+ case SMB2_SET_INFO: {
+ mutex_unlock(&tcon->ses->session_mutex);
+ unload_nls(nls_codepage);
+ return -EAGAIN;
+ }
+ }
+ }
+ mutex_unlock(&tcon->ses->session_mutex);
+ unload_nls(nls_codepage);
+
+ } else {
+ return -EIO;
+ }
+ }
+ if (rc)
+ return rc;
+
+get_buf:
+ /* BB eventually switch this to SMB2 specific small buf size */
+ *request_buf = cifs_small_buf_get();
+ if (*request_buf == NULL) {
+ /* BB should we add a retry in here if not a writepage? */
+ return -ENOMEM;
+ }
+
+ smb2_hdr_assemble((struct smb2_hdr *) *request_buf, smb2_command,
+ tcon);
+
+ if (tcon != NULL) {
+ cifs_stats_inc(&tcon->num_smbs_sent);
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_sent[le16_to_cpu(smb2_command)]);
+ }
+
+ return rc;
+}
+
+int
+small_smb2_init_no_tc(__le16 smb2_command, struct cifs_ses *ses,
+ void **request_buf)
+{
+ int rc;
+ struct smb2_hdr *buffer;
+
+ rc = small_smb2_init(smb2_command, NULL, request_buf);
+ if (rc)
+ return rc;
+
+ buffer = (struct smb2_hdr *)*request_buf;
+
+ /* BB Set SMB2 flags */
+
+ /* uid, tid can stay at zero as set in header assemble */
+
+ /* BB add support for turning on the signing when
+ this function is used after 1st of session setup requests */
+
+ return rc;
+}
+
+static int
+validate_buf(unsigned int offset, unsigned int buffer_length,
+ struct smb2_hdr *hdr, unsigned int min_buf_size)
+
+{
+ unsigned int smb_len = be32_to_cpu(hdr->smb2_buf_length);
+ char *end_of_smb = smb_len + 4 /* RFC1001 length field */ + (char *)hdr;
+ char *begin_of_buf = 4 /* RFC1001 len field */ + offset + (char *)hdr;
+ char *end_of_buf = begin_of_buf + buffer_length;
+
+
+ if (buffer_length < min_buf_size) {
+ cERROR(1, "buffer length %d smaller than minimum size %d",
+ buffer_length, min_buf_size);
+ return -EINVAL;
+ }
+
+ /* check if beyond RFC1001 maximum length */
+ if ((smb_len > 0x7FFFFF) || (buffer_length > 0x7FFFFF)) {
+ cERROR(1, "buffer length %d or smb length %d too large",
+ buffer_length, smb_len);
+ return -EINVAL;
+ }
+
+ if ((begin_of_buf > end_of_smb) || (end_of_buf > end_of_smb)) {
+ cERROR(1, "illegal server response, bad offset to data");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * If SMB buffer fields valid, copy into temporary buffer to hold result
+ * Caller must free buffer
+ */
+static int
+validate_and_copy_buf(unsigned int offset, unsigned int buffer_length,
+ struct smb2_hdr *hdr, unsigned int minbufsize, char *pdata)
+
+{
+ char *begin_of_buf = 4 /* RFC1001 len field */ + offset + (char *)hdr;
+ int rc;
+
+ if (!pdata)
+ return -EINVAL;
+
+ rc = validate_buf(offset, buffer_length, hdr, minbufsize);
+ if (rc)
+ return rc;
+
+ memcpy(pdata, begin_of_buf, buffer_length);
+
+ return 0;
+}
+
+static int
+validate_and_copy_ea_buf(int ret_value,
+ int output_buf_offset, int output_buf_len,
+ struct smb2_hdr *hdr, int min_buf_size,
+ char *pdata, int pdata_len, char *ea_name,
+ const char *prefix, int prefix_len)
+{
+ int smb_len = be32_to_cpu(hdr->smb2_buf_length);
+ char *end_of_smb = smb_len + 4 /* RFC1001 length field */ + (char *)hdr;
+ char *begin_of_buf = 4 /* RFC1001 len field */
+ + output_buf_offset + (char *)hdr;
+ char *end_of_buf = begin_of_buf + output_buf_len;
+ char *curr_buf_pos = begin_of_buf;
+ int next_ea_offset = 1, pdata_offset = 0, curr_buf_offset = 0,
+ name_len, value_len, tot_written = 0;
+ FILE_FULL_EA_INFO *curr_ea = (FILE_FULL_EA_INFO *)begin_of_buf;
+
+ if (output_buf_len < min_buf_size) {
+ cERROR(1, "buffer length %d smaller than minimum size %d",
+ output_buf_len, min_buf_size);
+ return -EINVAL;
+ }
+
+ /* check if beyond RFC1001 maximum length */
+ if ((smb_len > 0x7FFFFF) || (output_buf_len > 0x7FFFFF)) {
+ cERROR(1, "buffer length %d or smb length %d too large",
+ output_buf_len, smb_len);
+ return -EINVAL;
+ }
+
+ if (end_of_buf > end_of_smb) {
+ cERROR(1, "illegal server response, bad offset to data");
+ return -EINVAL;
+ }
+
+ while (curr_buf_pos < end_of_buf
+ && curr_buf_offset < output_buf_len
+ && tot_written <= pdata_len
+ && next_ea_offset != 0) {
+ next_ea_offset = le32_to_cpu(curr_ea->NextEntryOffset);
+ /*= curr_ea->Flags;*/
+ name_len = curr_ea->EaNameLength;
+ value_len = curr_ea->EaValueLength;
+
+ /* check there aren't too many eas */
+ if (pdata_offset + name_len + 6 > pdata_len) {
+ cERROR(1, "EA list excedes size of user buffer.");
+ return -EINVAL;
+ }
+
+ if (ea_name != NULL) { /* Find single value user requested. */
+ if (strlen(ea_name) == name_len
+ && ((!strncmp(curr_ea->EaName,
+ prefix, prefix_len)
+ && strncmp(ea_name, curr_ea->EaName
+ + prefix_len, name_len
+ - prefix_len) == 0)
+ || (strncmp(XATTR_USER_PREFIX, prefix,
+ prefix_len) == 0
+ && strncmp(ea_name, curr_ea->EaName,
+ name_len) == 0))) {
+
+ memcpy(pdata, curr_ea->EaName + name_len + 1,
+ value_len);
+ memcpy(pdata+value_len, "\0", 1);
+ tot_written += value_len;
+ break;
+ }
+ } else { /* Form a list of all ea names */
+ if (strncmp(curr_ea->EaName, XATTR_SECURITY_PREFIX,
+ XATTR_SECURITY_PREFIX_LEN)
+ && strncmp(curr_ea->EaName, XATTR_OS2_PREFIX,
+ XATTR_OS2_PREFIX_LEN)) {
+
+ memcpy(pdata, XATTR_USER_PREFIX,
+ XATTR_USER_PREFIX_LEN);
+ memcpy(pdata+XATTR_USER_PREFIX_LEN,
+ curr_ea->EaName, name_len);
+ memcpy(pdata+XATTR_USER_PREFIX_LEN+name_len,
+ "\0", 1);
+ tot_written += name_len +
+ XATTR_USER_PREFIX_LEN + 1;
+ pdata += name_len + XATTR_USER_PREFIX_LEN + 1;
+ } else {
+ memcpy(pdata, curr_ea->EaName, name_len);
+ memcpy(pdata+name_len, "\0", 1);
+ tot_written += name_len + 1;
+ pdata += name_len + 1;
+ }
+ }
+
+ if (next_ea_offset == 0)
+ break;
+ curr_buf_offset += next_ea_offset;
+ curr_buf_pos += next_ea_offset;
+ curr_ea = (FILE_FULL_EA_INFO *)curr_buf_pos;
+ }
+ return tot_written;
+}
+
+static void free_rsp_buf(int resp_buftype, void *pSMB2r)
+{
+ if (resp_buftype == CIFS_SMALL_BUFFER)
+ cifs_small_buf_release(pSMB2r);
+ else if (resp_buftype == CIFS_LARGE_BUFFER)
+ cifs_buf_release(pSMB2r);
+}
+
+#define SMB2_NUM_PROT 2
+
+#define SMB2_PROT 0
+#define SMB21_PROT 1
+#define BAD_PROT 0xFFFF
+
+static struct {
+ int index;
+ __le16 name;
+} smb2protocols[] = {
+ {SMB2_PROT, cpu_to_le16(0x0202)},
+ {SMB21_PROT, cpu_to_le16(0x0210)},
+ {BAD_PROT, cpu_to_le16(0xFFFF)}
+};
+
+/*
+ *
+ * SMB2 Worker functions follow:
+ *
+ * The general structure of the worker functions is:
+ * 1) Call smb2_init (assembles SMB2 header)
+ * 2) Initialize SMB2 command specific fields in fixed length area of SMB
+ * 3) Call smb_sendrcv2 (sends request on socket and waits for response)
+ * 4) Decode SMB2 command specific fields in the fixed length area
+ * 5) Decode variable length data area (if any for this SMB2 command type)
+ * 6) Call free smb buffer
+ * 7) return
+ *
+ */
+
+int
+SMB2_negotiate(unsigned int xid, struct cifs_ses *ses)
+{
+ struct smb2_negotiate_req *pSMB2;
+ struct smb2_negotiate_rsp *pSMB2r;
+ struct kvec iov[1];
+ int rc = 0;
+ int status;
+ int resp_buftype;
+ struct TCP_Server_Info *server;
+ unsigned int sec_flags;
+ u16 i;
+ u16 temp = 0;
+ int blob_offset, blob_length;
+ char *security_blob;
+
+ cFYI(1, "Negotiate protocol");
+
+ if (ses->server)
+ server = ses->server;
+ else {
+ rc = -EIO;
+ return rc;
+ }
+
+ rc = small_smb2_init(SMB2_NEGOTIATE, NULL, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ /* if any of auth flags (ie not sign or seal) are overriden use them */
+ if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
+ sec_flags = ses->overrideSecFlg; /* BB FIXME fix sign flags?*/
+ else /* if override flags set only sign/seal OR them with global auth */
+ sec_flags = global_secflags | ses->overrideSecFlg;
+
+ cFYI(1, "sec_flags 0x%x", sec_flags);
+
+ pSMB2->hdr.SessionId = 0;
+
+ for (i = 0; i < SMB2_NUM_PROT; i++)
+ pSMB2->Dialects[i] = smb2protocols[i].name;
+
+ pSMB2->DialectCount = cpu_to_le16(i);
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length) + (i * 2));
+
+ /* only one of SMB2 signing flags may be set in SMB2 request */
+ if ((sec_flags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN)
+ temp = SMB2_NEGOTIATE_SIGNING_REQUIRED;
+ else if (sec_flags & CIFSSEC_MAY_SIGN) /* MAY_SIGN is a single flag */
+ temp = SMB2_NEGOTIATE_SIGNING_ENABLED;
+
+ pSMB2->SecurityMode = cpu_to_le16(temp);
+
+ pSMB2->Capabilities = cpu_to_le32(SMB2_GLOBAL_CAP_DFS);
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4;
+
+ rc = smb2_sendrcv2(xid, ses, iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+
+ cFYI(1, "negotiate returned buftype %d with rc %d status 0x%x",
+ resp_buftype, rc, status);
+ pSMB2r = (struct smb2_negotiate_rsp *)iov[0].iov_base;
+ /* no tcon so can't do cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]); */
+ if (rc != 0)
+ goto neg_exit;
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto neg_exit;
+ }
+
+ cFYI(1, "mode 0x%x", pSMB2r->SecurityMode);
+
+ if (pSMB2r->DialectRevision == smb2protocols[SMB21_PROT].name)
+ cFYI(1, "negotiated smb2.1 dialect");
+ else if (pSMB2r->DialectRevision == smb2protocols[SMB2_PROT].name)
+ cFYI(1, "negotiated smb2 dialect");
+ else {
+ cERROR(1, "Illegal dialect returned by server %d",
+ le16_to_cpu(pSMB2r->DialectRevision));
+ rc = -EIO;
+ goto neg_exit;
+ }
+ ses->server->smb2_dialect_revision = pSMB2r->DialectRevision;
+
+ ses->server->max_read = le32_to_cpu(pSMB2r->MaxReadSize);
+ ses->server->max_write = le32_to_cpu(pSMB2r->MaxWriteSize);
+ /* BB Do we need to validate the SecurityMode? */
+ ses->server->sec_mode = le16_to_cpu(pSMB2r->SecurityMode);
+ ses->server->capabilities = le32_to_cpu(pSMB2r->Capabilities);
+
+ security_blob = smb2_get_data_area_len(&blob_offset, &blob_length,
+ &pSMB2r->hdr);
+ if (blob_length == 0) {
+ cERROR(1, "missing security blob on negprot");
+ rc = -EIO;
+ goto neg_exit;
+ }
+#ifdef CONFIG_SMB2_ASN1 /* BB REMOVEME when updated asn1.c ready */
+ rc = decode_neg_token_init(security_blob, blob_length,
+ &ses->server->sec_type);
+ if (rc == 1)
+ rc = 0;
+ else if (rc == 0) {
+ rc = -EIO;
+ goto neg_exit;
+ }
+#endif
+
+neg_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ return rc;
+}
+
+int
+SMB2_sess_setup(unsigned int xid, struct cifs_ses *ses,
+ const struct nls_table *nls_cp)
+{
+ struct sess_setup_req *pSMB2;
+ struct sess_setup_rsp *pSMB2r = NULL;
+ struct kvec iov[2];
+ int rc = 0;
+ int status;
+ int resp_buftype;
+ __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
+ struct TCP_Server_Info *server;
+ unsigned int sec_flags;
+ u8 temp = 0;
+ u16 blob_length = 0;
+ char *security_blob;
+ char *ntlmssp_blob = NULL;
+ bool use_spnego = false; /* else use raw ntlmssp */
+
+ cFYI(1, "Session Setup");
+
+ if (ses->server)
+ server = ses->server;
+ else {
+ rc = -EIO;
+ return rc;
+ }
+
+ssetup_ntlmssp_authenticate:
+ if (phase == NtLmChallenge)
+ phase = NtLmAuthenticate; /* if ntlmssp, now final phase */
+
+ rc = small_smb2_init(SMB2_SESSION_SETUP, NULL, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ /* if any of auth flags (ie not sign or seal) are overriden use them */
+ if (ses->overrideSecFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
+ sec_flags = ses->overrideSecFlg; /* BB FIXME fix sign flags?*/
+ else /* if override flags set only sign/seal OR them with global auth */
+ sec_flags = global_secflags | ses->overrideSecFlg;
+
+ cFYI(1, "sec_flags 0x%x", sec_flags);
+
+ pSMB2->hdr.SessionId = 0; /* First session, not a reauthenticate */
+ pSMB2->VcNumber = 0; /* MBZ */
+
+ /* only one of SMB2 signing flags may be set in SMB2 request */
+ if ((sec_flags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN)
+ temp = SMB2_NEGOTIATE_SIGNING_REQUIRED;
+ else if (ses->server->sec_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED)
+ temp = SMB2_NEGOTIATE_SIGNING_REQUIRED;
+ else if (sec_flags & CIFSSEC_MAY_SIGN) /* MAY_SIGN is a single flag */
+ temp = SMB2_NEGOTIATE_SIGNING_ENABLED;
+
+ pSMB2->SecurityMode = temp;
+
+ /* We only support the DFS cap (others are currently undefined) */
+ pSMB2->Capabilities = cpu_to_le32(SMB2_GLOBAL_CAP_DFS
+ & ses->server->capabilities);
+ pSMB2->Channel = 0; /* MBZ */
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ + 4 /* rfc1001 len */ - 1 /* pad */;
+ if (phase == NtLmNegotiate) {
+ ntlmssp_blob = kmalloc(sizeof(struct _NEGOTIATE_MESSAGE),
+ GFP_KERNEL);
+ if (ntlmssp_blob == NULL) {
+ rc = -ENOMEM;
+ goto ssetup_exit;
+ }
+
+ build_ntlmssp_negotiate_blob(ntlmssp_blob, ses);
+ if (use_spnego) {
+/* blob_length = build_spnego_ntlmssp_blob(&security_blob,
+ sizeof(struct _NEGOTIATE_MESSAGE),
+ ntlmssp_blob); */
+ /* BB eventually need to add this */
+ cERROR(1, "spnego not supported for SMB2 yet");
+ rc = -EOPNOTSUPP;
+ kfree(ntlmssp_blob);
+ goto ssetup_exit;
+ } else {
+ blob_length = sizeof(struct _NEGOTIATE_MESSAGE);
+ /* with raw NTLMSSP we don't encapsulate in SPNEGO */
+ security_blob = ntlmssp_blob;
+ }
+ } else if (phase == NtLmAuthenticate) {
+ pSMB2->hdr.SessionId = ses->Suid;
+ ntlmssp_blob = kzalloc(sizeof(struct _NEGOTIATE_MESSAGE) + 500,
+ GFP_KERNEL);
+ if (ntlmssp_blob == NULL) {
+ cERROR(1, "failed to malloc ntlmssp blob");
+ rc = -ENOMEM;
+ goto ssetup_exit;
+ }
+ rc = build_ntlmssp_auth_blob(ntlmssp_blob, &blob_length,
+ ses, nls_cp);
+ if (rc) {
+ cFYI(1, "build_ntlmssp_auth_blob failed %d", rc);
+ goto ssetup_exit; /* BB double check error handling */
+ }
+ if (use_spnego) {
+/* blob_length = build_spnego_ntlmssp_blob(&security_blob,
+ blob_length,
+ ntlmssp_blob);*/
+ cERROR(1, "spnego not supported for SMB2 yet");
+ rc = -EOPNOTSUPP;
+ kfree(ntlmssp_blob);
+ goto ssetup_exit;
+ } else {
+ security_blob = ntlmssp_blob;
+ }
+ } else {
+ cERROR(1, "illegal ntlmssp phase");
+ rc = -EIO;
+ goto ssetup_exit;
+ }
+
+ /* Testing shows that buffer offset must be at location of Buffer[0] */
+ pSMB2->SecurityBufferOffset = cpu_to_le16(sizeof(struct sess_setup_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+ pSMB2->SecurityBufferLength = cpu_to_le16(blob_length);
+ iov[1].iov_base = security_blob;
+ iov[1].iov_len = blob_length;
+
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ - 1 /* pad */ + blob_length);
+
+ /* BB add code to build os and lm fields */
+
+ rc = smb2_sendrcv2(xid, ses, iov, 2, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ kfree(security_blob);
+ cFYI(1, "sess setup returned buftype %d with rc %d status 0x%x",
+ resp_buftype, rc, status);
+ pSMB2r = (struct sess_setup_rsp *)iov[0].iov_base;
+ if (pSMB2r->hdr.Status ==
+ cpu_to_le32(STATUS_MORE_PROCESSING_REQUIRED)) {
+ if (phase != NtLmNegotiate) {
+ cERROR(1, "Unexpected more processing error");
+ goto ssetup_exit;
+ }
+ if (offsetof(struct sess_setup_rsp, Buffer) - 4 /* RFC hdr */ !=
+ le16_to_cpu(pSMB2r->SecurityBufferOffset)) {
+ cERROR(1, "Invalid security buffer offset %d",
+ le16_to_cpu(pSMB2r->SecurityBufferOffset));
+ rc = -EIO;
+ goto ssetup_exit;
+ }
+
+ /* NTLMSSP Negotiate sent now processing challenge (response) */
+ phase = NtLmChallenge; /* process ntlmssp challenge */
+ rc = 0; /* MORE_PROCESSING is not an error here but expected */
+ ses->Suid = pSMB2r->hdr.SessionId;
+ rc = decode_ntlmssp_challenge(pSMB2r->Buffer,
+ le16_to_cpu(pSMB2r->SecurityBufferLength), ses);
+ }
+
+ /* BB eventually add code for SPNEGO decoding of NtlmChallenge blob,
+ but at least the raw NTLMSSP case works */
+
+ /* no tcon so can't do cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]); */
+ if (rc != 0)
+ goto ssetup_exit;
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto ssetup_exit;
+ }
+
+ ses->session_flags = le16_to_cpu(pSMB2r->SessionFlags);
+ssetup_exit:
+ kfree(ntlmssp_blob);
+ ntlmssp_blob = NULL;
+ free_rsp_buf(resp_buftype, pSMB2r);
+
+ /* if ntlmssp, and negotiate succeeded, proceed to authenticate phase */
+ if ((phase == NtLmChallenge) && (rc == 0))
+ goto ssetup_ntlmssp_authenticate;
+ return rc;
+}
+
+int
+SMB2_tcon(unsigned int xid, struct cifs_ses *ses,
+ const char *tree, struct cifs_tcon *tcon,
+ const struct nls_table *cp)
+{
+ struct tree_connect_req *pSMB2;
+ struct tree_connect_rsp *pSMB2r = NULL;
+ struct kvec iov[2];
+ int rc = 0;
+ int resp_buftype;
+ int unc_path_len;
+ int status;
+ struct TCP_Server_Info *server;
+ __le16 *unc_path = NULL;
+
+ cFYI(1, "TCON");
+
+ if ((ses->server) && tree)
+ server = ses->server;
+ else
+ return -EIO;
+
+ if (tcon && tcon->bad_network_name)
+ return -ENOENT;
+
+ unc_path = smb2_strndup_to_ucs(tree, MAX_NAME /* BB find better */,
+ &unc_path_len, cp);
+ if (unc_path == NULL)
+ return -ENOMEM;
+
+ if (unc_path_len < 2) {
+ kfree(unc_path);
+ return -EINVAL;
+ }
+
+ rc = small_smb2_init(SMB2_TREE_CONNECT, tcon, (void **) &pSMB2);
+ if (rc) {
+ kfree(unc_path);
+ return rc;
+ }
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ + 4 /* rfc1001 len */ - 1 /* pad */;
+
+ /* Testing shows that buffer offset must be at location of Buffer[0] */
+ pSMB2->PathOffset = cpu_to_le16(sizeof(struct tree_connect_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+ pSMB2->PathLength = cpu_to_le16(unc_path_len - 2);
+ iov[1].iov_base = unc_path;
+ iov[1].iov_len = unc_path_len;
+
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ - 1 /* pad */ + unc_path_len);
+
+ rc = smb2_sendrcv2(xid, ses, iov, 2, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "tcon buftype %d rc %d status %d", resp_buftype, rc, status);
+ pSMB2r = (struct tree_connect_rsp *)iov[0].iov_base;
+
+ if (rc != 0) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2TREE_CONNECT]);
+ tcon->need_reconnect = true;
+ goto tcon_exit;
+ }
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto tcon_exit;
+ }
+
+ if (pSMB2r->ShareType & SMB2_SHARE_TYPE_DISK)
+ cFYI(1, "connection to disk share");
+ else if (pSMB2r->ShareType & SMB2_SHARE_TYPE_PIPE) {
+ tcon->ipc = true;
+ cFYI(1, "connection to pipe share");
+ } else if (pSMB2r->ShareType & SMB2_SHARE_TYPE_PRINT) {
+ tcon->print = true;
+ cFYI(1, "connection to printer");
+ } else {
+ cERROR(1, "unknown share type %d", pSMB2r->ShareType);
+ rc = -EOPNOTSUPP;
+ goto tcon_exit;
+ }
+
+ tcon->share_flags = le32_to_cpu(pSMB2r->ShareFlags);
+ tcon->tidStatus = CifsGood;
+ tcon->need_reconnect = false;
+ tcon->tid = pSMB2r->hdr.TreeId;
+ if ((pSMB2r->Capabilities & SMB2_SHARE_CAP_DFS) &&
+ ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0))
+ cERROR(1, "DFS capability contradicts DFS flag");
+
+ tcon->maximal_access = le32_to_cpu(pSMB2r->MaximalAccess);
+
+ strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
+tcon_exit:
+ if (pSMB2r->hdr.Status == STATUS_BAD_NETWORK_NAME) {
+ cERROR(1, "BAD_NETWORK_NAME: %s", tree);
+ tcon->bad_network_name = true;
+ }
+ free_rsp_buf(resp_buftype, pSMB2r);
+ kfree(unc_path);
+
+ return rc;
+}
+
+int
+SMB2_logoff(const int xid, struct cifs_ses *ses)
+{
+ struct logoff_req *pSMB2; /* response is also trivial struct */
+ int rc = 0;
+ struct TCP_Server_Info *server;
+
+ cFYI(1, "disconnect session %p", ses);
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_LOGOFF, NULL, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ /* since no tcon, smb2_init can not do this, so do here */
+ pSMB2->hdr.SessionId = ses->Suid;
+
+ rc = smb2_sendrcv_norsp(xid, ses, &pSMB2->hdr,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ /* no tcon so can't do cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]); */
+ return rc;
+}
+
+int SMB2_tdis(const int xid, struct cifs_tcon *tcon)
+{
+ struct tree_disconnect_req *pSMB2; /* response is also trivial struct */
+ int rc = 0;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+
+ cFYI(1, "Tree Disconnect");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ if ((tcon->need_reconnect) || (tcon->ses->need_reconnect))
+ return 0;
+
+ rc = small_smb2_init(SMB2_TREE_DISCONNECT, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ rc = smb2_sendrcv_norsp(xid, ses, &pSMB2->hdr,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ if (rc)
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2TREE_DISCONNECT]);
+
+ return rc;
+}
+
+int SMB2_open(const int xid, struct cifs_tcon *tcon, __le16 *path,
+ u64 *persistent_fid, u64 *volatile_fid, __le32 desired_access,
+ __le32 create_disposition, __le32 file_attributes,
+ __le32 create_options)
+{
+ struct create_req *pSMB2;
+ struct create_rsp *pSMB2r;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+ struct kvec iov[2];
+ int resp_buftype;
+ int status;
+ int uni_path_len;
+ int rc = 0;
+ int num_iovecs = 2;
+
+ cFYI(1, "create/open");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_CREATE, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ if (oplockEnabled)
+ pSMB2->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_BATCH;
+ else
+ pSMB2->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_NONE;
+ pSMB2->ImpersonationLevel = IL_IMPERSONATION;
+ pSMB2->DesiredAccess = desired_access;
+ pSMB2->FileAttributes = file_attributes; /* ignored on open */
+ pSMB2->ShareAccess = FILE_SHARE_ALL;
+ pSMB2->CreateDisposition = create_disposition;
+ pSMB2->CreateOptions = create_options;
+ uni_path_len = (2 * UniStrnlen(path, PATH_MAX)) + 2;
+ pSMB2->NameOffset = cpu_to_le16(sizeof(struct create_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+
+ iov[0].iov_base = (char *)pSMB2;
+
+ /* rfc1001 length field is 4 bytes so added below */
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4;
+
+ /* MUST set path len (NameLength) to 0 opening root of share */
+ if (uni_path_len >= 4) {
+ pSMB2->NameLength = cpu_to_le16(uni_path_len - 2);
+ /* -1 since last byte is buf[0] which is sent below (path) */
+ iov[0].iov_len--;
+ iov[1].iov_len = uni_path_len;
+ iov[1].iov_base = path;
+ /* -1 since last byte is buf[0] which was counted in smb2_buf_len */
+ pSMB2->hdr.smb2_buf_length = cpu_to_be32(be32_to_cpu(
+ pSMB2->hdr.smb2_buf_length) + uni_path_len - 1);
+ } else {
+ num_iovecs = 1;
+ pSMB2->NameLength = 0;
+ }
+
+/* cERROR(1, "unipathlen 0x%x iov0len 0x%x iov1len 0x%x", uni_path_len,
+ iov[0].iov_len, iov[1].iov_len); */ /* BB REMOVEME BB */
+ rc = smb2_sendrcv2(xid, ses, iov, num_iovecs, &resp_buftype /* ret */,
+ &status, CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "creat buftype %d rc %d status %d", resp_buftype, rc, status);
+ pSMB2r = (struct create_rsp *)iov[0].iov_base;
+
+ if (rc != 0) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2CREATE]);
+ goto creat_exit;
+ }
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto creat_exit;
+ }
+ *persistent_fid = pSMB2r->PersistentFileId;
+ *volatile_fid = pSMB2r->VolatileFileId;
+creat_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ return rc;
+}
+
+int SMB2_close(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_file_id, u64 volatile_file_id)
+{
+ struct close_req *pSMB2;
+ struct close_rsp *pSMB2r;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+ struct kvec iov[1];
+ int resp_buftype;
+ int status;
+ int rc = 0;
+
+ cFYI(1, "Close");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_CLOSE, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->PersistentFileId = persistent_file_id;
+ pSMB2->VolatileFileId = volatile_file_id;
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ + 4 /* rfc1001 len */;
+
+ rc = smb2_sendrcv2(xid, ses, iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "CLOSE buftype %d rc %d status %d", resp_buftype, rc, status);
+ pSMB2r = (struct close_rsp *)iov[0].iov_base;
+
+ if (rc != 0) {
+ if (tcon)
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2CLOSE]);
+ goto close_exit;
+ }
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto close_exit;
+ }
+
+ /* BB FIXME - decode close response, update inode for caching */
+
+close_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ return rc;
+}
+
+int SMB2_flush(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_file_id, u64 volatile_file_id)
+{
+ struct flush_req *pSMB2;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+ struct kvec iov[1];
+ int resp_buftype;
+ int status;
+ int rc = 0;
+
+ cFYI(1, "Flush");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_FLUSH, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->PersistentFileId = persistent_file_id;
+ pSMB2->VolatileFileId = volatile_file_id;
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ + 4 /* rfc1001 len */;
+
+ rc = smb2_sendrcv2(xid, ses, iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "FLUSH rc %d status %d", rc, status);
+
+ if ((rc != 0) && tcon)
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2FLUSH]);
+
+ free_rsp_buf(resp_buftype, iov[0].iov_base);
+ return rc;
+}
+
+
+/* Although the tcon value is not needed to send the echo, the
+ echo is useful when problems with slow operations show up
+ on a tcon, and also after a mount to recognize very slow links
+ so it is useful to associate the results of echo with a tcon
+ and pass in a tcon to this function */
+int SMB2_echo(const int xid, struct cifs_tcon *tcon)
+{
+ struct echo_req *pSMB2;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+ struct kvec iov[1];
+ int resp_buftype;
+ int status;
+ int rc = 0;
+ unsigned long when_sent;
+
+ cFYI(1, "Echo");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_ECHO, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ + 4 /* rfc1001 len */;
+
+ when_sent = jiffies;
+ rc = smb2_sendrcv2(xid, ses, iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+
+ /* 15 jiffies is about 60 milliseconds - and plenty of time for network
+ request to reach server and be processed but if it takes 1000 jiffies
+ (about 4 seconds) then network or server is sick. 15 seconds and it
+ would have timed out and returned an error */
+ if (time_before(jiffies, when_sent + 3))
+ tcon->ses->server->speed = SMB2_ECHO_FAST;
+ else if (time_before(jiffies, when_sent + 15))
+ tcon->ses->server->speed = SMB2_ECHO_OK;
+ else if (time_before(jiffies, when_sent + 125)) {
+ tcon->ses->server->speed = SMB2_ECHO_SLOW;
+ cERROR(1, "slow network, SMB2 echo took %lu jiffies",
+ when_sent - jiffies);
+ } else if (time_before(jiffies, when_sent + 1000)) {
+ tcon->ses->server->speed = SMB2_ECHO_VERY_SLOW;
+ cERROR(1, "bad network? SMB2 echo took %lu jiffies",
+ when_sent - jiffies);
+ } else {
+ tcon->ses->server->speed = SMB2_ECHO_TIMEOUT;
+ cERROR(1, "server may be down - echo took %lu jiffies",
+ when_sent - jiffies);
+ }
+
+ cFYI(1, "ECHO speed %d rc %d status %d", tcon->ses->server->speed, rc, status);
+
+ if (rc != 0)
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2ECHO]);
+
+ free_rsp_buf(resp_buftype, iov[0].iov_base);
+ return rc;
+}
+
+static unsigned
+int is_symlink_relative(const char *symname)
+{
+ if ((strstr(symname, "./")) || (strstr(symname, "../")))
+ return 1;
+ else
+ return 0;
+}
+
+static int
+build_symlink_inputbuf(struct symlink_reparse_data_buf *inpbuf,
+ const char *symname, __le16 *pathbuf, unsigned int *pathbuflen)
+{
+ int uni_sym_len;
+ __le16 *nameptr = pathbuf;
+
+ uni_sym_len = cifs_strtoUCS(nameptr, symname,
+ strlen(symname), load_nls_default());
+ nameptr += uni_sym_len;
+ cifs_strtoUCS(nameptr, symname, strlen(symname), load_nls_default());
+
+ *pathbuflen = 4 * uni_sym_len;
+ inpbuf->reparse_tag = cpu_to_le32(MS_REPARSE_TAG);
+ inpbuf->reparse_datalength = cpu_to_le16(*pathbuflen + 12);
+ inpbuf->reserved1 = 0x0;
+ inpbuf->sub_nameoffset = 0x0;
+ inpbuf->sub_namelength = cpu_to_le16(2 * uni_sym_len);
+ inpbuf->print_nameoffset = 2 * uni_sym_len;
+ inpbuf->print_namelength = cpu_to_le16(2 * uni_sym_len);
+ if (is_symlink_relative(symname))
+ inpbuf->flags = cpu_to_le32(SYMLINK_FLAG_RELATIVE);
+ else
+ inpbuf->flags = 0x0;
+
+ return 0;
+}
+
+int
+SMB2_symlink_ioctl(const int xid, struct cifs_tcon *tcon, u32 ctlcode,
+ u64 persistent_fid, u64 volatile_fid, const char *symname)
+{
+ struct ioctl_req *pSMB2;
+ struct ioctl_rsp *pSMB2r = NULL;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+ struct kvec iov[3];
+ int resp_buftype;
+ int status;
+ int rc = 0;
+ int num_iovecs = 3;
+ unsigned int symbuflen = 0;
+ unsigned int pathbuflen = 0;
+ __le16 *pathbuf;
+ struct symlink_reparse_data_buf symlinkbuf;
+
+ cFYI(1, "SMB2_symlink_ioctl");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_IOCTL, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ /* allocate large enough buffer to hold unichar symname, twice */
+ pathbuf = kmalloc(2 * 4 * strlen(symname), GFP_KERNEL);
+ if (pathbuf == NULL) {
+ rc = -ENOMEM;
+ goto ioctl_exit;
+ }
+
+ pSMB2->Ctlcode = cpu_to_le32(ctlcode);
+ pSMB2->Fileid[0] = persistent_fid;
+ pSMB2->Fileid[1] = volatile_fid;
+
+ symlinkbuf.reparse_datalength = 0x0;
+ rc = build_symlink_inputbuf(&symlinkbuf, symname,
+ pathbuf, &pathbuflen);
+ if (rc) {
+ cERROR(1, "Error %d buidling symlink ioctl input buffer", rc);
+ goto ioctl_exit;
+ }
+ symbuflen = sizeof(struct symlink_reparse_data_buf) - 1;
+
+ pSMB2->Inputoffset = cpu_to_le16(sizeof(struct ioctl_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+ pSMB2->Inputcount = cpu_to_le16(symbuflen + pathbuflen);
+ pSMB2->Maxinputresp = 0;
+
+ pSMB2->Outputoffset = cpu_to_le16(sizeof(struct ioctl_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+ pSMB2->Outputcount = 0;
+ pSMB2->Maxoutputresp = 0;
+
+ pSMB2->Flags = cpu_to_le32(SMB2_IOCTL_IS_FSCTL);
+
+ iov[0].iov_base = (char *)pSMB2;
+ /* added 4 bytes of rfc1001 length field and subtracted 1 for buffer */
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4 - 1;
+
+ iov[1].iov_base = &symlinkbuf;
+ iov[1].iov_len = symbuflen;
+
+ iov[2].iov_base = pathbuf;
+ iov[2].iov_len = pathbuflen;
+
+ pSMB2->hdr.smb2_buf_length = cpu_to_be32(be32_to_cpu(
+ pSMB2->hdr.smb2_buf_length) + symbuflen + pathbuflen - 1);
+
+ rc = smb2_sendrcv2(xid, ses, iov, num_iovecs, &resp_buftype /* ret */,
+ &status, CIFS_STD_OP | CIFS_LOG_ERROR);
+
+ pSMB2r = (struct ioctl_rsp *)iov[0].iov_base;
+
+ if (rc != 0) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2IOCTL]);
+ goto ioctl_exit;
+ }
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto ioctl_exit;
+ }
+
+ioctl_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ kfree(pathbuf);
+ return rc;
+}
+
+static unsigned int
+num_entries(char *bufstart, char *end_of_buf, char **lastentry)
+{
+ int len;
+ unsigned int entrycount = 0;
+ unsigned int next_offset = 0;
+ struct file_full_directory_info *entryptr;
+
+ if (bufstart == NULL)
+ return 0;
+
+ entryptr = (struct file_full_directory_info *)bufstart;
+
+ while (1) {
+ entryptr = (struct file_full_directory_info *)
+ ((char *)entryptr + next_offset);
+
+ if ((char *)entryptr + sizeof(struct file_full_directory_info) >
+ end_of_buf) {
+ cERROR(1, "malformed search entry would overflow");
+ break;
+ }
+
+ len = le32_to_cpu(entryptr->filename_length);
+ if ((char *)entryptr + sizeof(struct file_full_directory_info) +
+ len > end_of_buf) {
+ cERROR(1, "directory entry name would overflow frame"
+ " end of buf %p", end_of_buf);
+ break;
+ }
+
+ *lastentry = (char *)entryptr;
+
+ entrycount += 1;
+
+ next_offset = le32_to_cpu(entryptr->next_entry_offset);
+ if (!next_offset)
+ break;
+ }
+
+ return entrycount;
+}
+
+/*
+ * Readdir/FindFirst
+ *
+ */
+int SMB2_query_directory(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid, int index,
+ struct smb2_search *psrch_inf)
+{
+ struct query_directory_req *pSMB2;
+ struct query_directory_rsp *pSMB2r = NULL;
+ struct kvec iov[2];
+ int rc = 0;
+ int len;
+ int resp_buftype;
+ int status;
+ unsigned char *bufptr;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+ __le16 asteriks = cpu_to_le16('*');
+ char *end_of_smb;
+
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_QUERY_DIRECTORY, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->FileInformationClass = FILEID_FULL_DIRECTORY_INFORMATION;
+
+ pSMB2->FileIndex = cpu_to_le32(index);
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+
+ len = 0x2;
+ bufptr = pSMB2->Buffer;
+ memcpy(bufptr, &asteriks, len);
+
+ pSMB2->FileNameOffset =
+ cpu_to_le16(sizeof(struct query_directory_req) - 1 - 4);
+ pSMB2->FileNameLength = cpu_to_le16(len);
+ /* BB could be 30 bytes or so longer if we used SMB2 specific
+ buffer lengths, but this is safe and close enough */
+ pSMB2->OutputBufferLength = CIFSMaxBufSize -
+ sizeof(struct query_directory_rsp);
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4 - 1;
+
+ iov[1].iov_base = (char *)(pSMB2->Buffer);
+ iov[1].iov_len = len;
+
+ pSMB2->hdr.smb2_buf_length = cpu_to_be32(be32_to_cpu(
+ pSMB2->hdr.smb2_buf_length) + len - 1);
+
+ rc = smb2_sendrcv2(xid, ses, iov, 2, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "rddir buftype %d rc %d status %d", resp_buftype, rc, status);
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2QUERY_DIRECTORY]);
+ goto qdir_exit;
+ }
+ pSMB2r = (struct query_directory_rsp *)iov[0].iov_base;
+
+ rc = validate_buf(le16_to_cpu(pSMB2r->OutputBufferOffset),
+ le32_to_cpu(pSMB2r->OutputBufferLength), &pSMB2r->hdr,
+ sizeof(struct file_full_directory_info));
+ if (rc)
+ goto qdir_exit;
+
+ psrch_inf->ntwrk_buf_start = (char *)pSMB2r;
+ psrch_inf->srch_entries_start = psrch_inf->last_entry = 4 /* RFCLEN */ +
+ (char *)&pSMB2r->hdr + le16_to_cpu(pSMB2r->OutputBufferOffset);
+ end_of_smb = be32_to_cpu(pSMB2r->hdr.smb2_buf_length) +
+ 4 /* RFC1001len field */ + (char *)&pSMB2r->hdr;
+ psrch_inf->entries_in_buf = num_entries(psrch_inf->srch_entries_start,
+ end_of_smb,
+ &psrch_inf->last_entry);
+ psrch_inf->index_of_last_entry += psrch_inf->entries_in_buf;
+ cFYI(1, "num entries %d last_index %lld srch start %p srch end %p",
+ psrch_inf->entries_in_buf, psrch_inf->index_of_last_entry,
+ psrch_inf->srch_entries_start, psrch_inf->last_entry);
+ if (resp_buftype == CIFS_LARGE_BUFFER)
+ psrch_inf->small_buf = false;
+ else if (resp_buftype == CIFS_SMALL_BUFFER)
+ psrch_inf->small_buf = true;
+ else
+ cERROR(1, "illegal search buffer type");
+
+ if (le32_to_cpu(pSMB2r->hdr.Status) == STATUS_NO_MORE_FILES)
+ psrch_inf->search_end = 1;
+ else
+ psrch_inf->search_end = 0;
+
+ return rc;
+
+qdir_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ return rc;
+}
+
+static void copy_fs_info_to_kstatfs(struct fs_full_size_info *pfs_inf,
+ struct kstatfs *pkstat)
+{
+ pkstat->f_bsize = le32_to_cpu(pfs_inf->BytesPerSector) *
+ le32_to_cpu(pfs_inf->SectorsPerAllocationUnit);
+ pkstat->f_blocks = le64_to_cpu(pfs_inf->TotalAllocationUnits);
+ pkstat->f_bfree = le64_to_cpu(pfs_inf->ActualAvailableAllocationUnits);
+ pkstat->f_bavail = le64_to_cpu(pfs_inf->CallerAvailableAllocationUnits);
+
+/* __kernel_fsid_t f_fsid; */ /* get volume uuid from other level (once) */
+/* long f_frsize; what are these?
+ long f_spare[5]; */
+ return;
+}
+
+static int build_qfs_info_req(struct kvec *iov, struct cifs_tcon *tcon,
+ int level, int outbuf_len,
+ u64 persistent_fid, u64 volatile_fid)
+{
+ int rc;
+ struct query_info_req *pSMB2;
+
+ cFYI(1, "Query FSInfo level %d", level);
+
+ if ((tcon->ses == NULL) || (tcon->ses->server == NULL))
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_QUERY_INFO, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->InfoType = SMB2_O_INFO_FILESYSTEM;
+ pSMB2->FileInfoClass = level;
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->InputBufferOffset = cpu_to_le16(sizeof(struct query_info_req)
+ - 1 /* pad */ - 4 /* do not count RFC1001 len field */);
+ pSMB2->OutputBufferLength =
+ cpu_to_le32(outbuf_len + sizeof(struct query_info_rsp) - 1 - 4);
+
+ iov->iov_base = (char *)pSMB2;
+ iov->iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4;
+ return 0;
+}
+
+int SMB2_QFS_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid, struct kstatfs *fsdat)
+{
+ struct query_info_rsp *pSMB2r = NULL;
+ struct kvec iov;
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ struct cifs_ses *ses = tcon->ses;
+ struct fs_full_size_info *psize_inf = NULL;
+
+ rc = build_qfs_info_req(&iov, tcon, FS_FULL_SIZE_INFORMATION,
+ sizeof(struct fs_full_size_info),
+ persistent_fid, volatile_fid);
+ if (rc)
+ return rc;
+
+ rc = smb2_sendrcv2(xid, ses, &iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "qfsinfo buftype %d rc %d status %d", resp_buftype, rc, status);
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2QUERY_INFO]);
+ goto qinf_exit;
+ }
+ pSMB2r = (struct query_info_rsp *)iov.iov_base;
+
+ psize_inf = (struct fs_full_size_info *)(4 /* RFC1001 len field */ +
+ le16_to_cpu(pSMB2r->OutputBufferOffset) + (char *)&pSMB2r->hdr);
+ rc = validate_buf(le16_to_cpu(pSMB2r->OutputBufferOffset),
+ le32_to_cpu(pSMB2r->OutputBufferLength),
+ &pSMB2r->hdr, sizeof(struct fs_full_size_info));
+ if (!rc)
+ copy_fs_info_to_kstatfs(psize_inf, fsdat);
+
+qinf_exit:
+ free_rsp_buf(resp_buftype, iov.iov_base);
+ return rc;
+}
+
+#define MAX_NTFS_VOL_LABEL_LEN 32 /* We don't use this, but allow for its len */
+
+int SMB2_QFS_vol_info(const int xid, struct cifs_tcon *tcon, u64 persistent_fid,
+ u64 volatile_fid)
+{
+ struct query_info_rsp *pSMB2r = NULL;
+ struct kvec iov;
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ struct cifs_ses *ses = tcon->ses;
+ struct fs_volume_info *pvol_inf = NULL;
+
+ rc = build_qfs_info_req(&iov, tcon, FS_VOLUME_INFORMATION,
+ sizeof(struct fs_volume_info)
+ + (2 * MAX_NTFS_VOL_LABEL_LEN),
+ persistent_fid, volatile_fid);
+ if (rc)
+ return rc;
+
+ rc = smb2_sendrcv2(xid, ses, &iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+
+ cFYI(1, "volinfo buftype %d rc %d status %d", resp_buftype, rc, status);
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2QUERY_INFO]);
+ goto qvolinf_exit;
+ }
+ pSMB2r = (struct query_info_rsp *)iov.iov_base;
+
+ pvol_inf = (struct fs_volume_info *)(4 /* RFC1001 len field */ +
+ le16_to_cpu(pSMB2r->OutputBufferOffset) + (char *)&pSMB2r->hdr);
+ rc = validate_buf(le16_to_cpu(pSMB2r->OutputBufferOffset),
+ le32_to_cpu(pSMB2r->OutputBufferLength),
+ &pSMB2r->hdr, sizeof(struct fs_volume_info));
+ if (rc)
+ goto qvolinf_exit;
+
+ tcon->vol_serial_number = le32_to_cpu(pvol_inf->VolumeSerialNumber);
+ tcon->vol_create_time = pvol_inf->VolumeCreationTime;
+qvolinf_exit:
+ free_rsp_buf(resp_buftype, iov.iov_base);
+ return rc;
+}
+
+int SMB2_QFS_attribute_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid)
+{
+ struct query_info_rsp *pSMB2r = NULL;
+ struct kvec iov;
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ unsigned int struct_len;
+ struct cifs_ses *ses = tcon->ses;
+ struct fs_attribute_info *pattr_inf = NULL;
+
+ rc = build_qfs_info_req(&iov, tcon, FS_ATTRIBUTE_INFORMATION,
+ sizeof(struct fs_attribute_info),
+ persistent_fid, volatile_fid);
+ if (rc)
+ return rc;
+
+ rc = smb2_sendrcv2(xid, ses, &iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "qfsattr buftype %d rc %d status %d", resp_buftype, rc, status);
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2QUERY_INFO]);
+ goto qfsattr_exit;
+ }
+ pSMB2r = (struct query_info_rsp *)iov.iov_base;
+
+ pattr_inf = (struct fs_attribute_info *)(4 /* RFC1001 len field */ +
+ le16_to_cpu(pSMB2r->OutputBufferOffset) + (char *)&pSMB2r->hdr);
+ struct_len = le16_to_cpu(pSMB2r->OutputBufferLength);
+ rc = validate_buf(le16_to_cpu(pSMB2r->OutputBufferOffset), struct_len,
+ &pSMB2r->hdr,
+ /* attr info includes a name so have to
+ make sure struct is at least big enough
+ for fixed portion */
+ sizeof(struct fs_attribute_info) - MAX_FS_NAME);
+ if (!rc) {
+ if (struct_len > sizeof(struct fs_attribute_info))
+ struct_len = sizeof(struct fs_attribute_info);
+ /* In case srv returned less than attr info, need to zero 1st */
+ memset(&tcon->fsAttrInfo, 0, sizeof(struct fs_attribute_info));
+ memcpy(&tcon->fsAttrInfo, pattr_inf, struct_len);
+ }
+
+qfsattr_exit:
+ free_rsp_buf(resp_buftype, iov.iov_base);
+
+ return rc;
+}
+
+int SMB2_QFS_device_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid)
+{
+ struct query_info_rsp *pSMB2r = NULL;
+ struct kvec iov;
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ struct cifs_ses *ses = tcon->ses;
+ struct fs_device_info *pdev_inf = NULL;
+
+ rc = build_qfs_info_req(&iov, tcon, FS_DEVICE_INFORMATION,
+ sizeof(struct fs_device_info),
+ persistent_fid, volatile_fid);
+ if (rc)
+ return rc;
+
+ rc = smb2_sendrcv2(xid, ses, &iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "qfsdev buftype %d rc %d status %d", resp_buftype, rc, status);
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2QUERY_INFO]);
+ goto qfsdev_exit;
+ }
+ pSMB2r = (struct query_info_rsp *)iov.iov_base;
+
+ pdev_inf = (struct fs_device_info *)(4 /* RFC1001 len field */ +
+ le16_to_cpu(pSMB2r->OutputBufferOffset) + (char *)&pSMB2r->hdr);
+ rc = validate_buf(le16_to_cpu(pSMB2r->OutputBufferOffset),
+ le32_to_cpu(pSMB2r->OutputBufferLength),
+ &pSMB2r->hdr, sizeof(struct fs_device_info));
+ if (!rc)
+ memcpy(&tcon->fsDevInfo, pdev_inf,
+ sizeof(struct fs_device_info));
+
+qfsdev_exit:
+ free_rsp_buf(resp_buftype, iov.iov_base);
+
+ return rc;
+}
+
+int SMB2_oplock_break(struct cifs_tcon *ptcon, __u64 netfid)
+{
+ /* BB FIXME BB */
+ return -EOPNOTSUPP;
+}
+
+int SMB2_query_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid,
+ FILE_ALL_INFO *pdata)
+{
+ struct query_info_req *pSMB2;
+ struct query_info_rsp *pSMB2r = NULL;
+ struct kvec iov[2];
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+
+ cFYI(1, "Query Info");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_QUERY_INFO, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->InfoType = SMB2_O_INFO_FILE;
+ pSMB2->FileInfoClass = FILE_ALL_INFORMATION;
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->InputBufferOffset = cpu_to_le16(sizeof(struct query_info_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+ pSMB2->OutputBufferLength = sizeof(FILE_ALL_INFO_SMB2)
+ + sizeof(struct query_info_rsp);
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4;
+
+ rc = smb2_sendrcv2(xid, ses, iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "qinfo buftype %d rc %d status %d", resp_buftype, rc, status);
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2QUERY_INFO]);
+ goto qinf_exit;
+ }
+ pSMB2r = (struct query_info_rsp *)iov[0].iov_base;
+
+ rc = validate_and_copy_buf(le16_to_cpu(pSMB2r->OutputBufferOffset),
+ le32_to_cpu(pSMB2r->OutputBufferLength),
+ &pSMB2r->hdr, sizeof(FILE_ALL_INFO_SMB2),
+ (char *)pdata);
+
+qinf_exit:
+ free_rsp_buf(resp_buftype, iov[0].iov_base);
+ return rc;
+}
+
+int SMB2_query_full_ea_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid,
+ char *pdata, int buf_len, int rsp_output_len,
+ struct kvec *iov, int n_vec, const char *prefix,
+ int prefix_len)
+{
+ struct query_info_req *pSMB2;
+ struct query_info_rsp *pSMB2r = NULL;
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+ int ret_value = iov[1].iov_len == 0;
+
+ cFYI(1, "Query Full EA Info");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_QUERY_INFO, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->InfoType = SMB2_O_INFO_FILE;
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->InputBufferLength = iov[1].iov_len;
+ pSMB2->InputBufferOffset =
+ cpu_to_le16(offsetof(struct query_info_req, Buffer) - 4);
+
+ if (rsp_output_len == 0) /* No hint output buffer size? */
+ pSMB2->OutputBufferLength =
+ sizeof(FILE_FULL_EA_INFO)*10*2;
+ else /* Hint to output buffer size given (plus some for metadata) */
+ pSMB2->OutputBufferLength =
+ sizeof(FILE_FULL_EA_INFO)*rsp_output_len*2;
+
+ iov[0].iov_base = (char *)pSMB2;
+
+ if (n_vec > 2) { /* Requesting specific attribute name */
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ + 4 - 1;
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ - 1 /*pad*/ + iov[1].iov_len + iov[2].iov_len);
+ pSMB2->FileInfoClass = FILE_FULL_EA_INFORMATION;
+ } else { /* Requesting list of attributes */
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4;
+ pSMB2->FileInfoClass = FILE_FULL_EA_INFORMATION;
+ }
+
+ rc = smb2_sendrcv2(xid, ses, iov, n_vec, &resp_buftype, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "qfulleainfo buftype %d rc %d status %d",
+ resp_buftype, rc, status);
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2QUERY_INFO]);
+ goto qinf_exit;
+ }
+
+ pSMB2r = (struct query_info_rsp *)iov[0].iov_base;
+ rc = validate_and_copy_ea_buf(ret_value,
+ le16_to_cpu(pSMB2r->OutputBufferOffset),
+ le32_to_cpu(pSMB2r->OutputBufferLength),
+ &pSMB2r->hdr, 8, pdata, buf_len,
+ (char *)iov[2].iov_base, prefix, prefix_len);
+qinf_exit:
+ free_rsp_buf(resp_buftype, iov[0].iov_base);
+ return rc;
+}
+
+/* BB Following two functions could merge to use common helper later */
+int SMB2_set_delete(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid)
+{
+ struct set_info_req *pSMB2;
+ struct set_info_rsp *pSMB2r = NULL;
+ struct kvec iov[1];
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+
+ cFYI(1, "Set Info");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_SET_INFO, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->InfoType = SMB2_O_INFO_FILE;
+ pSMB2->FileInfoClass = FILE_DISPOSITION_INFORMATION;
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->BufferOffset = cpu_to_le16(sizeof(struct set_info_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+ pSMB2->BufferLength = cpu_to_le32(1);
+ pSMB2->Buffer[0] = 1;
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4;
+
+ rc = smb2_sendrcv2(xid, ses, iov, 1, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "sinfo buftype %d rc %d status %d", resp_buftype, rc, status);
+ pSMB2r = (struct set_info_rsp *)iov[0].iov_base;
+
+ if (rc != 0) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2SET_INFO]);
+ goto set_delete_exit;
+ }
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto set_delete_exit;
+ }
+
+set_delete_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ return rc;
+}
+
+int SMB2_set_hardlink(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid, __le16 *target_file)
+{
+ struct set_info_req *pSMB2;
+ struct set_info_rsp *pSMB2r = NULL;
+ struct kvec iov[2];
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ int uni_path_len;
+ struct TCP_Server_Info *server;
+ struct FileLinkInformation *pfli;
+ struct cifs_ses *ses = tcon->ses;
+
+ cFYI(1, "Create hard link");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_SET_INFO, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->InfoType = SMB2_O_INFO_FILE;
+ pSMB2->FileInfoClass = FILE_LINK_INFORMATION;
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->BufferOffset = cpu_to_le16(sizeof(struct set_info_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+
+ uni_path_len = (2 * UniStrnlen(target_file, PATH_MAX)) + 2;
+ pSMB2->BufferOffset = cpu_to_le16(sizeof(struct set_info_req) - 1
+ /* pad */ - 4 /* do not count rfc1001 len field */);
+ pSMB2->BufferLength = cpu_to_le32(sizeof(struct FileLinkInformation) +
+ uni_path_len);
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4 - 1;
+ iov[0].iov_len += sizeof(struct FileLinkInformation);
+ iov[1].iov_base = target_file;
+ iov[1].iov_len = uni_path_len; /* This is two bytes more - includes
+ null - is it better to send without */
+
+ pfli = (struct FileLinkInformation *)pSMB2->Buffer;
+ pfli->ReplaceIfExists = 0; /* 1 = replace existing link with new */
+ /* 0 = fail if link already exists */
+ pfli->RootDirectory = 0; /* MBZ for network ops (why does spec say?) */
+ pfli->FileNameLength = cpu_to_le32(uni_path_len - 2);
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length) - 1 +
+ sizeof(struct FileLinkInformation) + uni_path_len);
+
+ rc = smb2_sendrcv2(xid, ses, iov, 2, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "sinfo buftype %d rc %d status %d", resp_buftype, rc, status);
+ pSMB2r = (struct set_info_rsp *)iov[0].iov_base;
+
+ if (rc != 0) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2SET_INFO]);
+ goto set_link_exit;
+ }
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto set_link_exit;
+ }
+
+set_link_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ return rc;
+}
+
+int SMB2_rename(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid, __le16 *target_file)
+{
+ struct set_info_req *pSMB2;
+ struct set_info_rsp *pSMB2r = NULL;
+ struct kvec iov[2];
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ int uni_path_len;
+ struct TCP_Server_Info *server;
+ struct FileRenameInformation *pfli;
+ struct cifs_ses *ses = tcon->ses;
+
+ cFYI(1, "rename");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_SET_INFO, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->InfoType = SMB2_O_INFO_FILE;
+ pSMB2->FileInfoClass = FILE_RENAME_INFORMATION;
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->BufferOffset = cpu_to_le16(sizeof(struct set_info_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+
+ uni_path_len = (2 * UniStrnlen(target_file, PATH_MAX)) + 2;
+ pSMB2->BufferOffset = cpu_to_le16(sizeof(struct set_info_req) - 1
+ /* pad */ - 4 /* do not count rfc1001 len field */);
+ pSMB2->BufferLength = cpu_to_le32(sizeof(struct FileRenameInformation) +
+ uni_path_len);
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4 - 1;
+ iov[0].iov_len += sizeof(struct FileRenameInformation);
+ iov[1].iov_base = target_file;
+ iov[1].iov_len = uni_path_len; /* This is two bytes more - includes
+ null - is it better to send without */
+
+ pfli = (struct FileRenameInformation *)pSMB2->Buffer;
+ pfli->ReplaceIfExists = 0; /* 1 = replace existing link with new */
+ /* 0 = fail if link already exists */
+ pfli->RootDirectory = 0; /* MBZ for network ops (why does spec say?) */
+ pfli->FileNameLength = cpu_to_le32(uni_path_len - 2);
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length) - 1 +
+ sizeof(struct FileRenameInformation) + uni_path_len);
+
+ rc = smb2_sendrcv2(xid, ses, iov, 2, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ pSMB2r = (struct set_info_rsp *)iov[0].iov_base;
+
+ if (rc != 0) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2SET_INFO]);
+ goto rename_exit;
+ }
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto rename_exit;
+ }
+
+rename_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ return rc;
+}
+
+int SMB2_set_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid,
+ FILE_BASIC_INFO *pdata)
+{
+ struct set_info_req *pSMB2;
+ struct set_info_rsp *pSMB2r = NULL;
+ struct kvec iov[2];
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+
+ cFYI(1, "Set Info");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ if (pdata == NULL)
+ return -EINVAL;
+
+ rc = small_smb2_init(SMB2_SET_INFO, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->InfoType = SMB2_O_INFO_FILE;
+ pSMB2->FileInfoClass = FILE_BASIC_INFORMATION;
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->BufferOffset = cpu_to_le16(sizeof(struct set_info_req)
+ - 1 /* pad */ - 4 /* do not count rfc1001 len field */);
+ pSMB2->BufferLength = cpu_to_le32(sizeof(FILE_BASIC_INFO));
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4 - 1;
+
+ iov[1].iov_base = pdata;
+ iov[1].iov_len = sizeof(FILE_BASIC_INFO);
+
+ pSMB2->hdr.smb2_buf_length = cpu_to_be32(be32_to_cpu(
+ pSMB2->hdr.smb2_buf_length) + sizeof(FILE_BASIC_INFO) - 1);
+ rc = smb2_sendrcv2(xid, ses, iov, 2, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ cFYI(1, "sinfo buftype %d rc %d status %d", resp_buftype, rc, status);
+ pSMB2r = (struct set_info_rsp *)iov[0].iov_base;
+
+ if (rc != 0) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2SET_INFO]);
+ goto set_info_exit;
+ }
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto set_info_exit;
+ }
+
+set_info_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ return rc;
+}
+
+int SMB2_set_ea_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid, struct kvec iov[4])
+{
+ struct set_info_req *pSMB2;
+ struct set_info_rsp *pSMB2r = NULL;
+ int rc = 0;
+ int resp_buftype;
+ int status;
+ struct TCP_Server_Info *server;
+ struct cifs_ses *ses = tcon->ses;
+
+ cFYI(1, "set_ea_info");
+
+ if (ses && (ses->server))
+ server = ses->server;
+ else
+ return -EIO;
+
+ rc = small_smb2_init(SMB2_SET_INFO, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ pSMB2->InfoType = SMB2_O_INFO_FILE;
+ pSMB2->FileInfoClass = FILE_FULL_EA_INFORMATION;
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+
+ pSMB2->BufferOffset = cpu_to_le16(sizeof(struct set_info_req) - 1
+ /* pad */ - 4 /* rfc1001 len field */);
+ pSMB2->BufferLength = cpu_to_le32(sizeof(FILE_FULL_EA_INFO) - 2 +
+ iov[2].iov_len /* name */
+ + iov[3].iov_len /* value */);
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4 - 1;
+
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ - 1 /*pad*/ + iov[1].iov_len + iov[2].iov_len
+ + iov[3].iov_len);
+
+ rc = smb2_sendrcv2(xid, ses, iov, 4, &resp_buftype /* ret */, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ pSMB2r = (struct set_info_rsp *)iov[0].iov_base;
+
+ if (rc != 0) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2SET_INFO]);
+ goto rename_exit;
+ }
+
+ if (pSMB2r == NULL) {
+ rc = -EIO;
+ goto rename_exit;
+ }
+
+rename_exit:
+ free_rsp_buf(resp_buftype, pSMB2r);
+ return rc;
+}
+
+/* To form a chain of read requests, any read requests after the
+ * first should have the end_of_chain boolean set to true. */
+int new_read_req(struct kvec *iov, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid,
+ const unsigned int count, const __u64 lseek,
+ unsigned int remaining_bytes,
+ int request_type)
+{
+ int rc = -EACCES;
+ struct read_req *pSMB2 = NULL;
+
+ rc = small_smb2_init(SMB2_READ, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+ if (tcon->ses->server == NULL)
+ return -ECONNABORTED;
+
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->ReadChannelInfoOffset = 0; /* reserved */
+ pSMB2->ReadChannelInfoLength = 0; /* reserved */
+ pSMB2->Channel = 0; /* reserved */
+ pSMB2->MinimumCount = 0;
+ pSMB2->Length = cpu_to_le32(count);
+ pSMB2->Offset = cpu_to_le64(lseek);
+
+ if (request_type & CHAINED_REQUEST) {
+ if (!(request_type & END_OF_CHAIN)) {
+ pSMB2->hdr.NextCommand =
+ be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4;
+ } else /* END_OF_CHAIN */
+ pSMB2->hdr.NextCommand = 0;
+ if (request_type & RELATED_REQUEST) {
+ pSMB2->hdr.Flags |= SMB2_FLAGS_RELATED_OPERATIONS;
+ /* related requests use info from previous
+ * read request in chain. */
+ pSMB2->hdr.SessionId = 0xFFFFFFFF;
+ pSMB2->hdr.TreeId = 0xFFFFFFFF;
+ pSMB2->PersistentFileId = 0xFFFFFFFF;
+ pSMB2->VolatileFileId = 0xFFFFFFFF;
+ }
+ }
+ if (remaining_bytes > count)
+ pSMB2->RemainingBytes = cpu_to_le32(remaining_bytes);
+ else
+ pSMB2->RemainingBytes = 0;
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4;
+ return rc;
+}
+
+int SMB2_read(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid,
+ const unsigned int count, const __u64 lseek,
+ unsigned int *nbytes, char **buf, int *pbuf_type,
+ unsigned int remaining_bytes)
+{
+ int status, resp_buftype, rc = -EACCES;
+ struct read_rsp *pSMB2r = NULL;
+ struct kvec iov[1];
+
+ *nbytes = 0;
+ rc = new_read_req(iov, tcon, persistent_fid, volatile_fid,
+ count, lseek, remaining_bytes, 0);
+ if (rc)
+ return rc;
+ rc = smb2_sendrcv2(xid, tcon->ses, iov, 1,
+ &resp_buftype, &status,
+ CIFS_STD_OP | CIFS_LOG_ERROR);
+ if (status == STATUS_END_OF_FILE) {
+ free_rsp_buf(resp_buftype, iov[0].iov_base);
+ return 0;
+ }
+
+ cFYI(1, "read returned buftype %d with rc %d status 0x%x",
+ resp_buftype, rc, status);
+
+ pSMB2r = (struct read_rsp *)iov[0].iov_base;
+
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2READ]);
+ cERROR(1, "Send error in read = %d", rc);
+ } else {
+ *nbytes = le32_to_cpu(pSMB2r->DataLength);
+ if ((*nbytes > SMB2_MAX_MSGSIZE)
+ || (*nbytes > count)) {
+ cFYI(1, "bad length %d for count %d",
+ *nbytes, count);
+ rc = -EIO;
+ *nbytes = 0;
+ }
+ }
+ if (resp_buftype != CIFS_NO_BUFFER) {
+ *buf = iov[0].iov_base;
+ if (resp_buftype == CIFS_SMALL_BUFFER)
+ *pbuf_type = CIFS_SMALL_BUFFER;
+ else if (resp_buftype == CIFS_LARGE_BUFFER)
+ *pbuf_type = CIFS_LARGE_BUFFER;
+ }
+ return rc;
+}
+
+/* SMB2_write function gets iov pointer to kvec array with n_vec as a length.
+ The length must be at least 2 because the first element of the array is
+ SMB2 header. Other elements contain a data to write, its length is specified
+ by count. */
+int SMB2_write(const int xid, struct cifs_tcon *tcon,
+ const u64 persistent_fid, const u64 volatile_fid,
+ const unsigned int count, const __u64 lseek,
+ unsigned int *nbytes, struct kvec *iov, int n_vec,
+ const unsigned int remaining_bytes, int wtimeout)
+{
+ int rc = 0;
+ struct write_req *pSMB2 = NULL;
+ struct write_rsp *pSMB2r = NULL;
+ int status, resp_buftype;
+ *nbytes = 0;
+
+ if (n_vec < 2)
+ return rc;
+
+ rc = small_smb2_init(SMB2_WRITE, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ if (tcon->ses->server == NULL)
+ return -ECONNABORTED;
+
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->WriteChannelInfoOffset = 0;
+ pSMB2->WriteChannelInfoLength = 0;
+ pSMB2->Channel = 0;
+ pSMB2->Length = cpu_to_le32(count);
+ pSMB2->Offset = cpu_to_le64(lseek);
+ pSMB2->DataOffset = cpu_to_le16(offsetof(struct write_req, Buffer) - 4);
+ pSMB2->RemainingBytes = 0;
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4 - 1;
+
+ /* length of entire message including data to be written */
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ - 1 /* pad */ + count);
+
+ rc = smb2_sendrcv2(xid, tcon->ses, iov, n_vec, &resp_buftype, &status,
+ wtimeout | CIFS_LOG_ERROR);
+
+ cFYI(1, "write returned buftype %d with rc %d status 0x%x",
+ resp_buftype, rc, status);
+
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2WRITE]);
+ cERROR(1, "Send error in write = %d", rc);
+ } else {
+ pSMB2r = (struct write_rsp *)iov[0].iov_base;
+ *nbytes = le32_to_cpu(pSMB2r->DataLength);
+ free_rsp_buf(resp_buftype, pSMB2r);
+ }
+ return rc;
+}
+
+/* SMB2_write_complex function gets iov pointer to kvec array with n_vec as a
+ length. The length must be at least 2 because the first element of the array
+ is SMB2 header. Other elements contain a data to write, its length is
+ specified by count. */
+int SMB2_write_complex(const int xid, struct cifs_tcon *tcon,
+ const u64 persistent_fid, const u64 volatile_fid,
+ const unsigned int count, const __u64 lseek,
+ unsigned int *nbytes, struct kvec *iov, int n_vec,
+ const unsigned int remaining_bytes, struct mid_q_entry **mid,
+ const unsigned int size)
+{
+ int rc = 0;
+ struct write_req *pSMB2 = NULL;
+ struct write_rsp *pSMB2r = NULL;
+ int status, resp_buftype;
+ *nbytes = 0;
+
+ if (n_vec < 2)
+ return rc;
+
+ rc = small_smb2_init(SMB2_WRITE, tcon, (void **) &pSMB2);
+ if (rc)
+ return rc;
+
+ if (tcon->ses->server == NULL)
+ return -ECONNABORTED;
+
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+ pSMB2->WriteChannelInfoOffset = 0;
+ pSMB2->WriteChannelInfoLength = 0;
+ pSMB2->Channel = 0;
+ pSMB2->Length = cpu_to_le32(count);
+ pSMB2->Offset = cpu_to_le64(lseek);
+ pSMB2->DataOffset = cpu_to_le16(offsetof(struct write_req, Buffer) - 4);
+ pSMB2->RemainingBytes = 0;
+
+ iov[0].iov_base = (char *)pSMB2;
+ iov[0].iov_len = be32_to_cpu(pSMB2->hdr.smb2_buf_length) + 4 - 1;
+
+ /* length of entire message including data to be written */
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ - 1 /* pad */ + count);
+
+ rc = smb2_send_complex(xid, tcon->ses, iov, n_vec, &resp_buftype,
+ &status, mid, size);
+
+ cFYI(1, "write returned buftype %d with rc %d status 0x%x",
+ resp_buftype, rc, status);
+
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2WRITE]);
+ cERROR(1, "Send error in write = %d", rc);
+ } else {
+ pSMB2r = (struct write_rsp *)iov[0].iov_base;
+ *nbytes = le32_to_cpu(pSMB2r->DataLength);
+ free_rsp_buf(resp_buftype, pSMB2r);
+ }
+
+ return rc;
+}
+
+int SMB2_lock(const int xid, struct cifs_tcon *tcon,
+ const u64 persistent_fid, const u64 volatile_fid,
+ u64 length, u64 offset, u32 lockFlags, int wait)
+{
+ int rc = 0;
+ struct lock_req *pSMB2 = NULL;
+/* lock_rsp *pSMB2r = NULL; */ /* No resp data other than rc to parse */
+ int pbytes_returned;
+ int timeout = 0;
+
+ cFYI(1, "SMB2_lock timeout %d numLock %d", wait, 1);
+ rc = small_smb2_init(SMB2_LOCK, tcon, (void **) &pSMB2);
+
+ if (rc)
+ return rc;
+
+ if (wait)
+ timeout = CIFS_BLOCKING_OP; /* blocking operation, no timeout */
+
+ pSMB2->LockCount = 1;
+
+ pSMB2->PersistentFileId = persistent_fid;
+ pSMB2->VolatileFileId = volatile_fid;
+
+ pSMB2->locks[0].Length = length;
+ pSMB2->locks[0].Offset = offset;
+ pSMB2->locks[0].Flags = lockFlags;
+
+ pSMB2->hdr.smb2_buf_length =
+ cpu_to_be32(be32_to_cpu(pSMB2->hdr.smb2_buf_length)
+ - 1 /* pad */ + sizeof(struct smb2_lock_element));
+
+ if (wait) {
+ rc = smb2_sendrcv_blocking(xid, tcon,
+ (struct smb2_hdr *)pSMB2,
+ (struct smb2_hdr *)pSMB2,
+ &pbytes_returned);
+
+ } else {
+ rc = smb2_sendrcv_norsp(xid, tcon->ses,
+ (struct smb2_hdr *)pSMB2, timeout);
+ /* SMB2 buffer freed by function above */
+ }
+ if (rc) {
+ cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2LOCK]);
+ cFYI(1, "Send error in Lock = %d", rc);
+ }
+
+ /* Note: On -EAGAIN error only caller can retry on handle based calls
+ since file handle passed in no longer valid */
+ return rc;
+}
+
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
new file mode 100644
index 000000000000..a926fd195100
--- /dev/null
+++ b/fs/cifs/smb2pdu.h
@@ -0,0 +1,996 @@
+/*
+ * fs/cifs/smb2pdu.h
+ *
+ * Copyright (c) International Business Machines Corp., 2009, 2010
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _SMB2PDU_H
+#define _SMB2PDU_H
+
+#include <net/sock.h>
+
+#define SMB2_PORT 445
+#define RFC1001_PORT 139
+
+/*
+ * Note that, due to trying to use names similar to the protocol specifications,
+ * there are many mixed case field names in the structures below. Although
+ * this does not match typical Linux kernel style, it is necessary to be
+ * be able to match against the protocol specfication.
+ *
+ * SMB2 commands
+ * Some commands have minimal (wct=0,bcc=0), or uninteresting, responses
+ * (ie no useful data other than the SMB error code itself) and are marked such
+ * Knowing this helps avoid response buffer allocations and copy in some cases
+ */
+
+/* List is sent on wire as little endian */
+#define SMB2_NEGOTIATE cpu_to_le16(0x0000)
+#define SMB2_SESSION_SETUP cpu_to_le16(0x0001)
+#define SMB2_LOGOFF cpu_to_le16(0x0002) /* trivial request/resp */
+#define SMB2_TREE_CONNECT cpu_to_le16(0x0003)
+#define SMB2_TREE_DISCONNECT cpu_to_le16(0x0004) /* trivial req/resp */
+#define SMB2_CREATE cpu_to_le16(0x0005)
+#define SMB2_CLOSE cpu_to_le16(0x0006)
+#define SMB2_FLUSH cpu_to_le16(0x0007) /* trivial resp */
+#define SMB2_READ cpu_to_le16(0x0008)
+#define SMB2_WRITE cpu_to_le16(0x0009)
+#define SMB2_LOCK cpu_to_le16(0x000A)
+#define SMB2_IOCTL cpu_to_le16(0x000B)
+#define SMB2_CANCEL cpu_to_le16(0x000C)
+#define SMB2_ECHO cpu_to_le16(0x000D)
+#define SMB2_QUERY_DIRECTORY cpu_to_le16(0x000E)
+#define SMB2_CHANGE_NOTIFY cpu_to_le16(0x000F)
+#define SMB2_QUERY_INFO cpu_to_le16(0x0010)
+#define SMB2_SET_INFO cpu_to_le16(0x0011)
+#define SMB2_OPLOCK_BREAK cpu_to_le16(0x0012)
+
+/* Same List of commands in host endian */
+#define SMB2NEGOTIATE 0x0000
+#define SMB2SESSION_SETUP 0x0001
+#define SMB2LOGOFF 0x0002 /* trivial request/resp */
+#define SMB2TREE_CONNECT 0x0003
+#define SMB2TREE_DISCONNECT 0x0004 /* trivial req/resp */
+#define SMB2CREATE 0x0005
+#define SMB2CLOSE 0x0006
+#define SMB2FLUSH 0x0007 /* trivial resp */
+#define SMB2READ 0x0008
+#define SMB2WRITE 0x0009
+#define SMB2LOCK 0x000A
+#define SMB2IOCTL 0x000B
+#define SMB2CANCEL 0x000C
+#define SMB2ECHO 0x000D
+#define SMB2QUERY_DIRECTORY 0x000E
+#define SMB2CHANGE_NOTIFY 0x000F
+#define SMB2QUERY_INFO 0x0010
+#define SMB2SET_INFO 0x0011
+#define SMB2OPLOCK_BREAK 0x0012
+
+#define NUMBER_OF_SMB2_COMMANDS 0x0013
+
+/* BB FIXME - analyze following three length fields BB */
+#define MAX_SMB2_SMALL_BUFFER_SIZE 460 /* big enough for most */
+#define MAX_SMB2_HDR_SIZE 0x78 /* 4 len + 64 hdr + (2*24 wct) + 2 bct + 2 pad */
+#define SMB2_SMALL_PATH 112 /* allows for one fewer than (460-120)/3 */
+
+/* File Attrubutes */
+
+#define FILE_ATTRIBUTE_READONLY 0x00000001
+#define FILE_ATTRIBUTE_HIDDEN 0x00000002
+#define FILE_ATTRIBUTE_SYSTEM 0x00000004
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
+#define FILE_ATTRIBUTE_NORMAL 0x00000080
+#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
+#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
+#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
+#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
+#define FILE_ATTRIBUTE_OFFLINE 0x00001000
+#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
+#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
+
+/*
+ * SMB2 flag definitions
+ */
+
+#define SMB2FLG_RESPONSE 0x0001 /* this PDU is a response from server */
+
+/*
+ * SMB2 Header Definition
+ *
+ * "MBZ" : Must be Zero
+ * "BB" : BugBug, Something to check/review/analyze later
+ * "PDU" : "Protocol Data Unit" (ie a network "frame")
+ *
+ */
+struct smb2_hdr {
+ __be32 smb2_buf_length; /* big endian on wire */
+ /* length is only two or three bytes - with
+ one or two byte type preceding it that MBZ */
+ __u8 ProtocolId[4]; /* 0xFE 'S' 'M' 'B' */
+ __le16 StructureSize; /* 64 */
+ __le16 CreditCharge; /* MBZ */
+ __le32 Status; /* Error from server */
+ __le16 Command;
+ __le16 CreditRequest; /* CreditResponse */
+ __le32 Flags;
+ __le32 NextCommand;
+ __u64 MessageId; /* opaque - so can stay little endian */
+ __le32 ProcessId;
+ __u32 TreeId; /* opaque - so do not make little endian */
+ __u64 SessionId; /* opaque - so do not make little endian */
+ __u8 Signature[16];
+ /* Usually followed by __le16 StructureSize of request or response
+ structure which follows */
+} __attribute__((packed));
+
+struct smb2_async_hdr {
+ __be32 smb2_buf_length; /* big endian on wire */
+ /* length is only two or three bytes - with
+ one or two byte type preceding it that MBZ */
+ __u8 ProtocolId[4]; /* 0xFE 'S' 'M' 'B' */
+ __le16 StructureSize; /* 64 */
+ __le16 CreditCharge; /* MBZ */
+ __le32 Status; /* Error from server */
+ __le16 Command;
+ __le16 CreditResponse;
+ __le32 Flags;
+ __le32 NextCommand;
+ __u64 MessageId; /* opaque - so can stay little endian */
+ __u64 AsyncId;
+ __u64 SessionId; /* opaque - so do not make little endian */
+ __u8 Signature[16];
+ /* Usually followed by __le16 StructureSize of request or response
+ structure which follows */
+} __attribute__((packed));
+
+struct smb2_pdu {
+ struct smb2_hdr hdr;
+ __le16 StructureSize2; /* size of wct area (varies, request specific) */
+} __attribute__((packed));
+
+/*
+ * SMB2 flag definitions
+ */
+#define SMB2_FLAGS_SERVER_TO_REDIR cpu_to_le32(0x00000001) /* Response */
+#define SMB2_FLAGS_ASYNC_COMMAND cpu_to_le32(0x00000002)
+#define SMB2_FLAGS_RELATED_OPERATIONS cpu_to_le32(0x00000004)
+#define SMB2_FLAGS_SIGNED cpu_to_le32(0x00000008)
+#define SMB2_FLAGS_DFS_OPERATIONS cpu_to_le32(0x10000000)
+
+/*
+ * Definitions for SMB2 Protocol Data Units (network frames)
+ *
+ * See MS-SMB2.PDF specification for protocol details.
+ * The Naming convention is the lower case version of the SMB2
+ * command code name for the struct. Note that structures must be packed.
+ *
+ */
+struct smb2_err_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize;
+ __le16 Reserved; /* MBZ */
+ __le32 ByteCount; /* even if zero, at least one byte follows */
+ __u8 ErrorData[1]; /* variable length */
+} __attribute__((packed));
+
+/* Symlink error response for error STATUS_STOPPED_ON_SYMLINK
+ Following is the ErrorData structure */
+struct symlink_err_data {
+ __le32 SymLinkLength;
+ __le32 SymLinkErrorTag;
+ __le32 ReparseTag;
+ __le16 ReparseDataLength;
+ __le16 Reserved; /* MBZ */
+ __le16 SubstituteNameOffset;
+ __le16 SubstituteNameLength;
+ __le16 PrintNameOffset;
+ __le16 PrintNameLength;
+ __le32 Flags;
+ __u8 PathBuffer[0]; /* variable length */
+} __attribute__((packed));
+
+struct smb2_negotiate_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 36 */
+ __le16 DialectCount;
+ __le16 SecurityMode;
+ __le16 Reserved; /* MBZ */
+ __le32 Capabilities;
+ __u8 ClientGUID[16]; /* MBZ */
+ __le64 ClientStartTime; /* MBZ */
+ __le16 Dialects[2]; /* variable length */ /* Must include 0x0202 */
+} __attribute__((packed));
+/* SecurityMode flags */
+#define SMB2_NEGOTIATE_SIGNING_ENABLED 0x0001
+#define SMB2_NEGOTIATE_SIGNING_REQUIRED 0x0002
+/* Capabilities flags */
+#define SMB2_GLOBAL_CAP_DFS 0x00000001
+#define SMB2_GLOBAL_CAP_LEASING 0x00000002 /* Resp only New to SMB2.1 */
+#define SMB2_GLOBAL_CAP_LARGE_MTU 0X00000004 /* Resp only New to SMB2.1 */
+
+struct smb2_negotiate_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 65 */
+ __le16 SecurityMode;
+ __le16 DialectRevision; /* Should be 0x0202 */
+ __le16 Reserved; /* MBZ */
+ __u8 ServerGUID[16];
+ __le32 Capabilities;
+ __le32 MaxTransactSize;
+ __le32 MaxReadSize;
+ __le32 MaxWriteSize;
+ __le64 SystemTime; /* MBZ */
+ __le64 ServerStartTime;
+ __le16 SecurityBufferOffset;
+ __le16 SecurityBufferLength;
+ __le32 Reserved2; /* may be any value, Ignore */
+ __u8 Buffer[1]; /* variable length GSS security buffer */
+} __attribute__((packed));
+
+struct sess_setup_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 25 */
+ __u8 VcNumber;
+ __u8 SecurityMode;
+ __le32 Capabilities;
+ __le32 Channel;
+ __le16 SecurityBufferOffset;
+ __le16 SecurityBufferLength;
+ __le64 PreviousSessionId;
+ __u8 Buffer[1]; /* variable length GSS security buffer */
+} __attribute__((packed));
+
+/* Currently defined SessionFlags */
+#define SMB2_SESSION_FLAG_IS_GUEST 0x0001
+#define SMB2_SESSION_FLAG_IS_NULL 0x0002
+struct sess_setup_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 9 */
+ __le16 SessionFlags;
+ __le16 SecurityBufferOffset;
+ __le16 SecurityBufferLength;
+ __u8 Buffer[1]; /* variable length GSS security buffer */
+} __attribute__((packed));
+
+struct logoff_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __le16 Reserved;
+} __attribute__((packed));
+
+struct logoff_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __le16 Reserved;
+} __attribute__((packed));
+
+struct tree_connect_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 9 */
+ __le16 Reserved;
+ __le16 PathOffset;
+ __le16 PathLength;
+ __u8 Buffer[1]; /* variable length */
+} __attribute__((packed));
+
+struct tree_connect_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 16 */
+ __u8 ShareType; /* see below */
+ __u8 Reserved;
+ __le32 ShareFlags; /* see below */
+ __le32 Capabilities; /* see below */
+ __le32 MaximalAccess;
+} __attribute__((packed));
+
+/* Possible ShareType values */
+#define SMB2_SHARE_TYPE_DISK 0x01
+#define SMB2_SHARE_TYPE_PIPE 0x02
+#define SMB2_SHARE_TYPE_PRINT 0x03
+
+/* Possible ShareFlags - exactly one and only one of the first 4 caching flags
+ must be set (any of the remaining, SHI1005, flags may be set individually
+ or in combination */
+#define SMB2_SHAREFLAG_MANUAL_CACHING 0x00000000
+#define SMB2_SHAREFLAG_AUTO_CACHING 0x00000010
+#define SMB2_SHAREFLAG_VDO_CACHING 0x00000020
+#define SMB2_SHAREFLAG_NO_CACHING 0x00000030
+#define SHI1005_FLAGS_DFS 0x00000001
+#define SHI1005_FLAGS_DFS_ROOT 0x00000002
+#define SHI1005_FLAGS_RESTRICT_EXCLUSIVE_OPENS 0x00000100
+#define SHI1005_FLAGS_FORCE_SHARED_DELETE 0x00000200
+#define SHI1005_FLAGS_ALLOW_NAMESPACE_CACHING 0x00000400
+#define SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM 0x00000800
+#define SHI1005_FLAGS_FORCE_LEVELII_OPLOCK 0x00001000
+#define SHI1005_FLAGS_ENABLE_HASH 0x00002000
+
+/* Possible share capabilities */
+#define SMB2_SHARE_CAP_DFS cpu_to_le32(0x00000008)
+
+struct tree_disconnect_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __le16 Reserved;
+} __attribute__((packed));
+
+struct tree_disconnect_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __le16 Reserved;
+} __attribute__((packed));
+
+/* Oplock levels */
+#define SMB2_OPLOCK_LEVEL_NONE 0x00
+#define SMB2_OPLOCK_LEVEL_II 0x01
+#define SMB2_OPLOCK_LEVEL_EXCLUSIVE 0x08
+#define SMB2_OPLOCK_LEVEL_BATCH 0x09
+#define SMB2_OPLOCK_LEVEL_LEASE 0xFF
+
+/* Desired Access Flags */
+#define FILE_READ_DATA_LE cpu_to_le32(0x00000001)
+#define FILE_WRITE_DATA_LE cpu_to_le32(0x00000002)
+#define FILE_APPEND_DATA_LE cpu_to_le32(0x00000004)
+#define FILE_READ_EA_LE cpu_to_le32(0x00000008)
+#define FILE_WRITE_EA_LE cpu_to_le32(0x00000010)
+#define FILE_EXECUTE_LE cpu_to_le32(0x00000020)
+#define FILE_READ_ATTRIBUTES_LE cpu_to_le32(0x00000080)
+#define FILE_WRITE_ATTRIBUTES_LE cpu_to_le32(0x00000100)
+#define FILE_DELETE_LE cpu_to_le32(0x00010000)
+#define FILE_READ_CONTROL_LE cpu_to_le32(0x00020000)
+#define FILE_WRITE_DAC_LE cpu_to_le32(0x00040000)
+#define FILE_WRITE_OWNER_LE cpu_to_le32(0x00080000)
+#define FILE_SYNCHRONIZE_LE cpu_to_le32(0x00100000)
+#define FILE_ACCESS_SYSTEM_SECURITY_LE cpu_to_le32(0x01000000)
+#define FILE_MAXIMAL_ACCESS_LE cpu_to_le32(0x02000000)
+#define FILE_GENERIC_ALL_LE cpu_to_le32(0x10000000)
+#define FILE_GENERIC_EXECUTE_LE cpu_to_le32(0x20000000)
+#define FILE_GENERIC_WRITE_LE cpu_to_le32(0x40000000)
+#define FILE_GENERIC_READ_LE cpu_to_le32(0x80000000)
+
+/* ShareAccess Flags */
+#define FILE_SHARE_READ_LE cpu_to_le32(0x00000001)
+#define FILE_SHARE_WRITE_LE cpu_to_le32(0x00000002)
+#define FILE_SHARE_DELETE_LE cpu_to_le32(0x00000004)
+#define FILE_SHARE_ALL_LE cpu_to_le32(0x00000007)
+
+/* CreateDisposition Flags */
+#define FILE_SUPERSEDE_LE cpu_to_le32(0x00000000)
+#define FILE_OPEN_LE cpu_to_le32(0x00000001)
+#define FILE_CREATE_LE cpu_to_le32(0x00000002)
+#define FILE_OPEN_IF_LE cpu_to_le32(0x00000003)
+#define FILE_OVERWRITE_LE cpu_to_le32(0x00000004)
+#define FILE_OVERWRITE_IF_LE cpu_to_le32(0x00000005)
+
+/* CreateOptions Flags */
+#define FILE_DIRECTORY_FILE_LE cpu_to_le32(0x00000001)
+#define FILE_WRITE_THROUGH_LE cpu_to_le32(0x00000002)
+#define FILE_SEQUENTIAL_ONLY_LE cpu_to_le32(0x00000004)
+#define FILE_NO_INTERMEDIATE_BUFFERRING_LE cpu_to_le32(0x00000008)
+#define FILE_SYNCHRONOUS_IO_ALERT_LE cpu_to_le32(0x00000010)
+#define FILE_SYNCHRONOUS_IO_NON_ALERT_LE cpu_to_le32(0x00000020)
+#define FILE_NON_DIRECTORY_FILE_LE cpu_to_le32(0x00000040)
+#define FILE_COMPLETE_IF_OPLOCKED_LE cpu_to_le32(0x00000100)
+#define FILE_NO_EA_KNOWLEDGE_LE cpu_to_le32(0x00000200)
+#define FILE_RANDOM_ACCESS_LE cpu_to_le32(0x00000800)
+#define FILE_DELETE_ON_CLOSE_LE cpu_to_le32(0x00001000)
+#define FILE_OPEN_BY_FILE_ID_LE cpu_to_le32(0x00002000)
+#define FILE_OPEN_FOR_BACKUP_INTENT_LE cpu_to_le32(0x00004000)
+#define FILE_NO_COMPRESSION_LE cpu_to_le32(0x00008000)
+#define FILE_RESERVE_OPFILTER_LE cpu_to_le32(0x00100000)
+#define FILE_OPEN_REPARSE_POINT_LE cpu_to_le32(0x00200000)
+#define FILE_OPEN_NO_RECALL_LE cpu_to_le32(0x00400000)
+#define FILE_OPEN_FOR_FREE_SPACE_QUERY_LE cpu_to_le32(0x00800000)
+
+#define FILE_READ_RIGHTS_LE (FILE_READ_DATA_LE | FILE_READ_EA_LE \
+ | FILE_READ_ATTRIBUTES_LE)
+#define FILE_WRITE_RIGHTS_LE (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE \
+ | FILE_WRITE_EA_LE | FILE_WRITE_ATTRIBUTES_LE)
+#define FILE_EXEC_RIGHTS_LE (FILE_EXECUTE_LE)
+
+/* Impersonation Levels */
+#define IL_ANONYMOUS cpu_to_le32(0x00000000)
+#define IL_IDENTIFICATION cpu_to_le32(0x00000001)
+#define IL_IMPERSONATION cpu_to_le32(0x00000002)
+#define IL_DELEGATE cpu_to_le32(0x00000003)
+
+/* Create Context Values */
+#define SMB2_CREATE_EA_BUFFER "ExtA" /* extended attributes */
+#define SMB2_CREATE_SD_BUFFER "SecD" /* security descriptor */
+#define SMB2_CREATE_DURABLE_HANDLE_REQUEST "DHnQ"
+#define SMB2_CREATE_DURABLE_HANDLE_RECONNECT "DHnC"
+#define SMB2_CREATE_ALLOCATION_SIZE "AlSi"
+#define SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST "MxAc"
+#define SMB2_CREATE_TIMEWARP_REQUEST "TWrp"
+#define SMB2_CREATE_QUERY_ON_DISK_ID "QFid"
+#define SMB2_CREATE_REQUEST_LEASE "RqLs"
+
+struct create_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 57 */
+ __u8 SecurityFlags;
+ __u8 RequestedOplockLevel;
+ __le32 ImpersonationLevel;
+ __le64 SmbCreateFlags;
+ __le64 Reserved;
+ __le32 DesiredAccess;
+ __le32 FileAttributes;
+ __le32 ShareAccess;
+ __le32 CreateDisposition;
+ __le32 CreateOptions;
+ __le16 NameOffset;
+ __le16 NameLength;
+ __le32 CreateContextsOffset;
+ __le32 CreateContextsLength;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+struct create_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 89 */
+ __u8 OplockLevel;
+ __u8 Reserved;
+ __le32 CreateAction;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 AllocationSize;
+ __le64 EndofFile;
+ __le32 FileAttributes;
+ __le32 Reserved2;
+ __u64 PersistentFileId; /* opaque endianness */
+ __u64 VolatileFileId; /* opaque endianness */
+ __le32 CreateContextsOffset;
+ __le32 CreateContextsLength;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+/* Currently defined values for close flags */
+#define SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB cpu_to_le16(0x0001)
+struct close_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 24 */
+ __le16 Flags;
+ __le32 Reserved;
+ __u64 PersistentFileId; /* opaque endianness */
+ __u64 VolatileFileId; /* opaque endianness */
+} __attribute__((packed));
+
+struct close_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* 60 */
+ __le16 Flags;
+ __le32 Reserved;
+ __le64 CreationTime;
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le64 AllocationSize; /* Beginning of FILE_STANDARD_INFO equivalent */
+ __le64 EndOfFile;
+ __le32 Attributes;
+} __attribute__((packed));
+
+struct flush_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 24 */
+ __le16 Reserved1;
+ __le32 Reserved2;
+ __u64 PersistentFileId; /* opaque endianness */
+ __u64 VolatileFileId; /* opaque endianness */
+} __attribute__((packed));
+
+struct flush_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize;
+ __le16 Reserved;
+} __attribute__((packed));
+
+struct read_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 49 */
+ __u8 Padding; /* offset from start of SMB2 header to place read */
+ __u8 Reserved;
+ __le32 Length;
+ __le64 Offset;
+ __u64 PersistentFileId; /* opaque endianness */
+ __u64 VolatileFileId; /* opaque endianness */
+ __le32 MinimumCount;
+ __le32 Channel; /* Reserved MBZ */
+ __le32 RemainingBytes;
+ __le16 ReadChannelInfoOffset; /* Reserved MBZ */
+ __le16 ReadChannelInfoLength; /* Reserved MBZ */
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+struct read_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 17 */
+ __u8 DataOffset;
+ __u8 Reserved;
+ __le32 DataLength;
+ __le32 DataRemaining;
+ __u32 Reserved2;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+/* For write request Flags field below the following flag is defined: */
+#define SMB2_WRITEFLAG_WRITE_THROUGH 0x00000001
+
+struct write_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 49 */
+ __le16 DataOffset; /* offset from start of SMB2 header to write data */
+ __le32 Length;
+ __le64 Offset;
+ __u64 PersistentFileId; /* opaque endianness */
+ __u64 VolatileFileId; /* opaque endianness */
+ __le32 Channel; /* Reserved MBZ */
+ __le32 RemainingBytes;
+ __le16 WriteChannelInfoOffset; /* Reserved MBZ */
+ __le16 WriteChannelInfoLength; /* Reserved MBZ */
+ __le32 Flags;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+struct write_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 17 */
+ __u8 DataOffset;
+ __u8 Reserved;
+ __le32 DataLength;
+ __le32 DataRemaining;
+ __u32 Reserved2;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+#define SMB2_LOCKFLAG_SHARED_LOCK 0x0001
+#define SMB2_LOCKFLAG_EXCLUSIVE_LOCK 0x0002
+#define SMB2_LOCKFLAG_UNLOCK 0x0004
+#define SMB2_LOCKFLAG_FAIL_IMMEDIATELY 0x0010
+
+struct smb2_lock_element {
+ __le64 Offset;
+ __le64 Length;
+ __le16 Flags;
+ __le16 Reserved;
+} __attribute__((packed));
+
+#define LOCKING_ANDX_OPLOCK_RELEASE 0x02
+
+struct lock_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 48 */
+ __le16 LockCount;
+ __le32 Reserved;
+ __u64 PersistentFileId; /* opaque endianness */
+ __u64 VolatileFileId; /* opaque endianness */
+ /* Followed by at least one */
+ struct smb2_lock_element locks[1];
+} __attribute__((packed));
+
+struct lock_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __le16 Reserved;
+} __attribute__((packed));
+
+struct echo_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __u16 Reserved;
+} __attribute__((packed));
+
+struct echo_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 4 */
+ __u16 Reserved;
+} __attribute__((packed));
+
+/* search (query_directory) Flags field */
+#define SMB2_RESTART_SCANS 0x01
+#define SMB2_RETURN_SINGLE_ENTRY 0x02
+#define SMB2_INDEX_SPECIFIED 0x04
+#define SMB2_REOPEN 0x10
+
+struct query_directory_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 33 */
+ __u8 FileInformationClass;
+ __u8 Flags;
+ __le32 FileIndex;
+ __u64 PersistentFileId; /* opaque endianness */
+ __u64 VolatileFileId; /* opaque endianness */
+ __le16 FileNameOffset;
+ __le16 FileNameLength;
+ __le32 OutputBufferLength;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+struct query_directory_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 9 */
+ __le16 OutputBufferOffset;
+ __le32 OutputBufferLength;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+/* Possible InfoType values */
+#define SMB2_O_INFO_FILE 0x01
+#define SMB2_O_INFO_FILESYSTEM 0x02
+#define SMB2_O_INFO_SECURITY 0x03
+#define SMB2_O_INFO_QUOTA 0x04
+
+struct query_info_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 41 */
+ __u8 InfoType;
+ __u8 FileInfoClass;
+ __le32 OutputBufferLength;
+ __le16 InputBufferOffset;
+ __u16 Reserved;
+ __le32 InputBufferLength;
+ __le32 AdditionalInformation;
+ __le32 Flags;
+ __u64 PersistentFileId; /* opaque endianness */
+ __u64 VolatileFileId; /* opaque endianness */
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+struct query_info_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 9 */
+ __le16 OutputBufferOffset;
+ __le32 OutputBufferLength;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+struct set_info_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 33 */
+ __u8 InfoType;
+ __u8 FileInfoClass;
+ __le32 BufferLength;
+ __le16 BufferOffset;
+ __u16 Reserved;
+ __le32 AdditionalInformation;
+ __u64 PersistentFileId; /* opaque endianness */
+ __u64 VolatileFileId; /* opaque endianness */
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+struct set_info_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 2 */
+} __attribute__((packed));
+
+struct ioctl_req {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 57 */
+ __le16 Reserved;
+ __le32 Ctlcode;
+ __le64 Fileid[2]; /* persistent and volatile */
+ __le32 Inputoffset;
+ __le32 Inputcount;
+ __le32 Maxinputresp;
+ __le32 Outputoffset;
+ __le32 Outputcount;
+ __le32 Maxoutputresp;
+ __le32 Flags;
+ __le32 Reserved2;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+struct ioctl_rsp {
+ struct smb2_hdr hdr;
+ __le16 StructureSize; /* Must be 49 */
+ __le16 Reserved;
+ __le32 Ctlcode;
+ __le16 Fileid[2]; /* persistent and volatile */
+ __le32 Inputoffset;
+ __le32 Inputcount;
+ __le32 Outputoffset;
+ __le32 Outputcount;
+ __le32 Flags;
+ __le32 Reserved2;
+ __u8 Buffer[1];
+} __attribute__((packed));
+
+/*****************************************************************
+ * All constants go here
+ *****************************************************************
+ */
+
+/*
+ * Starting value for maximum SMB size negotiation
+ */
+#define SMB2_MAX_MSGSIZE (4*4096)
+
+
+#define SMB2_NETWORK_OPSYS "SMB2 VFS Client for Linux"
+
+/*
+ * PDU infolevel structure definitions
+ * BB consider moving to a different header
+ */
+
+/* File System Information Classes */
+#define FS_VOLUME_INFORMATION 1 /* Query */
+#define FS_LABEL_INFORMATION 2 /* Set */
+#define FS_SIZE_INFORMATION 3 /* Query */
+#define FS_DEVICE_INFORMATION 4 /* Query */
+#define FS_ATTRIBUTE_INFORMATION 5 /* Query */
+#define FS_CONTROL_INFORMATION 6 /* Query, Set */
+#define FS_FULL_SIZE_INFORMATION 7 /* Query */
+#define FS_OBJECT_ID_INFORMATION 8 /* Query, Set */
+#define FS_DRIVER_PATH_INFORMATION 9 /* Query */
+
+struct fs_full_size_info {
+ __le64 TotalAllocationUnits;
+ __le64 CallerAvailableAllocationUnits;
+ __le64 ActualAvailableAllocationUnits;
+ __le32 SectorsPerAllocationUnit;
+ __le32 BytesPerSector;
+};
+
+struct fs_volume_info {
+ __le64 VolumeCreationTime;
+ __le32 VolumeSerialNumber;
+ __le32 VolumeLabelLength;
+ __u8 SupportsObjects; /* 1 = supports object oriented fs objects */
+ __u8 Reserved;
+ /* Variable Length VolumeLabel follows */
+};
+
+struct fs_device_info {
+ __le32 DeviceType; /* see below */
+ __le32 DeviceCharacteristics;
+} __attribute__((packed)); /* device info level 0x104 */
+
+/* DeviceType Flags (remember to endian convert them) */
+#define FILE_DEVICE_CD_ROM 0x00000002
+#define FILE_DEVICE_CD_ROM_FILE_SYSTEM 0x00000003
+#define FILE_DEVICE_DFS 0x00000006
+#define FILE_DEVICE_DISK 0x00000007
+#define FILE_DEVICE_DISK_FILE_SYSTEM 0x00000008
+#define FILE_DEVICE_FILE_SYSTEM 0x00000009
+#define FILE_DEVICE_NAMED_PIPE 0x00000011
+#define FILE_DEVICE_NETWORK 0x00000012
+#define FILE_DEVICE_NETWORK_FILE_SYSTEM 0x00000014
+#define FILE_DEVICE_NULL 0x00000015
+#define FILE_DEVICE_PARALLEL_PORT 0x00000016
+#define FILE_DEVICE_PRINTER 0x00000018
+#define FILE_DEVICE_SERIAL_PORT 0x0000001b
+#define FILE_DEVICE_STREAMS 0x0000001e
+#define FILE_DEVICE_TAPE 0x0000001f
+#define FILE_DEVICE_TAPE_FILE_SYSTEM 0x00000020
+#define FILE_DEVICE_VIRTUAL_DISK 0x00000024
+#define FILE_DEVICE_NETWORK_REDIRECTOR 0x00000028
+
+#define MAX_FS_NAME 20 /* twice size of longest name ("FAT32") is plenty */
+/* this field is for debugging/informational purposes anyway, so could be
+truncated if extremely long fs names were later created */
+struct fs_attribute_info {
+ __le32 Attributes;
+ __le32 MaximumComponentNameLength;
+ __le32 FileSystemNameLength;
+ char FileSystemName[MAX_FS_NAME]; /* not null terminated */
+} __attribute__((packed));
+
+/* Attributes (remember to endian convert them) */
+#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
+#define FILE_CASE_PRESERVED_NAMES 0x00000002
+#define FILE_UNICODE_ON_DISK 0x00000004
+#define FILE_PERSISTENT_ACLS 0x00000008
+#define FILE_FILE_COMPRESSION 0x00000010
+#define FILE_VOLUME_QUOTAS 0x00000020
+#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
+#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080
+#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
+#define FILE_VOLUME_IS_COMPRESSED 0x00008000
+#define FILE_SUPPORTS_OBJECT_IDS 0x00010000
+#define FILE_SUPPORTS_ENCRYPTION 0x00020000
+#define FILE_NAMED_STREAMS 0x00040000
+#define FILE_READ_ONLY_VOLUME 0x00080000
+#define FILE_SEQUENTIAL_WRITE_ONCE 0x00100000
+#define FILE_SUPPORTS_TRANSACTIONS 0x00200000
+#define FILE_SUPPORTS_HARD_LINKS 0x00400000
+#define FILE_SUPPORTS_EXTENDED_ATTRS 0x00800000
+#define FILE_SUPPORTS_OPEN_BY_FILE_ID 0x01000000
+#define FILE_SUPPORTS_USN_JOURNAL 0x02000000
+
+/* partial list of QUERY INFO levels */
+#define FILE_DIRECTORY_INFORMATION 1
+#define FILE_FULL_DIRECTORY_INFORMATION 2
+#define FILE_BOTH_DIRECTORY_INFORMATION 3
+#define FILE_BASIC_INFORMATION 4
+#define FILE_STANDARD_INFORMATION 5
+#define FILE_INTERNAL_INFORMATION 6
+#define FILE_EA_INFORMATION 7
+#define FILE_ACCESS_INFORMATION 8
+#define FILE_NAME_INFORMATION 9
+#define FILE_RENAME_INFORMATION 10
+#define FILE_LINK_INFORMATION 11
+#define FILE_NAMES_INFORMATION 12
+#define FILE_DISPOSITION_INFORMATION 13
+#define FILE_POSITION_INFORMATION 14
+#define FILE_FULL_EA_INFORMATION 15
+#define FILE_MODE_INFORMATION 16
+#define FILE_ALIGNMENT_INFORMATION 17
+#define FILE_ALL_INFORMATION 18
+#define FILE_ALLOCATION_INFORMATION 19
+#define FILE_END_OF_FILE_INFORMATION 20
+#define FILE_ALTERNATE_NAME_INFORMATION 21
+#define FILE_STREAM_INFORMATION 22
+#define FILE_PIPE_INFORMATION 23
+#define FILE_PIPE_LOCAL_INFORMATION 24
+#define FILE_PIPE_REMOTE_INFORMATION 25
+#define FILE_MAILSLOT_QUERY_INFORMATION 26
+#define FILE_MAILSLOT_SET_INFORMATION 27
+#define FILE_COMPRESSION_INFORMATION 28
+#define FILE_OBJECT_ID_INFORMATION 29
+/* Number 30 not defined in documents */
+#define FILE_MOVE_CLUSTER_INFORMATION 31
+#define FILE_QUOTA_INFORMATION 32
+#define FILE_REPARSE_POINT_INFORMATION 33
+#define FILE_NETWORK_OPEN_INFORMATION 34
+#define FILE_ATTRIBUTE_TAG_INFORMATION 35
+#define FILE_TRACKING_INFORMATION 36
+#define FILEID_BOTH_DIRECTORY_INFORMATION 37
+#define FILEID_FULL_DIRECTORY_INFORMATION 38
+#define FILE_VALID_DATA_LENGTH_INFORMATION 39
+#define FILE_SHORT_NAME_INFORMATION 40
+#define FILE_SFIO_RESERVE_INFORMATION 44
+#define FILE_SFIO_VOLUME_INFORMATION 45
+#define FILE_HARD_LINK_INFORMATION 46
+#define FILE_NORMALIZED_NAME_INFORMATION 48
+#define FILEID_GLOBAL_TX_DIRECTORY_INFORMATION 50
+#define FILE_STANDARD_LINK_INFORMATION 54
+
+struct file_both_directory_info {
+ __le32 next_entry_offset;
+ __u32 file_index;
+ __le64 creation_time;
+ __le64 last_access_time;
+ __le64 last_write_time;
+ __le64 change_time;
+ __le64 end_of_file;
+ __le64 allocation_size;
+ __le32 file_attribute;
+ __le32 filename_length;
+ __le32 easize;
+ __u8 shortname_length;
+ __u8 reserved1;
+ __u8 short_name[24];
+ __u16 reserved2;
+ __le64 file_id;
+ char filename[0];
+} __attribute__((packed));
+
+struct file_full_directory_info {
+ __le32 next_entry_offset;
+ __u32 file_index;
+ __le64 creation_time;
+ __le64 last_access_time;
+ __le64 last_write_time;
+ __le64 change_time;
+ __le64 end_of_file;
+ __le64 allocation_size;
+ __le32 file_attribute;
+ __le32 filename_length;
+ __le32 easize;
+ __u32 reserved2;
+ __le64 file_id;
+ char filename[0];
+} __attribute__((packed));
+
+typedef struct { /* data block encoding of response to level 5 query */
+ __le64 AllocationSize;
+ __le64 EndOfFile; /* size ie offset to first free byte in file */
+ __le32 NumberOfLinks; /* hard links */
+ __u8 DeletePending;
+ __u8 Directory;
+ __u16 Pad2;
+} __attribute__((packed)) FILE_STANDARD_INFO; /* level 5 QPathInfo */
+
+struct FileRenameInformation { /* encoding of request for level 10 */
+ __u8 ReplaceIfExists; /* 1 = replace existing file with new */
+ /* 0 = fail if target file already exists */
+ __u8 Reserved[7];
+ __u64 RootDirectory; /* MBZ for network operations (why says spec?) */
+ __le32 FileNameLength;
+ char FileName[0]; /* New name to be assigned */
+} __attribute__((packed)); /* level 10 set */
+
+struct FileLinkInformation { /* encoding of request for level 11 */
+ __u8 ReplaceIfExists; /* 1 = replace existing link with new */
+ /* 0 = fail if link already exists */
+ __u8 Reserved[7];
+ __u64 RootDirectory; /* MBZ for network operations (why says spec?) */
+ __le32 FileNameLength;
+ char FileName[0]; /* Name to be assigned to new link */
+} __attribute__((packed)); /* level 11 set */
+
+
+/* This level 18, although with struct with same name is different from cifs
+ level 0x107. level 0x107 has an extra u64 between AccessFlags and
+ CurrentByteOffset */
+typedef struct { /* data block encoding of response to level 18 */
+ __le64 CreationTime; /* Beginning of FILE_BASIC_INFO equivalent */
+ __le64 LastAccessTime;
+ __le64 LastWriteTime;
+ __le64 ChangeTime;
+ __le32 Attributes;
+ __u32 Pad1; /* End of FILE_BASIC_INFO_INFO equivalent */
+ __le64 AllocationSize; /* Beginning of FILE_STANDARD_INFO equivalent */
+ __le64 EndOfFile; /* size ie offset to first free byte in file */
+ __le32 NumberOfLinks; /* hard links */
+ __u8 DeletePending;
+ __u8 Directory;
+ __u16 Pad2; /* End of FILE_STANDARD_INFO equivalent */
+ __le64 IndexNumber;
+ __le32 EASize;
+ __le32 AccessFlags;
+ __le64 CurrentByteOffset;
+ __le32 Mode;
+ __le32 AlignmentRequirement;
+ __le32 FileNameLength;
+ char FileName[1];
+} __attribute__((packed)) FILE_ALL_INFO_SMB2; /* level 18 Query */
+
+typedef struct { /* data block encoding of request to level 15 */
+ __le64 NextEntryOffset;
+ __u8 EaNameLength;
+ char EaName[1];
+} __attribute__((packed)) FILE_GET_EA_INFO; /* level 15 Query */
+
+typedef struct { /* data block encoding of response to level 15 */
+ __le32 NextEntryOffset;
+ __u8 Flags;
+ __u8 EaNameLength;
+ __le16 EaValueLength;
+ char EaName[1];
+ char EaValue[1];
+} __attribute__((packed)) FILE_FULL_EA_INFO; /* level 15 Query */
+
+/* DFS Flags */ /* BB check if these changed in SMB2 from old transact2
+ get DFS referral flags BB */
+#define DFSREF_REFERRAL_SERVER 0x00000001 /* all targets are DFS roots */
+#define DFSREF_STORAGE_SERVER 0x00000002 /* no further ref requests needed */
+#define DFSREF_TARGET_FAILBACK 0x00000004 /* only for DFS referral version 4 */
+
+/* BB note that various other infolevels are defined in cifspdu.h, although most
+ are obsolete now (for SMB2) or unneeded, some may be useful to move here */
+
+#define SMB2_IOCTL_IS_FSCTL 0x1
+#define SYMLINK_FLAG_RELATIVE 0x1
+#define MS_REPARSE_TAG 0xA000000C
+
+struct symlink_reparse_data_buf {
+ __le32 reparse_tag;
+ __le16 reparse_datalength;
+ __le16 reserved1;
+ __le16 sub_nameoffset;
+ __le16 sub_namelength;
+ __le16 print_nameoffset;
+ __le16 print_namelength;
+ __le32 flags;
+ char pathbuffer[1];
+} __attribute__((packed));
+
+#endif /* _SMB2PDU_H */
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
new file mode 100644
index 000000000000..018d36f7bbca
--- /dev/null
+++ b/fs/cifs/smb2proto.h
@@ -0,0 +1,203 @@
+/*
+ * fs/cifs/smb2proto.h
+ *
+ * Copyright (c) International Business Machines Corp., 2002,2011
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef _SMB2PROTO_H
+#define _SMB2PROTO_H
+#include <linux/nls.h>
+#include <linux/key-type.h>
+
+struct statfs;
+
+/*
+ *****************************************************************
+ * All Prototypes
+ *****************************************************************
+ */
+
+/* extern char *build_smb2path_from_dentry(struct dentry *);
+extern __le16 *build_ucspath_from_dentry(struct dentry *);
+extern __le16 *smb2_build_path_to_root(struct cifs_sb_info *smb2_sb);
+extern void free_rsp_buf(int resp_buftype, void *pSMB2r);
+extern struct smb2_hdr *smb2_buf_get(void);
+extern void smb2_buf_release(void *);
+extern struct smb2_hdr *smb2_small_buf_get(void);
+extern void smb2_small_buf_release(void *);
+extern __u64 get_mid(struct TCP_Server_Info *server);*/
+extern int small_smb2_init_no_tc(__le16 smb2_cmd,
+ struct cifs_ses *ses,
+ void **request_buf);
+extern int checkSMB2(struct smb2_hdr *smb2, __u64 mid, unsigned int length);
+extern char *smb2_get_data_area_len(int *poff, int *pln, struct smb2_hdr *psmb);
+extern unsigned int smb2_calc_size(struct smb2_hdr *ptr);
+extern int map_smb2_to_linux_error(struct smb2_hdr *smb2, int logErr);
+
+extern int smb2_send(struct TCP_Server_Info *, struct smb2_hdr *,
+ unsigned int /* length */);
+extern int smb2_sendrcv2(const unsigned int /* xid */ , struct cifs_ses *,
+ struct kvec *, int /* nvec to send */,
+ int * /* type of buf returned */,
+ int * /* smb2 network status code */, const int flags);
+extern int smb2_send_complex(const unsigned int, struct cifs_ses *,
+ struct kvec *, int /* nvec to send */,
+ int * /* type of buf returned */,
+ int * /* smb2 network status code */,
+ struct mid_q_entry **mid, const unsigned int size);
+extern int smb2_sendrcv_norsp(const unsigned int xid, struct cifs_ses *ses,
+ struct smb2_hdr *in_buf, int flags);
+extern int smb2_sendrcv_blocking(const unsigned int xid, struct cifs_tcon *tcon,
+ struct smb2_hdr *in_buf,
+ struct smb2_hdr *out_buf,
+ int *pbytes_returned);
+extern int sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *);
+/* BB FIXME - need to add SMB2's signing mechanism - not same as CIFS BB */
+/*extern int smb2_verify_signature(struct smb2_hdr *,
+ const struct mac_key *mac_key);*/
+extern int smb2_demultiplex_thread(struct TCP_Server_Info *server);
+extern int smb2_observe_thread(struct TCP_Server_Info *server);
+extern int smb2_reconnect(struct TCP_Server_Info *server);
+extern int smb2_setup_session(unsigned int xid, struct cifs_ses *pses_info,
+ struct nls_table *nls_info);
+extern int smb2_umount(struct super_block *, struct cifs_sb_info *);
+
+extern int smb2_get_inode_info(struct inode **pinode, __le16 *search_path,
+ FILE_ALL_INFO *pfile_info, struct super_block *sb,
+ int xid);
+extern struct smb2_file *smb2_new_fileinfo(struct inode *newinode,
+ u64 persistfid, u64 volatile_fid,
+ struct file *file, struct vfsmount *mnt,
+ unsigned int oflags);
+extern bool smb2_is_size_safe_to_change(struct smb2_inode *smb2_ind,
+ __u64 end_of_file);
+extern struct inode *smb2_iget(struct super_block *sb,
+ struct cifs_fattr *fattr);
+extern void smb2_allinfo_to_fattr(struct cifs_fattr *attr,
+ FILE_ALL_INFO *pfile_info,
+ struct cifs_sb_info *smb2_sb);
+extern void smb2_create_dfs_attr(struct cifs_fattr *fattr,
+ struct super_block *sb);
+extern void cifs_fattr_to_inode(struct inode *pinode, struct cifs_fattr *attr);
+extern int smb2_fsync(struct file *file, int datasync);
+extern int smb2_flush(struct file *file, fl_owner_t id);
+
+/* extern char *smb2_compose_mount_options(const char *sb_mountdata,
+ const char *fullpath, const struct dfs_info3_param *ref,
+ char **devname);
+extern void smb2_dfs_release_automount_timer(void);
+
+extern void smb2_del_oplock_entry(struct oplock_entry *);
+extern struct oplock_entry *smb2_alloc_oplock_entry(struct inode *inode, u64 fd,
+ struct cifs_tcon *tcon);
+extern int decode_neg_token_init(unsigned char *security_blob, int length,
+ enum security_enum *sec_type); */
+
+/*
+ * SMB2 Worker functions - most of protocol specific implementation details
+ * are contained within these calls
+ */
+extern int SMB2_negotiate(unsigned int xid, struct cifs_ses *ses);
+extern int SMB2_sess_setup(unsigned int xid, struct cifs_ses *ses,
+ const struct nls_table *nls_cp);
+extern int SMB2_tcon(unsigned int xid, struct cifs_ses *ses,
+ const char *tree, struct cifs_tcon *tcon,
+ const struct nls_table *);
+extern int SMB2_tdis(const int xid, struct cifs_tcon *tcon);
+extern int SMB2_logoff(const int xid, struct cifs_ses *ses);
+extern int SMB2_echo(const int xid, struct cifs_tcon *tcon);
+extern int SMB2_QFS_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_file_id, u64 volatile_file_id,
+ struct kstatfs *FSData);
+extern int SMB2_QFS_vol_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid);
+extern int SMB2_QFS_attribute_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid);
+extern int SMB2_QFS_device_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid);
+extern int SMB2_oplock_break(struct cifs_tcon *ptcon, __u64 netfid);
+extern int SMB2_query_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_file_id, u64 volatile_file_id,
+ FILE_ALL_INFO *pFindData);
+int SMB2_query_directory(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid, int index, struct smb2_search *);
+extern int SMB2_set_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_file_id, u64 volatile_file_id,
+ FILE_BASIC_INFO *pFindData);
+extern int SMB2_set_delete(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_file_id, u64 volatile_file_id);
+extern int SMB2_set_hardlink(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid, __le16 *target_file);
+extern int SMB2_rename(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid, __le16 *target_file);
+extern int SMB2_open(const int xid, struct cifs_tcon *tcon, __le16 *path,
+ u64 *persistent_fid, u64 *volatile_fid, __le32 desired_access,
+ __le32 create_disposition, __le32 file_attributes,
+ __le32 create_options);
+extern int SMB2_symlink_ioctl(const int, struct cifs_tcon *, u32, u64, u64,
+ const char *);
+extern int SMB2_close(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_file_id, u64 volatile_file_id);
+extern int SMB2_read(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid,
+ const unsigned int count, const __u64 lseek,
+ unsigned int *nbytes, char **buf, int *pbuf_type,
+ unsigned int remaining_bytes);
+extern int SMB2_write(const int xid, struct cifs_tcon *tcon,
+ const u64 persistent_fid, const u64 volatile_fid,
+ const unsigned int count, const __u64 lseek,
+ unsigned int *nbytes, struct kvec *iov, int n_vec,
+ const unsigned int remaining_bytes, int wtimeout);
+extern int SMB2_write_complex(const int xid, struct cifs_tcon *tcon,
+ const u64 persistent_fid, const u64 volatile_fid,
+ const unsigned int count, const __u64 lseek,
+ unsigned int *nbytes, struct kvec *iov, int n_vec,
+ const unsigned int remaining_bytes, struct mid_q_entry **mid,
+ const unsigned int size);
+extern int SMB2_flush(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_file_id, u64 volatile_file_id);
+extern int SMB2_query_full_ea_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid,
+ char *pdata, int buf_len, int rsp_output_len,
+ struct kvec *iov, int n_vec,
+ const char *prefix, int prefix_len);
+extern int SMB2_set_ea_info(const int xid, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid,
+ struct kvec iov[4]);
+extern int SMB2_lock(const int xid, struct cifs_tcon *tcon,
+ const u64 persistent_fid, const u64 volatile_fid,
+ u64 length, u64 offset, u32 lockFlags, int wait);
+extern void DeleteMidQEntryComplex(struct mid_q_entry *midEntry);
+extern int new_read_req(struct kvec *iov, struct cifs_tcon *tcon,
+ u64 persistent_fid, u64 volatile_fid,
+ const unsigned int count, const __u64 lseek,
+ unsigned int remaining_bytes,
+ int request_type);
+extern int allocate_mid(struct cifs_ses *ses, struct smb2_hdr *in_buf,
+ struct mid_q_entry **ppmidq);
+extern int smb2_sendv(struct TCP_Server_Info *server, struct kvec *iov,
+ int n_vec);
+extern int wait_for_free_request(struct cifs_ses *ses, const int long_op);
+extern int smb2_wait_on_complex_mid(struct cifs_ses *ses,
+ struct mid_q_entry *mid,
+ unsigned long timeout,
+ unsigned long time_to_wait);
+extern int smb2_readresp(struct TCP_Server_Info *server, bool cleanup);
+/* extern void smb2_oplock_break(struct work_struct *);
+extern bool is_smb2_oplock_break(struct smb2_hdr *, struct TCP_Server_Info *); */
+
+#endif /* _SMB2PROTO_H */
diff --git a/fs/cifs/smb2sess.c b/fs/cifs/smb2sess.c
new file mode 100644
index 000000000000..9ef7d9391262
--- /dev/null
+++ b/fs/cifs/smb2sess.c
@@ -0,0 +1,80 @@
+/*
+ * fs/smb2/sess.c
+ *
+ * SMB/CIFS session setup handling routines
+ *
+ * Copyright (c) International Business Machines Corp., 2009
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "smb2pdu.h"
+#include "cifsglob.h"
+#include "cifsproto.h"
+#include "smb2proto.h"
+#include "cifs_debug.h"
+
+int smb2_setup_session(unsigned int xid, struct cifs_ses *psesinfo,
+ struct nls_table *nls_info)
+{
+ int rc = 0;
+ struct TCP_Server_Info *server = psesinfo->server;
+
+ /* We used to server->check max_buf in cifs, but does not get
+ returned in smb2 so check max_read instead */
+ if (server->max_read == 0) /* no need to send on reconnect */ {
+ atomic_set(&server->credits, 1);
+ rc = SMB2_negotiate(xid, psesinfo);
+ if (rc == -EAGAIN) {
+ /* retry only once on 1st time connection */
+ rc = SMB2_negotiate(xid, psesinfo);
+ if (rc == -EAGAIN)
+ rc = -EHOSTDOWN;
+ }
+ if (rc == 0) {
+ spin_lock(&GlobalMid_Lock);
+ if (server->tcpStatus != CifsExiting)
+ server->tcpStatus = CifsGood;
+ else
+ rc = -EHOSTDOWN;
+ spin_unlock(&GlobalMid_Lock);
+
+ }
+ }
+
+ if (rc)
+ goto ss_err_exit;
+
+ /* psesinfo->sequence_number = 0;*/
+ cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
+ server->sec_mode, server->capabilities, server->timeAdj);
+
+ rc = SMB2_sess_setup(xid, psesinfo, nls_info);
+ if (rc) {
+ cERROR(1, "error in SessSetup = %d", rc);
+ goto ss_err_exit;
+ }
+
+ cFYI(1, "SMB2 Session Established successfully");
+ spin_lock(&GlobalMid_Lock);
+ psesinfo->status = CifsGood;
+ psesinfo->need_reconnect = false;
+ spin_unlock(&GlobalMid_Lock);
+
+ss_err_exit:
+ return rc;
+}
+
diff --git a/fs/cifs/smb2status.h b/fs/cifs/smb2status.h
new file mode 100644
index 000000000000..0d17af8ef3ee
--- /dev/null
+++ b/fs/cifs/smb2status.h
@@ -0,0 +1,1782 @@
+/*
+ * fs/smb2/smb2status.h
+ *
+ * SMB2 Status code (network error) definitions
+ * Definitions are from MS-ERREF
+ *
+ * Copyright (c) International Business Machines Corp., 2009,2011
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * 0 1 2 3 4 5 6 7 8 9 0 A B C D E F 0 1 2 3 4 5 6 7 8 9 A B C D E F
+ * SEV C N <-------Facility--------> <------Error Status Code------>
+ *
+ * C is set if "customer defined" error, N bit is reserved and MBZ
+ */
+
+#define STATUS_SEVERITY_SUCCESS cpu_to_le32 0x0000
+#define STATUS_SEVERITY_INFORMATIONAL cpu_to_le32 0x0001
+#define STATUS_SEVERITY_WARNING cpu_to_le32 0x0002
+#define STATUS_SEVERITY_ERROR cpu_to_le32 0x0003
+
+struct ntstatus {
+ /* Facility is the high 12 bits of the following field */
+ __le32 Facility; /* low 2 bits Severity, next is Customer, then rsrvd */
+ __le32 Code;
+};
+
+#define STATUS_SUCCESS 0x00000000
+#define STATUS_WAIT_0 0x00000000
+#define STATUS_WAIT_1 0x00000001
+#define STATUS_WAIT_2 0x00000002
+#define STATUS_WAIT_3 0x00000003
+#define STATUS_WAIT_63 0x0000003F
+#define STATUS_ABANDONED 0x00000080
+#define STATUS_ABANDONED_WAIT_0 0x00000080
+#define STATUS_ABANDONED_WAIT_63 0x000000BF
+#define STATUS_USER_APC 0x000000C0
+#define STATUS_KERNEL_APC 0x00000100
+#define STATUS_ALERTED 0x00000101
+#define STATUS_TIMEOUT 0x00000102
+#define STATUS_PENDING 0x00000103
+#define STATUS_REPARSE 0x00000104
+#define STATUS_MORE_ENTRIES 0x00000105
+#define STATUS_NOT_ALL_ASSIGNED 0x00000106
+#define STATUS_SOME_NOT_MAPPED 0x00000107
+#define STATUS_OPLOCK_BREAK_IN_PROGRESS 0x00000108
+#define STATUS_VOLUME_MOUNTED 0x00000109
+#define STATUS_RXACT_COMMITTED 0x0000010A
+#define STATUS_NOTIFY_CLEANUP 0x0000010B
+#define STATUS_NOTIFY_ENUM_DIR 0x0000010C
+#define STATUS_NO_QUOTAS_FOR_ACCOUNT 0x0000010D
+#define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED 0x0000010E
+#define STATUS_PAGE_FAULT_TRANSITION 0x00000110
+#define STATUS_PAGE_FAULT_DEMAND_ZERO 0x00000111
+#define STATUS_PAGE_FAULT_COPY_ON_WRITE 0x00000112
+#define STATUS_PAGE_FAULT_GUARD_PAGE 0x00000113
+#define STATUS_PAGE_FAULT_PAGING_FILE 0x00000114
+#define STATUS_CACHE_PAGE_LOCKED 0x00000115
+#define STATUS_CRASH_DUMP 0x00000116
+#define STATUS_BUFFER_ALL_ZEROS 0x00000117
+#define STATUS_REPARSE_OBJECT 0x00000118
+#define STATUS_RESOURCE_REQUIREMENTS_CHANGED 0x00000119
+#define STATUS_TRANSLATION_COMPLETE 0x00000120
+#define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY 0x00000121
+#define STATUS_NOTHING_TO_TERMINATE 0x00000122
+#define STATUS_PROCESS_NOT_IN_JOB 0x00000123
+#define STATUS_PROCESS_IN_JOB 0x00000124
+#define STATUS_VOLSNAP_HIBERNATE_READY 0x00000125
+#define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY 0x00000126
+#define STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED 0x00000127
+#define STATUS_INTERRUPT_STILL_CONNECTED 0x00000128
+#define STATUS_PROCESS_CLONED 0x00000129
+#define STATUS_FILE_LOCKED_WITH_ONLY_READERS 0x0000012A
+#define STATUS_FILE_LOCKED_WITH_WRITERS 0x0000012B
+#define STATUS_RESOURCEMANAGER_READ_ONLY 0x00000202
+#define STATUS_WAIT_FOR_OPLOCK 0x00000367
+#define DBG_EXCEPTION_HANDLED 0x00010001
+#define DBG_CONTINUE 0x00010002
+#define STATUS_FLT_IO_COMPLETE 0x001C0001
+#define STATUS_OBJECT_NAME_EXISTS 0x40000000
+#define STATUS_THREAD_WAS_SUSPENDED 0x40000001
+#define STATUS_WORKING_SET_LIMIT_RANGE 0x40000002
+#define STATUS_IMAGE_NOT_AT_BASE 0x40000003
+#define STATUS_RXACT_STATE_CREATED 0x40000004
+#define STATUS_SEGMENT_NOTIFICATION 0x40000005
+#define STATUS_LOCAL_USER_SESSION_KEY 0x40000006
+#define STATUS_BAD_CURRENT_DIRECTORY 0x40000007
+#define STATUS_SERIAL_MORE_WRITES 0x40000008
+#define STATUS_REGISTRY_RECOVERED 0x40000009
+#define STATUS_FT_READ_RECOVERY_FROM_BACKUP 0x4000000A
+#define STATUS_FT_WRITE_RECOVERY 0x4000000B
+#define STATUS_SERIAL_COUNTER_TIMEOUT 0x4000000C
+#define STATUS_NULL_LM_PASSWORD 0x4000000D
+#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH 0x4000000E
+#define STATUS_RECEIVE_PARTIAL 0x4000000F
+#define STATUS_RECEIVE_EXPEDITED 0x40000010
+#define STATUS_RECEIVE_PARTIAL_EXPEDITED 0x40000011
+#define STATUS_EVENT_DONE 0x40000012
+#define STATUS_EVENT_PENDING 0x40000013
+#define STATUS_CHECKING_FILE_SYSTEM 0x40000014
+#define STATUS_FATAL_APP_EXIT 0x40000015
+#define STATUS_PREDEFINED_HANDLE 0x40000016
+#define STATUS_WAS_UNLOCKED 0x40000017
+#define STATUS_SERVICE_NOTIFICATION 0x40000018
+#define STATUS_WAS_LOCKED 0x40000019
+#define STATUS_LOG_HARD_ERROR 0x4000001A
+#define STATUS_ALREADY_WIN32 0x4000001B
+#define STATUS_WX86_UNSIMULATE 0x4000001C
+#define STATUS_WX86_CONTINUE 0x4000001D
+#define STATUS_WX86_SINGLE_STEP 0x4000001E
+#define STATUS_WX86_BREAKPOINT 0x4000001F
+#define STATUS_WX86_EXCEPTION_CONTINUE 0x40000020
+#define STATUS_WX86_EXCEPTION_LASTCHANCE 0x40000021
+#define STATUS_WX86_EXCEPTION_CHAIN 0x40000022
+#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE 0x40000023
+#define STATUS_NO_YIELD_PERFORMED 0x40000024
+#define STATUS_TIMER_RESUME_IGNORED 0x40000025
+#define STATUS_ARBITRATION_UNHANDLED 0x40000026
+#define STATUS_CARDBUS_NOT_SUPPORTED 0x40000027
+#define STATUS_WX86_CREATEWX86TIB 0x40000028
+#define STATUS_MP_PROCESSOR_MISMATCH 0x40000029
+#define STATUS_HIBERNATED 0x4000002A
+#define STATUS_RESUME_HIBERNATION 0x4000002B
+#define STATUS_FIRMWARE_UPDATED 0x4000002C
+#define STATUS_DRIVERS_LEAKING_LOCKED_PAGES 0x4000002D
+#define STATUS_MESSAGE_RETRIEVED 0x4000002E
+#define STATUS_SYSTEM_POWERSTATE_TRANSITION 0x4000002F
+#define STATUS_ALPC_CHECK_COMPLETION_LIST 0x40000030
+#define STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION 0x40000031
+#define STATUS_ACCESS_AUDIT_BY_POLICY 0x40000032
+#define STATUS_ABANDON_HIBERFILE 0x40000033
+#define STATUS_BIZRULES_NOT_ENABLED 0x40000034
+#define STATUS_WAKE_SYSTEM 0x40000294
+#define STATUS_DS_SHUTTING_DOWN 0x40000370
+#define DBG_REPLY_LATER 0x40010001
+#define DBG_UNABLE_TO_PROVIDE_HANDLE 0x40010002
+#define DBG_TERMINATE_THREAD 0x40010003
+#define DBG_TERMINATE_PROCESS 0x40010004
+#define DBG_CONTROL_C 0x40010005
+#define DBG_PRINTEXCEPTION_C 0x40010006
+#define DBG_RIPEXCEPTION 0x40010007
+#define DBG_CONTROL_BREAK 0x40010008
+#define DBG_COMMAND_EXCEPTION 0x40010009
+#define RPC_NT_UUID_LOCAL_ONLY 0x40020056
+#define RPC_NT_SEND_INCOMPLETE 0x400200AF
+#define STATUS_CTX_CDM_CONNECT 0x400A0004
+#define STATUS_CTX_CDM_DISCONNECT 0x400A0005
+#define STATUS_SXS_RELEASE_ACTIVATION_CONTEXT 0x4015000D
+#define STATUS_RECOVERY_NOT_NEEDED 0x40190034
+#define STATUS_RM_ALREADY_STARTED 0x40190035
+#define STATUS_LOG_NO_RESTART 0x401A000C
+#define STATUS_VIDEO_DRIVER_DEBUG_REPORT_REQUEST 0x401B00EC
+#define STATUS_GRAPHICS_PARTIAL_DATA_POPULATED 0x401E000A
+#define STATUS_GRAPHICS_DRIVER_MISMATCH 0x401E0117
+#define STATUS_GRAPHICS_MODE_NOT_PINNED 0x401E0307
+#define STATUS_GRAPHICS_NO_PREFERRED_MODE 0x401E031E
+#define STATUS_GRAPHICS_DATASET_IS_EMPTY 0x401E034B
+#define STATUS_GRAPHICS_NO_MORE_ELEMENTS_IN_DATASET 0x401E034C
+#define STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_PINNED 0x401E0351
+#define STATUS_GRAPHICS_UNKNOWN_CHILD_STATUS 0x401E042F
+#define STATUS_GRAPHICS_LEADLINK_START_DEFERRED 0x401E0437
+#define STATUS_GRAPHICS_POLLING_TOO_FREQUENTLY 0x401E0439
+#define STATUS_GRAPHICS_START_DEFERRED 0x401E043A
+#define STATUS_NDIS_INDICATION_REQUIRED 0x40230001
+#define STATUS_GUARD_PAGE_VIOLATION 0x80000001
+#define STATUS_DATATYPE_MISALIGNMENT 0x80000002
+#define STATUS_BREAKPOINT 0x80000003
+#define STATUS_SINGLE_STEP 0x80000004
+#define STATUS_BUFFER_OVERFLOW 0x80000005
+#define STATUS_NO_MORE_FILES 0x80000006
+#define STATUS_WAKE_SYSTEM_DEBUGGER 0x80000007
+#define STATUS_HANDLES_CLOSED 0x8000000A
+#define STATUS_NO_INHERITANCE 0x8000000B
+#define STATUS_GUID_SUBSTITUTION_MADE 0x8000000C
+#define STATUS_PARTIAL_COPY 0x8000000D
+#define STATUS_DEVICE_PAPER_EMPTY 0x8000000E
+#define STATUS_DEVICE_POWERED_OFF 0x8000000F
+#define STATUS_DEVICE_OFF_LINE 0x80000010
+#define STATUS_DEVICE_BUSY 0x80000011
+#define STATUS_NO_MORE_EAS 0x80000012
+#define STATUS_INVALID_EA_NAME 0x80000013
+#define STATUS_EA_LIST_INCONSISTENT 0x80000014
+#define STATUS_INVALID_EA_FLAG 0x80000015
+#define STATUS_VERIFY_REQUIRED 0x80000016
+#define STATUS_EXTRANEOUS_INFORMATION 0x80000017
+#define STATUS_RXACT_COMMIT_NECESSARY 0x80000018
+#define STATUS_NO_MORE_ENTRIES 0x8000001A
+#define STATUS_FILEMARK_DETECTED 0x8000001B
+#define STATUS_MEDIA_CHANGED 0x8000001C
+#define STATUS_BUS_RESET 0x8000001D
+#define STATUS_END_OF_MEDIA 0x8000001E
+#define STATUS_BEGINNING_OF_MEDIA 0x8000001F
+#define STATUS_MEDIA_CHECK 0x80000020
+#define STATUS_SETMARK_DETECTED 0x80000021
+#define STATUS_NO_DATA_DETECTED 0x80000022
+#define STATUS_REDIRECTOR_HAS_OPEN_HANDLES 0x80000023
+#define STATUS_SERVER_HAS_OPEN_HANDLES 0x80000024
+#define STATUS_ALREADY_DISCONNECTED 0x80000025
+#define STATUS_LONGJUMP 0x80000026
+#define STATUS_CLEANER_CARTRIDGE_INSTALLED 0x80000027
+#define STATUS_PLUGPLAY_QUERY_VETOED 0x80000028
+#define STATUS_UNWIND_CONSOLIDATE 0x80000029
+#define STATUS_REGISTRY_HIVE_RECOVERED 0x8000002A
+#define STATUS_DLL_MIGHT_BE_INSECURE 0x8000002B
+#define STATUS_DLL_MIGHT_BE_INCOMPATIBLE 0x8000002C
+#define STATUS_STOPPED_ON_SYMLINK 0x8000002D
+#define STATUS_DEVICE_REQUIRES_CLEANING 0x80000288
+#define STATUS_DEVICE_DOOR_OPEN 0x80000289
+#define STATUS_DATA_LOST_REPAIR 0x80000803
+#define DBG_EXCEPTION_NOT_HANDLED 0x80010001
+#define STATUS_CLUSTER_NODE_ALREADY_UP 0x80130001
+#define STATUS_CLUSTER_NODE_ALREADY_DOWN 0x80130002
+#define STATUS_CLUSTER_NETWORK_ALREADY_ONLINE 0x80130003
+#define STATUS_CLUSTER_NETWORK_ALREADY_OFFLINE 0x80130004
+#define STATUS_CLUSTER_NODE_ALREADY_MEMBER 0x80130005
+#define STATUS_COULD_NOT_RESIZE_LOG 0x80190009
+#define STATUS_NO_TXF_METADATA 0x80190029
+#define STATUS_CANT_RECOVER_WITH_HANDLE_OPEN 0x80190031
+#define STATUS_TXF_METADATA_ALREADY_PRESENT 0x80190041
+#define STATUS_TRANSACTION_SCOPE_CALLBACKS_NOT_SET 0x80190042
+#define STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD_RECOVERED 0x801B00EB
+#define STATUS_FLT_BUFFER_TOO_SMALL 0x801C0001
+#define STATUS_FVE_PARTIAL_METADATA 0x80210001
+#define STATUS_UNSUCCESSFUL 0xC0000001
+#define STATUS_NOT_IMPLEMENTED 0xC0000002
+#define STATUS_INVALID_INFO_CLASS 0xC0000003
+#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
+#define STATUS_ACCESS_VIOLATION 0xC0000005
+#define STATUS_IN_PAGE_ERROR 0xC0000006
+#define STATUS_PAGEFILE_QUOTA 0xC0000007
+#define STATUS_INVALID_HANDLE 0xC0000008
+#define STATUS_BAD_INITIAL_STACK 0xC0000009
+#define STATUS_BAD_INITIAL_PC 0xC000000A
+#define STATUS_INVALID_CID 0xC000000B
+#define STATUS_TIMER_NOT_CANCELED 0xC000000C
+#define STATUS_INVALID_PARAMETER 0xC000000D
+#define STATUS_NO_SUCH_DEVICE 0xC000000E
+#define STATUS_NO_SUCH_FILE 0xC000000F
+#define STATUS_INVALID_DEVICE_REQUEST 0xC0000010
+#define STATUS_END_OF_FILE 0xC0000011
+#define STATUS_WRONG_VOLUME 0xC0000012
+#define STATUS_NO_MEDIA_IN_DEVICE 0xC0000013
+#define STATUS_UNRECOGNIZED_MEDIA 0xC0000014
+#define STATUS_NONEXISTENT_SECTOR 0xC0000015
+#define STATUS_MORE_PROCESSING_REQUIRED 0xC0000016
+#define STATUS_NO_MEMORY 0xC0000017
+#define STATUS_CONFLICTING_ADDRESSES 0xC0000018
+#define STATUS_NOT_MAPPED_VIEW 0xC0000019
+#define STATUS_UNABLE_TO_FREE_VM 0xC000001A
+#define STATUS_UNABLE_TO_DELETE_SECTION 0xC000001B
+#define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C
+#define STATUS_ILLEGAL_INSTRUCTION 0xC000001D
+#define STATUS_INVALID_LOCK_SEQUENCE 0xC000001E
+#define STATUS_INVALID_VIEW_SIZE 0xC000001F
+#define STATUS_INVALID_FILE_FOR_SECTION 0xC0000020
+#define STATUS_ALREADY_COMMITTED 0xC0000021
+#define STATUS_ACCESS_DENIED 0xC0000022
+#define STATUS_BUFFER_TOO_SMALL 0xC0000023
+#define STATUS_OBJECT_TYPE_MISMATCH 0xC0000024
+#define STATUS_NONCONTINUABLE_EXCEPTION 0xC0000025
+#define STATUS_INVALID_DISPOSITION 0xC0000026
+#define STATUS_UNWIND 0xC0000027
+#define STATUS_BAD_STACK 0xC0000028
+#define STATUS_INVALID_UNWIND_TARGET 0xC0000029
+#define STATUS_NOT_LOCKED 0xC000002A
+#define STATUS_PARITY_ERROR 0xC000002B
+#define STATUS_UNABLE_TO_DECOMMIT_VM 0xC000002C
+#define STATUS_NOT_COMMITTED 0xC000002D
+#define STATUS_INVALID_PORT_ATTRIBUTES 0xC000002E
+#define STATUS_PORT_MESSAGE_TOO_LONG 0xC000002F
+#define STATUS_INVALID_PARAMETER_MIX 0xC0000030
+#define STATUS_INVALID_QUOTA_LOWER 0xC0000031
+#define STATUS_DISK_CORRUPT_ERROR 0xC0000032
+#define STATUS_OBJECT_NAME_INVALID 0xC0000033
+#define STATUS_OBJECT_NAME_NOT_FOUND 0xC0000034
+#define STATUS_OBJECT_NAME_COLLISION 0xC0000035
+#define STATUS_PORT_DISCONNECTED 0xC0000037
+#define STATUS_DEVICE_ALREADY_ATTACHED 0xC0000038
+#define STATUS_OBJECT_PATH_INVALID 0xC0000039
+#define STATUS_OBJECT_PATH_NOT_FOUND 0xC000003A
+#define STATUS_OBJECT_PATH_SYNTAX_BAD 0xC000003B
+#define STATUS_DATA_OVERRUN 0xC000003C
+#define STATUS_DATA_LATE_ERROR 0xC000003D
+#define STATUS_DATA_ERROR 0xC000003E
+#define STATUS_CRC_ERROR 0xC000003F
+#define STATUS_SECTION_TOO_BIG 0xC0000040
+#define STATUS_PORT_CONNECTION_REFUSED 0xC0000041
+#define STATUS_INVALID_PORT_HANDLE 0xC0000042
+#define STATUS_SHARING_VIOLATION 0xC0000043
+#define STATUS_QUOTA_EXCEEDED 0xC0000044
+#define STATUS_INVALID_PAGE_PROTECTION 0xC0000045
+#define STATUS_MUTANT_NOT_OWNED 0xC0000046
+#define STATUS_SEMAPHORE_LIMIT_EXCEEDED 0xC0000047
+#define STATUS_PORT_ALREADY_SET 0xC0000048
+#define STATUS_SECTION_NOT_IMAGE 0xC0000049
+#define STATUS_SUSPEND_COUNT_EXCEEDED 0xC000004A
+#define STATUS_THREAD_IS_TERMINATING 0xC000004B
+#define STATUS_BAD_WORKING_SET_LIMIT 0xC000004C
+#define STATUS_INCOMPATIBLE_FILE_MAP 0xC000004D
+#define STATUS_SECTION_PROTECTION 0xC000004E
+#define STATUS_EAS_NOT_SUPPORTED 0xC000004F
+#define STATUS_EA_TOO_LARGE 0xC0000050
+#define STATUS_NONEXISTENT_EA_ENTRY 0xC0000051
+#define STATUS_NO_EAS_ON_FILE 0xC0000052
+#define STATUS_EA_CORRUPT_ERROR 0xC0000053
+#define STATUS_FILE_LOCK_CONFLICT 0xC0000054
+#define STATUS_LOCK_NOT_GRANTED 0xC0000055
+#define STATUS_DELETE_PENDING 0xC0000056
+#define STATUS_CTL_FILE_NOT_SUPPORTED 0xC0000057
+#define STATUS_UNKNOWN_REVISION 0xC0000058
+#define STATUS_REVISION_MISMATCH 0xC0000059
+#define STATUS_INVALID_OWNER 0xC000005A
+#define STATUS_INVALID_PRIMARY_GROUP 0xC000005B
+#define STATUS_NO_IMPERSONATION_TOKEN 0xC000005C
+#define STATUS_CANT_DISABLE_MANDATORY 0xC000005D
+#define STATUS_NO_LOGON_SERVERS 0xC000005E
+#define STATUS_NO_SUCH_LOGON_SESSION 0xC000005F
+#define STATUS_NO_SUCH_PRIVILEGE 0xC0000060
+#define STATUS_PRIVILEGE_NOT_HELD 0xC0000061
+#define STATUS_INVALID_ACCOUNT_NAME 0xC0000062
+#define STATUS_USER_EXISTS 0xC0000063
+#define STATUS_NO_SUCH_USER 0xC0000064
+#define STATUS_GROUP_EXISTS 0xC0000065
+#define STATUS_NO_SUCH_GROUP 0xC0000066
+#define STATUS_MEMBER_IN_GROUP 0xC0000067
+#define STATUS_MEMBER_NOT_IN_GROUP 0xC0000068
+#define STATUS_LAST_ADMIN 0xC0000069
+#define STATUS_WRONG_PASSWORD 0xC000006A
+#define STATUS_ILL_FORMED_PASSWORD 0xC000006B
+#define STATUS_PASSWORD_RESTRICTION 0xC000006C
+#define STATUS_LOGON_FAILURE 0xC000006D
+#define STATUS_ACCOUNT_RESTRICTION 0xC000006E
+#define STATUS_INVALID_LOGON_HOURS 0xC000006F
+#define STATUS_INVALID_WORKSTATION 0xC0000070
+#define STATUS_PASSWORD_EXPIRED 0xC0000071
+#define STATUS_ACCOUNT_DISABLED 0xC0000072
+#define STATUS_NONE_MAPPED 0xC0000073
+#define STATUS_TOO_MANY_LUIDS_REQUESTED 0xC0000074
+#define STATUS_LUIDS_EXHAUSTED 0xC0000075
+#define STATUS_INVALID_SUB_AUTHORITY 0xC0000076
+#define STATUS_INVALID_ACL 0xC0000077
+#define STATUS_INVALID_SID 0xC0000078
+#define STATUS_INVALID_SECURITY_DESCR 0xC0000079
+#define STATUS_PROCEDURE_NOT_FOUND 0xC000007A
+#define STATUS_INVALID_IMAGE_FORMAT 0xC000007B
+#define STATUS_NO_TOKEN 0xC000007C
+#define STATUS_BAD_INHERITANCE_ACL 0xC000007D
+#define STATUS_RANGE_NOT_LOCKED 0xC000007E
+#define STATUS_DISK_FULL 0xC000007F
+#define STATUS_SERVER_DISABLED 0xC0000080
+#define STATUS_SERVER_NOT_DISABLED 0xC0000081
+#define STATUS_TOO_MANY_GUIDS_REQUESTED 0xC0000082
+#define STATUS_GUIDS_EXHAUSTED 0xC0000083
+#define STATUS_INVALID_ID_AUTHORITY 0xC0000084
+#define STATUS_AGENTS_EXHAUSTED 0xC0000085
+#define STATUS_INVALID_VOLUME_LABEL 0xC0000086
+#define STATUS_SECTION_NOT_EXTENDED 0xC0000087
+#define STATUS_NOT_MAPPED_DATA 0xC0000088
+#define STATUS_RESOURCE_DATA_NOT_FOUND 0xC0000089
+#define STATUS_RESOURCE_TYPE_NOT_FOUND 0xC000008A
+#define STATUS_RESOURCE_NAME_NOT_FOUND 0xC000008B
+#define STATUS_ARRAY_BOUNDS_EXCEEDED 0xC000008C
+#define STATUS_FLOAT_DENORMAL_OPERAND 0xC000008D
+#define STATUS_FLOAT_DIVIDE_BY_ZERO 0xC000008E
+#define STATUS_FLOAT_INEXACT_RESULT 0xC000008F
+#define STATUS_FLOAT_INVALID_OPERATION 0xC0000090
+#define STATUS_FLOAT_OVERFLOW 0xC0000091
+#define STATUS_FLOAT_STACK_CHECK 0xC0000092
+#define STATUS_FLOAT_UNDERFLOW 0xC0000093
+#define STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000094
+#define STATUS_INTEGER_OVERFLOW 0xC0000095
+#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096
+#define STATUS_TOO_MANY_PAGING_FILES 0xC0000097
+#define STATUS_FILE_INVALID 0xC0000098
+#define STATUS_ALLOTTED_SPACE_EXCEEDED 0xC0000099
+#define STATUS_INSUFFICIENT_RESOURCES 0xC000009A
+#define STATUS_DFS_EXIT_PATH_FOUND 0xC000009B
+#define STATUS_DEVICE_DATA_ERROR 0xC000009C
+#define STATUS_DEVICE_NOT_CONNECTED 0xC000009D
+#define STATUS_DEVICE_POWER_FAILURE 0xC000009E
+#define STATUS_FREE_VM_NOT_AT_BASE 0xC000009F
+#define STATUS_MEMORY_NOT_ALLOCATED 0xC00000A0
+#define STATUS_WORKING_SET_QUOTA 0xC00000A1
+#define STATUS_MEDIA_WRITE_PROTECTED 0xC00000A2
+#define STATUS_DEVICE_NOT_READY 0xC00000A3
+#define STATUS_INVALID_GROUP_ATTRIBUTES 0xC00000A4
+#define STATUS_BAD_IMPERSONATION_LEVEL 0xC00000A5
+#define STATUS_CANT_OPEN_ANONYMOUS 0xC00000A6
+#define STATUS_BAD_VALIDATION_CLASS 0xC00000A7
+#define STATUS_BAD_TOKEN_TYPE 0xC00000A8
+#define STATUS_BAD_MASTER_BOOT_RECORD 0xC00000A9
+#define STATUS_INSTRUCTION_MISALIGNMENT 0xC00000AA
+#define STATUS_INSTANCE_NOT_AVAILABLE 0xC00000AB
+#define STATUS_PIPE_NOT_AVAILABLE 0xC00000AC
+#define STATUS_INVALID_PIPE_STATE 0xC00000AD
+#define STATUS_PIPE_BUSY 0xC00000AE
+#define STATUS_ILLEGAL_FUNCTION 0xC00000AF
+#define STATUS_PIPE_DISCONNECTED 0xC00000B0
+#define STATUS_PIPE_CLOSING 0xC00000B1
+#define STATUS_PIPE_CONNECTED 0xC00000B2
+#define STATUS_PIPE_LISTENING 0xC00000B3
+#define STATUS_INVALID_READ_MODE 0xC00000B4
+#define STATUS_IO_TIMEOUT 0xC00000B5
+#define STATUS_FILE_FORCED_CLOSED 0xC00000B6
+#define STATUS_PROFILING_NOT_STARTED 0xC00000B7
+#define STATUS_PROFILING_NOT_STOPPED 0xC00000B8
+#define STATUS_COULD_NOT_INTERPRET 0xC00000B9
+#define STATUS_FILE_IS_A_DIRECTORY 0xC00000BA
+#define STATUS_NOT_SUPPORTED 0xC00000BB
+#define STATUS_REMOTE_NOT_LISTENING 0xC00000BC
+#define STATUS_DUPLICATE_NAME 0xC00000BD
+#define STATUS_BAD_NETWORK_PATH 0xC00000BE
+#define STATUS_NETWORK_BUSY 0xC00000BF
+#define STATUS_DEVICE_DOES_NOT_EXIST 0xC00000C0
+#define STATUS_TOO_MANY_COMMANDS 0xC00000C1
+#define STATUS_ADAPTER_HARDWARE_ERROR 0xC00000C2
+#define STATUS_INVALID_NETWORK_RESPONSE 0xC00000C3
+#define STATUS_UNEXPECTED_NETWORK_ERROR 0xC00000C4
+#define STATUS_BAD_REMOTE_ADAPTER 0xC00000C5
+#define STATUS_PRINT_QUEUE_FULL 0xC00000C6
+#define STATUS_NO_SPOOL_SPACE 0xC00000C7
+#define STATUS_PRINT_CANCELLED 0xC00000C8
+#define STATUS_NETWORK_NAME_DELETED 0xC00000C9
+#define STATUS_NETWORK_ACCESS_DENIED 0xC00000CA
+#define STATUS_BAD_DEVICE_TYPE 0xC00000CB
+#define STATUS_BAD_NETWORK_NAME 0xC00000CC
+#define STATUS_TOO_MANY_NAMES 0xC00000CD
+#define STATUS_TOO_MANY_SESSIONS 0xC00000CE
+#define STATUS_SHARING_PAUSED 0xC00000CF
+#define STATUS_REQUEST_NOT_ACCEPTED 0xC00000D0
+#define STATUS_REDIRECTOR_PAUSED 0xC00000D1
+#define STATUS_NET_WRITE_FAULT 0xC00000D2
+#define STATUS_PROFILING_AT_LIMIT 0xC00000D3
+#define STATUS_NOT_SAME_DEVICE 0xC00000D4
+#define STATUS_FILE_RENAMED 0xC00000D5
+#define STATUS_VIRTUAL_CIRCUIT_CLOSED 0xC00000D6
+#define STATUS_NO_SECURITY_ON_OBJECT 0xC00000D7
+#define STATUS_CANT_WAIT 0xC00000D8
+#define STATUS_PIPE_EMPTY 0xC00000D9
+#define STATUS_CANT_ACCESS_DOMAIN_INFO 0xC00000DA
+#define STATUS_CANT_TERMINATE_SELF 0xC00000DB
+#define STATUS_INVALID_SERVER_STATE 0xC00000DC
+#define STATUS_INVALID_DOMAIN_STATE 0xC00000DD
+#define STATUS_INVALID_DOMAIN_ROLE 0xC00000DE
+#define STATUS_NO_SUCH_DOMAIN 0xC00000DF
+#define STATUS_DOMAIN_EXISTS 0xC00000E0
+#define STATUS_DOMAIN_LIMIT_EXCEEDED 0xC00000E1
+#define STATUS_OPLOCK_NOT_GRANTED 0xC00000E2
+#define STATUS_INVALID_OPLOCK_PROTOCOL 0xC00000E3
+#define STATUS_INTERNAL_DB_CORRUPTION 0xC00000E4
+#define STATUS_INTERNAL_ERROR 0xC00000E5
+#define STATUS_GENERIC_NOT_MAPPED 0xC00000E6
+#define STATUS_BAD_DESCRIPTOR_FORMAT 0xC00000E7
+#define STATUS_INVALID_USER_BUFFER 0xC00000E8
+#define STATUS_UNEXPECTED_IO_ERROR 0xC00000E9
+#define STATUS_UNEXPECTED_MM_CREATE_ERR 0xC00000EA
+#define STATUS_UNEXPECTED_MM_MAP_ERROR 0xC00000EB
+#define STATUS_UNEXPECTED_MM_EXTEND_ERR 0xC00000EC
+#define STATUS_NOT_LOGON_PROCESS 0xC00000ED
+#define STATUS_LOGON_SESSION_EXISTS 0xC00000EE
+#define STATUS_INVALID_PARAMETER_1 0xC00000EF
+#define STATUS_INVALID_PARAMETER_2 0xC00000F0
+#define STATUS_INVALID_PARAMETER_3 0xC00000F1
+#define STATUS_INVALID_PARAMETER_4 0xC00000F2
+#define STATUS_INVALID_PARAMETER_5 0xC00000F3
+#define STATUS_INVALID_PARAMETER_6 0xC00000F4
+#define STATUS_INVALID_PARAMETER_7 0xC00000F5
+#define STATUS_INVALID_PARAMETER_8 0xC00000F6
+#define STATUS_INVALID_PARAMETER_9 0xC00000F7
+#define STATUS_INVALID_PARAMETER_10 0xC00000F8
+#define STATUS_INVALID_PARAMETER_11 0xC00000F9
+#define STATUS_INVALID_PARAMETER_12 0xC00000FA
+#define STATUS_REDIRECTOR_NOT_STARTED 0xC00000FB
+#define STATUS_REDIRECTOR_STARTED 0xC00000FC
+#define STATUS_STACK_OVERFLOW 0xC00000FD
+#define STATUS_NO_SUCH_PACKAGE 0xC00000FE
+#define STATUS_BAD_FUNCTION_TABLE 0xC00000FF
+#define STATUS_VARIABLE_NOT_FOUND 0xC0000100
+#define STATUS_DIRECTORY_NOT_EMPTY 0xC0000101
+#define STATUS_FILE_CORRUPT_ERROR 0xC0000102
+#define STATUS_NOT_A_DIRECTORY 0xC0000103
+#define STATUS_BAD_LOGON_SESSION_STATE 0xC0000104
+#define STATUS_LOGON_SESSION_COLLISION 0xC0000105
+#define STATUS_NAME_TOO_LONG 0xC0000106
+#define STATUS_FILES_OPEN 0xC0000107
+#define STATUS_CONNECTION_IN_USE 0xC0000108
+#define STATUS_MESSAGE_NOT_FOUND 0xC0000109
+#define STATUS_PROCESS_IS_TERMINATING 0xC000010A
+#define STATUS_INVALID_LOGON_TYPE 0xC000010B
+#define STATUS_NO_GUID_TRANSLATION 0xC000010C
+#define STATUS_CANNOT_IMPERSONATE 0xC000010D
+#define STATUS_IMAGE_ALREADY_LOADED 0xC000010E
+#define STATUS_ABIOS_NOT_PRESENT 0xC000010F
+#define STATUS_ABIOS_LID_NOT_EXIST 0xC0000110
+#define STATUS_ABIOS_LID_ALREADY_OWNED 0xC0000111
+#define STATUS_ABIOS_NOT_LID_OWNER 0xC0000112
+#define STATUS_ABIOS_INVALID_COMMAND 0xC0000113
+#define STATUS_ABIOS_INVALID_LID 0xC0000114
+#define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE 0xC0000115
+#define STATUS_ABIOS_INVALID_SELECTOR 0xC0000116
+#define STATUS_NO_LDT 0xC0000117
+#define STATUS_INVALID_LDT_SIZE 0xC0000118
+#define STATUS_INVALID_LDT_OFFSET 0xC0000119
+#define STATUS_INVALID_LDT_DESCRIPTOR 0xC000011A
+#define STATUS_INVALID_IMAGE_NE_FORMAT 0xC000011B
+#define STATUS_RXACT_INVALID_STATE 0xC000011C
+#define STATUS_RXACT_COMMIT_FAILURE 0xC000011D
+#define STATUS_MAPPED_FILE_SIZE_ZERO 0xC000011E
+#define STATUS_TOO_MANY_OPENED_FILES 0xC000011F
+#define STATUS_CANCELLED 0xC0000120
+#define STATUS_CANNOT_DELETE 0xC0000121
+#define STATUS_INVALID_COMPUTER_NAME 0xC0000122
+#define STATUS_FILE_DELETED 0xC0000123
+#define STATUS_SPECIAL_ACCOUNT 0xC0000124
+#define STATUS_SPECIAL_GROUP 0xC0000125
+#define STATUS_SPECIAL_USER 0xC0000126
+#define STATUS_MEMBERS_PRIMARY_GROUP 0xC0000127
+#define STATUS_FILE_CLOSED 0xC0000128
+#define STATUS_TOO_MANY_THREADS 0xC0000129
+#define STATUS_THREAD_NOT_IN_PROCESS 0xC000012A
+#define STATUS_TOKEN_ALREADY_IN_USE 0xC000012B
+#define STATUS_PAGEFILE_QUOTA_EXCEEDED 0xC000012C
+#define STATUS_COMMITMENT_LIMIT 0xC000012D
+#define STATUS_INVALID_IMAGE_LE_FORMAT 0xC000012E
+#define STATUS_INVALID_IMAGE_NOT_MZ 0xC000012F
+#define STATUS_INVALID_IMAGE_PROTECT 0xC0000130
+#define STATUS_INVALID_IMAGE_WIN_16 0xC0000131
+#define STATUS_LOGON_SERVER_CONFLICT 0xC0000132
+#define STATUS_TIME_DIFFERENCE_AT_DC 0xC0000133
+#define STATUS_SYNCHRONIZATION_REQUIRED 0xC0000134
+#define STATUS_DLL_NOT_FOUND 0xC0000135
+#define STATUS_OPEN_FAILED 0xC0000136
+#define STATUS_IO_PRIVILEGE_FAILED 0xC0000137
+#define STATUS_ORDINAL_NOT_FOUND 0xC0000138
+#define STATUS_ENTRYPOINT_NOT_FOUND 0xC0000139
+#define STATUS_CONTROL_C_EXIT 0xC000013A
+#define STATUS_LOCAL_DISCONNECT 0xC000013B
+#define STATUS_REMOTE_DISCONNECT 0xC000013C
+#define STATUS_REMOTE_RESOURCES 0xC000013D
+#define STATUS_LINK_FAILED 0xC000013E
+#define STATUS_LINK_TIMEOUT 0xC000013F
+#define STATUS_INVALID_CONNECTION 0xC0000140
+#define STATUS_INVALID_ADDRESS 0xC0000141
+#define STATUS_DLL_INIT_FAILED 0xC0000142
+#define STATUS_MISSING_SYSTEMFILE 0xC0000143
+#define STATUS_UNHANDLED_EXCEPTION 0xC0000144
+#define STATUS_APP_INIT_FAILURE 0xC0000145
+#define STATUS_PAGEFILE_CREATE_FAILED 0xC0000146
+#define STATUS_NO_PAGEFILE 0xC0000147
+#define STATUS_INVALID_LEVEL 0xC0000148
+#define STATUS_WRONG_PASSWORD_CORE 0xC0000149
+#define STATUS_ILLEGAL_FLOAT_CONTEXT 0xC000014A
+#define STATUS_PIPE_BROKEN 0xC000014B
+#define STATUS_REGISTRY_CORRUPT 0xC000014C
+#define STATUS_REGISTRY_IO_FAILED 0xC000014D
+#define STATUS_NO_EVENT_PAIR 0xC000014E
+#define STATUS_UNRECOGNIZED_VOLUME 0xC000014F
+#define STATUS_SERIAL_NO_DEVICE_INITED 0xC0000150
+#define STATUS_NO_SUCH_ALIAS 0xC0000151
+#define STATUS_MEMBER_NOT_IN_ALIAS 0xC0000152
+#define STATUS_MEMBER_IN_ALIAS 0xC0000153
+#define STATUS_ALIAS_EXISTS 0xC0000154
+#define STATUS_LOGON_NOT_GRANTED 0xC0000155
+#define STATUS_TOO_MANY_SECRETS 0xC0000156
+#define STATUS_SECRET_TOO_LONG 0xC0000157
+#define STATUS_INTERNAL_DB_ERROR 0xC0000158
+#define STATUS_FULLSCREEN_MODE 0xC0000159
+#define STATUS_TOO_MANY_CONTEXT_IDS 0xC000015A
+#define STATUS_LOGON_TYPE_NOT_GRANTED 0xC000015B
+#define STATUS_NOT_REGISTRY_FILE 0xC000015C
+#define STATUS_NT_CROSS_ENCRYPTION_REQUIRED 0xC000015D
+#define STATUS_DOMAIN_CTRLR_CONFIG_ERROR 0xC000015E
+#define STATUS_FT_MISSING_MEMBER 0xC000015F
+#define STATUS_ILL_FORMED_SERVICE_ENTRY 0xC0000160
+#define STATUS_ILLEGAL_CHARACTER 0xC0000161
+#define STATUS_UNMAPPABLE_CHARACTER 0xC0000162
+#define STATUS_UNDEFINED_CHARACTER 0xC0000163
+#define STATUS_FLOPPY_VOLUME 0xC0000164
+#define STATUS_FLOPPY_ID_MARK_NOT_FOUND 0xC0000165
+#define STATUS_FLOPPY_WRONG_CYLINDER 0xC0000166
+#define STATUS_FLOPPY_UNKNOWN_ERROR 0xC0000167
+#define STATUS_FLOPPY_BAD_REGISTERS 0xC0000168
+#define STATUS_DISK_RECALIBRATE_FAILED 0xC0000169
+#define STATUS_DISK_OPERATION_FAILED 0xC000016A
+#define STATUS_DISK_RESET_FAILED 0xC000016B
+#define STATUS_SHARED_IRQ_BUSY 0xC000016C
+#define STATUS_FT_ORPHANING 0xC000016D
+#define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT 0xC000016E
+#define STATUS_PARTITION_FAILURE 0xC0000172
+#define STATUS_INVALID_BLOCK_LENGTH 0xC0000173
+#define STATUS_DEVICE_NOT_PARTITIONED 0xC0000174
+#define STATUS_UNABLE_TO_LOCK_MEDIA 0xC0000175
+#define STATUS_UNABLE_TO_UNLOAD_MEDIA 0xC0000176
+#define STATUS_EOM_OVERFLOW 0xC0000177
+#define STATUS_NO_MEDIA 0xC0000178
+#define STATUS_NO_SUCH_MEMBER 0xC000017A
+#define STATUS_INVALID_MEMBER 0xC000017B
+#define STATUS_KEY_DELETED 0xC000017C
+#define STATUS_NO_LOG_SPACE 0xC000017D
+#define STATUS_TOO_MANY_SIDS 0xC000017E
+#define STATUS_LM_CROSS_ENCRYPTION_REQUIRED 0xC000017F
+#define STATUS_KEY_HAS_CHILDREN 0xC0000180
+#define STATUS_CHILD_MUST_BE_VOLATILE 0xC0000181
+#define STATUS_DEVICE_CONFIGURATION_ERROR 0xC0000182
+#define STATUS_DRIVER_INTERNAL_ERROR 0xC0000183
+#define STATUS_INVALID_DEVICE_STATE 0xC0000184
+#define STATUS_IO_DEVICE_ERROR 0xC0000185
+#define STATUS_DEVICE_PROTOCOL_ERROR 0xC0000186
+#define STATUS_BACKUP_CONTROLLER 0xC0000187
+#define STATUS_LOG_FILE_FULL 0xC0000188
+#define STATUS_TOO_LATE 0xC0000189
+#define STATUS_NO_TRUST_LSA_SECRET 0xC000018A
+#define STATUS_NO_TRUST_SAM_ACCOUNT 0xC000018B
+#define STATUS_TRUSTED_DOMAIN_FAILURE 0xC000018C
+#define STATUS_TRUSTED_RELATIONSHIP_FAILURE 0xC000018D
+#define STATUS_EVENTLOG_FILE_CORRUPT 0xC000018E
+#define STATUS_EVENTLOG_CANT_START 0xC000018F
+#define STATUS_TRUST_FAILURE 0xC0000190
+#define STATUS_MUTANT_LIMIT_EXCEEDED 0xC0000191
+#define STATUS_NETLOGON_NOT_STARTED 0xC0000192
+#define STATUS_ACCOUNT_EXPIRED 0xC0000193
+#define STATUS_POSSIBLE_DEADLOCK 0xC0000194
+#define STATUS_NETWORK_CREDENTIAL_CONFLICT 0xC0000195
+#define STATUS_REMOTE_SESSION_LIMIT 0xC0000196
+#define STATUS_EVENTLOG_FILE_CHANGED 0xC0000197
+#define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 0xC0000198
+#define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT 0xC0000199
+#define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT 0xC000019A
+#define STATUS_DOMAIN_TRUST_INCONSISTENT 0xC000019B
+#define STATUS_FS_DRIVER_REQUIRED 0xC000019C
+#define STATUS_IMAGE_ALREADY_LOADED_AS_DLL 0xC000019D
+#define STATUS_NETWORK_OPEN_RESTRICTION 0xC0000201
+#define STATUS_NO_USER_SESSION_KEY 0xC0000202
+#define STATUS_USER_SESSION_DELETED 0xC0000203
+#define STATUS_RESOURCE_LANG_NOT_FOUND 0xC0000204
+#define STATUS_INSUFF_SERVER_RESOURCES 0xC0000205
+#define STATUS_INVALID_BUFFER_SIZE 0xC0000206
+#define STATUS_INVALID_ADDRESS_COMPONENT 0xC0000207
+#define STATUS_INVALID_ADDRESS_WILDCARD 0xC0000208
+#define STATUS_TOO_MANY_ADDRESSES 0xC0000209
+#define STATUS_ADDRESS_ALREADY_EXISTS 0xC000020A
+#define STATUS_ADDRESS_CLOSED 0xC000020B
+#define STATUS_CONNECTION_DISCONNECTED 0xC000020C
+#define STATUS_CONNECTION_RESET 0xC000020D
+#define STATUS_TOO_MANY_NODES 0xC000020E
+#define STATUS_TRANSACTION_ABORTED 0xC000020F
+#define STATUS_TRANSACTION_TIMED_OUT 0xC0000210
+#define STATUS_TRANSACTION_NO_RELEASE 0xC0000211
+#define STATUS_TRANSACTION_NO_MATCH 0xC0000212
+#define STATUS_TRANSACTION_RESPONDED 0xC0000213
+#define STATUS_TRANSACTION_INVALID_ID 0xC0000214
+#define STATUS_TRANSACTION_INVALID_TYPE 0xC0000215
+#define STATUS_NOT_SERVER_SESSION 0xC0000216
+#define STATUS_NOT_CLIENT_SESSION 0xC0000217
+#define STATUS_CANNOT_LOAD_REGISTRY_FILE 0xC0000218
+#define STATUS_DEBUG_ATTACH_FAILED 0xC0000219
+#define STATUS_SYSTEM_PROCESS_TERMINATED 0xC000021A
+#define STATUS_DATA_NOT_ACCEPTED 0xC000021B
+#define STATUS_NO_BROWSER_SERVERS_FOUND 0xC000021C
+#define STATUS_VDM_HARD_ERROR 0xC000021D
+#define STATUS_DRIVER_CANCEL_TIMEOUT 0xC000021E
+#define STATUS_REPLY_MESSAGE_MISMATCH 0xC000021F
+#define STATUS_MAPPED_ALIGNMENT 0xC0000220
+#define STATUS_IMAGE_CHECKSUM_MISMATCH 0xC0000221
+#define STATUS_LOST_WRITEBEHIND_DATA 0xC0000222
+#define STATUS_CLIENT_SERVER_PARAMETERS_INVALID 0xC0000223
+#define STATUS_PASSWORD_MUST_CHANGE 0xC0000224
+#define STATUS_NOT_FOUND 0xC0000225
+#define STATUS_NOT_TINY_STREAM 0xC0000226
+#define STATUS_RECOVERY_FAILURE 0xC0000227
+#define STATUS_STACK_OVERFLOW_READ 0xC0000228
+#define STATUS_FAIL_CHECK 0xC0000229
+#define STATUS_DUPLICATE_OBJECTID 0xC000022A
+#define STATUS_OBJECTID_EXISTS 0xC000022B
+#define STATUS_CONVERT_TO_LARGE 0xC000022C
+#define STATUS_RETRY 0xC000022D
+#define STATUS_FOUND_OUT_OF_SCOPE 0xC000022E
+#define STATUS_ALLOCATE_BUCKET 0xC000022F
+#define STATUS_PROPSET_NOT_FOUND 0xC0000230
+#define STATUS_MARSHALL_OVERFLOW 0xC0000231
+#define STATUS_INVALID_VARIANT 0xC0000232
+#define STATUS_DOMAIN_CONTROLLER_NOT_FOUND 0xC0000233
+#define STATUS_ACCOUNT_LOCKED_OUT 0xC0000234
+#define STATUS_HANDLE_NOT_CLOSABLE 0xC0000235
+#define STATUS_CONNECTION_REFUSED 0xC0000236
+#define STATUS_GRACEFUL_DISCONNECT 0xC0000237
+#define STATUS_ADDRESS_ALREADY_ASSOCIATED 0xC0000238
+#define STATUS_ADDRESS_NOT_ASSOCIATED 0xC0000239
+#define STATUS_CONNECTION_INVALID 0xC000023A
+#define STATUS_CONNECTION_ACTIVE 0xC000023B
+#define STATUS_NETWORK_UNREACHABLE 0xC000023C
+#define STATUS_HOST_UNREACHABLE 0xC000023D
+#define STATUS_PROTOCOL_UNREACHABLE 0xC000023E
+#define STATUS_PORT_UNREACHABLE 0xC000023F
+#define STATUS_REQUEST_ABORTED 0xC0000240
+#define STATUS_CONNECTION_ABORTED 0xC0000241
+#define STATUS_BAD_COMPRESSION_BUFFER 0xC0000242
+#define STATUS_USER_MAPPED_FILE 0xC0000243
+#define STATUS_AUDIT_FAILED 0xC0000244
+#define STATUS_TIMER_RESOLUTION_NOT_SET 0xC0000245
+#define STATUS_CONNECTION_COUNT_LIMIT 0xC0000246
+#define STATUS_LOGIN_TIME_RESTRICTION 0xC0000247
+#define STATUS_LOGIN_WKSTA_RESTRICTION 0xC0000248
+#define STATUS_IMAGE_MP_UP_MISMATCH 0xC0000249
+#define STATUS_INSUFFICIENT_LOGON_INFO 0xC0000250
+#define STATUS_BAD_DLL_ENTRYPOINT 0xC0000251
+#define STATUS_BAD_SERVICE_ENTRYPOINT 0xC0000252
+#define STATUS_LPC_REPLY_LOST 0xC0000253
+#define STATUS_IP_ADDRESS_CONFLICT1 0xC0000254
+#define STATUS_IP_ADDRESS_CONFLICT2 0xC0000255
+#define STATUS_REGISTRY_QUOTA_LIMIT 0xC0000256
+#define STATUS_PATH_NOT_COVERED 0xC0000257
+#define STATUS_NO_CALLBACK_ACTIVE 0xC0000258
+#define STATUS_LICENSE_QUOTA_EXCEEDED 0xC0000259
+#define STATUS_PWD_TOO_SHORT 0xC000025A
+#define STATUS_PWD_TOO_RECENT 0xC000025B
+#define STATUS_PWD_HISTORY_CONFLICT 0xC000025C
+#define STATUS_PLUGPLAY_NO_DEVICE 0xC000025E
+#define STATUS_UNSUPPORTED_COMPRESSION 0xC000025F
+#define STATUS_INVALID_HW_PROFILE 0xC0000260
+#define STATUS_INVALID_PLUGPLAY_DEVICE_PATH 0xC0000261
+#define STATUS_DRIVER_ORDINAL_NOT_FOUND 0xC0000262
+#define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND 0xC0000263
+#define STATUS_RESOURCE_NOT_OWNED 0xC0000264
+#define STATUS_TOO_MANY_LINKS 0xC0000265
+#define STATUS_QUOTA_LIST_INCONSISTENT 0xC0000266
+#define STATUS_FILE_IS_OFFLINE 0xC0000267
+#define STATUS_EVALUATION_EXPIRATION 0xC0000268
+#define STATUS_ILLEGAL_DLL_RELOCATION 0xC0000269
+#define STATUS_LICENSE_VIOLATION 0xC000026A
+#define STATUS_DLL_INIT_FAILED_LOGOFF 0xC000026B
+#define STATUS_DRIVER_UNABLE_TO_LOAD 0xC000026C
+#define STATUS_DFS_UNAVAILABLE 0xC000026D
+#define STATUS_VOLUME_DISMOUNTED 0xC000026E
+#define STATUS_WX86_INTERNAL_ERROR 0xC000026F
+#define STATUS_WX86_FLOAT_STACK_CHECK 0xC0000270
+#define STATUS_VALIDATE_CONTINUE 0xC0000271
+#define STATUS_NO_MATCH 0xC0000272
+#define STATUS_NO_MORE_MATCHES 0xC0000273
+#define STATUS_NOT_A_REPARSE_POINT 0xC0000275
+#define STATUS_IO_REPARSE_TAG_INVALID 0xC0000276
+#define STATUS_IO_REPARSE_TAG_MISMATCH 0xC0000277
+#define STATUS_IO_REPARSE_DATA_INVALID 0xC0000278
+#define STATUS_IO_REPARSE_TAG_NOT_HANDLED 0xC0000279
+#define STATUS_REPARSE_POINT_NOT_RESOLVED 0xC0000280
+#define STATUS_DIRECTORY_IS_A_REPARSE_POINT 0xC0000281
+#define STATUS_RANGE_LIST_CONFLICT 0xC0000282
+#define STATUS_SOURCE_ELEMENT_EMPTY 0xC0000283
+#define STATUS_DESTINATION_ELEMENT_FULL 0xC0000284
+#define STATUS_ILLEGAL_ELEMENT_ADDRESS 0xC0000285
+#define STATUS_MAGAZINE_NOT_PRESENT 0xC0000286
+#define STATUS_REINITIALIZATION_NEEDED 0xC0000287
+#define STATUS_ENCRYPTION_FAILED 0xC000028A
+#define STATUS_DECRYPTION_FAILED 0xC000028B
+#define STATUS_RANGE_NOT_FOUND 0xC000028C
+#define STATUS_NO_RECOVERY_POLICY 0xC000028D
+#define STATUS_NO_EFS 0xC000028E
+#define STATUS_WRONG_EFS 0xC000028F
+#define STATUS_NO_USER_KEYS 0xC0000290
+#define STATUS_FILE_NOT_ENCRYPTED 0xC0000291
+#define STATUS_NOT_EXPORT_FORMAT 0xC0000292
+#define STATUS_FILE_ENCRYPTED 0xC0000293
+#define STATUS_WMI_GUID_NOT_FOUND 0xC0000295
+#define STATUS_WMI_INSTANCE_NOT_FOUND 0xC0000296
+#define STATUS_WMI_ITEMID_NOT_FOUND 0xC0000297
+#define STATUS_WMI_TRY_AGAIN 0xC0000298
+#define STATUS_SHARED_POLICY 0xC0000299
+#define STATUS_POLICY_OBJECT_NOT_FOUND 0xC000029A
+#define STATUS_POLICY_ONLY_IN_DS 0xC000029B
+#define STATUS_VOLUME_NOT_UPGRADED 0xC000029C
+#define STATUS_REMOTE_STORAGE_NOT_ACTIVE 0xC000029D
+#define STATUS_REMOTE_STORAGE_MEDIA_ERROR 0xC000029E
+#define STATUS_NO_TRACKING_SERVICE 0xC000029F
+#define STATUS_SERVER_SID_MISMATCH 0xC00002A0
+#define STATUS_DS_NO_ATTRIBUTE_OR_VALUE 0xC00002A1
+#define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX 0xC00002A2
+#define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED 0xC00002A3
+#define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS 0xC00002A4
+#define STATUS_DS_BUSY 0xC00002A5
+#define STATUS_DS_UNAVAILABLE 0xC00002A6
+#define STATUS_DS_NO_RIDS_ALLOCATED 0xC00002A7
+#define STATUS_DS_NO_MORE_RIDS 0xC00002A8
+#define STATUS_DS_INCORRECT_ROLE_OWNER 0xC00002A9
+#define STATUS_DS_RIDMGR_INIT_ERROR 0xC00002AA
+#define STATUS_DS_OBJ_CLASS_VIOLATION 0xC00002AB
+#define STATUS_DS_CANT_ON_NON_LEAF 0xC00002AC
+#define STATUS_DS_CANT_ON_RDN 0xC00002AD
+#define STATUS_DS_CANT_MOD_OBJ_CLASS 0xC00002AE
+#define STATUS_DS_CROSS_DOM_MOVE_FAILED 0xC00002AF
+#define STATUS_DS_GC_NOT_AVAILABLE 0xC00002B0
+#define STATUS_DIRECTORY_SERVICE_REQUIRED 0xC00002B1
+#define STATUS_REPARSE_ATTRIBUTE_CONFLICT 0xC00002B2
+#define STATUS_CANT_ENABLE_DENY_ONLY 0xC00002B3
+#define STATUS_FLOAT_MULTIPLE_FAULTS 0xC00002B4
+#define STATUS_FLOAT_MULTIPLE_TRAPS 0xC00002B5
+#define STATUS_DEVICE_REMOVED 0xC00002B6
+#define STATUS_JOURNAL_DELETE_IN_PROGRESS 0xC00002B7
+#define STATUS_JOURNAL_NOT_ACTIVE 0xC00002B8
+#define STATUS_NOINTERFACE 0xC00002B9
+#define STATUS_DS_ADMIN_LIMIT_EXCEEDED 0xC00002C1
+#define STATUS_DRIVER_FAILED_SLEEP 0xC00002C2
+#define STATUS_MUTUAL_AUTHENTICATION_FAILED 0xC00002C3
+#define STATUS_CORRUPT_SYSTEM_FILE 0xC00002C4
+#define STATUS_DATATYPE_MISALIGNMENT_ERROR 0xC00002C5
+#define STATUS_WMI_READ_ONLY 0xC00002C6
+#define STATUS_WMI_SET_FAILURE 0xC00002C7
+#define STATUS_COMMITMENT_MINIMUM 0xC00002C8
+#define STATUS_REG_NAT_CONSUMPTION 0xC00002C9
+#define STATUS_TRANSPORT_FULL 0xC00002CA
+#define STATUS_DS_SAM_INIT_FAILURE 0xC00002CB
+#define STATUS_ONLY_IF_CONNECTED 0xC00002CC
+#define STATUS_DS_SENSITIVE_GROUP_VIOLATION 0xC00002CD
+#define STATUS_PNP_RESTART_ENUMERATION 0xC00002CE
+#define STATUS_JOURNAL_ENTRY_DELETED 0xC00002CF
+#define STATUS_DS_CANT_MOD_PRIMARYGROUPID 0xC00002D0
+#define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE 0xC00002D1
+#define STATUS_PNP_REBOOT_REQUIRED 0xC00002D2
+#define STATUS_POWER_STATE_INVALID 0xC00002D3
+#define STATUS_DS_INVALID_GROUP_TYPE 0xC00002D4
+#define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN 0xC00002D5
+#define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN 0xC00002D6
+#define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER 0xC00002D7
+#define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER 0xC00002D8
+#define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER 0xC00002D9
+#define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER 0xC00002DA
+#define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER 0xC00002DB
+#define STATUS_DS_HAVE_PRIMARY_MEMBERS 0xC00002DC
+#define STATUS_WMI_NOT_SUPPORTED 0xC00002DD
+#define STATUS_INSUFFICIENT_POWER 0xC00002DE
+#define STATUS_SAM_NEED_BOOTKEY_PASSWORD 0xC00002DF
+#define STATUS_SAM_NEED_BOOTKEY_FLOPPY 0xC00002E0
+#define STATUS_DS_CANT_START 0xC00002E1
+#define STATUS_DS_INIT_FAILURE 0xC00002E2
+#define STATUS_SAM_INIT_FAILURE 0xC00002E3
+#define STATUS_DS_GC_REQUIRED 0xC00002E4
+#define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY 0xC00002E5
+#define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS 0xC00002E6
+#define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED 0xC00002E7
+#define STATUS_MULTIPLE_FAULT_VIOLATION 0xC00002E8
+#define STATUS_CURRENT_DOMAIN_NOT_ALLOWED 0xC00002E9
+#define STATUS_CANNOT_MAKE 0xC00002EA
+#define STATUS_SYSTEM_SHUTDOWN 0xC00002EB
+#define STATUS_DS_INIT_FAILURE_CONSOLE 0xC00002EC
+#define STATUS_DS_SAM_INIT_FAILURE_CONSOLE 0xC00002ED
+#define STATUS_UNFINISHED_CONTEXT_DELETED 0xC00002EE
+#define STATUS_NO_TGT_REPLY 0xC00002EF
+#define STATUS_OBJECTID_NOT_FOUND 0xC00002F0
+#define STATUS_NO_IP_ADDRESSES 0xC00002F1
+#define STATUS_WRONG_CREDENTIAL_HANDLE 0xC00002F2
+#define STATUS_CRYPTO_SYSTEM_INVALID 0xC00002F3
+#define STATUS_MAX_REFERRALS_EXCEEDED 0xC00002F4
+#define STATUS_MUST_BE_KDC 0xC00002F5
+#define STATUS_STRONG_CRYPTO_NOT_SUPPORTED 0xC00002F6
+#define STATUS_TOO_MANY_PRINCIPALS 0xC00002F7
+#define STATUS_NO_PA_DATA 0xC00002F8
+#define STATUS_PKINIT_NAME_MISMATCH 0xC00002F9
+#define STATUS_SMARTCARD_LOGON_REQUIRED 0xC00002FA
+#define STATUS_KDC_INVALID_REQUEST 0xC00002FB
+#define STATUS_KDC_UNABLE_TO_REFER 0xC00002FC
+#define STATUS_KDC_UNKNOWN_ETYPE 0xC00002FD
+#define STATUS_SHUTDOWN_IN_PROGRESS 0xC00002FE
+#define STATUS_SERVER_SHUTDOWN_IN_PROGRESS 0xC00002FF
+#define STATUS_NOT_SUPPORTED_ON_SBS 0xC0000300
+#define STATUS_WMI_GUID_DISCONNECTED 0xC0000301
+#define STATUS_WMI_ALREADY_DISABLED 0xC0000302
+#define STATUS_WMI_ALREADY_ENABLED 0xC0000303
+#define STATUS_MFT_TOO_FRAGMENTED 0xC0000304
+#define STATUS_COPY_PROTECTION_FAILURE 0xC0000305
+#define STATUS_CSS_AUTHENTICATION_FAILURE 0xC0000306
+#define STATUS_CSS_KEY_NOT_PRESENT 0xC0000307
+#define STATUS_CSS_KEY_NOT_ESTABLISHED 0xC0000308
+#define STATUS_CSS_SCRAMBLED_SECTOR 0xC0000309
+#define STATUS_CSS_REGION_MISMATCH 0xC000030A
+#define STATUS_CSS_RESETS_EXHAUSTED 0xC000030B
+#define STATUS_PKINIT_FAILURE 0xC0000320
+#define STATUS_SMARTCARD_SUBSYSTEM_FAILURE 0xC0000321
+#define STATUS_NO_KERB_KEY 0xC0000322
+#define STATUS_HOST_DOWN 0xC0000350
+#define STATUS_UNSUPPORTED_PREAUTH 0xC0000351
+#define STATUS_EFS_ALG_BLOB_TOO_BIG 0xC0000352
+#define STATUS_PORT_NOT_SET 0xC0000353
+#define STATUS_DEBUGGER_INACTIVE 0xC0000354
+#define STATUS_DS_VERSION_CHECK_FAILURE 0xC0000355
+#define STATUS_AUDITING_DISABLED 0xC0000356
+#define STATUS_PRENT4_MACHINE_ACCOUNT 0xC0000357
+#define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER 0xC0000358
+#define STATUS_INVALID_IMAGE_WIN_32 0xC0000359
+#define STATUS_INVALID_IMAGE_WIN_64 0xC000035A
+#define STATUS_BAD_BINDINGS 0xC000035B
+#define STATUS_NETWORK_SESSION_EXPIRED 0xC000035C
+#define STATUS_APPHELP_BLOCK 0xC000035D
+#define STATUS_ALL_SIDS_FILTERED 0xC000035E
+#define STATUS_NOT_SAFE_MODE_DRIVER 0xC000035F
+#define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT 0xC0000361
+#define STATUS_ACCESS_DISABLED_BY_POLICY_PATH 0xC0000362
+#define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER 0xC0000363
+#define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER 0xC0000364
+#define STATUS_FAILED_DRIVER_ENTRY 0xC0000365
+#define STATUS_DEVICE_ENUMERATION_ERROR 0xC0000366
+#define STATUS_MOUNT_POINT_NOT_RESOLVED 0xC0000368
+#define STATUS_INVALID_DEVICE_OBJECT_PARAMETER 0xC0000369
+#define STATUS_MCA_OCCURED 0xC000036A
+#define STATUS_DRIVER_BLOCKED_CRITICAL 0xC000036B
+#define STATUS_DRIVER_BLOCKED 0xC000036C
+#define STATUS_DRIVER_DATABASE_ERROR 0xC000036D
+#define STATUS_SYSTEM_HIVE_TOO_LARGE 0xC000036E
+#define STATUS_INVALID_IMPORT_OF_NON_DLL 0xC000036F
+#define STATUS_NO_SECRETS 0xC0000371
+#define STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY 0xC0000372
+#define STATUS_FAILED_STACK_SWITCH 0xC0000373
+#define STATUS_HEAP_CORRUPTION 0xC0000374
+#define STATUS_SMARTCARD_WRONG_PIN 0xC0000380
+#define STATUS_SMARTCARD_CARD_BLOCKED 0xC0000381
+#define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED 0xC0000382
+#define STATUS_SMARTCARD_NO_CARD 0xC0000383
+#define STATUS_SMARTCARD_NO_KEY_CONTAINER 0xC0000384
+#define STATUS_SMARTCARD_NO_CERTIFICATE 0xC0000385
+#define STATUS_SMARTCARD_NO_KEYSET 0xC0000386
+#define STATUS_SMARTCARD_IO_ERROR 0xC0000387
+#define STATUS_DOWNGRADE_DETECTED 0xC0000388
+#define STATUS_SMARTCARD_CERT_REVOKED 0xC0000389
+#define STATUS_ISSUING_CA_UNTRUSTED 0xC000038A
+#define STATUS_REVOCATION_OFFLINE_C 0xC000038B
+#define STATUS_PKINIT_CLIENT_FAILURE 0xC000038C
+#define STATUS_SMARTCARD_CERT_EXPIRED 0xC000038D
+#define STATUS_DRIVER_FAILED_PRIOR_UNLOAD 0xC000038E
+#define STATUS_SMARTCARD_SILENT_CONTEXT 0xC000038F
+#define STATUS_PER_USER_TRUST_QUOTA_EXCEEDED 0xC0000401
+#define STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED 0xC0000402
+#define STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED 0xC0000403
+#define STATUS_DS_NAME_NOT_UNIQUE 0xC0000404
+#define STATUS_DS_DUPLICATE_ID_FOUND 0xC0000405
+#define STATUS_DS_GROUP_CONVERSION_ERROR 0xC0000406
+#define STATUS_VOLSNAP_PREPARE_HIBERNATE 0xC0000407
+#define STATUS_USER2USER_REQUIRED 0xC0000408
+#define STATUS_STACK_BUFFER_OVERRUN 0xC0000409
+#define STATUS_NO_S4U_PROT_SUPPORT 0xC000040A
+#define STATUS_CROSSREALM_DELEGATION_FAILURE 0xC000040B
+#define STATUS_REVOCATION_OFFLINE_KDC 0xC000040C
+#define STATUS_ISSUING_CA_UNTRUSTED_KDC 0xC000040D
+#define STATUS_KDC_CERT_EXPIRED 0xC000040E
+#define STATUS_KDC_CERT_REVOKED 0xC000040F
+#define STATUS_PARAMETER_QUOTA_EXCEEDED 0xC0000410
+#define STATUS_HIBERNATION_FAILURE 0xC0000411
+#define STATUS_DELAY_LOAD_FAILED 0xC0000412
+#define STATUS_AUTHENTICATION_FIREWALL_FAILED 0xC0000413
+#define STATUS_VDM_DISALLOWED 0xC0000414
+#define STATUS_HUNG_DISPLAY_DRIVER_THREAD 0xC0000415
+#define STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE 0xC0000416
+#define STATUS_INVALID_CRUNTIME_PARAMETER 0xC0000417
+#define STATUS_NTLM_BLOCKED 0xC0000418
+#define STATUS_ASSERTION_FAILURE 0xC0000420
+#define STATUS_VERIFIER_STOP 0xC0000421
+#define STATUS_CALLBACK_POP_STACK 0xC0000423
+#define STATUS_INCOMPATIBLE_DRIVER_BLOCKED 0xC0000424
+#define STATUS_HIVE_UNLOADED 0xC0000425
+#define STATUS_COMPRESSION_DISABLED 0xC0000426
+#define STATUS_FILE_SYSTEM_LIMITATION 0xC0000427
+#define STATUS_INVALID_IMAGE_HASH 0xC0000428
+#define STATUS_NOT_CAPABLE 0xC0000429
+#define STATUS_REQUEST_OUT_OF_SEQUENCE 0xC000042A
+#define STATUS_IMPLEMENTATION_LIMIT 0xC000042B
+#define STATUS_ELEVATION_REQUIRED 0xC000042C
+#define STATUS_BEYOND_VDL 0xC0000432
+#define STATUS_ENCOUNTERED_WRITE_IN_PROGRESS 0xC0000433
+#define STATUS_PTE_CHANGED 0xC0000434
+#define STATUS_PURGE_FAILED 0xC0000435
+#define STATUS_CRED_REQUIRES_CONFIRMATION 0xC0000440
+#define STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE 0xC0000441
+#define STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER 0xC0000442
+#define STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE 0xC0000443
+#define STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE 0xC0000444
+#define STATUS_CS_ENCRYPTION_FILE_NOT_CSE 0xC0000445
+#define STATUS_INVALID_LABEL 0xC0000446
+#define STATUS_DRIVER_PROCESS_TERMINATED 0xC0000450
+#define STATUS_AMBIGUOUS_SYSTEM_DEVICE 0xC0000451
+#define STATUS_SYSTEM_DEVICE_NOT_FOUND 0xC0000452
+#define STATUS_RESTART_BOOT_APPLICATION 0xC0000453
+#define STATUS_INVALID_TASK_NAME 0xC0000500
+#define STATUS_INVALID_TASK_INDEX 0xC0000501
+#define STATUS_THREAD_ALREADY_IN_TASK 0xC0000502
+#define STATUS_CALLBACK_BYPASS 0xC0000503
+#define STATUS_PORT_CLOSED 0xC0000700
+#define STATUS_MESSAGE_LOST 0xC0000701
+#define STATUS_INVALID_MESSAGE 0xC0000702
+#define STATUS_REQUEST_CANCELED 0xC0000703
+#define STATUS_RECURSIVE_DISPATCH 0xC0000704
+#define STATUS_LPC_RECEIVE_BUFFER_EXPECTED 0xC0000705
+#define STATUS_LPC_INVALID_CONNECTION_USAGE 0xC0000706
+#define STATUS_LPC_REQUESTS_NOT_ALLOWED 0xC0000707
+#define STATUS_RESOURCE_IN_USE 0xC0000708
+#define STATUS_HARDWARE_MEMORY_ERROR 0xC0000709
+#define STATUS_THREADPOOL_HANDLE_EXCEPTION 0xC000070A
+#define STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED 0xC000070B
+#define STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED 0xC000070C
+#define STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED 0xC000070D
+#define STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED 0xC000070E
+#define STATUS_THREADPOOL_RELEASED_DURING_OPERATION 0xC000070F
+#define STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING 0xC0000710
+#define STATUS_APC_RETURNED_WHILE_IMPERSONATING 0xC0000711
+#define STATUS_PROCESS_IS_PROTECTED 0xC0000712
+#define STATUS_MCA_EXCEPTION 0xC0000713
+#define STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE 0xC0000714
+#define STATUS_SYMLINK_CLASS_DISABLED 0xC0000715
+#define STATUS_INVALID_IDN_NORMALIZATION 0xC0000716
+#define STATUS_NO_UNICODE_TRANSLATION 0xC0000717
+#define STATUS_ALREADY_REGISTERED 0xC0000718
+#define STATUS_CONTEXT_MISMATCH 0xC0000719
+#define STATUS_PORT_ALREADY_HAS_COMPLETION_LIST 0xC000071A
+#define STATUS_CALLBACK_RETURNED_THREAD_PRIORITY 0xC000071B
+#define STATUS_INVALID_THREAD 0xC000071C
+#define STATUS_CALLBACK_RETURNED_TRANSACTION 0xC000071D
+#define STATUS_CALLBACK_RETURNED_LDR_LOCK 0xC000071E
+#define STATUS_CALLBACK_RETURNED_LANG 0xC000071F
+#define STATUS_CALLBACK_RETURNED_PRI_BACK 0xC0000720
+#define STATUS_CALLBACK_RETURNED_THREAD_AFFINITY 0xC0000721
+#define STATUS_DISK_REPAIR_DISABLED 0xC0000800
+#define STATUS_DS_DOMAIN_RENAME_IN_PROGRESS 0xC0000801
+#define STATUS_DISK_QUOTA_EXCEEDED 0xC0000802
+#define STATUS_CONTENT_BLOCKED 0xC0000804
+#define STATUS_BAD_CLUSTERS 0xC0000805
+#define STATUS_VOLUME_DIRTY 0xC0000806
+#define STATUS_FILE_CHECKED_OUT 0xC0000901
+#define STATUS_CHECKOUT_REQUIRED 0xC0000902
+#define STATUS_BAD_FILE_TYPE 0xC0000903
+#define STATUS_FILE_TOO_LARGE 0xC0000904
+#define STATUS_FORMS_AUTH_REQUIRED 0xC0000905
+#define STATUS_VIRUS_INFECTED 0xC0000906
+#define STATUS_VIRUS_DELETED 0xC0000907
+#define STATUS_BAD_MCFG_TABLE 0xC0000908
+#define STATUS_WOW_ASSERTION 0xC0009898
+#define STATUS_INVALID_SIGNATURE 0xC000A000
+#define STATUS_HMAC_NOT_SUPPORTED 0xC000A001
+#define STATUS_IPSEC_QUEUE_OVERFLOW 0xC000A010
+#define STATUS_ND_QUEUE_OVERFLOW 0xC000A011
+#define STATUS_HOPLIMIT_EXCEEDED 0xC000A012
+#define STATUS_PROTOCOL_NOT_SUPPORTED 0xC000A013
+#define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED 0xC000A080
+#define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR 0xC000A081
+#define STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR 0xC000A082
+#define STATUS_XML_PARSE_ERROR 0xC000A083
+#define STATUS_XMLDSIG_ERROR 0xC000A084
+#define STATUS_WRONG_COMPARTMENT 0xC000A085
+#define STATUS_AUTHIP_FAILURE 0xC000A086
+#define DBG_NO_STATE_CHANGE 0xC0010001
+#define DBG_APP_NOT_IDLE 0xC0010002
+#define RPC_NT_INVALID_STRING_BINDING 0xC0020001
+#define RPC_NT_WRONG_KIND_OF_BINDING 0xC0020002
+#define RPC_NT_INVALID_BINDING 0xC0020003
+#define RPC_NT_PROTSEQ_NOT_SUPPORTED 0xC0020004
+#define RPC_NT_INVALID_RPC_PROTSEQ 0xC0020005
+#define RPC_NT_INVALID_STRING_UUID 0xC0020006
+#define RPC_NT_INVALID_ENDPOINT_FORMAT 0xC0020007
+#define RPC_NT_INVALID_NET_ADDR 0xC0020008
+#define RPC_NT_NO_ENDPOINT_FOUND 0xC0020009
+#define RPC_NT_INVALID_TIMEOUT 0xC002000A
+#define RPC_NT_OBJECT_NOT_FOUND 0xC002000B
+#define RPC_NT_ALREADY_REGISTERED 0xC002000C
+#define RPC_NT_TYPE_ALREADY_REGISTERED 0xC002000D
+#define RPC_NT_ALREADY_LISTENING 0xC002000E
+#define RPC_NT_NO_PROTSEQS_REGISTERED 0xC002000F
+#define RPC_NT_NOT_LISTENING 0xC0020010
+#define RPC_NT_UNKNOWN_MGR_TYPE 0xC0020011
+#define RPC_NT_UNKNOWN_IF 0xC0020012
+#define RPC_NT_NO_BINDINGS 0xC0020013
+#define RPC_NT_NO_PROTSEQS 0xC0020014
+#define RPC_NT_CANT_CREATE_ENDPOINT 0xC0020015
+#define RPC_NT_OUT_OF_RESOURCES 0xC0020016
+#define RPC_NT_SERVER_UNAVAILABLE 0xC0020017
+#define RPC_NT_SERVER_TOO_BUSY 0xC0020018
+#define RPC_NT_INVALID_NETWORK_OPTIONS 0xC0020019
+#define RPC_NT_NO_CALL_ACTIVE 0xC002001A
+#define RPC_NT_CALL_FAILED 0xC002001B
+#define RPC_NT_CALL_FAILED_DNE 0xC002001C
+#define RPC_NT_PROTOCOL_ERROR 0xC002001D
+#define RPC_NT_UNSUPPORTED_TRANS_SYN 0xC002001F
+#define RPC_NT_UNSUPPORTED_TYPE 0xC0020021
+#define RPC_NT_INVALID_TAG 0xC0020022
+#define RPC_NT_INVALID_BOUND 0xC0020023
+#define RPC_NT_NO_ENTRY_NAME 0xC0020024
+#define RPC_NT_INVALID_NAME_SYNTAX 0xC0020025
+#define RPC_NT_UNSUPPORTED_NAME_SYNTAX 0xC0020026
+#define RPC_NT_UUID_NO_ADDRESS 0xC0020028
+#define RPC_NT_DUPLICATE_ENDPOINT 0xC0020029
+#define RPC_NT_UNKNOWN_AUTHN_TYPE 0xC002002A
+#define RPC_NT_MAX_CALLS_TOO_SMALL 0xC002002B
+#define RPC_NT_STRING_TOO_LONG 0xC002002C
+#define RPC_NT_PROTSEQ_NOT_FOUND 0xC002002D
+#define RPC_NT_PROCNUM_OUT_OF_RANGE 0xC002002E
+#define RPC_NT_BINDING_HAS_NO_AUTH 0xC002002F
+#define RPC_NT_UNKNOWN_AUTHN_SERVICE 0xC0020030
+#define RPC_NT_UNKNOWN_AUTHN_LEVEL 0xC0020031
+#define RPC_NT_INVALID_AUTH_IDENTITY 0xC0020032
+#define RPC_NT_UNKNOWN_AUTHZ_SERVICE 0xC0020033
+#define EPT_NT_INVALID_ENTRY 0xC0020034
+#define EPT_NT_CANT_PERFORM_OP 0xC0020035
+#define EPT_NT_NOT_REGISTERED 0xC0020036
+#define RPC_NT_NOTHING_TO_EXPORT 0xC0020037
+#define RPC_NT_INCOMPLETE_NAME 0xC0020038
+#define RPC_NT_INVALID_VERS_OPTION 0xC0020039
+#define RPC_NT_NO_MORE_MEMBERS 0xC002003A
+#define RPC_NT_NOT_ALL_OBJS_UNEXPORTED 0xC002003B
+#define RPC_NT_INTERFACE_NOT_FOUND 0xC002003C
+#define RPC_NT_ENTRY_ALREADY_EXISTS 0xC002003D
+#define RPC_NT_ENTRY_NOT_FOUND 0xC002003E
+#define RPC_NT_NAME_SERVICE_UNAVAILABLE 0xC002003F
+#define RPC_NT_INVALID_NAF_ID 0xC0020040
+#define RPC_NT_CANNOT_SUPPORT 0xC0020041
+#define RPC_NT_NO_CONTEXT_AVAILABLE 0xC0020042
+#define RPC_NT_INTERNAL_ERROR 0xC0020043
+#define RPC_NT_ZERO_DIVIDE 0xC0020044
+#define RPC_NT_ADDRESS_ERROR 0xC0020045
+#define RPC_NT_FP_DIV_ZERO 0xC0020046
+#define RPC_NT_FP_UNDERFLOW 0xC0020047
+#define RPC_NT_FP_OVERFLOW 0xC0020048
+#define RPC_NT_CALL_IN_PROGRESS 0xC0020049
+#define RPC_NT_NO_MORE_BINDINGS 0xC002004A
+#define RPC_NT_GROUP_MEMBER_NOT_FOUND 0xC002004B
+#define EPT_NT_CANT_CREATE 0xC002004C
+#define RPC_NT_INVALID_OBJECT 0xC002004D
+#define RPC_NT_NO_INTERFACES 0xC002004F
+#define RPC_NT_CALL_CANCELLED 0xC0020050
+#define RPC_NT_BINDING_INCOMPLETE 0xC0020051
+#define RPC_NT_COMM_FAILURE 0xC0020052
+#define RPC_NT_UNSUPPORTED_AUTHN_LEVEL 0xC0020053
+#define RPC_NT_NO_PRINC_NAME 0xC0020054
+#define RPC_NT_NOT_RPC_ERROR 0xC0020055
+#define RPC_NT_SEC_PKG_ERROR 0xC0020057
+#define RPC_NT_NOT_CANCELLED 0xC0020058
+#define RPC_NT_INVALID_ASYNC_HANDLE 0xC0020062
+#define RPC_NT_INVALID_ASYNC_CALL 0xC0020063
+#define RPC_NT_PROXY_ACCESS_DENIED 0xC0020064
+#define RPC_NT_NO_MORE_ENTRIES 0xC0030001
+#define RPC_NT_SS_CHAR_TRANS_OPEN_FAIL 0xC0030002
+#define RPC_NT_SS_CHAR_TRANS_SHORT_FILE 0xC0030003
+#define RPC_NT_SS_IN_NULL_CONTEXT 0xC0030004
+#define RPC_NT_SS_CONTEXT_MISMATCH 0xC0030005
+#define RPC_NT_SS_CONTEXT_DAMAGED 0xC0030006
+#define RPC_NT_SS_HANDLES_MISMATCH 0xC0030007
+#define RPC_NT_SS_CANNOT_GET_CALL_HANDLE 0xC0030008
+#define RPC_NT_NULL_REF_POINTER 0xC0030009
+#define RPC_NT_ENUM_VALUE_OUT_OF_RANGE 0xC003000A
+#define RPC_NT_BYTE_COUNT_TOO_SMALL 0xC003000B
+#define RPC_NT_BAD_STUB_DATA 0xC003000C
+#define RPC_NT_INVALID_ES_ACTION 0xC0030059
+#define RPC_NT_WRONG_ES_VERSION 0xC003005A
+#define RPC_NT_WRONG_STUB_VERSION 0xC003005B
+#define RPC_NT_INVALID_PIPE_OBJECT 0xC003005C
+#define RPC_NT_INVALID_PIPE_OPERATION 0xC003005D
+#define RPC_NT_WRONG_PIPE_VERSION 0xC003005E
+#define RPC_NT_PIPE_CLOSED 0xC003005F
+#define RPC_NT_PIPE_DISCIPLINE_ERROR 0xC0030060
+#define RPC_NT_PIPE_EMPTY 0xC0030061
+#define STATUS_PNP_BAD_MPS_TABLE 0xC0040035
+#define STATUS_PNP_TRANSLATION_FAILED 0xC0040036
+#define STATUS_PNP_IRQ_TRANSLATION_FAILED 0xC0040037
+#define STATUS_PNP_INVALID_ID 0xC0040038
+#define STATUS_IO_REISSUE_AS_CACHED 0xC0040039
+#define STATUS_CTX_WINSTATION_NAME_INVALID 0xC00A0001
+#define STATUS_CTX_INVALID_PD 0xC00A0002
+#define STATUS_CTX_PD_NOT_FOUND 0xC00A0003
+#define STATUS_CTX_CLOSE_PENDING 0xC00A0006
+#define STATUS_CTX_NO_OUTBUF 0xC00A0007
+#define STATUS_CTX_MODEM_INF_NOT_FOUND 0xC00A0008
+#define STATUS_CTX_INVALID_MODEMNAME 0xC00A0009
+#define STATUS_CTX_RESPONSE_ERROR 0xC00A000A
+#define STATUS_CTX_MODEM_RESPONSE_TIMEOUT 0xC00A000B
+#define STATUS_CTX_MODEM_RESPONSE_NO_CARRIER 0xC00A000C
+#define STATUS_CTX_MODEM_RESPONSE_NO_DIALTONE 0xC00A000D
+#define STATUS_CTX_MODEM_RESPONSE_BUSY 0xC00A000E
+#define STATUS_CTX_MODEM_RESPONSE_VOICE 0xC00A000F
+#define STATUS_CTX_TD_ERROR 0xC00A0010
+#define STATUS_CTX_LICENSE_CLIENT_INVALID 0xC00A0012
+#define STATUS_CTX_LICENSE_NOT_AVAILABLE 0xC00A0013
+#define STATUS_CTX_LICENSE_EXPIRED 0xC00A0014
+#define STATUS_CTX_WINSTATION_NOT_FOUND 0xC00A0015
+#define STATUS_CTX_WINSTATION_NAME_COLLISION 0xC00A0016
+#define STATUS_CTX_WINSTATION_BUSY 0xC00A0017
+#define STATUS_CTX_BAD_VIDEO_MODE 0xC00A0018
+#define STATUS_CTX_GRAPHICS_INVALID 0xC00A0022
+#define STATUS_CTX_NOT_CONSOLE 0xC00A0024
+#define STATUS_CTX_CLIENT_QUERY_TIMEOUT 0xC00A0026
+#define STATUS_CTX_CONSOLE_DISCONNECT 0xC00A0027
+#define STATUS_CTX_CONSOLE_CONNECT 0xC00A0028
+#define STATUS_CTX_SHADOW_DENIED 0xC00A002A
+#define STATUS_CTX_WINSTATION_ACCESS_DENIED 0xC00A002B
+#define STATUS_CTX_INVALID_WD 0xC00A002E
+#define STATUS_CTX_WD_NOT_FOUND 0xC00A002F
+#define STATUS_CTX_SHADOW_INVALID 0xC00A0030
+#define STATUS_CTX_SHADOW_DISABLED 0xC00A0031
+#define STATUS_RDP_PROTOCOL_ERROR 0xC00A0032
+#define STATUS_CTX_CLIENT_LICENSE_NOT_SET 0xC00A0033
+#define STATUS_CTX_CLIENT_LICENSE_IN_USE 0xC00A0034
+#define STATUS_CTX_SHADOW_ENDED_BY_MODE_CHANGE 0xC00A0035
+#define STATUS_CTX_SHADOW_NOT_RUNNING 0xC00A0036
+#define STATUS_CTX_LOGON_DISABLED 0xC00A0037
+#define STATUS_CTX_SECURITY_LAYER_ERROR 0xC00A0038
+#define STATUS_TS_INCOMPATIBLE_SESSIONS 0xC00A0039
+#define STATUS_MUI_FILE_NOT_FOUND 0xC00B0001
+#define STATUS_MUI_INVALID_FILE 0xC00B0002
+#define STATUS_MUI_INVALID_RC_CONFIG 0xC00B0003
+#define STATUS_MUI_INVALID_LOCALE_NAME 0xC00B0004
+#define STATUS_MUI_INVALID_ULTIMATEFALLBACK_NAME 0xC00B0005
+#define STATUS_MUI_FILE_NOT_LOADED 0xC00B0006
+#define STATUS_RESOURCE_ENUM_USER_STOP 0xC00B0007
+#define STATUS_CLUSTER_INVALID_NODE 0xC0130001
+#define STATUS_CLUSTER_NODE_EXISTS 0xC0130002
+#define STATUS_CLUSTER_JOIN_IN_PROGRESS 0xC0130003
+#define STATUS_CLUSTER_NODE_NOT_FOUND 0xC0130004
+#define STATUS_CLUSTER_LOCAL_NODE_NOT_FOUND 0xC0130005
+#define STATUS_CLUSTER_NETWORK_EXISTS 0xC0130006
+#define STATUS_CLUSTER_NETWORK_NOT_FOUND 0xC0130007
+#define STATUS_CLUSTER_NETINTERFACE_EXISTS 0xC0130008
+#define STATUS_CLUSTER_NETINTERFACE_NOT_FOUND 0xC0130009
+#define STATUS_CLUSTER_INVALID_REQUEST 0xC013000A
+#define STATUS_CLUSTER_INVALID_NETWORK_PROVIDER 0xC013000B
+#define STATUS_CLUSTER_NODE_DOWN 0xC013000C
+#define STATUS_CLUSTER_NODE_UNREACHABLE 0xC013000D
+#define STATUS_CLUSTER_NODE_NOT_MEMBER 0xC013000E
+#define STATUS_CLUSTER_JOIN_NOT_IN_PROGRESS 0xC013000F
+#define STATUS_CLUSTER_INVALID_NETWORK 0xC0130010
+#define STATUS_CLUSTER_NO_NET_ADAPTERS 0xC0130011
+#define STATUS_CLUSTER_NODE_UP 0xC0130012
+#define STATUS_CLUSTER_NODE_PAUSED 0xC0130013
+#define STATUS_CLUSTER_NODE_NOT_PAUSED 0xC0130014
+#define STATUS_CLUSTER_NO_SECURITY_CONTEXT 0xC0130015
+#define STATUS_CLUSTER_NETWORK_NOT_INTERNAL 0xC0130016
+#define STATUS_CLUSTER_POISONED 0xC0130017
+#define STATUS_ACPI_INVALID_OPCODE 0xC0140001
+#define STATUS_ACPI_STACK_OVERFLOW 0xC0140002
+#define STATUS_ACPI_ASSERT_FAILED 0xC0140003
+#define STATUS_ACPI_INVALID_INDEX 0xC0140004
+#define STATUS_ACPI_INVALID_ARGUMENT 0xC0140005
+#define STATUS_ACPI_FATAL 0xC0140006
+#define STATUS_ACPI_INVALID_SUPERNAME 0xC0140007
+#define STATUS_ACPI_INVALID_ARGTYPE 0xC0140008
+#define STATUS_ACPI_INVALID_OBJTYPE 0xC0140009
+#define STATUS_ACPI_INVALID_TARGETTYPE 0xC014000A
+#define STATUS_ACPI_INCORRECT_ARGUMENT_COUNT 0xC014000B
+#define STATUS_ACPI_ADDRESS_NOT_MAPPED 0xC014000C
+#define STATUS_ACPI_INVALID_EVENTTYPE 0xC014000D
+#define STATUS_ACPI_HANDLER_COLLISION 0xC014000E
+#define STATUS_ACPI_INVALID_DATA 0xC014000F
+#define STATUS_ACPI_INVALID_REGION 0xC0140010
+#define STATUS_ACPI_INVALID_ACCESS_SIZE 0xC0140011
+#define STATUS_ACPI_ACQUIRE_GLOBAL_LOCK 0xC0140012
+#define STATUS_ACPI_ALREADY_INITIALIZED 0xC0140013
+#define STATUS_ACPI_NOT_INITIALIZED 0xC0140014
+#define STATUS_ACPI_INVALID_MUTEX_LEVEL 0xC0140015
+#define STATUS_ACPI_MUTEX_NOT_OWNED 0xC0140016
+#define STATUS_ACPI_MUTEX_NOT_OWNER 0xC0140017
+#define STATUS_ACPI_RS_ACCESS 0xC0140018
+#define STATUS_ACPI_INVALID_TABLE 0xC0140019
+#define STATUS_ACPI_REG_HANDLER_FAILED 0xC0140020
+#define STATUS_ACPI_POWER_REQUEST_FAILED 0xC0140021
+#define STATUS_SXS_SECTION_NOT_FOUND 0xC0150001
+#define STATUS_SXS_CANT_GEN_ACTCTX 0xC0150002
+#define STATUS_SXS_INVALID_ACTCTXDATA_FORMAT 0xC0150003
+#define STATUS_SXS_ASSEMBLY_NOT_FOUND 0xC0150004
+#define STATUS_SXS_MANIFEST_FORMAT_ERROR 0xC0150005
+#define STATUS_SXS_MANIFEST_PARSE_ERROR 0xC0150006
+#define STATUS_SXS_ACTIVATION_CONTEXT_DISABLED 0xC0150007
+#define STATUS_SXS_KEY_NOT_FOUND 0xC0150008
+#define STATUS_SXS_VERSION_CONFLICT 0xC0150009
+#define STATUS_SXS_WRONG_SECTION_TYPE 0xC015000A
+#define STATUS_SXS_THREAD_QUERIES_DISABLED 0xC015000B
+#define STATUS_SXS_ASSEMBLY_MISSING 0xC015000C
+#define STATUS_SXS_PROCESS_DEFAULT_ALREADY_SET 0xC015000E
+#define STATUS_SXS_EARLY_DEACTIVATION 0xC015000F
+#define STATUS_SXS_INVALID_DEACTIVATION 0xC0150010
+#define STATUS_SXS_MULTIPLE_DEACTIVATION 0xC0150011
+#define STATUS_SXS_SYSTEM_DEFAULT_ACTIVATION_CONTEXT_EMPTY 0xC0150012
+#define STATUS_SXS_PROCESS_TERMINATION_REQUESTED 0xC0150013
+#define STATUS_SXS_CORRUPT_ACTIVATION_STACK 0xC0150014
+#define STATUS_SXS_CORRUPTION 0xC0150015
+#define STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_VALUE 0xC0150016
+#define STATUS_SXS_INVALID_IDENTITY_ATTRIBUTE_NAME 0xC0150017
+#define STATUS_SXS_IDENTITY_DUPLICATE_ATTRIBUTE 0xC0150018
+#define STATUS_SXS_IDENTITY_PARSE_ERROR 0xC0150019
+#define STATUS_SXS_COMPONENT_STORE_CORRUPT 0xC015001A
+#define STATUS_SXS_FILE_HASH_MISMATCH 0xC015001B
+#define STATUS_SXS_MANIFEST_IDENTITY_SAME_BUT_CONTENTS_DIFFERENT 0xC015001C
+#define STATUS_SXS_IDENTITIES_DIFFERENT 0xC015001D
+#define STATUS_SXS_ASSEMBLY_IS_NOT_A_DEPLOYMENT 0xC015001E
+#define STATUS_SXS_FILE_NOT_PART_OF_ASSEMBLY 0xC015001F
+#define STATUS_ADVANCED_INSTALLER_FAILED 0xC0150020
+#define STATUS_XML_ENCODING_MISMATCH 0xC0150021
+#define STATUS_SXS_MANIFEST_TOO_BIG 0xC0150022
+#define STATUS_SXS_SETTING_NOT_REGISTERED 0xC0150023
+#define STATUS_SXS_TRANSACTION_CLOSURE_INCOMPLETE 0xC0150024
+#define STATUS_SMI_PRIMITIVE_INSTALLER_FAILED 0xC0150025
+#define STATUS_GENERIC_COMMAND_FAILED 0xC0150026
+#define STATUS_SXS_FILE_HASH_MISSING 0xC0150027
+#define STATUS_TRANSACTIONAL_CONFLICT 0xC0190001
+#define STATUS_INVALID_TRANSACTION 0xC0190002
+#define STATUS_TRANSACTION_NOT_ACTIVE 0xC0190003
+#define STATUS_TM_INITIALIZATION_FAILED 0xC0190004
+#define STATUS_RM_NOT_ACTIVE 0xC0190005
+#define STATUS_RM_METADATA_CORRUPT 0xC0190006
+#define STATUS_TRANSACTION_NOT_JOINED 0xC0190007
+#define STATUS_DIRECTORY_NOT_RM 0xC0190008
+#define STATUS_TRANSACTIONS_UNSUPPORTED_REMOTE 0xC019000A
+#define STATUS_LOG_RESIZE_INVALID_SIZE 0xC019000B
+#define STATUS_REMOTE_FILE_VERSION_MISMATCH 0xC019000C
+#define STATUS_CRM_PROTOCOL_ALREADY_EXISTS 0xC019000F
+#define STATUS_TRANSACTION_PROPAGATION_FAILED 0xC0190010
+#define STATUS_CRM_PROTOCOL_NOT_FOUND 0xC0190011
+#define STATUS_TRANSACTION_SUPERIOR_EXISTS 0xC0190012
+#define STATUS_TRANSACTION_REQUEST_NOT_VALID 0xC0190013
+#define STATUS_TRANSACTION_NOT_REQUESTED 0xC0190014
+#define STATUS_TRANSACTION_ALREADY_ABORTED 0xC0190015
+#define STATUS_TRANSACTION_ALREADY_COMMITTED 0xC0190016
+#define STATUS_TRANSACTION_INVALID_MARSHALL_BUFFER 0xC0190017
+#define STATUS_CURRENT_TRANSACTION_NOT_VALID 0xC0190018
+#define STATUS_LOG_GROWTH_FAILED 0xC0190019
+#define STATUS_OBJECT_NO_LONGER_EXISTS 0xC0190021
+#define STATUS_STREAM_MINIVERSION_NOT_FOUND 0xC0190022
+#define STATUS_STREAM_MINIVERSION_NOT_VALID 0xC0190023
+#define STATUS_MINIVERSION_INACCESSIBLE_FROM_SPECIFIED_TRANSACTION 0xC0190024
+#define STATUS_CANT_OPEN_MINIVERSION_WITH_MODIFY_INTENT 0xC0190025
+#define STATUS_CANT_CREATE_MORE_STREAM_MINIVERSIONS 0xC0190026
+#define STATUS_HANDLE_NO_LONGER_VALID 0xC0190028
+#define STATUS_LOG_CORRUPTION_DETECTED 0xC0190030
+#define STATUS_RM_DISCONNECTED 0xC0190032
+#define STATUS_ENLISTMENT_NOT_SUPERIOR 0xC0190033
+#define STATUS_FILE_IDENTITY_NOT_PERSISTENT 0xC0190036
+#define STATUS_CANT_BREAK_TRANSACTIONAL_DEPENDENCY 0xC0190037
+#define STATUS_CANT_CROSS_RM_BOUNDARY 0xC0190038
+#define STATUS_TXF_DIR_NOT_EMPTY 0xC0190039
+#define STATUS_INDOUBT_TRANSACTIONS_EXIST 0xC019003A
+#define STATUS_TM_VOLATILE 0xC019003B
+#define STATUS_ROLLBACK_TIMER_EXPIRED 0xC019003C
+#define STATUS_TXF_ATTRIBUTE_CORRUPT 0xC019003D
+#define STATUS_EFS_NOT_ALLOWED_IN_TRANSACTION 0xC019003E
+#define STATUS_TRANSACTIONAL_OPEN_NOT_ALLOWED 0xC019003F
+#define STATUS_TRANSACTED_MAPPING_UNSUPPORTED_REMOTE 0xC0190040
+#define STATUS_TRANSACTION_REQUIRED_PROMOTION 0xC0190043
+#define STATUS_CANNOT_EXECUTE_FILE_IN_TRANSACTION 0xC0190044
+#define STATUS_TRANSACTIONS_NOT_FROZEN 0xC0190045
+#define STATUS_TRANSACTION_FREEZE_IN_PROGRESS 0xC0190046
+#define STATUS_NOT_SNAPSHOT_VOLUME 0xC0190047
+#define STATUS_NO_SAVEPOINT_WITH_OPEN_FILES 0xC0190048
+#define STATUS_SPARSE_NOT_ALLOWED_IN_TRANSACTION 0xC0190049
+#define STATUS_TM_IDENTITY_MISMATCH 0xC019004A
+#define STATUS_FLOATED_SECTION 0xC019004B
+#define STATUS_CANNOT_ACCEPT_TRANSACTED_WORK 0xC019004C
+#define STATUS_CANNOT_ABORT_TRANSACTIONS 0xC019004D
+#define STATUS_TRANSACTION_NOT_FOUND 0xC019004E
+#define STATUS_RESOURCEMANAGER_NOT_FOUND 0xC019004F
+#define STATUS_ENLISTMENT_NOT_FOUND 0xC0190050
+#define STATUS_TRANSACTIONMANAGER_NOT_FOUND 0xC0190051
+#define STATUS_TRANSACTIONMANAGER_NOT_ONLINE 0xC0190052
+#define STATUS_TRANSACTIONMANAGER_RECOVERY_NAME_COLLISION 0xC0190053
+#define STATUS_TRANSACTION_NOT_ROOT 0xC0190054
+#define STATUS_TRANSACTION_OBJECT_EXPIRED 0xC0190055
+#define STATUS_COMPRESSION_NOT_ALLOWED_IN_TRANSACTION 0xC0190056
+#define STATUS_TRANSACTION_RESPONSE_NOT_ENLISTED 0xC0190057
+#define STATUS_TRANSACTION_RECORD_TOO_LONG 0xC0190058
+#define STATUS_NO_LINK_TRACKING_IN_TRANSACTION 0xC0190059
+#define STATUS_OPERATION_NOT_SUPPORTED_IN_TRANSACTION 0xC019005A
+#define STATUS_TRANSACTION_INTEGRITY_VIOLATED 0xC019005B
+#define STATUS_LOG_SECTOR_INVALID 0xC01A0001
+#define STATUS_LOG_SECTOR_PARITY_INVALID 0xC01A0002
+#define STATUS_LOG_SECTOR_REMAPPED 0xC01A0003
+#define STATUS_LOG_BLOCK_INCOMPLETE 0xC01A0004
+#define STATUS_LOG_INVALID_RANGE 0xC01A0005
+#define STATUS_LOG_BLOCKS_EXHAUSTED 0xC01A0006
+#define STATUS_LOG_READ_CONTEXT_INVALID 0xC01A0007
+#define STATUS_LOG_RESTART_INVALID 0xC01A0008
+#define STATUS_LOG_BLOCK_VERSION 0xC01A0009
+#define STATUS_LOG_BLOCK_INVALID 0xC01A000A
+#define STATUS_LOG_READ_MODE_INVALID 0xC01A000B
+#define STATUS_LOG_METADATA_CORRUPT 0xC01A000D
+#define STATUS_LOG_METADATA_INVALID 0xC01A000E
+#define STATUS_LOG_METADATA_INCONSISTENT 0xC01A000F
+#define STATUS_LOG_RESERVATION_INVALID 0xC01A0010
+#define STATUS_LOG_CANT_DELETE 0xC01A0011
+#define STATUS_LOG_CONTAINER_LIMIT_EXCEEDED 0xC01A0012
+#define STATUS_LOG_START_OF_LOG 0xC01A0013
+#define STATUS_LOG_POLICY_ALREADY_INSTALLED 0xC01A0014
+#define STATUS_LOG_POLICY_NOT_INSTALLED 0xC01A0015
+#define STATUS_LOG_POLICY_INVALID 0xC01A0016
+#define STATUS_LOG_POLICY_CONFLICT 0xC01A0017
+#define STATUS_LOG_PINNED_ARCHIVE_TAIL 0xC01A0018
+#define STATUS_LOG_RECORD_NONEXISTENT 0xC01A0019
+#define STATUS_LOG_RECORDS_RESERVED_INVALID 0xC01A001A
+#define STATUS_LOG_SPACE_RESERVED_INVALID 0xC01A001B
+#define STATUS_LOG_TAIL_INVALID 0xC01A001C
+#define STATUS_LOG_FULL 0xC01A001D
+#define STATUS_LOG_MULTIPLEXED 0xC01A001E
+#define STATUS_LOG_DEDICATED 0xC01A001F
+#define STATUS_LOG_ARCHIVE_NOT_IN_PROGRESS 0xC01A0020
+#define STATUS_LOG_ARCHIVE_IN_PROGRESS 0xC01A0021
+#define STATUS_LOG_EPHEMERAL 0xC01A0022
+#define STATUS_LOG_NOT_ENOUGH_CONTAINERS 0xC01A0023
+#define STATUS_LOG_CLIENT_ALREADY_REGISTERED 0xC01A0024
+#define STATUS_LOG_CLIENT_NOT_REGISTERED 0xC01A0025
+#define STATUS_LOG_FULL_HANDLER_IN_PROGRESS 0xC01A0026
+#define STATUS_LOG_CONTAINER_READ_FAILED 0xC01A0027
+#define STATUS_LOG_CONTAINER_WRITE_FAILED 0xC01A0028
+#define STATUS_LOG_CONTAINER_OPEN_FAILED 0xC01A0029
+#define STATUS_LOG_CONTAINER_STATE_INVALID 0xC01A002A
+#define STATUS_LOG_STATE_INVALID 0xC01A002B
+#define STATUS_LOG_PINNED 0xC01A002C
+#define STATUS_LOG_METADATA_FLUSH_FAILED 0xC01A002D
+#define STATUS_LOG_INCONSISTENT_SECURITY 0xC01A002E
+#define STATUS_LOG_APPENDED_FLUSH_FAILED 0xC01A002F
+#define STATUS_LOG_PINNED_RESERVATION 0xC01A0030
+#define STATUS_VIDEO_HUNG_DISPLAY_DRIVER_THREAD 0xC01B00EA
+#define STATUS_FLT_NO_HANDLER_DEFINED 0xC01C0001
+#define STATUS_FLT_CONTEXT_ALREADY_DEFINED 0xC01C0002
+#define STATUS_FLT_INVALID_ASYNCHRONOUS_REQUEST 0xC01C0003
+#define STATUS_FLT_DISALLOW_FAST_IO 0xC01C0004
+#define STATUS_FLT_INVALID_NAME_REQUEST 0xC01C0005
+#define STATUS_FLT_NOT_SAFE_TO_POST_OPERATION 0xC01C0006
+#define STATUS_FLT_NOT_INITIALIZED 0xC01C0007
+#define STATUS_FLT_FILTER_NOT_READY 0xC01C0008
+#define STATUS_FLT_POST_OPERATION_CLEANUP 0xC01C0009
+#define STATUS_FLT_INTERNAL_ERROR 0xC01C000A
+#define STATUS_FLT_DELETING_OBJECT 0xC01C000B
+#define STATUS_FLT_MUST_BE_NONPAGED_POOL 0xC01C000C
+#define STATUS_FLT_DUPLICATE_ENTRY 0xC01C000D
+#define STATUS_FLT_CBDQ_DISABLED 0xC01C000E
+#define STATUS_FLT_DO_NOT_ATTACH 0xC01C000F
+#define STATUS_FLT_DO_NOT_DETACH 0xC01C0010
+#define STATUS_FLT_INSTANCE_ALTITUDE_COLLISION 0xC01C0011
+#define STATUS_FLT_INSTANCE_NAME_COLLISION 0xC01C0012
+#define STATUS_FLT_FILTER_NOT_FOUND 0xC01C0013
+#define STATUS_FLT_VOLUME_NOT_FOUND 0xC01C0014
+#define STATUS_FLT_INSTANCE_NOT_FOUND 0xC01C0015
+#define STATUS_FLT_CONTEXT_ALLOCATION_NOT_FOUND 0xC01C0016
+#define STATUS_FLT_INVALID_CONTEXT_REGISTRATION 0xC01C0017
+#define STATUS_FLT_NAME_CACHE_MISS 0xC01C0018
+#define STATUS_FLT_NO_DEVICE_OBJECT 0xC01C0019
+#define STATUS_FLT_VOLUME_ALREADY_MOUNTED 0xC01C001A
+#define STATUS_FLT_ALREADY_ENLISTED 0xC01C001B
+#define STATUS_FLT_CONTEXT_ALREADY_LINKED 0xC01C001C
+#define STATUS_FLT_NO_WAITER_FOR_REPLY 0xC01C0020
+#define STATUS_MONITOR_NO_DESCRIPTOR 0xC01D0001
+#define STATUS_MONITOR_UNKNOWN_DESCRIPTOR_FORMAT 0xC01D0002
+#define STATUS_MONITOR_INVALID_DESCRIPTOR_CHECKSUM 0xC01D0003
+#define STATUS_MONITOR_INVALID_STANDARD_TIMING_BLOCK 0xC01D0004
+#define STATUS_MONITOR_WMI_DATABLOCK_REGISTRATION_FAILED 0xC01D0005
+#define STATUS_MONITOR_INVALID_SERIAL_NUMBER_MONDSC_BLOCK 0xC01D0006
+#define STATUS_MONITOR_INVALID_USER_FRIENDLY_MONDSC_BLOCK 0xC01D0007
+#define STATUS_MONITOR_NO_MORE_DESCRIPTOR_DATA 0xC01D0008
+#define STATUS_MONITOR_INVALID_DETAILED_TIMING_BLOCK 0xC01D0009
+#define STATUS_GRAPHICS_NOT_EXCLUSIVE_MODE_OWNER 0xC01E0000
+#define STATUS_GRAPHICS_INSUFFICIENT_DMA_BUFFER 0xC01E0001
+#define STATUS_GRAPHICS_INVALID_DISPLAY_ADAPTER 0xC01E0002
+#define STATUS_GRAPHICS_ADAPTER_WAS_RESET 0xC01E0003
+#define STATUS_GRAPHICS_INVALID_DRIVER_MODEL 0xC01E0004
+#define STATUS_GRAPHICS_PRESENT_MODE_CHANGED 0xC01E0005
+#define STATUS_GRAPHICS_PRESENT_OCCLUDED 0xC01E0006
+#define STATUS_GRAPHICS_PRESENT_DENIED 0xC01E0007
+#define STATUS_GRAPHICS_CANNOTCOLORCONVERT 0xC01E0008
+#define STATUS_GRAPHICS_NO_VIDEO_MEMORY 0xC01E0100
+#define STATUS_GRAPHICS_CANT_LOCK_MEMORY 0xC01E0101
+#define STATUS_GRAPHICS_ALLOCATION_BUSY 0xC01E0102
+#define STATUS_GRAPHICS_TOO_MANY_REFERENCES 0xC01E0103
+#define STATUS_GRAPHICS_TRY_AGAIN_LATER 0xC01E0104
+#define STATUS_GRAPHICS_TRY_AGAIN_NOW 0xC01E0105
+#define STATUS_GRAPHICS_ALLOCATION_INVALID 0xC01E0106
+#define STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNAVAILABLE 0xC01E0107
+#define STATUS_GRAPHICS_UNSWIZZLING_APERTURE_UNSUPPORTED 0xC01E0108
+#define STATUS_GRAPHICS_CANT_EVICT_PINNED_ALLOCATION 0xC01E0109
+#define STATUS_GRAPHICS_INVALID_ALLOCATION_USAGE 0xC01E0110
+#define STATUS_GRAPHICS_CANT_RENDER_LOCKED_ALLOCATION 0xC01E0111
+#define STATUS_GRAPHICS_ALLOCATION_CLOSED 0xC01E0112
+#define STATUS_GRAPHICS_INVALID_ALLOCATION_INSTANCE 0xC01E0113
+#define STATUS_GRAPHICS_INVALID_ALLOCATION_HANDLE 0xC01E0114
+#define STATUS_GRAPHICS_WRONG_ALLOCATION_DEVICE 0xC01E0115
+#define STATUS_GRAPHICS_ALLOCATION_CONTENT_LOST 0xC01E0116
+#define STATUS_GRAPHICS_GPU_EXCEPTION_ON_DEVICE 0xC01E0200
+#define STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY 0xC01E0300
+#define STATUS_GRAPHICS_VIDPN_TOPOLOGY_NOT_SUPPORTED 0xC01E0301
+#define STATUS_GRAPHICS_VIDPN_TOPOLOGY_CURRENTLY_NOT_SUPPORTED 0xC01E0302
+#define STATUS_GRAPHICS_INVALID_VIDPN 0xC01E0303
+#define STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE 0xC01E0304
+#define STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET 0xC01E0305
+#define STATUS_GRAPHICS_VIDPN_MODALITY_NOT_SUPPORTED 0xC01E0306
+#define STATUS_GRAPHICS_INVALID_VIDPN_SOURCEMODESET 0xC01E0308
+#define STATUS_GRAPHICS_INVALID_VIDPN_TARGETMODESET 0xC01E0309
+#define STATUS_GRAPHICS_INVALID_FREQUENCY 0xC01E030A
+#define STATUS_GRAPHICS_INVALID_ACTIVE_REGION 0xC01E030B
+#define STATUS_GRAPHICS_INVALID_TOTAL_REGION 0xC01E030C
+#define STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_SOURCE_MODE 0xC01E0310
+#define STATUS_GRAPHICS_INVALID_VIDEO_PRESENT_TARGET_MODE 0xC01E0311
+#define STATUS_GRAPHICS_PINNED_MODE_MUST_REMAIN_IN_SET 0xC01E0312
+#define STATUS_GRAPHICS_PATH_ALREADY_IN_TOPOLOGY 0xC01E0313
+#define STATUS_GRAPHICS_MODE_ALREADY_IN_MODESET 0xC01E0314
+#define STATUS_GRAPHICS_INVALID_VIDEOPRESENTSOURCESET 0xC01E0315
+#define STATUS_GRAPHICS_INVALID_VIDEOPRESENTTARGETSET 0xC01E0316
+#define STATUS_GRAPHICS_SOURCE_ALREADY_IN_SET 0xC01E0317
+#define STATUS_GRAPHICS_TARGET_ALREADY_IN_SET 0xC01E0318
+#define STATUS_GRAPHICS_INVALID_VIDPN_PRESENT_PATH 0xC01E0319
+#define STATUS_GRAPHICS_NO_RECOMMENDED_VIDPN_TOPOLOGY 0xC01E031A
+#define STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGESET 0xC01E031B
+#define STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE 0xC01E031C
+#define STATUS_GRAPHICS_FREQUENCYRANGE_NOT_IN_SET 0xC01E031D
+#define STATUS_GRAPHICS_FREQUENCYRANGE_ALREADY_IN_SET 0xC01E031F
+#define STATUS_GRAPHICS_STALE_MODESET 0xC01E0320
+#define STATUS_GRAPHICS_INVALID_MONITOR_SOURCEMODESET 0xC01E0321
+#define STATUS_GRAPHICS_INVALID_MONITOR_SOURCE_MODE 0xC01E0322
+#define STATUS_GRAPHICS_NO_RECOMMENDED_FUNCTIONAL_VIDPN 0xC01E0323
+#define STATUS_GRAPHICS_MODE_ID_MUST_BE_UNIQUE 0xC01E0324
+#define STATUS_GRAPHICS_EMPTY_ADAPTER_MONITOR_MODE_SUPPORT_INTERSECTION 0xC01E0325
+#define STATUS_GRAPHICS_VIDEO_PRESENT_TARGETS_LESS_THAN_SOURCES 0xC01E0326
+#define STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY 0xC01E0327
+#define STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_SOURCE 0xC01E0328
+#define STATUS_GRAPHICS_ADAPTER_MUST_HAVE_AT_LEAST_ONE_TARGET 0xC01E0329
+#define STATUS_GRAPHICS_INVALID_MONITORDESCRIPTORSET 0xC01E032A
+#define STATUS_GRAPHICS_INVALID_MONITORDESCRIPTOR 0xC01E032B
+#define STATUS_GRAPHICS_MONITORDESCRIPTOR_NOT_IN_SET 0xC01E032C
+#define STATUS_GRAPHICS_MONITORDESCRIPTOR_ALREADY_IN_SET 0xC01E032D
+#define STATUS_GRAPHICS_MONITORDESCRIPTOR_ID_MUST_BE_UNIQUE 0xC01E032E
+#define STATUS_GRAPHICS_INVALID_VIDPN_TARGET_SUBSET_TYPE 0xC01E032F
+#define STATUS_GRAPHICS_RESOURCES_NOT_RELATED 0xC01E0330
+#define STATUS_GRAPHICS_SOURCE_ID_MUST_BE_UNIQUE 0xC01E0331
+#define STATUS_GRAPHICS_TARGET_ID_MUST_BE_UNIQUE 0xC01E0332
+#define STATUS_GRAPHICS_NO_AVAILABLE_VIDPN_TARGET 0xC01E0333
+#define STATUS_GRAPHICS_MONITOR_COULD_NOT_BE_ASSOCIATED_WITH_ADAPTER 0xC01E0334
+#define STATUS_GRAPHICS_NO_VIDPNMGR 0xC01E0335
+#define STATUS_GRAPHICS_NO_ACTIVE_VIDPN 0xC01E0336
+#define STATUS_GRAPHICS_STALE_VIDPN_TOPOLOGY 0xC01E0337
+#define STATUS_GRAPHICS_MONITOR_NOT_CONNECTED 0xC01E0338
+#define STATUS_GRAPHICS_SOURCE_NOT_IN_TOPOLOGY 0xC01E0339
+#define STATUS_GRAPHICS_INVALID_PRIMARYSURFACE_SIZE 0xC01E033A
+#define STATUS_GRAPHICS_INVALID_VISIBLEREGION_SIZE 0xC01E033B
+#define STATUS_GRAPHICS_INVALID_STRIDE 0xC01E033C
+#define STATUS_GRAPHICS_INVALID_PIXELFORMAT 0xC01E033D
+#define STATUS_GRAPHICS_INVALID_COLORBASIS 0xC01E033E
+#define STATUS_GRAPHICS_INVALID_PIXELVALUEACCESSMODE 0xC01E033F
+#define STATUS_GRAPHICS_TARGET_NOT_IN_TOPOLOGY 0xC01E0340
+#define STATUS_GRAPHICS_NO_DISPLAY_MODE_MANAGEMENT_SUPPORT 0xC01E0341
+#define STATUS_GRAPHICS_VIDPN_SOURCE_IN_USE 0xC01E0342
+#define STATUS_GRAPHICS_CANT_ACCESS_ACTIVE_VIDPN 0xC01E0343
+#define STATUS_GRAPHICS_INVALID_PATH_IMPORTANCE_ORDINAL 0xC01E0344
+#define STATUS_GRAPHICS_INVALID_PATH_CONTENT_GEOMETRY_TRANSFORMATION 0xC01E0345
+#define STATUS_GRAPHICS_PATH_CONTENT_GEOMETRY_TRANSFORMATION_NOT_SUPPORTED 0xC01E0346
+#define STATUS_GRAPHICS_INVALID_GAMMA_RAMP 0xC01E0347
+#define STATUS_GRAPHICS_GAMMA_RAMP_NOT_SUPPORTED 0xC01E0348
+#define STATUS_GRAPHICS_MULTISAMPLING_NOT_SUPPORTED 0xC01E0349
+#define STATUS_GRAPHICS_MODE_NOT_IN_MODESET 0xC01E034A
+#define STATUS_GRAPHICS_INVALID_VIDPN_TOPOLOGY_RECOMMENDATION_REASON 0xC01E034D
+#define STATUS_GRAPHICS_INVALID_PATH_CONTENT_TYPE 0xC01E034E
+#define STATUS_GRAPHICS_INVALID_COPYPROTECTION_TYPE 0xC01E034F
+#define STATUS_GRAPHICS_UNASSIGNED_MODESET_ALREADY_EXISTS 0xC01E0350
+#define STATUS_GRAPHICS_INVALID_SCANLINE_ORDERING 0xC01E0352
+#define STATUS_GRAPHICS_TOPOLOGY_CHANGES_NOT_ALLOWED 0xC01E0353
+#define STATUS_GRAPHICS_NO_AVAILABLE_IMPORTANCE_ORDINALS 0xC01E0354
+#define STATUS_GRAPHICS_INCOMPATIBLE_PRIVATE_FORMAT 0xC01E0355
+#define STATUS_GRAPHICS_INVALID_MODE_PRUNING_ALGORITHM 0xC01E0356
+#define STATUS_GRAPHICS_INVALID_MONITOR_CAPABILITY_ORIGIN 0xC01E0357
+#define STATUS_GRAPHICS_INVALID_MONITOR_FREQUENCYRANGE_CONSTRAINT 0xC01E0358
+#define STATUS_GRAPHICS_MAX_NUM_PATHS_REACHED 0xC01E0359
+#define STATUS_GRAPHICS_CANCEL_VIDPN_TOPOLOGY_AUGMENTATION 0xC01E035A
+#define STATUS_GRAPHICS_INVALID_CLIENT_TYPE 0xC01E035B
+#define STATUS_GRAPHICS_CLIENTVIDPN_NOT_SET 0xC01E035C
+#define STATUS_GRAPHICS_SPECIFIED_CHILD_ALREADY_CONNECTED 0xC01E0400
+#define STATUS_GRAPHICS_CHILD_DESCRIPTOR_NOT_SUPPORTED 0xC01E0401
+#define STATUS_GRAPHICS_NOT_A_LINKED_ADAPTER 0xC01E0430
+#define STATUS_GRAPHICS_LEADLINK_NOT_ENUMERATED 0xC01E0431
+#define STATUS_GRAPHICS_CHAINLINKS_NOT_ENUMERATED 0xC01E0432
+#define STATUS_GRAPHICS_ADAPTER_CHAIN_NOT_READY 0xC01E0433
+#define STATUS_GRAPHICS_CHAINLINKS_NOT_STARTED 0xC01E0434
+#define STATUS_GRAPHICS_CHAINLINKS_NOT_POWERED_ON 0xC01E0435
+#define STATUS_GRAPHICS_INCONSISTENT_DEVICE_LINK_STATE 0xC01E0436
+#define STATUS_GRAPHICS_NOT_POST_DEVICE_DRIVER 0xC01E0438
+#define STATUS_GRAPHICS_ADAPTER_ACCESS_NOT_EXCLUDED 0xC01E043B
+#define STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_COPP_SEMANTICS 0xC01E051C
+#define STATUS_GRAPHICS_OPM_INVALID_INFORMATION_REQUEST 0xC01E051D
+#define STATUS_GRAPHICS_OPM_DRIVER_INTERNAL_ERROR 0xC01E051E
+#define STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_DOES_NOT_HAVE_OPM_SEMANTICS 0xC01E051F
+#define STATUS_GRAPHICS_OPM_SIGNALING_NOT_SUPPORTED 0xC01E0520
+#define STATUS_GRAPHICS_OPM_INVALID_CONFIGURATION_REQUEST 0xC01E0521
+#define STATUS_GRAPHICS_OPM_NOT_SUPPORTED 0xC01E0500
+#define STATUS_GRAPHICS_COPP_NOT_SUPPORTED 0xC01E0501
+#define STATUS_GRAPHICS_UAB_NOT_SUPPORTED 0xC01E0502
+#define STATUS_GRAPHICS_OPM_INVALID_ENCRYPTED_PARAMETERS 0xC01E0503
+#define STATUS_GRAPHICS_OPM_PARAMETER_ARRAY_TOO_SMALL 0xC01E0504
+#define STATUS_GRAPHICS_OPM_NO_PROTECTED_OUTPUTS_EXIST 0xC01E0505
+#define STATUS_GRAPHICS_PVP_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME 0xC01E0506
+#define STATUS_GRAPHICS_PVP_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP 0xC01E0507
+#define STATUS_GRAPHICS_PVP_MIRRORING_DEVICES_NOT_SUPPORTED 0xC01E0508
+#define STATUS_GRAPHICS_OPM_INVALID_POINTER 0xC01E050A
+#define STATUS_GRAPHICS_OPM_INTERNAL_ERROR 0xC01E050B
+#define STATUS_GRAPHICS_OPM_INVALID_HANDLE 0xC01E050C
+#define STATUS_GRAPHICS_PVP_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE 0xC01E050D
+#define STATUS_GRAPHICS_PVP_INVALID_CERTIFICATE_LENGTH 0xC01E050E
+#define STATUS_GRAPHICS_OPM_SPANNING_MODE_ENABLED 0xC01E050F
+#define STATUS_GRAPHICS_OPM_THEATER_MODE_ENABLED 0xC01E0510
+#define STATUS_GRAPHICS_PVP_HFS_FAILED 0xC01E0511
+#define STATUS_GRAPHICS_OPM_INVALID_SRM 0xC01E0512
+#define STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_HDCP 0xC01E0513
+#define STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_ACP 0xC01E0514
+#define STATUS_GRAPHICS_OPM_OUTPUT_DOES_NOT_SUPPORT_CGMSA 0xC01E0515
+#define STATUS_GRAPHICS_OPM_HDCP_SRM_NEVER_SET 0xC01E0516
+#define STATUS_GRAPHICS_OPM_RESOLUTION_TOO_HIGH 0xC01E0517
+#define STATUS_GRAPHICS_OPM_ALL_HDCP_HARDWARE_ALREADY_IN_USE 0xC01E0518
+#define STATUS_GRAPHICS_OPM_PROTECTED_OUTPUT_NO_LONGER_EXISTS 0xC01E051A
+#define STATUS_GRAPHICS_OPM_SESSION_TYPE_CHANGE_IN_PROGRESS 0xC01E051B
+#define STATUS_GRAPHICS_I2C_NOT_SUPPORTED 0xC01E0580
+#define STATUS_GRAPHICS_I2C_DEVICE_DOES_NOT_EXIST 0xC01E0581
+#define STATUS_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA 0xC01E0582
+#define STATUS_GRAPHICS_I2C_ERROR_RECEIVING_DATA 0xC01E0583
+#define STATUS_GRAPHICS_DDCCI_VCP_NOT_SUPPORTED 0xC01E0584
+#define STATUS_GRAPHICS_DDCCI_INVALID_DATA 0xC01E0585
+#define STATUS_GRAPHICS_DDCCI_MONITOR_RETURNED_INVALID_TIMING_STATUS_BYTE 0xC01E0586
+#define STATUS_GRAPHICS_DDCCI_INVALID_CAPABILITIES_STRING 0xC01E0587
+#define STATUS_GRAPHICS_MCA_INTERNAL_ERROR 0xC01E0588
+#define STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_COMMAND 0xC01E0589
+#define STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_LENGTH 0xC01E058A
+#define STATUS_GRAPHICS_DDCCI_INVALID_MESSAGE_CHECKSUM 0xC01E058B
+#define STATUS_GRAPHICS_INVALID_PHYSICAL_MONITOR_HANDLE 0xC01E058C
+#define STATUS_GRAPHICS_MONITOR_NO_LONGER_EXISTS 0xC01E058D
+#define STATUS_GRAPHICS_ONLY_CONSOLE_SESSION_SUPPORTED 0xC01E05E0
+#define STATUS_GRAPHICS_NO_DISPLAY_DEVICE_CORRESPONDS_TO_NAME 0xC01E05E1
+#define STATUS_GRAPHICS_DISPLAY_DEVICE_NOT_ATTACHED_TO_DESKTOP 0xC01E05E2
+#define STATUS_GRAPHICS_MIRRORING_DEVICES_NOT_SUPPORTED 0xC01E05E3
+#define STATUS_GRAPHICS_INVALID_POINTER 0xC01E05E4
+#define STATUS_GRAPHICS_NO_MONITORS_CORRESPOND_TO_DISPLAY_DEVICE 0xC01E05E5
+#define STATUS_GRAPHICS_PARAMETER_ARRAY_TOO_SMALL 0xC01E05E6
+#define STATUS_GRAPHICS_INTERNAL_ERROR 0xC01E05E7
+#define STATUS_GRAPHICS_SESSION_TYPE_CHANGE_IN_PROGRESS 0xC01E05E8
+#define STATUS_FVE_LOCKED_VOLUME 0xC0210000
+#define STATUS_FVE_NOT_ENCRYPTED 0xC0210001
+#define STATUS_FVE_BAD_INFORMATION 0xC0210002
+#define STATUS_FVE_TOO_SMALL 0xC0210003
+#define STATUS_FVE_FAILED_WRONG_FS 0xC0210004
+#define STATUS_FVE_FAILED_BAD_FS 0xC0210005
+#define STATUS_FVE_FS_NOT_EXTENDED 0xC0210006
+#define STATUS_FVE_FS_MOUNTED 0xC0210007
+#define STATUS_FVE_NO_LICENSE 0xC0210008
+#define STATUS_FVE_ACTION_NOT_ALLOWED 0xC0210009
+#define STATUS_FVE_BAD_DATA 0xC021000A
+#define STATUS_FVE_VOLUME_NOT_BOUND 0xC021000B
+#define STATUS_FVE_NOT_DATA_VOLUME 0xC021000C
+#define STATUS_FVE_CONV_READ_ERROR 0xC021000D
+#define STATUS_FVE_CONV_WRITE_ERROR 0xC021000E
+#define STATUS_FVE_OVERLAPPED_UPDATE 0xC021000F
+#define STATUS_FVE_FAILED_SECTOR_SIZE 0xC0210010
+#define STATUS_FVE_FAILED_AUTHENTICATION 0xC0210011
+#define STATUS_FVE_NOT_OS_VOLUME 0xC0210012
+#define STATUS_FVE_KEYFILE_NOT_FOUND 0xC0210013
+#define STATUS_FVE_KEYFILE_INVALID 0xC0210014
+#define STATUS_FVE_KEYFILE_NO_VMK 0xC0210015
+#define STATUS_FVE_TPM_DISABLED 0xC0210016
+#define STATUS_FVE_TPM_SRK_AUTH_NOT_ZERO 0xC0210017
+#define STATUS_FVE_TPM_INVALID_PCR 0xC0210018
+#define STATUS_FVE_TPM_NO_VMK 0xC0210019
+#define STATUS_FVE_PIN_INVALID 0xC021001A
+#define STATUS_FVE_AUTH_INVALID_APPLICATION 0xC021001B
+#define STATUS_FVE_AUTH_INVALID_CONFIG 0xC021001C
+#define STATUS_FVE_DEBUGGER_ENABLED 0xC021001D
+#define STATUS_FVE_DRY_RUN_FAILED 0xC021001E
+#define STATUS_FVE_BAD_METADATA_POINTER 0xC021001F
+#define STATUS_FVE_OLD_METADATA_COPY 0xC0210020
+#define STATUS_FVE_REBOOT_REQUIRED 0xC0210021
+#define STATUS_FVE_RAW_ACCESS 0xC0210022
+#define STATUS_FVE_RAW_BLOCKED 0xC0210023
+#define STATUS_FWP_CALLOUT_NOT_FOUND 0xC0220001
+#define STATUS_FWP_CONDITION_NOT_FOUND 0xC0220002
+#define STATUS_FWP_FILTER_NOT_FOUND 0xC0220003
+#define STATUS_FWP_LAYER_NOT_FOUND 0xC0220004
+#define STATUS_FWP_PROVIDER_NOT_FOUND 0xC0220005
+#define STATUS_FWP_PROVIDER_CONTEXT_NOT_FOUND 0xC0220006
+#define STATUS_FWP_SUBLAYER_NOT_FOUND 0xC0220007
+#define STATUS_FWP_NOT_FOUND 0xC0220008
+#define STATUS_FWP_ALREADY_EXISTS 0xC0220009
+#define STATUS_FWP_IN_USE 0xC022000A
+#define STATUS_FWP_DYNAMIC_SESSION_IN_PROGRESS 0xC022000B
+#define STATUS_FWP_WRONG_SESSION 0xC022000C
+#define STATUS_FWP_NO_TXN_IN_PROGRESS 0xC022000D
+#define STATUS_FWP_TXN_IN_PROGRESS 0xC022000E
+#define STATUS_FWP_TXN_ABORTED 0xC022000F
+#define STATUS_FWP_SESSION_ABORTED 0xC0220010
+#define STATUS_FWP_INCOMPATIBLE_TXN 0xC0220011
+#define STATUS_FWP_TIMEOUT 0xC0220012
+#define STATUS_FWP_NET_EVENTS_DISABLED 0xC0220013
+#define STATUS_FWP_INCOMPATIBLE_LAYER 0xC0220014
+#define STATUS_FWP_KM_CLIENTS_ONLY 0xC0220015
+#define STATUS_FWP_LIFETIME_MISMATCH 0xC0220016
+#define STATUS_FWP_BUILTIN_OBJECT 0xC0220017
+#define STATUS_FWP_TOO_MANY_BOOTTIME_FILTERS 0xC0220018
+#define STATUS_FWP_TOO_MANY_CALLOUTS 0xC0220018
+#define STATUS_FWP_NOTIFICATION_DROPPED 0xC0220019
+#define STATUS_FWP_TRAFFIC_MISMATCH 0xC022001A
+#define STATUS_FWP_INCOMPATIBLE_SA_STATE 0xC022001B
+#define STATUS_FWP_NULL_POINTER 0xC022001C
+#define STATUS_FWP_INVALID_ENUMERATOR 0xC022001D
+#define STATUS_FWP_INVALID_FLAGS 0xC022001E
+#define STATUS_FWP_INVALID_NET_MASK 0xC022001F
+#define STATUS_FWP_INVALID_RANGE 0xC0220020
+#define STATUS_FWP_INVALID_INTERVAL 0xC0220021
+#define STATUS_FWP_ZERO_LENGTH_ARRAY 0xC0220022
+#define STATUS_FWP_NULL_DISPLAY_NAME 0xC0220023
+#define STATUS_FWP_INVALID_ACTION_TYPE 0xC0220024
+#define STATUS_FWP_INVALID_WEIGHT 0xC0220025
+#define STATUS_FWP_MATCH_TYPE_MISMATCH 0xC0220026
+#define STATUS_FWP_TYPE_MISMATCH 0xC0220027
+#define STATUS_FWP_OUT_OF_BOUNDS 0xC0220028
+#define STATUS_FWP_RESERVED 0xC0220029
+#define STATUS_FWP_DUPLICATE_CONDITION 0xC022002A
+#define STATUS_FWP_DUPLICATE_KEYMOD 0xC022002B
+#define STATUS_FWP_ACTION_INCOMPATIBLE_WITH_LAYER 0xC022002C
+#define STATUS_FWP_ACTION_INCOMPATIBLE_WITH_SUBLAYER 0xC022002D
+#define STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_LAYER 0xC022002E
+#define STATUS_FWP_CONTEXT_INCOMPATIBLE_WITH_CALLOUT 0xC022002F
+#define STATUS_FWP_INCOMPATIBLE_AUTH_METHOD 0xC0220030
+#define STATUS_FWP_INCOMPATIBLE_DH_GROUP 0xC0220031
+#define STATUS_FWP_EM_NOT_SUPPORTED 0xC0220032
+#define STATUS_FWP_NEVER_MATCH 0xC0220033
+#define STATUS_FWP_PROVIDER_CONTEXT_MISMATCH 0xC0220034
+#define STATUS_FWP_INVALID_PARAMETER 0xC0220035
+#define STATUS_FWP_TOO_MANY_SUBLAYERS 0xC0220036
+#define STATUS_FWP_CALLOUT_NOTIFICATION_FAILED 0xC0220037
+#define STATUS_FWP_INCOMPATIBLE_AUTH_CONFIG 0xC0220038
+#define STATUS_FWP_INCOMPATIBLE_CIPHER_CONFIG 0xC0220039
+#define STATUS_FWP_TCPIP_NOT_READY 0xC0220100
+#define STATUS_FWP_INJECT_HANDLE_CLOSING 0xC0220101
+#define STATUS_FWP_INJECT_HANDLE_STALE 0xC0220102
+#define STATUS_FWP_CANNOT_PEND 0xC0220103
+#define STATUS_NDIS_CLOSING 0xC0230002
+#define STATUS_NDIS_BAD_VERSION 0xC0230004
+#define STATUS_NDIS_BAD_CHARACTERISTICS 0xC0230005
+#define STATUS_NDIS_ADAPTER_NOT_FOUND 0xC0230006
+#define STATUS_NDIS_OPEN_FAILED 0xC0230007
+#define STATUS_NDIS_DEVICE_FAILED 0xC0230008
+#define STATUS_NDIS_MULTICAST_FULL 0xC0230009
+#define STATUS_NDIS_MULTICAST_EXISTS 0xC023000A
+#define STATUS_NDIS_MULTICAST_NOT_FOUND 0xC023000B
+#define STATUS_NDIS_REQUEST_ABORTED 0xC023000C
+#define STATUS_NDIS_RESET_IN_PROGRESS 0xC023000D
+#define STATUS_NDIS_INVALID_PACKET 0xC023000F
+#define STATUS_NDIS_INVALID_DEVICE_REQUEST 0xC0230010
+#define STATUS_NDIS_ADAPTER_NOT_READY 0xC0230011
+#define STATUS_NDIS_INVALID_LENGTH 0xC0230014
+#define STATUS_NDIS_INVALID_DATA 0xC0230015
+#define STATUS_NDIS_BUFFER_TOO_SHORT 0xC0230016
+#define STATUS_NDIS_INVALID_OID 0xC0230017
+#define STATUS_NDIS_ADAPTER_REMOVED 0xC0230018
+#define STATUS_NDIS_UNSUPPORTED_MEDIA 0xC0230019
+#define STATUS_NDIS_GROUP_ADDRESS_IN_USE 0xC023001A
+#define STATUS_NDIS_FILE_NOT_FOUND 0xC023001B
+#define STATUS_NDIS_ERROR_READING_FILE 0xC023001C
+#define STATUS_NDIS_ALREADY_MAPPED 0xC023001D
+#define STATUS_NDIS_RESOURCE_CONFLICT 0xC023001E
+#define STATUS_NDIS_MEDIA_DISCONNECTED 0xC023001F
+#define STATUS_NDIS_INVALID_ADDRESS 0xC0230022
+#define STATUS_NDIS_PAUSED 0xC023002A
+#define STATUS_NDIS_INTERFACE_NOT_FOUND 0xC023002B
+#define STATUS_NDIS_UNSUPPORTED_REVISION 0xC023002C
+#define STATUS_NDIS_INVALID_PORT 0xC023002D
+#define STATUS_NDIS_INVALID_PORT_STATE 0xC023002E
+#define STATUS_NDIS_LOW_POWER_STATE 0xC023002F
+#define STATUS_NDIS_NOT_SUPPORTED 0xC02300BB
+#define STATUS_NDIS_DOT11_AUTO_CONFIG_ENABLED 0xC0232000
+#define STATUS_NDIS_DOT11_MEDIA_IN_USE 0xC0232001
+#define STATUS_NDIS_DOT11_POWER_STATE_INVALID 0xC0232002
+#define STATUS_IPSEC_BAD_SPI 0xC0360001
+#define STATUS_IPSEC_SA_LIFETIME_EXPIRED 0xC0360002
+#define STATUS_IPSEC_WRONG_SA 0xC0360003
+#define STATUS_IPSEC_REPLAY_CHECK_FAILED 0xC0360004
+#define STATUS_IPSEC_INVALID_PACKET 0xC0360005
+#define STATUS_IPSEC_INTEGRITY_CHECK_FAILED 0xC0360006
+#define STATUS_IPSEC_CLEAR_TEXT_DROP 0xC0360007
diff --git a/fs/cifs/smb2transport.c b/fs/cifs/smb2transport.c
new file mode 100644
index 000000000000..53cf4ecd7376
--- /dev/null
+++ b/fs/cifs/smb2transport.c
@@ -0,0 +1,140 @@
+/*
+ * fs/cifs/transport.c
+ *
+ * Copyright (C) International Business Machines Corp., 2002,2011
+ * Author(s): Steve French (sfrench@us.ibm.com)
+ * Jeremy Allison (jra@samba.org) 2006.
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
+ * the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/wait.h>
+#include <linux/net.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <asm/processor.h>
+#include <linux/mempool.h>
+#include "smb2pdu.h"
+#include "cifsglob.h"
+#include "cifsproto.h"
+#include "smb2proto.h"
+#include "cifs_debug.h"
+#include "smb2status.h"
+
+/*
+ * Send an (optionally, already signed) SMB2 request over a socket.
+ * This socket is already locked (by a mutex) by the caller so we
+ * won't have framing problems or mess up SMB2 signatures.
+ */
+
+int smb2_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)
+{
+ int rc = -EHOSTDOWN;
+
+ cFYI(1, "function not merged yet"); /* BB fixme */
+
+ return rc;
+}
+
+
+
+/*
+ *
+ * Send an SMB Request. No response info (other than return code)
+ * needs to be parsed.
+ *
+ * flags indicate the type of request buffer and how long to wait
+ * and whether to log NT STATUS code (error) before mapping it to POSIX error
+ *
+ */
+int
+smb2_sendrcv_norsp(const unsigned int xid, struct cifs_ses *ses,
+ struct smb2_hdr *in_buf, int flags)
+{
+ int rc;
+ struct kvec iov[1];
+ int resp_buf_type;
+
+ iov[0].iov_base = (char *)in_buf;
+ iov[0].iov_len = be32_to_cpu(in_buf->smb2_buf_length) + 4;
+ flags |= CIFS_NO_RESP;
+ rc = smb2_sendrcv2(xid, ses, iov, 1, &resp_buf_type, NULL, flags);
+ /* BB remove the following debug line eventually */
+ cFYI(1, "SendRcvNoRsp flags %d rc %d", flags, rc);
+
+ return rc;
+}
+
+static int
+smb2_send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
+ struct kvec *iov)
+{
+ int rsp_buf_type;
+ struct cifs_ses *ses = tcon->ses;
+ struct lock_req *pSMB2 = (struct lock_req *)iov[0].iov_base;
+
+ pSMB2->locks[0].Flags = SMB2_LOCKFLAG_UNLOCK;
+
+ return smb2_sendrcv2(xid, ses, iov, 1, &rsp_buf_type,
+ NULL, CIFS_STD_OP);
+}
+
+int
+smb2_sendrcv_blocking(const unsigned int xid, struct cifs_tcon *tcon,
+ struct smb2_hdr *in_buf,
+ struct smb2_hdr *out_buf,
+ int *pbytes_returned)
+{
+ int rc = -EHOSTDOWN;
+
+ cFYI(1, "function not merged yet"); /* BB fixme */
+
+ return rc;
+}
+
+/* sendrcv2 is passed a cifs_ses structure (rather than simply being
+ passed the ses->server->socket), because it needs the creds
+ contained in the cifs_ses struct in order to sign requests */
+int
+smb2_sendrcv2(const unsigned int xid, struct cifs_ses *ses,
+ struct kvec *iov, int n_vec, int *presp_buftype /* ret */,
+ int *status /* ret SMB2 network status code */, const int flags)
+{
+ int rc = -EHOSTDOWN;
+
+ cFYI(1, "function not merged yet"); /* BB fixme */
+
+ return rc;
+}
+
+/* smb2_send_complex is passed a cifs_ses structure (rather than simply being
+ passed the ses->server->socket), because it needs the creds
+ contained in the cifs_ses struct in order to sign requests */
+int
+smb2_send_complex(const unsigned int xid, struct cifs_ses *ses,
+ struct kvec *iov, int n_vec, int *presp_buftype /* ret */,
+ int *status /* ret SMB2 network status code */,
+ struct mid_q_entry **mid, const unsigned int size)
+{
+ int rc = -EHOSTDOWN;
+
+ cFYI(1, "function not merged yet"); /* BB fixme */
+
+ return rc;
+}
+
+/* BB add missing functions here */
diff --git a/fs/cifs/smbdes.c b/fs/cifs/smbdes.c
deleted file mode 100644
index 04721485925d..000000000000
--- a/fs/cifs/smbdes.c
+++ /dev/null
@@ -1,418 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
-
- a partial implementation of DES designed for use in the
- SMB authentication protocol
-
- Copyright (C) Andrew Tridgell 1998
- Modified by Steve French (sfrench@us.ibm.com) 2002,2004
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* NOTES:
-
- This code makes no attempt to be fast! In fact, it is a very
- slow implementation
-
- This code is NOT a complete DES implementation. It implements only
- the minimum necessary for SMB authentication, as used by all SMB
- products (including every copy of Microsoft Windows95 ever sold)
-
- In particular, it can only do a unchained forward DES pass. This
- means it is not possible to use this code for encryption/decryption
- of data, instead it is only useful as a "hash" algorithm.
-
- There is no entry point into this code that allows normal DES operation.
-
- I believe this means that this code does not come under ITAR
- regulations but this is NOT a legal opinion. If you are concerned
- about the applicability of ITAR regulations to this code then you
- should confirm it for yourself (and maybe let me know if you come
- up with a different answer to the one above)
-*/
-#include <linux/slab.h>
-#define uchar unsigned char
-
-static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,
- 1, 58, 50, 42, 34, 26, 18,
- 10, 2, 59, 51, 43, 35, 27,
- 19, 11, 3, 60, 52, 44, 36,
- 63, 55, 47, 39, 31, 23, 15,
- 7, 62, 54, 46, 38, 30, 22,
- 14, 6, 61, 53, 45, 37, 29,
- 21, 13, 5, 28, 20, 12, 4
-};
-
-static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,
- 3, 28, 15, 6, 21, 10,
- 23, 19, 12, 4, 26, 8,
- 16, 7, 27, 20, 13, 2,
- 41, 52, 31, 37, 47, 55,
- 30, 40, 51, 45, 33, 48,
- 44, 49, 39, 56, 34, 53,
- 46, 42, 50, 36, 29, 32
-};
-
-static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2,
- 60, 52, 44, 36, 28, 20, 12, 4,
- 62, 54, 46, 38, 30, 22, 14, 6,
- 64, 56, 48, 40, 32, 24, 16, 8,
- 57, 49, 41, 33, 25, 17, 9, 1,
- 59, 51, 43, 35, 27, 19, 11, 3,
- 61, 53, 45, 37, 29, 21, 13, 5,
- 63, 55, 47, 39, 31, 23, 15, 7
-};
-
-static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,
- 4, 5, 6, 7, 8, 9,
- 8, 9, 10, 11, 12, 13,
- 12, 13, 14, 15, 16, 17,
- 16, 17, 18, 19, 20, 21,
- 20, 21, 22, 23, 24, 25,
- 24, 25, 26, 27, 28, 29,
- 28, 29, 30, 31, 32, 1
-};
-
-static uchar perm5[32] = { 16, 7, 20, 21,
- 29, 12, 28, 17,
- 1, 15, 23, 26,
- 5, 18, 31, 10,
- 2, 8, 24, 14,
- 32, 27, 3, 9,
- 19, 13, 30, 6,
- 22, 11, 4, 25
-};
-
-static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32,
- 39, 7, 47, 15, 55, 23, 63, 31,
- 38, 6, 46, 14, 54, 22, 62, 30,
- 37, 5, 45, 13, 53, 21, 61, 29,
- 36, 4, 44, 12, 52, 20, 60, 28,
- 35, 3, 43, 11, 51, 19, 59, 27,
- 34, 2, 42, 10, 50, 18, 58, 26,
- 33, 1, 41, 9, 49, 17, 57, 25
-};
-
-static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
-
-static uchar sbox[8][4][16] = {
- {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
- {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
- {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
- {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} },
-
- {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
- {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
- {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
- {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} },
-
- {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
- {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
- {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
- {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} },
-
- {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
- {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
- {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
- {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} },
-
- {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
- {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
- {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
- {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} },
-
- {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
- {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
- {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
- {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} },
-
- {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
- {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
- {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
- {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} },
-
- {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
- {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
- {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
- {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} }
-};
-
-static void
-permute(char *out, char *in, uchar *p, int n)
-{
- int i;
- for (i = 0; i < n; i++)
- out[i] = in[p[i] - 1];
-}
-
-static void
-lshift(char *d, int count, int n)
-{
- char out[64];
- int i;
- for (i = 0; i < n; i++)
- out[i] = d[(i + count) % n];
- for (i = 0; i < n; i++)
- d[i] = out[i];
-}
-
-static void
-concat(char *out, char *in1, char *in2, int l1, int l2)
-{
- while (l1--)
- *out++ = *in1++;
- while (l2--)
- *out++ = *in2++;
-}
-
-static void
-xor(char *out, char *in1, char *in2, int n)
-{
- int i;
- for (i = 0; i < n; i++)
- out[i] = in1[i] ^ in2[i];
-}
-
-static void
-dohash(char *out, char *in, char *key, int forw)
-{
- int i, j, k;
- char *pk1;
- char c[28];
- char d[28];
- char *cd;
- char (*ki)[48];
- char *pd1;
- char l[32], r[32];
- char *rl;
-
- /* Have to reduce stack usage */
- pk1 = kmalloc(56+56+64+64, GFP_KERNEL);
- if (pk1 == NULL)
- return;
-
- ki = kmalloc(16*48, GFP_KERNEL);
- if (ki == NULL) {
- kfree(pk1);
- return;
- }
-
- cd = pk1 + 56;
- pd1 = cd + 56;
- rl = pd1 + 64;
-
- permute(pk1, key, perm1, 56);
-
- for (i = 0; i < 28; i++)
- c[i] = pk1[i];
- for (i = 0; i < 28; i++)
- d[i] = pk1[i + 28];
-
- for (i = 0; i < 16; i++) {
- lshift(c, sc[i], 28);
- lshift(d, sc[i], 28);
-
- concat(cd, c, d, 28, 28);
- permute(ki[i], cd, perm2, 48);
- }
-
- permute(pd1, in, perm3, 64);
-
- for (j = 0; j < 32; j++) {
- l[j] = pd1[j];
- r[j] = pd1[j + 32];
- }
-
- for (i = 0; i < 16; i++) {
- char *er; /* er[48] */
- char *erk; /* erk[48] */
- char b[8][6];
- char *cb; /* cb[32] */
- char *pcb; /* pcb[32] */
- char *r2; /* r2[32] */
-
- er = kmalloc(48+48+32+32+32, GFP_KERNEL);
- if (er == NULL) {
- kfree(pk1);
- kfree(ki);
- return;
- }
- erk = er+48;
- cb = erk+48;
- pcb = cb+32;
- r2 = pcb+32;
-
- permute(er, r, perm4, 48);
-
- xor(erk, er, ki[forw ? i : 15 - i], 48);
-
- for (j = 0; j < 8; j++)
- for (k = 0; k < 6; k++)
- b[j][k] = erk[j * 6 + k];
-
- for (j = 0; j < 8; j++) {
- int m, n;
- m = (b[j][0] << 1) | b[j][5];
-
- n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] <<
- 1) | b[j][4];
-
- for (k = 0; k < 4; k++)
- b[j][k] =
- (sbox[j][m][n] & (1 << (3 - k))) ? 1 : 0;
- }
-
- for (j = 0; j < 8; j++)
- for (k = 0; k < 4; k++)
- cb[j * 4 + k] = b[j][k];
- permute(pcb, cb, perm5, 32);
-
- xor(r2, l, pcb, 32);
-
- for (j = 0; j < 32; j++)
- l[j] = r[j];
-
- for (j = 0; j < 32; j++)
- r[j] = r2[j];
-
- kfree(er);
- }
-
- concat(rl, r, l, 32, 32);
-
- permute(out, rl, perm6, 64);
- kfree(pk1);
- kfree(ki);
-}
-
-static void
-str_to_key(unsigned char *str, unsigned char *key)
-{
- int i;
-
- key[0] = str[0] >> 1;
- key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
- key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
- key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
- key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
- key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
- key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
- key[7] = str[6] & 0x7F;
- for (i = 0; i < 8; i++)
- key[i] = (key[i] << 1);
-}
-
-static void
-smbhash(unsigned char *out, const unsigned char *in, unsigned char *key,
- int forw)
-{
- int i;
- char *outb; /* outb[64] */
- char *inb; /* inb[64] */
- char *keyb; /* keyb[64] */
- unsigned char key2[8];
-
- outb = kmalloc(64 * 3, GFP_KERNEL);
- if (outb == NULL)
- return;
-
- inb = outb + 64;
- keyb = inb + 64;
-
- str_to_key(key, key2);
-
- for (i = 0; i < 64; i++) {
- inb[i] = (in[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
- keyb[i] = (key2[i / 8] & (1 << (7 - (i % 8)))) ? 1 : 0;
- outb[i] = 0;
- }
-
- dohash(outb, inb, keyb, forw);
-
- for (i = 0; i < 8; i++)
- out[i] = 0;
-
- for (i = 0; i < 64; i++) {
- if (outb[i])
- out[i / 8] |= (1 << (7 - (i % 8)));
- }
- kfree(outb);
-}
-
-void
-E_P16(unsigned char *p14, unsigned char *p16)
-{
- unsigned char sp8[8] =
- { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
- smbhash(p16, sp8, p14, 1);
- smbhash(p16 + 8, sp8, p14 + 7, 1);
-}
-
-void
-E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
-{
- smbhash(p24, c8, p21, 1);
- smbhash(p24 + 8, c8, p21 + 7, 1);
- smbhash(p24 + 16, c8, p21 + 14, 1);
-}
-
-#if 0 /* currently unused */
-static void
-D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)
-{
- smbhash(out, in, p14, 0);
- smbhash(out + 8, in + 8, p14 + 7, 0);
-}
-
-static void
-E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)
-{
- smbhash(out, in, p14, 1);
- smbhash(out + 8, in + 8, p14 + 7, 1);
-}
-/* these routines are currently unneeded, but may be
- needed later */
-void
-cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key)
-{
- unsigned char buf[8];
-
- smbhash(buf, in, key, 1);
- smbhash(out, buf, key + 9, 1);
-}
-
-void
-cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key)
-{
- unsigned char buf[8];
- static unsigned char key2[8];
-
- smbhash(buf, in, key, 1);
- key2[0] = key[7];
- smbhash(out, buf, key2, 1);
-}
-
-void
-cred_hash3(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
-{
- static unsigned char key2[8];
-
- smbhash(out, in, key, forw);
- key2[0] = key[7];
- smbhash(out + 8, in + 8, key2, forw);
-}
-#endif /* unneeded routines */
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c
index b5041c849981..1525d5e662b6 100644
--- a/fs/cifs/smbencrypt.c
+++ b/fs/cifs/smbencrypt.c
@@ -47,6 +47,88 @@
#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&0xFF,CVAL(buf,pos+1)=(val)>>8)
#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))
+static void
+str_to_key(unsigned char *str, unsigned char *key)
+{
+ int i;
+
+ key[0] = str[0] >> 1;
+ key[1] = ((str[0] & 0x01) << 6) | (str[1] >> 2);
+ key[2] = ((str[1] & 0x03) << 5) | (str[2] >> 3);
+ key[3] = ((str[2] & 0x07) << 4) | (str[3] >> 4);
+ key[4] = ((str[3] & 0x0F) << 3) | (str[4] >> 5);
+ key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
+ key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
+ key[7] = str[6] & 0x7F;
+ for (i = 0; i < 8; i++)
+ key[i] = (key[i] << 1);
+}
+
+static int
+smbhash(unsigned char *out, const unsigned char *in, unsigned char *key)
+{
+ int rc;
+ unsigned char key2[8];
+ struct crypto_blkcipher *tfm_des;
+ struct scatterlist sgin, sgout;
+ struct blkcipher_desc desc;
+
+ str_to_key(key, key2);
+
+ tfm_des = crypto_alloc_blkcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC);
+ if (IS_ERR(tfm_des)) {
+ rc = PTR_ERR(tfm_des);
+ cERROR(1, "could not allocate des crypto API\n");
+ goto smbhash_err;
+ }
+
+ desc.tfm = tfm_des;
+
+ crypto_blkcipher_setkey(tfm_des, key2, 8);
+
+ sg_init_one(&sgin, in, 8);
+ sg_init_one(&sgout, out, 8);
+
+ rc = crypto_blkcipher_encrypt(&desc, &sgout, &sgin, 8);
+ if (rc) {
+ cERROR(1, "could not encrypt crypt key rc: %d\n", rc);
+ crypto_free_blkcipher(tfm_des);
+ goto smbhash_err;
+ }
+
+smbhash_err:
+ return rc;
+}
+
+static int
+E_P16(unsigned char *p14, unsigned char *p16)
+{
+ int rc;
+ unsigned char sp8[8] =
+ { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+
+ rc = smbhash(p16, sp8, p14);
+ if (rc)
+ return rc;
+ rc = smbhash(p16 + 8, sp8, p14 + 7);
+ return rc;
+}
+
+static int
+E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)
+{
+ int rc;
+
+ rc = smbhash(p24, c8, p21);
+ if (rc)
+ return rc;
+ rc = smbhash(p24 + 8, c8, p21 + 7);
+ if (rc)
+ return rc;
+ rc = smbhash(p24 + 16, c8, p21 + 14);
+ return rc;
+}
+
/* produce a md4 message digest from data of length n bytes */
int
mdfour(unsigned char *md4_hash, unsigned char *link_str, int link_len)
@@ -87,40 +169,30 @@ mdfour_err:
return rc;
}
-/* Does the des encryption from the NT or LM MD4 hash. */
-static void
-SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,
- unsigned char p24[24])
-{
- unsigned char p21[21];
-
- memset(p21, '\0', 21);
-
- memcpy(p21, passwd, 16);
- E_P24(p21, c8, p24);
-}
-
/*
This implements the X/Open SMB password encryption
It takes a password, a 8 byte "crypt key" and puts 24 bytes of
encrypted password into p24 */
/* Note that password must be uppercased and null terminated */
-void
+int
SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)
{
- unsigned char p14[15], p21[21];
+ int rc;
+ unsigned char p14[14], p16[16], p21[21];
- memset(p21, '\0', 21);
memset(p14, '\0', 14);
- strncpy((char *) p14, (char *) passwd, 14);
+ memset(p16, '\0', 16);
+ memset(p21, '\0', 21);
-/* strupper((char *)p14); *//* BB at least uppercase the easy range */
- E_P16(p14, p21);
+ memcpy(p14, passwd, 14);
+ rc = E_P16(p14, p16);
+ if (rc)
+ return rc;
- SMBOWFencrypt(p21, c8, p24);
+ memcpy(p21, p16, 16);
+ rc = E_P24(p21, c8, p24);
- memset(p14, 0, 15);
- memset(p21, 0, 21);
+ return rc;
}
/* Routines for Windows NT MD4 Hash functions. */
@@ -279,16 +351,18 @@ int
SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)
{
int rc;
- unsigned char p21[21];
+ unsigned char p16[16], p21[21];
+ memset(p16, '\0', 16);
memset(p21, '\0', 21);
- rc = E_md4hash(passwd, p21);
+ rc = E_md4hash(passwd, p16);
if (rc) {
cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc);
return rc;
}
- SMBOWFencrypt(p21, c8, p24);
+ memcpy(p21, p16, 16);
+ rc = E_P24(p21, c8, p24);
return rc;
}
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 46d8756f2b24..29dd7ed12d23 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -302,7 +302,7 @@ static int wait_for_free_request(struct TCP_Server_Info *server,
return 0;
}
-static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,
+static int allocate_mid(struct cifs_ses *ses, struct smb_hdr *in_buf,
struct mid_q_entry **ppmidQ)
{
if (ses->server->tcpStatus == CifsExiting) {
@@ -360,7 +360,7 @@ cifs_call_async(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
return rc;
/* enable signing if server requires it */
- if (server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
+ if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
in_buf->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
mutex_lock(&server->srv_mutex);
@@ -414,7 +414,7 @@ out_err:
*
*/
int
-SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,
+SendReceiveNoRsp(const unsigned int xid, struct cifs_ses *ses,
struct smb_hdr *in_buf, int flags)
{
int rc;
@@ -509,7 +509,7 @@ send_nt_cancel(struct TCP_Server_Info *server, struct smb_hdr *in_buf,
}
int
-SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
+SendReceive2(const unsigned int xid, struct cifs_ses *ses,
struct kvec *iov, int n_vec, int *pRespBufType /* ret */,
const int flags)
{
@@ -636,7 +636,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
dump_smb(midQ->resp_buf, 80);
/* convert the length into a more usable form */
if ((receive_len > 24) &&
- (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
+ (ses->server->sec_mode & (SECMODE_SIGN_REQUIRED |
SECMODE_SIGN_ENABLED))) {
rc = cifs_verify_signature(midQ->resp_buf,
ses->server,
@@ -674,7 +674,7 @@ out:
}
int
-SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
+SendReceive(const unsigned int xid, struct cifs_ses *ses,
struct smb_hdr *in_buf, struct smb_hdr *out_buf,
int *pbytes_returned, const int long_op)
{
@@ -789,7 +789,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
dump_smb(out_buf, 92);
/* convert the length into a more usable form */
if ((receive_len > 24) &&
- (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
+ (ses->server->sec_mode & (SECMODE_SIGN_REQUIRED |
SECMODE_SIGN_ENABLED))) {
rc = cifs_verify_signature(out_buf,
ses->server,
@@ -827,12 +827,12 @@ out:
blocking lock to return. */
static int
-send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
+send_lock_cancel(const unsigned int xid, struct cifs_tcon *tcon,
struct smb_hdr *in_buf,
struct smb_hdr *out_buf)
{
int bytes_returned;
- struct cifsSesInfo *ses = tcon->ses;
+ struct cifs_ses *ses = tcon->ses;
LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;
/* We just modify the current in_buf to change
@@ -849,7 +849,7 @@ send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,
}
int
-SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
+SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon,
struct smb_hdr *in_buf, struct smb_hdr *out_buf,
int *pbytes_returned)
{
@@ -857,7 +857,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
int rstart = 0;
unsigned int receive_len;
struct mid_q_entry *midQ;
- struct cifsSesInfo *ses;
+ struct cifs_ses *ses;
if (tcon == NULL || tcon->ses == NULL) {
cERROR(1, "Null smb session");
@@ -1001,7 +1001,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,
dump_smb(out_buf, 92);
/* convert the length into a more usable form */
if ((receive_len > 24) &&
- (ses->server->secMode & (SECMODE_SIGN_REQUIRED |
+ (ses->server->sec_mode & (SECMODE_SIGN_REQUIRED |
SECMODE_SIGN_ENABLED))) {
rc = cifs_verify_signature(out_buf,
ses->server,
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c
index eae2a1491608..2a22fb2989e4 100644
--- a/fs/cifs/xattr.c
+++ b/fs/cifs/xattr.c
@@ -49,7 +49,7 @@ int cifs_removexattr(struct dentry *direntry, const char *ea_name)
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct super_block *sb;
char *full_path = NULL;
@@ -109,9 +109,10 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct super_block *sb;
char *full_path;
+ struct cifs_ntsd *pacl;
if (direntry == NULL)
return -EIO;
@@ -166,6 +167,25 @@ int cifs_setxattr(struct dentry *direntry, const char *ea_name,
rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,
(__u16)value_size, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
+ } else if (strncmp(ea_name, CIFS_XATTR_CIFS_ACL,
+ strlen(CIFS_XATTR_CIFS_ACL)) == 0) {
+ pacl = kmalloc(value_size, GFP_KERNEL);
+ if (!pacl) {
+ cFYI(1, "%s: Can't allocate memory for ACL",
+ __func__);
+ rc = -ENOMEM;
+ } else {
+#ifdef CONFIG_CIFS_ACL
+ memcpy(pacl, ea_value, value_size);
+ rc = set_cifs_acl(pacl, value_size,
+ direntry->d_inode, full_path);
+ if (rc == 0) /* force revalidate of the inode */
+ CIFS_I(direntry->d_inode)->time = 0;
+ kfree(pacl);
+#else
+ cFYI(1, "Set CIFS ACL not supported yet");
+#endif /* CONFIG_CIFS_ACL */
+ }
} else {
int temp;
temp = strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,
@@ -220,7 +240,7 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct super_block *sb;
char *full_path;
@@ -352,7 +372,7 @@ ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)
int xid;
struct cifs_sb_info *cifs_sb;
struct tcon_link *tlink;
- struct cifsTconInfo *pTcon;
+ struct cifs_tcon *pTcon;
struct super_block *sb;
char *full_path;