<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kernel sources &#187; dns_resolve</title>
	<atom:link href="http://lynyrd.ru/category/dns_resolve/feed" rel="self" type="application/rss+xml" />
	<link>http://lynyrd.ru</link>
	<description></description>
	<lastBuildDate>Sun, 31 Jan 2010 05:51:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>xattr.c</title>
		<link>http://lynyrd.ru/xattr-c-3</link>
		<comments>http://lynyrd.ru/xattr-c-3#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:34:23 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/xattr-c-3</guid>
		<description><![CDATA[/*
 *   fs/cifs/xattr.c
 *
 *   Copyright (c) International Business Machines  Corp., 2003, 2007
 *   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 ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/xattr.c<span id="more-973"></span><br />
 *<br />
 *   Copyright (c) International Business Machines  Corp., 2003, 2007<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>#include
<linux/fs.h>
#include
<linux/posix_acl_xattr.h>
#include &laquo;cifsfs.h&raquo;<br />
#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifsproto.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;</p>
<p>#define MAX_EA_VALUE_SIZE 65535<br />
#define CIFS_XATTR_DOS_ATTRIB &laquo;user.DosAttrib&raquo;<br />
#define CIFS_XATTR_USER_PREFIX &laquo;user.&raquo;<br />
#define CIFS_XATTR_SYSTEM_PREFIX &laquo;system.&raquo;<br />
#define CIFS_XATTR_OS2_PREFIX &laquo;os2.&raquo;<br />
#define CIFS_XATTR_SECURITY_PREFIX &laquo;.security&raquo;<br />
#define CIFS_XATTR_TRUSTED_PREFIX &laquo;trusted.&raquo;<br />
#define XATTR_TRUSTED_PREFIX_LEN  8<br />
#define XATTR_SECURITY_PREFIX_LEN 9<br />
/* BB need to add server (Samba e.g) support for security and trusted prefix */</p>
<p>int cifs_removexattr(struct dentry *direntry, const char *ea_name)<br />
{<br />
	int rc = -EOPNOTSUPP;<br />
#ifdef CONFIG_CIFS_XATTR<br />
	int xid;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	struct super_block *sb;<br />
	char *full_path;</p>
<p>	if (direntry == NULL)<br />
		return -EIO;<br />
	if (direntry->d_inode == NULL)<br />
		return -EIO;<br />
	sb = direntry->d_inode->i_sb;<br />
	if (sb == NULL)<br />
		return -EIO;<br />
	xid = GetXid();</p>
<p>	cifs_sb = CIFS_SB(sb);<br />
	pTcon = cifs_sb->tcon;</p>
<p>	full_path = build_path_from_dentry(direntry);<br />
	if (full_path == NULL) {<br />
		rc = -ENOMEM;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}<br />
	if (ea_name == NULL) {<br />
		cFYI(1, (&raquo;Null xattr names not supported&raquo;));<br />
	} else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5)<br />
		&#038;&#038; (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4))) {<br />
		cFYI(1,<br />
		    (&raquo;illegal xattr request %s (only user namespace supported)&raquo;,<br />
			ea_name));<br />
		/* BB what if no namespace prefix? */<br />
		/* Should we just pass them to server, except for<br />
		system and perhaps security prefixes? */<br />
	} else {<br />
		if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_NO_XATTR)<br />
			goto remove_ea_exit;</p>
<p>		ea_name += 5; /* skip past user. prefix */<br />
		rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, NULL,<br />
			(__u16)0, cifs_sb->local_nls,<br />
			cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	}<br />
remove_ea_exit:<br />
	kfree(full_path);<br />
	FreeXid(xid);<br />
#endif<br />
	return rc;<br />
}</p>
<p>int cifs_setxattr(struct dentry *direntry, const char *ea_name,<br />
		  const void *ea_value, size_t value_size, int flags)<br />
{<br />
	int rc = -EOPNOTSUPP;<br />
#ifdef CONFIG_CIFS_XATTR<br />
	int xid;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	struct super_block *sb;<br />
	char *full_path;</p>
<p>	if (direntry == NULL)<br />
		return -EIO;<br />
	if (direntry->d_inode == NULL)<br />
		return -EIO;<br />
	sb = direntry->d_inode->i_sb;<br />
	if (sb == NULL)<br />
		return -EIO;<br />
	xid = GetXid();</p>
<p>	cifs_sb = CIFS_SB(sb);<br />
	pTcon = cifs_sb->tcon;</p>
<p>	full_path = build_path_from_dentry(direntry);<br />
	if (full_path == NULL) {<br />
		rc = -ENOMEM;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}<br />
	/* return dos attributes as pseudo xattr */<br />
	/* return alt name if available as pseudo attr */</p>
<p>	/* if proc/fs/cifs/streamstoxattr is set then<br />
		search server for EAs or streams to<br />
		returns as xattrs */<br />
	if (value_size > MAX_EA_VALUE_SIZE) {<br />
		cFYI(1, (&raquo;size of EA value too large&raquo;));<br />
		kfree(full_path);<br />
		FreeXid(xid);<br />
		return -EOPNOTSUPP;<br />
	}</p>
<p>	if (ea_name == NULL) {<br />
		cFYI(1, (&raquo;Null xattr names not supported&raquo;));<br />
	} else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {<br />
		if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_NO_XATTR)<br />
			goto set_ea_exit;<br />
		if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0)<br />
			cFYI(1, (&raquo;attempt to set cifs inode metadata&raquo;));</p>
<p>		ea_name += 5; /* skip past user. prefix */<br />
		rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,<br />
			(__u16)value_size, cifs_sb->local_nls,<br />
			cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	} else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {<br />
		if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_NO_XATTR)<br />
			goto set_ea_exit;</p>
<p>		ea_name += 4; /* skip past os2. prefix */<br />
		rc = CIFSSMBSetEA(xid, pTcon, full_path, ea_name, ea_value,<br />
			(__u16)value_size, cifs_sb->local_nls,<br />
			cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	} else {<br />
		int temp;<br />
		temp = strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,<br />
			strlen(POSIX_ACL_XATTR_ACCESS));<br />
		if (temp == 0) {<br />
#ifdef CONFIG_CIFS_POSIX<br />
			if (sb->s_flags &#038; MS_POSIXACL)<br />
				rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,<br />
					ea_value, (const int)value_size,<br />
					ACL_TYPE_ACCESS, cifs_sb->local_nls,<br />
					cifs_sb->mnt_cifs_flags &#038;<br />
						CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
			cFYI(1, (&raquo;set POSIX ACL rc %d&raquo;, rc));<br />
#else<br />
			cFYI(1, (&raquo;set POSIX ACL not supported&raquo;));<br />
#endif<br />
		} else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,<br />
				   strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {<br />
#ifdef CONFIG_CIFS_POSIX<br />
			if (sb->s_flags &#038; MS_POSIXACL)<br />
				rc = CIFSSMBSetPosixACL(xid, pTcon, full_path,<br />
					ea_value, (const int)value_size,<br />
					ACL_TYPE_DEFAULT, cifs_sb->local_nls,<br />
					cifs_sb->mnt_cifs_flags &#038;<br />
						CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
			cFYI(1, (&raquo;set POSIX default ACL rc %d&raquo;, rc));<br />
#else<br />
			cFYI(1, (&raquo;set default POSIX ACL not supported&raquo;));<br />
#endif<br />
		} else {<br />
			cFYI(1, (&raquo;illegal xattr request %s (only user namespace&raquo;<br />
				 &raquo; supported)&raquo;, ea_name));<br />
		  /* BB what if no namespace prefix? */<br />
		  /* Should we just pass them to server, except for<br />
		  system and perhaps security prefixes? */<br />
		}<br />
	}</p>
<p>set_ea_exit:<br />
	kfree(full_path);<br />
	FreeXid(xid);<br />
#endif<br />
	return rc;<br />
}</p>
<p>ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name,<br />
	void *ea_value, size_t buf_size)<br />
{<br />
	ssize_t rc = -EOPNOTSUPP;<br />
#ifdef CONFIG_CIFS_XATTR<br />
	int xid;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	struct super_block *sb;<br />
	char *full_path;</p>
<p>	if (direntry == NULL)<br />
		return -EIO;<br />
	if (direntry->d_inode == NULL)<br />
		return -EIO;<br />
	sb = direntry->d_inode->i_sb;<br />
	if (sb == NULL)<br />
		return -EIO;</p>
<p>	xid = GetXid();</p>
<p>	cifs_sb = CIFS_SB(sb);<br />
	pTcon = cifs_sb->tcon;</p>
<p>	full_path = build_path_from_dentry(direntry);<br />
	if (full_path == NULL) {<br />
		rc = -ENOMEM;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}<br />
	/* return dos attributes as pseudo xattr */<br />
	/* return alt name if available as pseudo attr */<br />
	if (ea_name == NULL) {<br />
		cFYI(1, (&raquo;Null xattr names not supported&raquo;));<br />
	} else if (strncmp(ea_name, CIFS_XATTR_USER_PREFIX, 5) == 0) {<br />
		if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_NO_XATTR)<br />
			goto get_ea_exit;</p>
<p>		if (strncmp(ea_name, CIFS_XATTR_DOS_ATTRIB, 14) == 0) {<br />
			cFYI(1, (&raquo;attempt to query cifs inode metadata&raquo;));<br />
			/* revalidate/getattr then populate from inode */<br />
		} /* BB add else when above is implemented */<br />
		ea_name += 5; /* skip past user. prefix */<br />
		rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,<br />
			buf_size, cifs_sb->local_nls,<br />
			cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	} else if (strncmp(ea_name, CIFS_XATTR_OS2_PREFIX, 4) == 0) {<br />
		if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_NO_XATTR)<br />
			goto get_ea_exit;</p>
<p>		ea_name += 4; /* skip past os2. prefix */<br />
		rc = CIFSSMBQueryEA(xid, pTcon, full_path, ea_name, ea_value,<br />
			buf_size, cifs_sb->local_nls,<br />
			cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	} else if (strncmp(ea_name, POSIX_ACL_XATTR_ACCESS,<br />
			  strlen(POSIX_ACL_XATTR_ACCESS)) == 0) {<br />
#ifdef CONFIG_CIFS_POSIX<br />
		if (sb->s_flags &#038; MS_POSIXACL)<br />
			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,<br />
				ea_value, buf_size, ACL_TYPE_ACCESS,<br />
				cifs_sb->local_nls,<br />
				cifs_sb->mnt_cifs_flags &#038;<br />
					CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
#ifdef CONFIG_CIFS_EXPERIMENTAL<br />
		else if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_CIFS_ACL) {<br />
			__u16 fid;<br />
			int oplock = 0;<br />
			struct cifs_ntsd *pacl = NULL;<br />
			__u32 buflen = 0;<br />
			if (experimEnabled)<br />
				rc = CIFSSMBOpen(xid, pTcon, full_path,<br />
					FILE_OPEN, GENERIC_READ, 0, &#038;fid,<br />
					&#038;oplock, NULL, cifs_sb->local_nls,<br />
					cifs_sb->mnt_cifs_flags &#038;<br />
					CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
			/* else rc is EOPNOTSUPP from above */</p>
<p>			if (rc == 0) {<br />
				rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, &#038;pacl,<br />
						      &#038;buflen);<br />
				CIFSSMBClose(xid, pTcon, fid);<br />
			}<br />
		}<br />
#endif /* EXPERIMENTAL */<br />
#else<br />
		cFYI(1, (&raquo;query POSIX ACL not supported yet&raquo;));<br />
#endif /* CONFIG_CIFS_POSIX */<br />
	} else if (strncmp(ea_name, POSIX_ACL_XATTR_DEFAULT,<br />
			  strlen(POSIX_ACL_XATTR_DEFAULT)) == 0) {<br />
#ifdef CONFIG_CIFS_POSIX<br />
		if (sb->s_flags &#038; MS_POSIXACL)<br />
			rc = CIFSSMBGetPosixACL(xid, pTcon, full_path,<br />
				ea_value, buf_size, ACL_TYPE_DEFAULT,<br />
				cifs_sb->local_nls,<br />
				cifs_sb->mnt_cifs_flags &#038;<br />
					CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
#else<br />
		cFYI(1, (&raquo;query POSIX default ACL not supported yet&raquo;));<br />
#endif<br />
	} else if (strncmp(ea_name,<br />
		  CIFS_XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0) {<br />
		cFYI(1, (&raquo;Trusted xattr namespace not supported yet&raquo;));<br />
	} else if (strncmp(ea_name,<br />
		  CIFS_XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN) == 0) {<br />
		cFYI(1, (&raquo;Security xattr namespace not supported yet&raquo;));<br />
	} else<br />
		cFYI(1,<br />
		    (&raquo;illegal xattr request %s (only user namespace supported)&raquo;,<br />
			ea_name));</p>
<p>	/* We could add an additional check for streams ie<br />
	    if proc/fs/cifs/streamstoxattr is set then<br />
		search server for EAs or streams to<br />
		returns as xattrs */</p>
<p>	if (rc == -EINVAL)<br />
		rc = -EOPNOTSUPP;</p>
<p>get_ea_exit:<br />
	kfree(full_path);<br />
	FreeXid(xid);<br />
#endif<br />
	return rc;<br />
}</p>
<p>ssize_t cifs_listxattr(struct dentry *direntry, char *data, size_t buf_size)<br />
{<br />
	ssize_t rc = -EOPNOTSUPP;<br />
#ifdef CONFIG_CIFS_XATTR<br />
	int xid;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	struct super_block *sb;<br />
	char *full_path;</p>
<p>	if (direntry == NULL)<br />
		return -EIO;<br />
	if (direntry->d_inode == NULL)<br />
		return -EIO;<br />
	sb = direntry->d_inode->i_sb;<br />
	if (sb == NULL)<br />
		return -EIO;</p>
<p>	cifs_sb = CIFS_SB(sb);<br />
	pTcon = cifs_sb->tcon;</p>
<p>	if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_NO_XATTR)<br />
		return -EOPNOTSUPP;</p>
<p>	xid = GetXid();</p>
<p>	full_path = build_path_from_dentry(direntry);<br />
	if (full_path == NULL) {<br />
		rc = -ENOMEM;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}<br />
	/* return dos attributes as pseudo xattr */<br />
	/* return alt name if available as pseudo attr */</p>
<p>	/* if proc/fs/cifs/streamstoxattr is set then<br />
		search server for EAs or streams to<br />
		returns as xattrs */<br />
	rc = CIFSSMBQAllEAs(xid, pTcon, full_path, data, buf_size,<br />
				cifs_sb->local_nls,<br />
				cifs_sb->mnt_cifs_flags &#038;<br />
					CIFS_MOUNT_MAP_SPECIAL_CHR);</p>
<p>	kfree(full_path);<br />
	FreeXid(xid);<br />
#endif<br />
	return rc;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/xattr-c-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>transport.c</title>
		<link>http://lynyrd.ru/transport-c</link>
		<comments>http://lynyrd.ru/transport-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:34:01 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/transport-c</guid>
		<description><![CDATA[/*
 *   fs/cifs/transport.c
 *
 *   Copyright (C) International Business Machines  Corp., 2002,2008
 *   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 ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/transport.c<span id="more-972"></span><br />
 *<br />
 *   Copyright (C) International Business Machines  Corp., 2002,2008<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *   Jeremy Allison (jra@samba.org) 2006.<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>#include
<linux/fs.h>
#include
<linux/list.h>
#include
<linux/wait.h>
#include
<linux/net.h>
#include
<linux/delay.h>
#include <asm/uaccess.h><br />
#include <asm/processor.h><br />
#include
<linux/mempool.h>
#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifsproto.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;</p>
<p>extern mempool_t *cifs_mid_poolp;<br />
extern struct kmem_cache *cifs_oplock_cachep;</p>
<p>static struct mid_q_entry *<br />
AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server)<br />
{<br />
	struct mid_q_entry *temp;</p>
<p>	if (server == NULL) {<br />
		cERROR(1, (&raquo;Null TCP session in AllocMidQEntry&raquo;));<br />
		return NULL;<br />
	}</p>
<p>	temp = mempool_alloc(cifs_mid_poolp, GFP_NOFS);<br />
	if (temp == NULL)<br />
		return temp;<br />
	else {<br />
		memset(temp, 0, sizeof(struct mid_q_entry));<br />
		temp->mid = smb_buffer->Mid;	/* always LE */<br />
		temp->pid = current->pid;<br />
		temp->command = smb_buffer->Command;<br />
		cFYI(1, (&raquo;For smb_command %d&raquo;, temp->command));<br />
	/*	do_gettimeofday(&#038;temp->when_sent);*/ /* easier to use jiffies */<br />
		/* when mid allocated can be before when sent */<br />
		temp->when_alloc = jiffies;<br />
		temp->tsk = current;<br />
	}</p>
<p>	spin_lock(&#038;GlobalMid_Lock);<br />
	list_add_tail(&#038;temp->qhead, &#038;server->pending_mid_q);<br />
	atomic_inc(&#038;midCount);<br />
	temp->midState = MID_REQUEST_ALLOCATED;<br />
	spin_unlock(&#038;GlobalMid_Lock);<br />
	return temp;<br />
}</p>
<p>static void<br />
DeleteMidQEntry(struct mid_q_entry *midEntry)<br />
{<br />
#ifdef CONFIG_CIFS_STATS2<br />
	unsigned long now;<br />
#endif<br />
	spin_lock(&#038;GlobalMid_Lock);<br />
	midEntry->midState = MID_FREE;<br />
	list_del(&#038;midEntry->qhead);<br />
	atomic_dec(&#038;midCount);<br />
	spin_unlock(&#038;GlobalMid_Lock);<br />
	if (midEntry->largeBuf)<br />
		cifs_buf_release(midEntry->resp_buf);<br />
	else<br />
		cifs_small_buf_release(midEntry->resp_buf);<br />
#ifdef CONFIG_CIFS_STATS2<br />
	now = jiffies;<br />
	/* commands taking longer than one second are indications that<br />
	   something is wrong, unless it is quite a slow link or server */<br />
	if ((now &#8211; midEntry->when_alloc) > HZ) {<br />
		if ((cifsFYI &#038; CIFS_TIMER) &#038;&#038;<br />
		   (midEntry->command != SMB_COM_LOCKING_ANDX)) {<br />
			printk(KERN_DEBUG &raquo; CIFS slow rsp: cmd %d mid %d&raquo;,<br />
			       midEntry->command, midEntry->mid);<br />
			printk(&raquo; A: 0x%lx S: 0x%lx R: 0x%lx\n&raquo;,<br />
			       now &#8211; midEntry->when_alloc,<br />
			       now &#8211; midEntry->when_sent,<br />
			       now &#8211; midEntry->when_received);<br />
		}<br />
	}<br />
#endif<br />
	mempool_free(midEntry, cifs_mid_poolp);<br />
}</p>
<p>static int<br />
smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec)<br />
{<br />
	int rc = 0;<br />
	int i = 0;<br />
	struct msghdr smb_msg;<br />
	struct smb_hdr *smb_buffer = iov[0].iov_base;<br />
	unsigned int len = iov[0].iov_len;<br />
	unsigned int total_len;<br />
	int first_vec = 0;<br />
	unsigned int smb_buf_length = smb_buffer->smb_buf_length;<br />
	struct socket *ssocket = server->ssocket;</p>
<p>	if (ssocket == NULL)<br />
		return -ENOTSOCK; /* BB eventually add reconnect code here */</p>
<p>	smb_msg.msg_name = (struct sockaddr *) &#038;server->addr.sockAddr;<br />
	smb_msg.msg_namelen = sizeof(struct sockaddr);<br />
	smb_msg.msg_control = NULL;<br />
	smb_msg.msg_controllen = 0;<br />
	if (server->noblocksnd)<br />
		smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL;<br />
	else<br />
		smb_msg.msg_flags = MSG_NOSIGNAL;</p>
<p>	/* smb header is converted in header_assemble. bcc and rest of SMB word<br />
	   area, and byte area if necessary, is converted to littleendian in<br />
	   cifssmb.c and RFC1001 len is converted to bigendian in smb_send<br />
	   Flags2 is converted in SendReceive */</p>
<p>	total_len = 0;<br />
	for (i = 0; i < n_vec; i++)<br />
		total_len += iov[i].iov_len;</p>
<p>	smb_buffer->smb_buf_length = cpu_to_be32(smb_buffer->smb_buf_length);<br />
	cFYI(1, (&raquo;Sending smb:  total_len %d&raquo;, total_len));<br />
	dump_smb(smb_buffer, len);</p>
<p>	i = 0;<br />
	while (total_len) {<br />
		rc = kernel_sendmsg(ssocket, &#038;smb_msg, &#038;iov[first_vec],<br />
				    n_vec &#8211; first_vec, total_len);<br />
		if ((rc == -ENOSPC) || (rc == -EAGAIN)) {<br />
			i++;<br />
			/* if blocking send we try 3 times, since each can block<br />
			   for 5 seconds. For nonblocking  we have to try more<br />
			   but wait increasing amounts of time allowing time for<br />
			   socket to clear.  The overall time we wait in either<br />
			   case to send on the socket is about 15 seconds.<br />
			   Similarly we wait for 15 seconds for<br />
			   a response from the server in SendReceive[2]<br />
			   for the server to send a response back for<br />
			   most types of requests (except SMB Write<br />
			   past end of file which can be slow, and<br />
			   blocking lock operations). NFS waits slightly longer<br />
			   than CIFS, but this can make it take longer for<br />
			   nonresponsive servers to be detected and 15 seconds<br />
			   is more than enough time for modern networks to<br />
			   send a packet.  In most cases if we fail to send<br />
			   after the retries we will kill the socket and<br />
			   reconnect which may clear the network problem.<br />
			*/<br />
			if ((i >= 14) || (!server->noblocksnd &#038;&#038; (i > 2))) {<br />
				cERROR(1,<br />
				   (&raquo;sends on sock %p stuck for 15 seconds&raquo;,<br />
				    ssocket));<br />
				rc = -EAGAIN;<br />
				break;<br />
			}<br />
			msleep(1 << i);<br />
			continue;<br />
		}<br />
		if (rc < 0)<br />
			break;</p>
<p>		if (rc == total_len) {<br />
			total_len = 0;<br />
			break;<br />
		} else if (rc > total_len) {<br />
			cERROR(1, (&raquo;sent %d requested %d&raquo;, rc, total_len));<br />
			break;<br />
		}<br />
		if (rc == 0) {<br />
			/* should never happen, letting socket clear before<br />
			   retrying is our only obvious option here */<br />
			cERROR(1, (&raquo;tcp sent no data&raquo;));<br />
			msleep(500);<br />
			continue;<br />
		}<br />
		total_len -= rc;<br />
		/* the line below resets i */<br />
		for (i = first_vec; i < n_vec; i++) {<br />
			if (iov[i].iov_len) {<br />
				if (rc > iov[i].iov_len) {<br />
					rc -= iov[i].iov_len;<br />
					iov[i].iov_len = 0;<br />
				} else {<br />
					iov[i].iov_base += rc;<br />
					iov[i].iov_len -= rc;<br />
					first_vec = i;<br />
					break;<br />
				}<br />
			}<br />
		}<br />
		i = 0; /* in case we get ENOSPC on the next send */<br />
	}</p>
<p>	if ((total_len > 0) &#038;&#038; (total_len != smb_buf_length + 4)) {<br />
		cFYI(1, (&raquo;partial send (%d remaining), terminating session&raquo;,<br />
			total_len));<br />
		/* If we have only sent part of an SMB then the next SMB<br />
		   could be taken as the remainder of this one.  We need<br />
		   to kill the socket so the server throws away the partial<br />
		   SMB */<br />
		server->tcpStatus = CifsNeedReconnect;<br />
	}</p>
<p>	if (rc < 0) {<br />
		cERROR(1, ("Error %d sending data on socket to server", rc));<br />
	} else<br />
		rc = 0;</p>
<p>	/* Don't want to modify the buffer as a<br />
	   side effect of this call. */<br />
	smb_buffer->smb_buf_length = smb_buf_length;</p>
<p>	return rc;<br />
}</p>
<p>int<br />
smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer,<br />
	 unsigned int smb_buf_length)<br />
{<br />
	struct kvec iov;</p>
<p>	iov.iov_base = smb_buffer;<br />
	iov.iov_len = smb_buf_length + 4;</p>
<p>	return smb_sendv(server, &#038;iov, 1);<br />
}</p>
<p>static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op)<br />
{<br />
	if (long_op == CIFS_ASYNC_OP) {<br />
		/* oplock breaks must not be held up */<br />
		atomic_inc(&#038;ses->server->inFlight);<br />
		return 0;<br />
	}</p>
<p>	spin_lock(&#038;GlobalMid_Lock);<br />
	while (1) {<br />
		if (atomic_read(&#038;ses->server->inFlight) >=<br />
				cifs_max_pending){<br />
			spin_unlock(&#038;GlobalMid_Lock);<br />
#ifdef CONFIG_CIFS_STATS2<br />
			atomic_inc(&#038;ses->server->num_waiters);<br />
#endif<br />
			wait_event(ses->server->request_q,<br />
				   atomic_read(&#038;ses->server->inFlight)<br />
				     < cifs_max_pending);<br />
#ifdef CONFIG_CIFS_STATS2<br />
			atomic_dec(&#038;ses->server->num_waiters);<br />
#endif<br />
			spin_lock(&#038;GlobalMid_Lock);<br />
		} else {<br />
			if (ses->server->tcpStatus == CifsExiting) {<br />
				spin_unlock(&#038;GlobalMid_Lock);<br />
				return -ENOENT;<br />
			}</p>
<p>			/* can not count locking commands against total<br />
			   as they are allowed to block on server */</p>
<p>			/* update # of requests on the wire to server */<br />
			if (long_op != CIFS_BLOCKING_OP)<br />
				atomic_inc(&#038;ses->server->inFlight);<br />
			spin_unlock(&#038;GlobalMid_Lock);<br />
			break;<br />
		}<br />
	}<br />
	return 0;<br />
}</p>
<p>static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf,<br />
			struct mid_q_entry **ppmidQ)<br />
{<br />
	if (ses->server->tcpStatus == CifsExiting) {<br />
		return -ENOENT;<br />
	}</p>
<p>	if (ses->server->tcpStatus == CifsNeedReconnect) {<br />
		cFYI(1, (&raquo;tcp session dead &#8211; return to caller to retry&raquo;));<br />
		return -EAGAIN;<br />
	}</p>
<p>	if (ses->status != CifsGood) {<br />
		/* check if SMB session is bad because we are setting it up */<br />
		if ((in_buf->Command != SMB_COM_SESSION_SETUP_ANDX) &#038;&#038;<br />
			(in_buf->Command != SMB_COM_NEGOTIATE))<br />
			return -EAGAIN;<br />
		/* else ok &#8211; we are setting up session */<br />
	}<br />
	*ppmidQ = AllocMidQEntry(in_buf, ses->server);<br />
	if (*ppmidQ == NULL)<br />
		return -ENOMEM;<br />
	return 0;<br />
}</p>
<p>static int wait_for_response(struct cifsSesInfo *ses,<br />
			struct mid_q_entry *midQ,<br />
			unsigned long timeout,<br />
			unsigned long time_to_wait)<br />
{<br />
	unsigned long curr_timeout;</p>
<p>	for (;;) {<br />
		curr_timeout = timeout + jiffies;<br />
		wait_event_timeout(ses->server->response_q,<br />
			midQ->midState != MID_REQUEST_SUBMITTED, timeout);</p>
<p>		if (time_after(jiffies, curr_timeout) &#038;&#038;<br />
			(midQ->midState == MID_REQUEST_SUBMITTED) &#038;&#038;<br />
			((ses->server->tcpStatus == CifsGood) ||<br />
			 (ses->server->tcpStatus == CifsNew))) {</p>
<p>			unsigned long lrt;</p>
<p>			/* We timed out. Is the server still<br />
			   sending replies ? */<br />
			spin_lock(&#038;GlobalMid_Lock);<br />
			lrt = ses->server->lstrp;<br />
			spin_unlock(&#038;GlobalMid_Lock);</p>
<p>			/* Calculate time_to_wait past last receive time.<br />
			 Although we prefer not to time out if the<br />
			 server is still responding &#8211; we will time<br />
			 out if the server takes more than 15 (or 45<br />
			 or 180) seconds to respond to this request<br />
			 and has not responded to any request from<br />
			 other threads on the client within 10 seconds */<br />
			lrt += time_to_wait;<br />
			if (time_after(jiffies, lrt)) {<br />
				/* No replies for time_to_wait. */<br />
				cERROR(1, (&raquo;server not responding&raquo;));<br />
				return -1;<br />
			}<br />
		} else {<br />
			return 0;<br />
		}<br />
	}<br />
}</p>
<p>/*<br />
 *<br />
 * Send an SMB Request.  No response info (other than return code)<br />
 * needs to be parsed.<br />
 *<br />
 * flags indicate the type of request buffer and how long to wait<br />
 * and whether to log NT STATUS code (error) before mapping it to POSIX error<br />
 *<br />
 */<br />
int<br />
SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses,<br />
		struct smb_hdr *in_buf, int flags)<br />
{<br />
	int rc;<br />
	struct kvec iov[1];<br />
	int resp_buf_type;</p>
<p>	iov[0].iov_base = (char *)in_buf;<br />
	iov[0].iov_len = in_buf->smb_buf_length + 4;<br />
	flags |= CIFS_NO_RESP;<br />
	rc = SendReceive2(xid, ses, iov, 1, &#038;resp_buf_type, flags);<br />
	cFYI(DBG2, (&raquo;SendRcvNoRsp flags %d rc %d&raquo;, flags, rc));</p>
<p>	return rc;<br />
}</p>
<p>int<br />
SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,<br />
	     struct kvec *iov, int n_vec, int *pRespBufType /* ret */,<br />
	     const int flags)<br />
{<br />
	int rc = 0;<br />
	int long_op;<br />
	unsigned int receive_len;<br />
	unsigned long timeout;<br />
	struct mid_q_entry *midQ;<br />
	struct smb_hdr *in_buf = iov[0].iov_base;</p>
<p>	long_op = flags &#038; CIFS_TIMEOUT_MASK;</p>
<p>	*pRespBufType = CIFS_NO_BUFFER;  /* no response buf yet */</p>
<p>	if ((ses == NULL) || (ses->server == NULL)) {<br />
		cifs_small_buf_release(in_buf);<br />
		cERROR(1, (&raquo;Null session&raquo;));<br />
		return -EIO;<br />
	}</p>
<p>	if (ses->server->tcpStatus == CifsExiting) {<br />
		cifs_small_buf_release(in_buf);<br />
		return -ENOENT;<br />
	}</p>
<p>	/* Ensure that we do not send more than 50 overlapping requests<br />
	   to the same server. We may make this configurable later or<br />
	   use ses->maxReq */</p>
<p>	rc = wait_for_free_request(ses, long_op);<br />
	if (rc) {<br />
		cifs_small_buf_release(in_buf);<br />
		return rc;<br />
	}</p>
<p>	/* make sure that we sign in the same order that we send on this socket<br />
	   and avoid races inside tcp sendmsg code that could cause corruption<br />
	   of smb data */</p>
<p>	mutex_lock(&#038;ses->server->srv_mutex);</p>
<p>	rc = allocate_mid(ses, in_buf, &#038;midQ);<br />
	if (rc) {<br />
		mutex_unlock(&#038;ses->server->srv_mutex);<br />
		cifs_small_buf_release(in_buf);<br />
		/* Update # of requests on wire to server */<br />
		atomic_dec(&#038;ses->server->inFlight);<br />
		wake_up(&#038;ses->server->request_q);<br />
		return rc;<br />
	}<br />
	rc = cifs_sign_smb2(iov, n_vec, ses->server, &#038;midQ->sequence_number);<br />
	if (rc) {<br />
		mutex_unlock(&#038;ses->server->srv_mutex);<br />
		cifs_small_buf_release(in_buf);<br />
		goto out;<br />
	}</p>
<p>	midQ->midState = MID_REQUEST_SUBMITTED;<br />
#ifdef CONFIG_CIFS_STATS2<br />
	atomic_inc(&#038;ses->server->inSend);<br />
#endif<br />
	rc = smb_sendv(ses->server, iov, n_vec);<br />
#ifdef CONFIG_CIFS_STATS2<br />
	atomic_dec(&#038;ses->server->inSend);<br />
	midQ->when_sent = jiffies;<br />
#endif</p>
<p>	mutex_unlock(&#038;ses->server->srv_mutex);<br />
	cifs_small_buf_release(in_buf);</p>
<p>	if (rc < 0)<br />
		goto out;</p>
<p>	if (long_op == CIFS_STD_OP)<br />
		timeout = 15 * HZ;<br />
	else if (long_op == CIFS_VLONG_OP) /* e.g. slow writes past EOF */<br />
		timeout = 180 * HZ;<br />
	else if (long_op == CIFS_LONG_OP)<br />
		timeout = 45 * HZ; /* should be greater than<br />
			servers oplock break timeout (about 43 seconds) */<br />
	else if (long_op == CIFS_ASYNC_OP)<br />
		goto out;<br />
	else if (long_op == CIFS_BLOCKING_OP)<br />
		timeout = 0x7FFFFFFF; /*  large, but not so large as to wrap */<br />
	else {<br />
		cERROR(1, ("unknown timeout flag %d", long_op));<br />
		rc = -EIO;<br />
		goto out;<br />
	}</p>
<p>	/* wait for 15 seconds or until woken up due to response arriving or<br />
	   due to last connection to this server being unmounted */<br />
	if (signal_pending(current)) {<br />
		/* if signal pending do not hold up user for full smb timeout<br />
		but we still give response a chance to complete */<br />
		timeout = 2 * HZ;<br />
	}</p>
<p>	/* No user interrupts in wait - wreaks havoc with performance */<br />
	wait_for_response(ses, midQ, timeout, 10 * HZ);</p>
<p>	spin_lock(&#038;GlobalMid_Lock);</p>
<p>	if (midQ->resp_buf == NULL) {<br />
		cERROR(1, (&raquo;No response to cmd %d mid %d&raquo;,<br />
			midQ->command, midQ->mid));<br />
		if (midQ->midState == MID_REQUEST_SUBMITTED) {<br />
			if (ses->server->tcpStatus == CifsExiting)<br />
				rc = -EHOSTDOWN;<br />
			else {<br />
				ses->server->tcpStatus = CifsNeedReconnect;<br />
				midQ->midState = MID_RETRY_NEEDED;<br />
			}<br />
		}</p>
<p>		if (rc != -EHOSTDOWN) {<br />
			if (midQ->midState == MID_RETRY_NEEDED) {<br />
				rc = -EAGAIN;<br />
				cFYI(1, (&raquo;marking request for retry&raquo;));<br />
			} else {<br />
				rc = -EIO;<br />
			}<br />
		}<br />
		spin_unlock(&#038;GlobalMid_Lock);<br />
		DeleteMidQEntry(midQ);<br />
		/* Update # of requests on wire to server */<br />
		atomic_dec(&#038;ses->server->inFlight);<br />
		wake_up(&#038;ses->server->request_q);<br />
		return rc;<br />
	}</p>
<p>	spin_unlock(&#038;GlobalMid_Lock);<br />
	receive_len = midQ->resp_buf->smb_buf_length;</p>
<p>	if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {<br />
		cERROR(1, (&raquo;Frame too large received.  Length: %d  Xid: %d&raquo;,<br />
			receive_len, xid));<br />
		rc = -EIO;<br />
		goto out;<br />
	}</p>
<p>	/* rcvd frame is ok */</p>
<p>	if (midQ->resp_buf &#038;&#038;<br />
	    (midQ->midState == MID_RESPONSE_RECEIVED)) {</p>
<p>		iov[0].iov_base = (char *)midQ->resp_buf;<br />
		if (midQ->largeBuf)<br />
			*pRespBufType = CIFS_LARGE_BUFFER;<br />
		else<br />
			*pRespBufType = CIFS_SMALL_BUFFER;<br />
		iov[0].iov_len = receive_len + 4;</p>
<p>		dump_smb(midQ->resp_buf, 80);<br />
		/* convert the length into a more usable form */<br />
		if ((receive_len > 24) &#038;&#038;<br />
		    (ses->server->secMode &#038; (SECMODE_SIGN_REQUIRED |<br />
					     SECMODE_SIGN_ENABLED))) {<br />
			rc = cifs_verify_signature(midQ->resp_buf,<br />
						&#038;ses->server->mac_signing_key,<br />
						midQ->sequence_number+1);<br />
			if (rc) {<br />
				cERROR(1, (&raquo;Unexpected SMB signature&raquo;));<br />
				/* BB FIXME add code to kill session */<br />
			}<br />
		}</p>
<p>		/* BB special case reconnect tid and uid here? */<br />
		rc = map_smb_to_linux_error(midQ->resp_buf,<br />
					    flags &#038; CIFS_LOG_ERROR);</p>
<p>		/* convert ByteCount if necessary */<br />
		if (receive_len >= sizeof(struct smb_hdr) &#8211; 4<br />
		    /* do not count RFC1001 header */  +<br />
		    (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ )<br />
			BCC(midQ->resp_buf) =<br />
				le16_to_cpu(BCC_LE(midQ->resp_buf));<br />
		if ((flags &#038; CIFS_NO_RESP) == 0)<br />
			midQ->resp_buf = NULL;  /* mark it so buf will<br />
						   not be freed by<br />
						   DeleteMidQEntry */<br />
	} else {<br />
		rc = -EIO;<br />
		cFYI(1, (&raquo;Bad MID state?&raquo;));<br />
	}</p>
<p>out:<br />
	DeleteMidQEntry(midQ);<br />
	atomic_dec(&#038;ses->server->inFlight);<br />
	wake_up(&#038;ses->server->request_q);</p>
<p>	return rc;<br />
}</p>
<p>int<br />
SendReceive(const unsigned int xid, struct cifsSesInfo *ses,<br />
	    struct smb_hdr *in_buf, struct smb_hdr *out_buf,<br />
	    int *pbytes_returned, const int long_op)<br />
{<br />
	int rc = 0;<br />
	unsigned int receive_len;<br />
	unsigned long timeout;<br />
	struct mid_q_entry *midQ;</p>
<p>	if (ses == NULL) {<br />
		cERROR(1, (&raquo;Null smb session&raquo;));<br />
		return -EIO;<br />
	}<br />
	if (ses->server == NULL) {<br />
		cERROR(1, (&raquo;Null tcp session&raquo;));<br />
		return -EIO;<br />
	}</p>
<p>	if (ses->server->tcpStatus == CifsExiting)<br />
		return -ENOENT;</p>
<p>	/* Ensure that we do not send more than 50 overlapping requests<br />
	   to the same server. We may make this configurable later or<br />
	   use ses->maxReq */</p>
<p>	if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE &#8211; 4) {<br />
		cERROR(1, (&raquo;Illegal length, greater than maximum frame, %d&raquo;,<br />
			   in_buf->smb_buf_length));<br />
		return -EIO;<br />
	}</p>
<p>	rc = wait_for_free_request(ses, long_op);<br />
	if (rc)<br />
		return rc;</p>
<p>	/* make sure that we sign in the same order that we send on this socket<br />
	   and avoid races inside tcp sendmsg code that could cause corruption<br />
	   of smb data */</p>
<p>	mutex_lock(&#038;ses->server->srv_mutex);</p>
<p>	rc = allocate_mid(ses, in_buf, &#038;midQ);<br />
	if (rc) {<br />
		mutex_unlock(&#038;ses->server->srv_mutex);<br />
		/* Update # of requests on wire to server */<br />
		atomic_dec(&#038;ses->server->inFlight);<br />
		wake_up(&#038;ses->server->request_q);<br />
		return rc;<br />
	}</p>
<p>	rc = cifs_sign_smb(in_buf, ses->server, &#038;midQ->sequence_number);<br />
	if (rc) {<br />
		mutex_unlock(&#038;ses->server->srv_mutex);<br />
		goto out;<br />
	}</p>
<p>	midQ->midState = MID_REQUEST_SUBMITTED;<br />
#ifdef CONFIG_CIFS_STATS2<br />
	atomic_inc(&#038;ses->server->inSend);<br />
#endif<br />
	rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);<br />
#ifdef CONFIG_CIFS_STATS2<br />
	atomic_dec(&#038;ses->server->inSend);<br />
	midQ->when_sent = jiffies;<br />
#endif<br />
	mutex_unlock(&#038;ses->server->srv_mutex);</p>
<p>	if (rc < 0)<br />
		goto out;</p>
<p>	if (long_op == CIFS_STD_OP)<br />
		timeout = 15 * HZ;<br />
	/* wait for 15 seconds or until woken up due to response arriving or<br />
	   due to last connection to this server being unmounted */<br />
	else if (long_op == CIFS_ASYNC_OP)<br />
		goto out;<br />
	else if (long_op == CIFS_VLONG_OP) /* writes past EOF can be slow */<br />
		timeout = 180 * HZ;<br />
	else if (long_op == CIFS_LONG_OP)<br />
		timeout = 45 * HZ; /* should be greater than<br />
			servers oplock break timeout (about 43 seconds) */<br />
	else if (long_op == CIFS_BLOCKING_OP)<br />
		timeout = 0x7FFFFFFF; /* large but no so large as to wrap */<br />
	else {<br />
		cERROR(1, ("unknown timeout flag %d", long_op));<br />
		rc = -EIO;<br />
		goto out;<br />
	}</p>
<p>	if (signal_pending(current)) {<br />
		/* if signal pending do not hold up user for full smb timeout<br />
		but we still give response a chance to complete */<br />
		timeout = 2 * HZ;<br />
	}</p>
<p>	/* No user interrupts in wait - wreaks havoc with performance */<br />
	wait_for_response(ses, midQ, timeout, 10 * HZ);</p>
<p>	spin_lock(&#038;GlobalMid_Lock);<br />
	if (midQ->resp_buf == NULL) {<br />
		cERROR(1, (&raquo;No response for cmd %d mid %d&raquo;,<br />
			  midQ->command, midQ->mid));<br />
		if (midQ->midState == MID_REQUEST_SUBMITTED) {<br />
			if (ses->server->tcpStatus == CifsExiting)<br />
				rc = -EHOSTDOWN;<br />
			else {<br />
				ses->server->tcpStatus = CifsNeedReconnect;<br />
				midQ->midState = MID_RETRY_NEEDED;<br />
			}<br />
		}</p>
<p>		if (rc != -EHOSTDOWN) {<br />
			if (midQ->midState == MID_RETRY_NEEDED) {<br />
				rc = -EAGAIN;<br />
				cFYI(1, (&raquo;marking request for retry&raquo;));<br />
			} else {<br />
				rc = -EIO;<br />
			}<br />
		}<br />
		spin_unlock(&#038;GlobalMid_Lock);<br />
		DeleteMidQEntry(midQ);<br />
		/* Update # of requests on wire to server */<br />
		atomic_dec(&#038;ses->server->inFlight);<br />
		wake_up(&#038;ses->server->request_q);<br />
		return rc;<br />
	}</p>
<p>	spin_unlock(&#038;GlobalMid_Lock);<br />
	receive_len = midQ->resp_buf->smb_buf_length;</p>
<p>	if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {<br />
		cERROR(1, (&raquo;Frame too large received.  Length: %d  Xid: %d&raquo;,<br />
			receive_len, xid));<br />
		rc = -EIO;<br />
		goto out;<br />
	}</p>
<p>	/* rcvd frame is ok */</p>
<p>	if (midQ->resp_buf &#038;&#038; out_buf<br />
	    &#038;&#038; (midQ->midState == MID_RESPONSE_RECEIVED)) {<br />
		out_buf->smb_buf_length = receive_len;<br />
		memcpy((char *)out_buf + 4,<br />
		       (char *)midQ->resp_buf + 4,<br />
		       receive_len);</p>
<p>		dump_smb(out_buf, 92);<br />
		/* convert the length into a more usable form */<br />
		if ((receive_len > 24) &#038;&#038;<br />
		    (ses->server->secMode &#038; (SECMODE_SIGN_REQUIRED |<br />
					     SECMODE_SIGN_ENABLED))) {<br />
			rc = cifs_verify_signature(out_buf,<br />
						&#038;ses->server->mac_signing_key,<br />
						midQ->sequence_number+1);<br />
			if (rc) {<br />
				cERROR(1, (&raquo;Unexpected SMB signature&raquo;));<br />
				/* BB FIXME add code to kill session */<br />
			}<br />
		}</p>
<p>		*pbytes_returned = out_buf->smb_buf_length;</p>
<p>		/* BB special case reconnect tid and uid here? */<br />
		rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );</p>
<p>		/* convert ByteCount if necessary */<br />
		if (receive_len >= sizeof(struct smb_hdr) &#8211; 4<br />
		    /* do not count RFC1001 header */  +<br />
		    (2 * out_buf->WordCount) + 2 /* bcc */ )<br />
			BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));<br />
	} else {<br />
		rc = -EIO;<br />
		cERROR(1, (&raquo;Bad MID state?&raquo;));<br />
	}</p>
<p>out:<br />
	DeleteMidQEntry(midQ);<br />
	atomic_dec(&#038;ses->server->inFlight);<br />
	wake_up(&#038;ses->server->request_q);</p>
<p>	return rc;<br />
}</p>
<p>/* Send an NT_CANCEL SMB to cause the POSIX blocking lock to return. */</p>
<p>static int<br />
send_nt_cancel(struct cifsTconInfo *tcon, struct smb_hdr *in_buf,<br />
		struct mid_q_entry *midQ)<br />
{<br />
	int rc = 0;<br />
	struct cifsSesInfo *ses = tcon->ses;<br />
	__u16 mid = in_buf->Mid;</p>
<p>	header_assemble(in_buf, SMB_COM_NT_CANCEL, tcon, 0);<br />
	in_buf->Mid = mid;<br />
	mutex_lock(&#038;ses->server->srv_mutex);<br />
	rc = cifs_sign_smb(in_buf, ses->server, &#038;midQ->sequence_number);<br />
	if (rc) {<br />
		mutex_unlock(&#038;ses->server->srv_mutex);<br />
		return rc;<br />
	}<br />
	rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);<br />
	mutex_unlock(&#038;ses->server->srv_mutex);<br />
	return rc;<br />
}</p>
<p>/* We send a LOCKINGX_CANCEL_LOCK to cause the Windows<br />
   blocking lock to return. */</p>
<p>static int<br />
send_lock_cancel(const unsigned int xid, struct cifsTconInfo *tcon,<br />
			struct smb_hdr *in_buf,<br />
			struct smb_hdr *out_buf)<br />
{<br />
	int bytes_returned;<br />
	struct cifsSesInfo *ses = tcon->ses;<br />
	LOCK_REQ *pSMB = (LOCK_REQ *)in_buf;</p>
<p>	/* We just modify the current in_buf to change<br />
	   the type of lock from LOCKING_ANDX_SHARED_LOCK<br />
	   or LOCKING_ANDX_EXCLUSIVE_LOCK to<br />
	   LOCKING_ANDX_CANCEL_LOCK. */</p>
<p>	pSMB->LockType = LOCKING_ANDX_CANCEL_LOCK|LOCKING_ANDX_LARGE_FILES;<br />
	pSMB->Timeout = 0;<br />
	pSMB->hdr.Mid = GetNextMid(ses->server);</p>
<p>	return SendReceive(xid, ses, in_buf, out_buf,<br />
			&#038;bytes_returned, CIFS_STD_OP);<br />
}</p>
<p>int<br />
SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon,<br />
	    struct smb_hdr *in_buf, struct smb_hdr *out_buf,<br />
	    int *pbytes_returned)<br />
{<br />
	int rc = 0;<br />
	int rstart = 0;<br />
	unsigned int receive_len;<br />
	struct mid_q_entry *midQ;<br />
	struct cifsSesInfo *ses;</p>
<p>	if (tcon == NULL || tcon->ses == NULL) {<br />
		cERROR(1, (&raquo;Null smb session&raquo;));<br />
		return -EIO;<br />
	}<br />
	ses = tcon->ses;</p>
<p>	if (ses->server == NULL) {<br />
		cERROR(1, (&raquo;Null tcp session&raquo;));<br />
		return -EIO;<br />
	}</p>
<p>	if (ses->server->tcpStatus == CifsExiting)<br />
		return -ENOENT;</p>
<p>	/* Ensure that we do not send more than 50 overlapping requests<br />
	   to the same server. We may make this configurable later or<br />
	   use ses->maxReq */</p>
<p>	if (in_buf->smb_buf_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE &#8211; 4) {<br />
		cERROR(1, (&raquo;Illegal length, greater than maximum frame, %d&raquo;,<br />
			   in_buf->smb_buf_length));<br />
		return -EIO;<br />
	}</p>
<p>	rc = wait_for_free_request(ses, CIFS_BLOCKING_OP);<br />
	if (rc)<br />
		return rc;</p>
<p>	/* make sure that we sign in the same order that we send on this socket<br />
	   and avoid races inside tcp sendmsg code that could cause corruption<br />
	   of smb data */</p>
<p>	mutex_lock(&#038;ses->server->srv_mutex);</p>
<p>	rc = allocate_mid(ses, in_buf, &#038;midQ);<br />
	if (rc) {<br />
		mutex_unlock(&#038;ses->server->srv_mutex);<br />
		return rc;<br />
	}</p>
<p>	rc = cifs_sign_smb(in_buf, ses->server, &#038;midQ->sequence_number);<br />
	if (rc) {<br />
		DeleteMidQEntry(midQ);<br />
		mutex_unlock(&#038;ses->server->srv_mutex);<br />
		return rc;<br />
	}</p>
<p>	midQ->midState = MID_REQUEST_SUBMITTED;<br />
#ifdef CONFIG_CIFS_STATS2<br />
	atomic_inc(&#038;ses->server->inSend);<br />
#endif<br />
	rc = smb_send(ses->server, in_buf, in_buf->smb_buf_length);<br />
#ifdef CONFIG_CIFS_STATS2<br />
	atomic_dec(&#038;ses->server->inSend);<br />
	midQ->when_sent = jiffies;<br />
#endif<br />
	mutex_unlock(&#038;ses->server->srv_mutex);</p>
<p>	if (rc < 0) {<br />
		DeleteMidQEntry(midQ);<br />
		return rc;<br />
	}</p>
<p>	/* Wait for a reply - allow signals to interrupt. */<br />
	rc = wait_event_interruptible(ses->server->response_q,<br />
		(!(midQ->midState == MID_REQUEST_SUBMITTED)) ||<br />
		((ses->server->tcpStatus != CifsGood) &#038;&#038;<br />
		 (ses->server->tcpStatus != CifsNew)));</p>
<p>	/* Were we interrupted by a signal ? */<br />
	if ((rc == -ERESTARTSYS) &#038;&#038;<br />
		(midQ->midState == MID_REQUEST_SUBMITTED) &#038;&#038;<br />
		((ses->server->tcpStatus == CifsGood) ||<br />
		 (ses->server->tcpStatus == CifsNew))) {</p>
<p>		if (in_buf->Command == SMB_COM_TRANSACTION2) {<br />
			/* POSIX lock. We send a NT_CANCEL SMB to cause the<br />
			   blocking lock to return. */</p>
<p>			rc = send_nt_cancel(tcon, in_buf, midQ);<br />
			if (rc) {<br />
				DeleteMidQEntry(midQ);<br />
				return rc;<br />
			}<br />
		} else {<br />
			/* Windows lock. We send a LOCKINGX_CANCEL_LOCK<br />
			   to cause the blocking lock to return. */</p>
<p>			rc = send_lock_cancel(xid, tcon, in_buf, out_buf);</p>
<p>			/* If we get -ENOLCK back the lock may have<br />
			   already been removed. Don&#8217;t exit in this case. */<br />
			if (rc &#038;&#038; rc != -ENOLCK) {<br />
				DeleteMidQEntry(midQ);<br />
				return rc;<br />
			}<br />
		}</p>
<p>		/* Wait 5 seconds for the response. */<br />
		if (wait_for_response(ses, midQ, 5 * HZ, 5 * HZ) == 0) {<br />
			/* We got the response &#8211; restart system call. */<br />
			rstart = 1;<br />
		}<br />
	}</p>
<p>	spin_lock(&#038;GlobalMid_Lock);<br />
	if (midQ->resp_buf) {<br />
		spin_unlock(&#038;GlobalMid_Lock);<br />
		receive_len = midQ->resp_buf->smb_buf_length;<br />
	} else {<br />
		cERROR(1, (&raquo;No response for cmd %d mid %d&raquo;,<br />
			  midQ->command, midQ->mid));<br />
		if (midQ->midState == MID_REQUEST_SUBMITTED) {<br />
			if (ses->server->tcpStatus == CifsExiting)<br />
				rc = -EHOSTDOWN;<br />
			else {<br />
				ses->server->tcpStatus = CifsNeedReconnect;<br />
				midQ->midState = MID_RETRY_NEEDED;<br />
			}<br />
		}</p>
<p>		if (rc != -EHOSTDOWN) {<br />
			if (midQ->midState == MID_RETRY_NEEDED) {<br />
				rc = -EAGAIN;<br />
				cFYI(1, (&raquo;marking request for retry&raquo;));<br />
			} else {<br />
				rc = -EIO;<br />
			}<br />
		}<br />
		spin_unlock(&#038;GlobalMid_Lock);<br />
		DeleteMidQEntry(midQ);<br />
		return rc;<br />
	}</p>
<p>	if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) {<br />
		cERROR(1, (&raquo;Frame too large received.  Length: %d  Xid: %d&raquo;,<br />
			receive_len, xid));<br />
		rc = -EIO;<br />
		goto out;<br />
	}</p>
<p>	/* rcvd frame is ok */</p>
<p>	if ((out_buf == NULL) || (midQ->midState != MID_RESPONSE_RECEIVED)) {<br />
		rc = -EIO;<br />
		cERROR(1, (&raquo;Bad MID state?&raquo;));<br />
		goto out;<br />
	}</p>
<p>	out_buf->smb_buf_length = receive_len;<br />
	memcpy((char *)out_buf + 4,<br />
	       (char *)midQ->resp_buf + 4,<br />
	       receive_len);</p>
<p>	dump_smb(out_buf, 92);<br />
	/* convert the length into a more usable form */<br />
	if ((receive_len > 24) &#038;&#038;<br />
	    (ses->server->secMode &#038; (SECMODE_SIGN_REQUIRED |<br />
				     SECMODE_SIGN_ENABLED))) {<br />
		rc = cifs_verify_signature(out_buf,<br />
					   &#038;ses->server->mac_signing_key,<br />
					   midQ->sequence_number+1);<br />
		if (rc) {<br />
			cERROR(1, (&raquo;Unexpected SMB signature&raquo;));<br />
			/* BB FIXME add code to kill session */<br />
		}<br />
	}</p>
<p>	*pbytes_returned = out_buf->smb_buf_length;</p>
<p>	/* BB special case reconnect tid and uid here? */<br />
	rc = map_smb_to_linux_error(out_buf, 0 /* no log */ );</p>
<p>	/* convert ByteCount if necessary */<br />
	if (receive_len >= sizeof(struct smb_hdr) &#8211; 4<br />
	    /* do not count RFC1001 header */  +<br />
	    (2 * out_buf->WordCount) + 2 /* bcc */ )<br />
		BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf));</p>
<p>out:<br />
	DeleteMidQEntry(midQ);<br />
	if (rstart &#038;&#038; rc == -EACCES)<br />
		return -ERESTARTSYS;<br />
	return rc;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/transport-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TODO</title>
		<link>http://lynyrd.ru/todo-2</link>
		<comments>http://lynyrd.ru/todo-2#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:33:44 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/?p=970</guid>
		<description><![CDATA[Version 1.53 May 20, 2008
A Partial List of Missing Features
==================================
Contributions are welcome.  There are plenty of opportunities
for visible, important contributions to this module.  Here
is a partial list of the known problems and missing features:
a) Support for SecurityDescriptors(Windows/CIFS ACLs) for chmod/chgrp/chown
so that these operations can be supported to Windows servers
b) Mapping POSIX ACLs (and ]]></description>
			<content:encoded><![CDATA[<p>Version 1.53 May 20, 2008<span id="more-970"></span></p>
<p>A Partial List of Missing Features<br />
==================================</p>
<p>Contributions are welcome.  There are plenty of opportunities<br />
for visible, important contributions to this module.  Here<br />
is a partial list of the known problems and missing features:</p>
<p>a) Support for SecurityDescriptors(Windows/CIFS ACLs) for chmod/chgrp/chown<br />
so that these operations can be supported to Windows servers</p>
<p>b) Mapping POSIX ACLs (and eventually NFSv4 ACLs) to CIFS<br />
SecurityDescriptors</p>
<p>c) Better pam/winbind integration (e.g. to handle uid mapping<br />
better)</p>
<p>d) Cleanup now unneeded SessSetup code in<br />
fs/cifs/connect.c and add back in NTLMSSP code if any servers<br />
need it</p>
<p>e) fix NTLMv2 signing when two mounts with different users to same<br />
server.</p>
<p>f) Directory entry caching relies on a 1 second timer, rather than<br />
using FindNotify or equivalent.  &#8211; (started)</p>
<p>g) quota support (needs minor kernel change since quota calls<br />
to make it to network filesystems or deviceless filesystems)</p>
<p>h) investigate sync behavior (including syncpage) and check<br />
for proper behavior of intr/nointr</p>
<p>i) improve support for very old servers (OS/2 and Win9x for example)<br />
Including support for changing the time remotely (utimes command).</p>
<p>j) hook lower into the sockets api (as NFS/SunRPC does) to avoid the<br />
extra copy in/out of the socket buffers in some cases.</p>
<p>k) Better optimize open (and pathbased setfilesize) to reduce the<br />
oplock breaks coming from windows srv.  Piggyback identical file<br />
opens on top of each other by incrementing reference count rather<br />
than resending (helps reduce server resource utilization and avoid<br />
spurious oplock breaks).</p>
<p>l) Improve performance of readpages by sending more than one read<br />
at a time when 8 pages or more are requested. In conjuntion<br />
add support for async_cifs_readpages.</p>
<p>m) Add support for storing symlink info to Windows servers<br />
in the Extended Attribute format their SFU clients would recognize.</p>
<p>n) Finish fcntl D_NOTIFY support so kde and gnome file list windows<br />
will autorefresh (partially complete by Asser). Needs minor kernel<br />
vfs change to support removing D_NOTIFY on a file.   </p>
<p>o) Add GUI tool to configure /proc/fs/cifs settings and for display of<br />
the CIFS statistics (started)</p>
<p>p) implement support for security and trusted categories of xattrs<br />
(requires minor protocol extension) to enable better support for SELINUX</p>
<p>q) Implement O_DIRECT flag on open (already supported on mount)</p>
<p>r) Create UID mapping facility so server UIDs can be mapped on a per<br />
mount or a per server basis to client UIDs or nobody if no mapping<br />
exists.  This is helpful when Unix extensions are negotiated to<br />
allow better permission checking when UIDs differ on the server<br />
and client.  Add new protocol request to the CIFS protocol<br />
standard for asking the server for the corresponding name of a<br />
particular uid.</p>
<p>s) Add support for CIFS Unix and also the newer POSIX extensions to the<br />
server side for Samba 4.</p>
<p>t) In support for OS/2 (LANMAN 1.2 and LANMAN2.1 based SMB servers)<br />
need to add ability to set time to server (utimes command)</p>
<p>u) DOS attrs &#8211; returned as pseudo-xattr in Samba format (check VFAT and NTFS for this too)</p>
<p>v) mount check for unmatched uids</p>
<p>w) Add support for new vfs entry points for setlease and fallocate </p>
<p>x) Fix Samba 3 server to handle Linux kernel aio so dbench with lots of<br />
processes can proceed better in parallel (on the server)</p>
<p>y) Fix Samba 3 to handle reads/writes over 127K (and remove the cifs mount<br />
restriction of wsize max being 127K) </p>
<p>KNOWN BUGS (updated April 24, 2007)<br />
====================================<br />
See http://bugzilla.samba.org &#8211; search on product &laquo;CifsVFS&raquo; for<br />
current bug list.</p>
<p>1) existing symbolic links (Windows reparse points) are recognized but<br />
can not be created remotely. They are implemented for Samba and those that<br />
support the CIFS Unix extensions, although earlier versions of Samba<br />
overly restrict the pathnames.<br />
2) follow_link and readdir code does not follow dfs junctions<br />
but recognizes them<br />
3) create of new files to FAT partitions on Windows servers can<br />
succeed but still return access denied (appears to be Windows<br />
server not cifs client problem) and has not been reproduced recently.<br />
NTFS partitions do not have this problem.<br />
4) Unix/POSIX capabilities are reset after reconnection, and affect<br />
a few fields in the tree connection but we do do not know which<br />
superblocks to apply these changes to.  We should probably walk<br />
the list of superblocks to set these.  Also need to check the<br />
flags on the second mount to the same share, and see if we<br />
can do the same trick that NFS does to remount duplicate shares.</p>
<p>Misc testing to do<br />
==================<br />
1) check out max path names and max path name components against various server<br />
types. Try nested symlinks (8 deep). Return max path name in stat -f information</p>
<p>2) Modify file portion of ltp so it can run against a mounted network<br />
share and run it against cifs vfs in automated fashion.</p>
<p>3) Additional performance testing and optimization using iozone and similar &#8211;<br />
there are some easy changes that can be done to parallelize sequential writes,<br />
and when signing is disabled to request larger read sizes (larger than<br />
negotiated size) and send larger write sizes to modern servers.</p>
<p>4) More exhaustively test against less common servers.  More testing<br />
against Windows 9x, Windows ME servers.</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/todo-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>smbfsctl.h</title>
		<link>http://lynyrd.ru/smbfsctl-h</link>
		<comments>http://lynyrd.ru/smbfsctl-h#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:33:26 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/smbfsctl-h</guid>
		<description><![CDATA[/*
 *   fs/cifs/smbfsctl.h: SMB, CIFS, SMB2 FSCTL definitions
 *
 *   Copyright (c) International Business Machines  Corp., 2002,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 ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/smbfsctl.h: SMB, CIFS, SMB2 FSCTL definitions<span id="more-969"></span><br />
 *<br />
 *   Copyright (c) International Business Machines  Corp., 2002,2009<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>/* IOCTL information */<br />
/*<br />
 * List of ioctl/fsctl function codes that are or could be useful in the<br />
 * future to remote clients like cifs or SMB2 client.  There is probably<br />
 * a slightly larger set of fsctls that NTFS local filesystem could handle,<br />
 * including the seven below that we do not have struct definitions for.<br />
 * Even with protocol definitions for most of these now available, we still<br />
 * need to do some experimentation to identify which are practical to do<br />
 * remotely.  Some of the following, such as the encryption/compression ones<br />
 * could be invoked from tools via a specialized hook into the VFS rather<br />
 * than via the standard vfs entry points<br />
 */<br />
#define FSCTL_REQUEST_OPLOCK_LEVEL_1 0&#215;00090000<br />
#define FSCTL_REQUEST_OPLOCK_LEVEL_2 0&#215;00090004<br />
#define FSCTL_REQUEST_BATCH_OPLOCK   0&#215;00090008<br />
#define FSCTL_LOCK_VOLUME            0&#215;00090018<br />
#define FSCTL_UNLOCK_VOLUME          0&#215;0009001C<br />
#define FSCTL_IS_PATHNAME_VALID      0&#215;0009002C /* BB add struct */<br />
#define FSCTL_GET_COMPRESSION        0&#215;0009003C /* BB add struct */<br />
#define FSCTL_SET_COMPRESSION        0&#215;0009C040 /* BB add struct */<br />
#define FSCTL_QUERY_FAT_BPB          0&#215;00090058 /* BB add struct */<br />
/* Verify the next FSCTL number, we had it as 0&#215;00090090 before */<br />
#define FSCTL_FILESYSTEM_GET_STATS   0&#215;00090060 /* BB add struct */<br />
#define FSCTL_GET_NTFS_VOLUME_DATA   0&#215;00090064 /* BB add struct */<br />
#define FSCTL_GET_RETRIEVAL_POINTERS 0&#215;00090073 /* BB add struct */<br />
#define FSCTL_IS_VOLUME_DIRTY        0&#215;00090078 /* BB add struct */<br />
#define FSCTL_ALLOW_EXTENDED_DASD_IO 0&#215;00090083 /* BB add struct */<br />
#define FSCTL_REQUEST_FILTER_OPLOCK  0&#215;0009008C<br />
#define FSCTL_FIND_FILES_BY_SID      0&#215;0009008F /* BB add struct */<br />
#define FSCTL_SET_OBJECT_ID          0&#215;00090098 /* BB add struct */<br />
#define FSCTL_GET_OBJECT_ID          0&#215;0009009C /* BB add struct */<br />
#define FSCTL_DELETE_OBJECT_ID       0&#215;000900A0 /* BB add struct */<br />
#define FSCTL_SET_REPARSE_POINT      0&#215;000900A4 /* BB add struct */<br />
#define FSCTL_GET_REPARSE_POINT      0&#215;000900A8 /* BB add struct */<br />
#define FSCTL_DELETE_REPARSE_POINT   0&#215;000900AC /* BB add struct */<br />
#define FSCTL_SET_OBJECT_ID_EXTENDED 0&#215;000900BC /* BB add struct */<br />
#define FSCTL_CREATE_OR_GET_OBJECT_ID 0&#215;000900C0 /* BB add struct */<br />
#define FSCTL_SET_SPARSE             0&#215;000900C4 /* BB add struct */<br />
#define FSCTL_SET_ZERO_DATA          0&#215;000900C8 /* BB add struct */<br />
#define FSCTL_SET_ENCRYPTION         0&#215;000900D7 /* BB add struct */<br />
#define FSCTL_ENCRYPTION_FSCTL_IO    0&#215;000900DB /* BB add struct */<br />
#define FSCTL_WRITE_RAW_ENCRYPTED    0&#215;000900DF /* BB add struct */<br />
#define FSCTL_READ_RAW_ENCRYPTED     0&#215;000900E3 /* BB add struct */<br />
#define FSCTL_READ_FILE_USN_DATA     0&#215;000900EB /* BB add struct */<br />
#define FSCTL_WRITE_USN_CLOSE_RECORD 0&#215;000900EF /* BB add struct */<br />
#define FSCTL_SIS_COPYFILE           0&#215;00090100 /* BB add struct */<br />
#define FSCTL_RECALL_FILE            0&#215;00090117 /* BB add struct */<br />
#define FSCTL_QUERY_SPARING_INFO     0&#215;00090138 /* BB add struct */<br />
#define FSCTL_SET_ZERO_ON_DEALLOC    0&#215;00090194 /* BB add struct */<br />
#define FSCTL_SET_SHORT_NAME_BEHAVIOR 0&#215;000901B4 /* BB add struct */<br />
#define FSCTL_QUERY_ALLOCATED_RANGES 0&#215;000940CF /* BB add struct */<br />
#define FSCTL_SET_DEFECT_MANAGEMENT  0&#215;00098134 /* BB add struct */<br />
#define FSCTL_SIS_LINK_FILES         0&#215;0009C104<br />
#define FSCTL_PIPE_PEEK              0&#215;0011400C /* BB add struct */<br />
#define FSCTL_PIPE_TRANSCEIVE        0&#215;0011C017 /* BB add struct */<br />
/* strange that the number for this op is not sequential with previous op */<br />
#define FSCTL_PIPE_WAIT              0&#215;00110018 /* BB add struct */<br />
#define FSCTL_LMR_GET_LINK_TRACK_INF 0&#215;001400E8 /* BB add struct */<br />
#define FSCTL_LMR_SET_LINK_TRACK_INF 0&#215;001400EC /* BB add struct */</p>
<p>#define IO_REPARSE_TAG_MOUNT_POINT   0xA0000003<br />
#define IO_REPARSE_TAG_HSM           0xC0000004<br />
#define IO_REPARSE_TAG_SIS           0&#215;80000007</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/smbfsctl-h/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>smberr.h</title>
		<link>http://lynyrd.ru/smberr-h</link>
		<comments>http://lynyrd.ru/smberr-h#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:33:09 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/smberr-h</guid>
		<description><![CDATA[/*
 *   fs/cifs/smberr.h
 *
 *   Copyright (c) International Business Machines  Corp., 2002,2004
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   See Error Codes section of the SNIA CIFS Specification
 *   for more information
 *
 *   This library is free software; you can redistribute ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/smberr.h<span id="more-968"></span><br />
 *<br />
 *   Copyright (c) International Business Machines  Corp., 2002,2004<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   See Error Codes section of the SNIA CIFS Specification<br />
 *   for more information<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>#define SUCCESS	0&#215;00	/* The request was successful. */<br />
#define ERRDOS	0&#215;01	/* Error is from the core DOS operating system set */<br />
#define ERRSRV	0&#215;02	/* Error is generated by the file server daemon */<br />
#define ERRHRD	0&#215;03	/* Error is a hardware error. */<br />
#define ERRCMD	0xFF	/* Command was not in the &laquo;SMB&raquo; format. */</p>
<p>/* The following error codes may be generated with the SUCCESS error class.*/</p>
<p>/*#define SUCCESS	0	The request was successful. */</p>
<p>/* The following error codes may be generated with the ERRDOS error class.*/</p>
<p>#define ERRbadfunc		1	/* Invalid function. The server did not<br />
					   recognize or could not perform a<br />
					   system call generated by the server,<br />
					   e.g., set the DIRECTORY attribute on<br />
					   a data file, invalid seek mode. */<br />
#define ERRbadfile		2	/* File not found. The last component<br />
					   of a file&#8217;s pathname could not be<br />
					   found. */<br />
#define ERRbadpath		3	/* Directory invalid. A directory<br />
					   component in a pathname could not be<br />
					   found. */<br />
#define ERRnofids		4	/* Too many open files. The server has<br />
					   no file handles available. */<br />
#define ERRnoaccess		5	/* Access denied, the client&#8217;s context<br />
					   does not permit the requested<br />
					   function. This includes the<br />
					   following conditions: invalid rename<br />
					   command, write to Fid open for read<br />
					   only, read on Fid open for write<br />
					   only, attempt to delete a non-empty<br />
					   directory */<br />
#define ERRbadfid		6	/* Invalid file handle. The file handle<br />
					   specified was not recognized by the<br />
					   server. */<br />
#define ERRbadmcb		7	/* Memory control blocks destroyed. */<br />
#define ERRnomem		8	/* Insufficient server memory to<br />
					   perform the requested function. */<br />
#define ERRbadmem		9	/* Invalid memory block address. */<br />
#define ERRbadenv		10	/* Invalid environment. */<br />
#define ERRbadformat		11	/* Invalid format. */<br />
#define ERRbadaccess		12	/* Invalid open mode. */<br />
#define ERRbaddata		13	/* Invalid data (generated only by<br />
					   IOCTL calls within the server). */<br />
#define ERRbaddrive		15	/* Invalid drive specified. */<br />
#define ERRremcd		16	/* A Delete Directory request attempted<br />
					   to remove the server&#8217;s current<br />
					   directory. */<br />
#define ERRdiffdevice		17	/* Not same device (e.g., a cross<br />
					   volume rename was attempted */<br />
#define ERRnofiles		18	/* A File Search command can find no<br />
					   more files matching the specified<br />
					   criteria. */<br />
#define ERRgeneral		31<br />
#define ERRbadshare		32	/* The sharing mode specified for an<br />
					   Open conflicts with existing FIDs on<br />
					   the file. */<br />
#define ERRlock			33	/* A Lock request conflicted with an<br />
					   existing lock or specified an<br />
					   invalid mode, or an Unlock requested<br />
					   attempted to remove a lock held by<br />
					   another process. */<br />
#define ERRunsup		50<br />
#define ERRnosuchshare		67<br />
#define ERRfilexists		80	/* The file named in the request<br />
					   already exists. */<br />
#define ERRinvparm		87<br />
#define ERRdiskfull		112<br />
#define ERRinvname		123<br />
#define ERRinvlevel		124<br />
#define ERRdirnotempty		145<br />
#define ERRnotlocked		158<br />
#define ERRcancelviolation	173<br />
#define ERRalreadyexists	183<br />
#define ERRbadpipe		230<br />
#define ERRpipebusy		231<br />
#define ERRpipeclosing		232<br />
#define ERRnotconnected		233<br />
#define ERRmoredata		234<br />
#define ERReasnotsupported	282<br />
#define ErrQuota		0&#215;200	/* The operation would cause a quota<br />
					   limit to be exceeded. */<br />
#define ErrNotALink		0&#215;201	/* A link operation was performed on a<br />
					   pathname that was not a link. */</p>
<p>/* Below errors are used internally (do not come over the wire) for passthrough<br />
   from STATUS codes to POSIX only  */<br />
#define ERRsymlink              0xFFFD<br />
#define ErrTooManyLinks         0xFFFE</p>
<p>/* Following error codes may be generated with the ERRSRV error class.*/</p>
<p>#define ERRerror		1	/* Non-specific error code. It is<br />
					   returned under the following<br />
					   conditions: resource other than disk<br />
					   space exhausted (e.g. TIDs), first<br />
					   SMB command was not negotiate,<br />
					   multiple negotiates attempted, and<br />
					   internal server error. */<br />
#define ERRbadpw		2	/* Bad password &#8211; name/password pair in<br />
					   a TreeConnect or Session Setup are<br />
					   invalid. */<br />
#define ERRbadtype		3	/* used for indicating DFS referral<br />
					   needed */<br />
#define ERRaccess		4	/* The client does not have the<br />
					   necessary access rights within the<br />
					   specified context for requested<br />
					   function. */<br />
#define ERRinvtid		5	/* The Tid specified in a command was<br />
					   invalid. */<br />
#define ERRinvnetname		6	/* Invalid network name in tree<br />
					   connect. */<br />
#define ERRinvdevice		7	/* Invalid device &#8211; printer request<br />
					   made to non-printer connection or<br />
					   non-printer request made to printer<br />
					   connection. */<br />
#define ERRqfull		49	/* Print queue full (files) &#8212; returned<br />
					   by open print file. */<br />
#define ERRqtoobig		50	/* Print queue full &#8212; no space. */<br />
#define ERRqeof			51	/* EOF on print queue dump */<br />
#define ERRinvpfid		52	/* Invalid print file FID. */<br />
#define ERRsmbcmd		64	/* The server did not recognize the<br />
					   command received. */<br />
#define ERRsrverror		65	/* The server encountered an internal<br />
					   error, e.g., system file<br />
					   unavailable. */<br />
#define ERRbadBID		66	/* (obsolete) */<br />
#define ERRfilespecs		67	/* The Fid and pathname parameters<br />
					   contained an invalid combination of<br />
					   values. */<br />
#define ERRbadLink		68	/* (obsolete) */<br />
#define ERRbadpermits		69	/* The access permissions specified for<br />
					   a file or directory are not a valid<br />
					   combination. */<br />
#define ERRbadPID		70<br />
#define ERRsetattrmode		71	/* attribute (mode) is invalid */<br />
#define ERRpaused		81	/* Server is paused */<br />
#define ERRmsgoff		82	/* reserved &#8211; messaging off */<br />
#define ERRnoroom		83	/* reserved &#8211; no room for message */<br />
#define ERRrmuns		87	/* reserved &#8211; too many remote names */<br />
#define ERRtimeout		88	/* operation timed out */<br />
#define ERRnoresource		89	/* No resources available for request<br />
					   */<br />
#define ERRtoomanyuids		90	/* Too many UIDs active on this session<br />
					   */<br />
#define ERRbaduid		91	/* The UID is not known as a valid user<br />
					   */<br />
#define ERRusempx		250	/* temporarily unable to use raw */<br />
#define ERRusestd		251	/* temporarily unable to use either raw<br />
					   or mpx */<br />
#define ERR_NOTIFY_ENUM_DIR	1024<br />
#define ERRnoSuchUser		2238	/* user account does not exist */<br />
#define ERRaccountexpired	2239<br />
#define ERRbadclient		2240	/* can not logon from this client */<br />
#define ERRbadLogonTime		2241	/* logon hours do not allow this */<br />
#define ERRpasswordExpired	2242<br />
#define ERRnetlogonNotStarted	2455<br />
#define ERRnosupport		0xFFFF</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/smberr-h/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>smbencrypt.c</title>
		<link>http://lynyrd.ru/smbencrypt-c</link>
		<comments>http://lynyrd.ru/smbencrypt-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:32:52 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/?p=966</guid>
		<description><![CDATA[/*
   Unix SMB/Netbios implementation.
   Version 1.9.
   SMB parameters and setup
   Copyright (C) Andrew Tridgell 1992-2000
   Copyright (C) Luke Kenneth Casson Leighton 1996-2000
   Modified by Jeremy Allison 1995.
   Copyright (C) Andrew Bartlett  2002-2003
   Modified by Steve French (sfrench@us.ibm.com) 2002-2003
 ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
   Unix SMB/Netbios implementation.<span id="more-966"></span><br />
   Version 1.9.<br />
   SMB parameters and setup<br />
   Copyright (C) Andrew Tridgell 1992-2000<br />
   Copyright (C) Luke Kenneth Casson Leighton 1996-2000<br />
   Modified by Jeremy Allison 1995.<br />
   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003<br />
   Modified by Steve French (sfrench@us.ibm.com) 2002-2003</p>
<p>   This program is free software; you can redistribute it and/or modify<br />
   it under the terms of the GNU General Public License as published by<br />
   the Free Software Foundation; either version 2 of the License, or<br />
   (at your option) any later version.</p>
<p>   This program is distributed in the hope that it will be useful,<br />
   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
   GNU General Public License for more details.</p>
<p>   You should have received a copy of the GNU General Public License<br />
   along with this program; if not, write to the Free Software<br />
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br />
*/</p>
<p>#include
<linux/module.h>
#include
<linux/fs.h>
#include
<linux/string.h>
#include
<linux/kernel.h>
#include
<linux/random.h>
#include &laquo;cifs_unicode.h&raquo;<br />
#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;md5.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;<br />
#include &laquo;cifsencrypt.h&raquo;</p>
<p>#ifndef false<br />
#define false 0<br />
#endif<br />
#ifndef true<br />
#define true 1<br />
#endif</p>
<p>/* following came from the other byteorder.h to avoid include conflicts */<br />
#define CVAL(buf,pos) (((unsigned char *)(buf))[pos])<br />
#define SSVALX(buf,pos,val) (CVAL(buf,pos)=(val)&#038;0xFF,CVAL(buf,pos+1)=(val)>>8)<br />
#define SSVAL(buf,pos,val) SSVALX((buf),(pos),((__u16)(val)))</p>
<p>/*The following definitions come from  libsmb/smbencrypt.c  */</p>
<p>void SMBencrypt(unsigned char *passwd, const unsigned char *c8,<br />
		unsigned char *p24);<br />
void E_md4hash(const unsigned char *passwd, unsigned char *p16);<br />
static void SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,<br />
		   unsigned char p24[24]);<br />
void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24);</p>
<p>/*<br />
   This implements the X/Open SMB password encryption<br />
   It takes a password, a 8 byte &laquo;crypt key&raquo; and puts 24 bytes of<br />
   encrypted password into p24 */<br />
/* Note that password must be uppercased and null terminated */<br />
void<br />
SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)<br />
{<br />
	unsigned char p14[15], p21[21];</p>
<p>	memset(p21, &#8216;\0&#8242;, 21);<br />
	memset(p14, &#8216;\0&#8242;, 14);<br />
	strncpy((char *) p14, (char *) passwd, 14);</p>
<p>/*	strupper((char *)p14); *//* BB at least uppercase the easy range */<br />
	E_P16(p14, p21);</p>
<p>	SMBOWFencrypt(p21, c8, p24);</p>
<p>	memset(p14, 0, 15);<br />
	memset(p21, 0, 21);<br />
}</p>
<p>/* Routines for Windows NT MD4 Hash functions. */<br />
static int<br />
_my_wcslen(__u16 *str)<br />
{<br />
	int len = 0;<br />
	while (*str++ != 0)<br />
		len++;<br />
	return len;<br />
}</p>
<p>/*<br />
 * Convert a string into an NT UNICODE string.<br />
 * Note that regardless of processor type<br />
 * this must be in intel (little-endian)<br />
 * format.<br />
 */</p>
<p>static int<br />
_my_mbstowcs(__u16 *dst, const unsigned char *src, int len)<br />
{	/* BB not a very good conversion routine &#8211; change/fix */<br />
	int i;<br />
	__u16 val;</p>
<p>	for (i = 0; i < len; i++) {<br />
		val = *src;<br />
		SSVAL(dst, 0, val);<br />
		dst++;<br />
		src++;<br />
		if (val == 0)<br />
			break;<br />
	}<br />
	return i;<br />
}</p>
<p>/*<br />
 * Creates the MD4 Hash of the users password in NT UNICODE.<br />
 */</p>
<p>void<br />
E_md4hash(const unsigned char *passwd, unsigned char *p16)<br />
{<br />
	int len;<br />
	__u16 wpwd[129];</p>
<p>	/* Password cannot be longer than 128 characters */<br />
	if (passwd) {<br />
		len = strlen((char *) passwd);<br />
		if (len > 128)<br />
			len = 128;</p>
<p>		/* Password must be converted to NT unicode */<br />
		_my_mbstowcs(wpwd, passwd, len);<br />
	} else<br />
		len = 0;</p>
<p>	wpwd[len] = 0;	/* Ensure string is null terminated */<br />
	/* Calculate length in bytes */<br />
	len = _my_wcslen(wpwd) * sizeof(__u16);</p>
<p>	mdfour(p16, (unsigned char *) wpwd, len);<br />
	memset(wpwd, 0, 129 * 2);<br />
}</p>
<p>#if 0 /* currently unused */<br />
/* Does both the NT and LM owfs of a user&#8217;s password */<br />
static void<br />
nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])<br />
{<br />
	char passwd[514];</p>
<p>	memset(passwd, &#8216;\0&#8242;, 514);<br />
	if (strlen(pwd) < 513)<br />
		strcpy(passwd, pwd);<br />
	else<br />
		memcpy(passwd, pwd, 512);<br />
	/* Calculate the MD4 hash (NT compatible) of the password */<br />
	memset(nt_p16, '\0', 16);<br />
	E_md4hash(passwd, nt_p16);</p>
<p>	/* Mangle the passwords into Lanman format */<br />
	passwd[14] = '\0';<br />
/*	strupper(passwd); */</p>
<p>	/* Calculate the SMB (lanman) hash functions of the password */</p>
<p>	memset(p16, '\0', 16);<br />
	E_P16((unsigned char *) passwd, (unsigned char *) p16);</p>
<p>	/* clear out local copy of user's password (just being paranoid). */<br />
	memset(passwd, '\0', sizeof(passwd));<br />
}<br />
#endif</p>
<p>/* Does the NTLMv2 owfs of a user's password */<br />
#if 0  /* function not needed yet - but will be soon */<br />
static void<br />
ntv2_owf_gen(const unsigned char owf[16], const char *user_n,<br />
		const char *domain_n, unsigned char kr_buf[16],<br />
		const struct nls_table *nls_codepage)<br />
{<br />
	wchar_t *user_u;<br />
	wchar_t *dom_u;<br />
	int user_l, domain_l;<br />
	struct HMACMD5Context ctx;</p>
<p>	/* might as well do one alloc to hold both (user_u and dom_u) */<br />
	user_u = kmalloc(2048 * sizeof(wchar_t), GFP_KERNEL);<br />
	if (user_u == NULL)<br />
		return;<br />
	dom_u = user_u + 1024;</p>
<p>	/* push_ucs2(NULL, user_u, user_n, (user_l+1)*2,<br />
			STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER);<br />
	   push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2,<br />
			STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); */</p>
<p>	/* BB user and domain may need to be uppercased */<br />
	user_l = cifs_strtoUCS(user_u, user_n, 511, nls_codepage);<br />
	domain_l = cifs_strtoUCS(dom_u, domain_n, 511, nls_codepage);</p>
<p>	user_l++;		/* trailing null */<br />
	domain_l++;</p>
<p>	hmac_md5_init_limK_to_64(owf, 16, &#038;ctx);<br />
	hmac_md5_update((const unsigned char *) user_u, user_l * 2, &#038;ctx);<br />
	hmac_md5_update((const unsigned char *) dom_u, domain_l * 2, &#038;ctx);<br />
	hmac_md5_final(kr_buf, &#038;ctx);</p>
<p>	kfree(user_u);<br />
}<br />
#endif</p>
<p>/* Does the des encryption from the NT or LM MD4 hash. */<br />
static void<br />
SMBOWFencrypt(unsigned char passwd[16], const unsigned char *c8,<br />
	      unsigned char p24[24])<br />
{<br />
	unsigned char p21[21];</p>
<p>	memset(p21, '\0', 21);</p>
<p>	memcpy(p21, passwd, 16);<br />
	E_P24(p21, c8, p24);<br />
}</p>
<p>/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */<br />
#if 0 /* currently unused */<br />
static void<br />
NTLMSSPOWFencrypt(unsigned char passwd[8],<br />
		  unsigned char *ntlmchalresp, unsigned char p24[24])<br />
{<br />
	unsigned char p21[21];</p>
<p>	memset(p21, '\0', 21);<br />
	memcpy(p21, passwd, 8);<br />
	memset(p21 + 8, 0xbd, 8);</p>
<p>	E_P24(p21, ntlmchalresp, p24);<br />
}<br />
#endif</p>
<p>/* Does the NT MD4 hash then des encryption. */</p>
<p>void<br />
SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)<br />
{<br />
	unsigned char p21[21];</p>
<p>	memset(p21, '\0', 21);</p>
<p>	E_md4hash(passwd, p21);<br />
	SMBOWFencrypt(p21, c8, p24);<br />
}</p>
<p>/* Does the md5 encryption from the NT hash for NTLMv2. */<br />
/* These routines will be needed later */<br />
#if 0<br />
static void<br />
SMBOWFencrypt_ntv2(const unsigned char kr[16],<br />
		   const struct data_blob *srv_chal,<br />
		   const struct data_blob *cli_chal, unsigned char resp_buf[16])<br />
{<br />
	struct HMACMD5Context ctx;</p>
<p>	hmac_md5_init_limK_to_64(kr, 16, &#038;ctx);<br />
	hmac_md5_update(srv_chal->data, srv_chal->length, &#038;ctx);<br />
	hmac_md5_update(cli_chal->data, cli_chal->length, &#038;ctx);<br />
	hmac_md5_final(resp_buf, &#038;ctx);<br />
}</p>
<p>static void<br />
SMBsesskeygen_ntv2(const unsigned char kr[16],<br />
		   const unsigned char *nt_resp, __u8 sess_key[16])<br />
{<br />
	struct HMACMD5Context ctx;</p>
<p>	hmac_md5_init_limK_to_64(kr, 16, &#038;ctx);<br />
	hmac_md5_update(nt_resp, 16, &#038;ctx);<br />
	hmac_md5_final((unsigned char *) sess_key, &#038;ctx);<br />
}</p>
<p>static void<br />
SMBsesskeygen_ntv1(const unsigned char kr[16],<br />
		   const unsigned char *nt_resp, __u8 sess_key[16])<br />
{<br />
	mdfour((unsigned char *) sess_key, (unsigned char *) kr, 16);<br />
}<br />
#endif</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/smbencrypt-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>smbdes.c</title>
		<link>http://lynyrd.ru/smbdes-c</link>
		<comments>http://lynyrd.ru/smbdes-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:32:31 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/?p=964</guid>
		<description><![CDATA[/*
   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
 ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
   Unix SMB/Netbios implementation.<span id="more-964"></span><br />
   Version 1.9.</p>
<p>   a partial implementation of DES designed for use in the<br />
   SMB authentication protocol</p>
<p>   Copyright (C) Andrew Tridgell 1998<br />
   Modified by Steve French (sfrench@us.ibm.com) 2002,2004</p>
<p>   This program is free software; you can redistribute it and/or modify<br />
   it under the terms of the GNU General Public License as published by<br />
   the Free Software Foundation; either version 2 of the License, or<br />
   (at your option) any later version.</p>
<p>   This program is distributed in the hope that it will be useful,<br />
   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
   GNU General Public License for more details.</p>
<p>   You should have received a copy of the GNU General Public License<br />
   along with this program; if not, write to the Free Software<br />
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br />
*/</p>
<p>/* NOTES:</p>
<p>   This code makes no attempt to be fast! In fact, it is a very<br />
   slow implementation</p>
<p>   This code is NOT a complete DES implementation. It implements only<br />
   the minimum necessary for SMB authentication, as used by all SMB<br />
   products (including every copy of Microsoft Windows95 ever sold)</p>
<p>   In particular, it can only do a unchained forward DES pass. This<br />
   means it is not possible to use this code for encryption/decryption<br />
   of data, instead it is only useful as a &laquo;hash&raquo; algorithm.</p>
<p>   There is no entry point into this code that allows normal DES operation.</p>
<p>   I believe this means that this code does not come under ITAR<br />
   regulations but this is NOT a legal opinion. If you are concerned<br />
   about the applicability of ITAR regulations to this code then you<br />
   should confirm it for yourself (and maybe let me know if you come<br />
   up with a different answer to the one above)<br />
*/<br />
#include
<linux/slab.h>
#include &laquo;cifsencrypt.h&raquo;<br />
#define uchar unsigned char</p>
<p>static uchar perm1[56] = { 57, 49, 41, 33, 25, 17, 9,<br />
	1, 58, 50, 42, 34, 26, 18,<br />
	10, 2, 59, 51, 43, 35, 27,<br />
	19, 11, 3, 60, 52, 44, 36,<br />
	63, 55, 47, 39, 31, 23, 15,<br />
	7, 62, 54, 46, 38, 30, 22,<br />
	14, 6, 61, 53, 45, 37, 29,<br />
	21, 13, 5, 28, 20, 12, 4<br />
};</p>
<p>static uchar perm2[48] = { 14, 17, 11, 24, 1, 5,<br />
	3, 28, 15, 6, 21, 10,<br />
	23, 19, 12, 4, 26, 8,<br />
	16, 7, 27, 20, 13, 2,<br />
	41, 52, 31, 37, 47, 55,<br />
	30, 40, 51, 45, 33, 48,<br />
	44, 49, 39, 56, 34, 53,<br />
	46, 42, 50, 36, 29, 32<br />
};</p>
<p>static uchar perm3[64] = { 58, 50, 42, 34, 26, 18, 10, 2,<br />
	60, 52, 44, 36, 28, 20, 12, 4,<br />
	62, 54, 46, 38, 30, 22, 14, 6,<br />
	64, 56, 48, 40, 32, 24, 16, 8,<br />
	57, 49, 41, 33, 25, 17, 9, 1,<br />
	59, 51, 43, 35, 27, 19, 11, 3,<br />
	61, 53, 45, 37, 29, 21, 13, 5,<br />
	63, 55, 47, 39, 31, 23, 15, 7<br />
};</p>
<p>static uchar perm4[48] = { 32, 1, 2, 3, 4, 5,<br />
	4, 5, 6, 7, 8, 9,<br />
	8, 9, 10, 11, 12, 13,<br />
	12, 13, 14, 15, 16, 17,<br />
	16, 17, 18, 19, 20, 21,<br />
	20, 21, 22, 23, 24, 25,<br />
	24, 25, 26, 27, 28, 29,<br />
	28, 29, 30, 31, 32, 1<br />
};</p>
<p>static uchar perm5[32] = { 16, 7, 20, 21,<br />
	29, 12, 28, 17,<br />
	1, 15, 23, 26,<br />
	5, 18, 31, 10,<br />
	2, 8, 24, 14,<br />
	32, 27, 3, 9,<br />
	19, 13, 30, 6,<br />
	22, 11, 4, 25<br />
};</p>
<p>static uchar perm6[64] = { 40, 8, 48, 16, 56, 24, 64, 32,<br />
	39, 7, 47, 15, 55, 23, 63, 31,<br />
	38, 6, 46, 14, 54, 22, 62, 30,<br />
	37, 5, 45, 13, 53, 21, 61, 29,<br />
	36, 4, 44, 12, 52, 20, 60, 28,<br />
	35, 3, 43, 11, 51, 19, 59, 27,<br />
	34, 2, 42, 10, 50, 18, 58, 26,<br />
	33, 1, 41, 9, 49, 17, 57, 25<br />
};</p>
<p>static uchar sc[16] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };</p>
<p>static uchar sbox[8][4][16] = {<br />
	{{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},<br />
	 {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},<br />
	 {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},<br />
	 {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13} },</p>
<p>	{{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},<br />
	 {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},<br />
	 {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},<br />
	 {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9} },</p>
<p>	{{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},<br />
	 {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},<br />
	 {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},<br />
	 {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12} },</p>
<p>	{{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},<br />
	 {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},<br />
	 {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},<br />
	 {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14} },</p>
<p>	{{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},<br />
	 {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},<br />
	 {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},<br />
	 {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3} },</p>
<p>	{{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},<br />
	 {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},<br />
	 {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},<br />
	 {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13} },</p>
<p>	{{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},<br />
	 {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},<br />
	 {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},<br />
	 {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12} },</p>
<p>	{{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},<br />
	 {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},<br />
	 {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},<br />
	 {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11} }<br />
};</p>
<p>static void<br />
permute(char *out, char *in, uchar *p, int n)<br />
{<br />
	int i;<br />
	for (i = 0; i < n; i++)<br />
		out[i] = in[p[i] - 1];<br />
}</p>
<p>static void<br />
lshift(char *d, int count, int n)<br />
{<br />
	char out[64];<br />
	int i;<br />
	for (i = 0; i < n; i++)<br />
		out[i] = d[(i + count) % n];<br />
	for (i = 0; i < n; i++)<br />
		d[i] = out[i];<br />
}</p>
<p>static void<br />
concat(char *out, char *in1, char *in2, int l1, int l2)<br />
{<br />
	while (l1--)<br />
		*out++ = *in1++;<br />
	while (l2--)<br />
		*out++ = *in2++;<br />
}</p>
<p>static void<br />
xor(char *out, char *in1, char *in2, int n)<br />
{<br />
	int i;<br />
	for (i = 0; i < n; i++)<br />
		out[i] = in1[i] ^ in2[i];<br />
}</p>
<p>static void<br />
dohash(char *out, char *in, char *key, int forw)<br />
{<br />
	int i, j, k;<br />
	char *pk1;<br />
	char c[28];<br />
	char d[28];<br />
	char *cd;<br />
	char (*ki)[48];<br />
	char *pd1;<br />
	char l[32], r[32];<br />
	char *rl;</p>
<p>	/* Have to reduce stack usage */<br />
	pk1 = kmalloc(56+56+64+64, GFP_KERNEL);<br />
	if (pk1 == NULL)<br />
		return;</p>
<p>	ki = kmalloc(16*48, GFP_KERNEL);<br />
	if (ki == NULL) {<br />
		kfree(pk1);<br />
		return;<br />
	}</p>
<p>	cd = pk1 + 56;<br />
	pd1 = cd  + 56;<br />
	rl = pd1 + 64;</p>
<p>	permute(pk1, key, perm1, 56);</p>
<p>	for (i = 0; i < 28; i++)<br />
		c[i] = pk1[i];<br />
	for (i = 0; i < 28; i++)<br />
		d[i] = pk1[i + 28];</p>
<p>	for (i = 0; i < 16; i++) {<br />
		lshift(c, sc[i], 28);<br />
		lshift(d, sc[i], 28);</p>
<p>		concat(cd, c, d, 28, 28);<br />
		permute(ki[i], cd, perm2, 48);<br />
	}</p>
<p>	permute(pd1, in, perm3, 64);</p>
<p>	for (j = 0; j < 32; j++) {<br />
		l[j] = pd1[j];<br />
		r[j] = pd1[j + 32];<br />
	}</p>
<p>	for (i = 0; i < 16; i++) {<br />
		char *er;  /* er[48]  */<br />
		char *erk; /* erk[48] */<br />
		char b[8][6];<br />
		char *cb;  /* cb[32]  */<br />
		char *pcb; /* pcb[32] */<br />
		char *r2;  /* r2[32]  */</p>
<p>		er = kmalloc(48+48+32+32+32, GFP_KERNEL);<br />
		if (er == NULL) {<br />
			kfree(pk1);<br />
			kfree(ki);<br />
			return;<br />
		}<br />
		erk = er+48;<br />
		cb  = erk+48;<br />
		pcb = cb+32;<br />
		r2  = pcb+32;</p>
<p>		permute(er, r, perm4, 48);</p>
<p>		xor(erk, er, ki[forw ? i : 15 - i], 48);</p>
<p>		for (j = 0; j < 8; j++)<br />
			for (k = 0; k < 6; k++)<br />
				b[j][k] = erk[j * 6 + k];</p>
<p>		for (j = 0; j < 8; j++) {<br />
			int m, n;<br />
			m = (b[j][0] << 1) | b[j][5];</p>
<p>			n = (b[j][1] << 3) | (b[j][2] << 2) | (b[j][3] <<<br />
							       1) | b[j][4];</p>
<p>			for (k = 0; k < 4; k++)<br />
				b[j][k] =<br />
				    (sbox[j][m][n] &#038; (1 << (3 - k))) ? 1 : 0;<br />
		}</p>
<p>		for (j = 0; j < 8; j++)<br />
			for (k = 0; k < 4; k++)<br />
				cb[j * 4 + k] = b[j][k];<br />
		permute(pcb, cb, perm5, 32);</p>
<p>		xor(r2, l, pcb, 32);</p>
<p>		for (j = 0; j < 32; j++)<br />
			l[j] = r[j];</p>
<p>		for (j = 0; j < 32; j++)<br />
			r[j] = r2[j];</p>
<p>		kfree(er);<br />
	}</p>
<p>	concat(rl, r, l, 32, 32);</p>
<p>	permute(out, rl, perm6, 64);<br />
	kfree(pk1);<br />
	kfree(ki);<br />
}</p>
<p>static void<br />
str_to_key(unsigned char *str, unsigned char *key)<br />
{<br />
	int i;</p>
<p>	key[0] = str[0] >> 1;<br />
	key[1] = ((str[0] &#038; 0&#215;01) << 6) | (str[1] >> 2);<br />
	key[2] = ((str[1] &#038; 0&#215;03) << 5) | (str[2] >> 3);<br />
	key[3] = ((str[2] &#038; 0&#215;07) << 4) | (str[3] >> 4);<br />
	key[4] = ((str[3] &#038; 0&#215;0F) << 3) | (str[4] >> 5);<br />
	key[5] = ((str[4] &#038; 0&#215;1F) << 2) | (str[5] >> 6);<br />
	key[6] = ((str[5] &#038; 0&#215;3F) << 1) | (str[6] >> 7);<br />
	key[7] = str[6] &#038; 0&#215;7F;<br />
	for (i = 0; i < 8; i++)<br />
		key[i] = (key[i] << 1);<br />
}</p>
<p>static void<br />
smbhash(unsigned char *out, const unsigned char *in, unsigned char *key,<br />
	int forw)<br />
{<br />
	int i;<br />
	char *outb; /* outb[64] */<br />
	char *inb;  /* inb[64]  */<br />
	char *keyb; /* keyb[64] */<br />
	unsigned char key2[8];</p>
<p>	outb = kmalloc(64 * 3, GFP_KERNEL);<br />
	if (outb == NULL)<br />
		return;</p>
<p>	inb  = outb + 64;<br />
	keyb = inb +  64;</p>
<p>	str_to_key(key, key2);</p>
<p>	for (i = 0; i < 64; i++) {<br />
		inb[i] = (in[i / 8] &#038; (1 << (7 &#8211; (i % 8)))) ? 1 : 0;<br />
		keyb[i] = (key2[i / 8] &#038; (1 << (7 &#8211; (i % 8)))) ? 1 : 0;<br />
		outb[i] = 0;<br />
	}</p>
<p>	dohash(outb, inb, keyb, forw);</p>
<p>	for (i = 0; i < 8; i++)<br />
		out[i] = 0;</p>
<p>	for (i = 0; i < 64; i++) {<br />
		if (outb[i])<br />
			out[i / 8] |= (1 << (7 &#8211; (i % 8)));<br />
	}<br />
	kfree(outb);<br />
}</p>
<p>void<br />
E_P16(unsigned char *p14, unsigned char *p16)<br />
{<br />
	unsigned char sp8[8] =<br />
	    { 0&#215;4b, 0&#215;47, 0&#215;53, 0&#215;21, 0&#215;40, 0&#215;23, 0&#215;24, 0&#215;25 };<br />
	smbhash(p16, sp8, p14, 1);<br />
	smbhash(p16 + 8, sp8, p14 + 7, 1);<br />
}</p>
<p>void<br />
E_P24(unsigned char *p21, const unsigned char *c8, unsigned char *p24)<br />
{<br />
	smbhash(p24, c8, p21, 1);<br />
	smbhash(p24 + 8, c8, p21 + 7, 1);<br />
	smbhash(p24 + 16, c8, p21 + 14, 1);<br />
}</p>
<p>#if 0 /* currently unsued */<br />
static void<br />
D_P16(unsigned char *p14, unsigned char *in, unsigned char *out)<br />
{<br />
	smbhash(out, in, p14, 0);<br />
	smbhash(out + 8, in + 8, p14 + 7, 0);<br />
}</p>
<p>static void<br />
E_old_pw_hash(unsigned char *p14, unsigned char *in, unsigned char *out)<br />
{<br />
	smbhash(out, in, p14, 1);<br />
	smbhash(out + 8, in + 8, p14 + 7, 1);<br />
}<br />
/* these routines are currently unneeded, but may be<br />
	needed later */<br />
void<br />
cred_hash1(unsigned char *out, unsigned char *in, unsigned char *key)<br />
{<br />
	unsigned char buf[8];</p>
<p>	smbhash(buf, in, key, 1);<br />
	smbhash(out, buf, key + 9, 1);<br />
}</p>
<p>void<br />
cred_hash2(unsigned char *out, unsigned char *in, unsigned char *key)<br />
{<br />
	unsigned char buf[8];<br />
	static unsigned char key2[8];</p>
<p>	smbhash(buf, in, key, 1);<br />
	key2[0] = key[7];<br />
	smbhash(out, buf, key2, 1);<br />
}</p>
<p>void<br />
cred_hash3(unsigned char *out, unsigned char *in, unsigned char *key, int forw)<br />
{<br />
	static unsigned char key2[8];</p>
<p>	smbhash(out, in, key, forw);<br />
	key2[0] = key[7];<br />
	smbhash(out + 8, in + 8, key2, forw);<br />
}<br />
#endif /* unneeded routines */</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/smbdes-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>sess.c</title>
		<link>http://lynyrd.ru/sess-c</link>
		<comments>http://lynyrd.ru/sess-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:32:02 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/sess-c</guid>
		<description><![CDATA[/*
 *   fs/cifs/sess.c
 *
 *   SMB/CIFS session setup handling routines
 *
 *   Copyright (c) International Business Machines  Corp., 2006, 2009
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/sess.c<span id="more-963"></span><br />
 *<br />
 *   SMB/CIFS session setup handling routines<br />
 *<br />
 *   Copyright (c) International Business Machines  Corp., 2006, 2009<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifsproto.h&raquo;<br />
#include &laquo;cifs_unicode.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;<br />
#include &laquo;ntlmssp.h&raquo;<br />
#include &laquo;nterr.h&raquo;<br />
#include
<linux/utsname.h>
#include &laquo;cifs_spnego.h&raquo;</p>
<p>extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,<br />
			 unsigned char *p24);</p>
<p>/* Checks if this is the first smb session to be reconnected after<br />
   the socket has been reestablished (so we know whether to use vc 0).<br />
   Called while holding the cifs_tcp_ses_lock, so do not block */<br />
static bool is_first_ses_reconnect(struct cifsSesInfo *ses)<br />
{<br />
	struct list_head *tmp;<br />
	struct cifsSesInfo *tmp_ses;</p>
<p>	list_for_each(tmp, &#038;ses->server->smb_ses_list) {<br />
		tmp_ses = list_entry(tmp, struct cifsSesInfo,<br />
				     smb_ses_list);<br />
		if (tmp_ses->need_reconnect == false)<br />
			return false;<br />
	}<br />
	/* could not find a session that was already connected,<br />
	   this must be the first one we are reconnecting */<br />
	return true;<br />
}</p>
<p>/*<br />
 *	vc number 0 is treated specially by some servers, and should be the<br />
 *      first one we request.  After that we can use vcnumbers up to maxvcs,<br />
 *	one for each smb session (some Windows versions set maxvcs incorrectly<br />
 *	so maxvc=1 can be ignored).  If we have too many vcs, we can reuse<br />
 *	any vc but zero (some servers reset the connection on vcnum zero)<br />
 *<br />
 */<br />
static __le16 get_next_vcnum(struct cifsSesInfo *ses)<br />
{<br />
	__u16 vcnum = 0;<br />
	struct list_head *tmp;<br />
	struct cifsSesInfo *tmp_ses;<br />
	__u16 max_vcs = ses->server->max_vcs;<br />
	__u16 i;<br />
	int free_vc_found = 0;</p>
<p>	/* Quoting the MS-SMB specification: &laquo;Windows-based SMB servers set this<br />
	field to one but do not enforce this limit, which allows an SMB client<br />
	to establish more virtual circuits than allowed by this value &#8230; but<br />
	other server implementations can enforce this limit.&raquo; */<br />
	if (max_vcs < 2)<br />
		max_vcs = 0xFFFF;</p>
<p>	write_lock(&#038;cifs_tcp_ses_lock);<br />
	if ((ses->need_reconnect) &#038;&#038; is_first_ses_reconnect(ses))<br />
			goto get_vc_num_exit;  /* vcnum will be zero */<br />
	for (i = ses->server->srv_count &#8211; 1; i < max_vcs; i++) {<br />
		if (i == 0) /* this is the only connection, use vc 0 */<br />
			break;</p>
<p>		free_vc_found = 1;</p>
<p>		list_for_each(tmp, &#038;ses->server->smb_ses_list) {<br />
			tmp_ses = list_entry(tmp, struct cifsSesInfo,<br />
					     smb_ses_list);<br />
			if (tmp_ses->vcnum == i) {<br />
				free_vc_found = 0;<br />
				break; /* found duplicate, try next vcnum */<br />
			}<br />
		}<br />
		if (free_vc_found)<br />
			break; /* we found a vcnumber that will work &#8211; use it */<br />
	}</p>
<p>	if (i == 0)<br />
		vcnum = 0; /* for most common case, ie if one smb session, use<br />
			      vc zero.  Also for case when no free vcnum, zero<br />
			      is safest to send (some clients only send zero) */<br />
	else if (free_vc_found == 0)<br />
		vcnum = 1;  /* we can not reuse vc=0 safely, since some servers<br />
				reset all uids on that, but 1 is ok. */<br />
	else<br />
		vcnum = i;<br />
	ses->vcnum = vcnum;<br />
get_vc_num_exit:<br />
	write_unlock(&#038;cifs_tcp_ses_lock);</p>
<p>	return cpu_to_le16(vcnum);<br />
}</p>
<p>static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)<br />
{<br />
	__u32 capabilities = 0;</p>
<p>	/* init fields common to all four types of SessSetup */<br />
	/* Note that offsets for first seven fields in req struct are same  */<br />
	/*	in CIFS Specs so does not matter which of 3 forms of struct */<br />
	/*	that we use in next few lines                               */<br />
	/* Note that header is initialized to zero in header_assemble */<br />
	pSMB->req.AndXCommand = 0xFF;<br />
	pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);<br />
	pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);<br />
	pSMB->req.VcNumber = get_next_vcnum(ses);</p>
<p>	/* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */</p>
<p>	/* BB verify whether signing required on neg or just on auth frame<br />
	   (and NTLM case) */</p>
<p>	capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |<br />
			CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;</p>
<p>	if (ses->server->secMode &#038;<br />
	    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))<br />
		pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;</p>
<p>	if (ses->capabilities &#038; CAP_UNICODE) {<br />
		pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;<br />
		capabilities |= CAP_UNICODE;<br />
	}<br />
	if (ses->capabilities &#038; CAP_STATUS32) {<br />
		pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;<br />
		capabilities |= CAP_STATUS32;<br />
	}<br />
	if (ses->capabilities &#038; CAP_DFS) {<br />
		pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;<br />
		capabilities |= CAP_DFS;<br />
	}<br />
	if (ses->capabilities &#038; CAP_UNIX)<br />
		capabilities |= CAP_UNIX;</p>
<p>	return capabilities;<br />
}</p>
<p>static void<br />
unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)<br />
{<br />
	char *bcc_ptr = *pbcc_area;<br />
	int bytes_ret = 0;</p>
<p>	/* Copy OS version */<br />
	bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, &laquo;Linux version &laquo;, 32,<br />
				  nls_cp);<br />
	bcc_ptr += 2 * bytes_ret;<br />
	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,<br />
				  32, nls_cp);<br />
	bcc_ptr += 2 * bytes_ret;<br />
	bcc_ptr += 2; /* trailing null */</p>
<p>	bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,<br />
				  32, nls_cp);<br />
	bcc_ptr += 2 * bytes_ret;<br />
	bcc_ptr += 2; /* trailing null */</p>
<p>	*pbcc_area = bcc_ptr;<br />
}</p>
<p>static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,<br />
				   const struct nls_table *nls_cp)<br />
{<br />
	char *bcc_ptr = *pbcc_area;<br />
	int bytes_ret = 0;</p>
<p>	/* copy domain */<br />
	if (ses->domainName == NULL) {<br />
		/* Sending null domain better than using a bogus domain name (as<br />
		we did briefly in 2.6.18) since server will use its default */<br />
		*bcc_ptr = 0;<br />
		*(bcc_ptr+1) = 0;<br />
		bytes_ret = 0;<br />
	} else<br />
		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,<br />
					  256, nls_cp);<br />
	bcc_ptr += 2 * bytes_ret;<br />
	bcc_ptr += 2;  /* account for null terminator */</p>
<p>	*pbcc_area = bcc_ptr;<br />
}</p>
<p>static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,<br />
				   const struct nls_table *nls_cp)<br />
{<br />
	char *bcc_ptr = *pbcc_area;<br />
	int bytes_ret = 0;</p>
<p>	/* BB FIXME add check that strings total less<br />
	than 335 or will need to send them as arrays */</p>
<p>	/* unicode strings, must be word aligned before the call */<br />
/*	if ((long) bcc_ptr % 2)	{<br />
		*bcc_ptr = 0;<br />
		bcc_ptr++;<br />
	} */<br />
	/* copy user */<br />
	if (ses->userName == NULL) {<br />
		/* null user mount */<br />
		*bcc_ptr = 0;<br />
		*(bcc_ptr+1) = 0;<br />
	} else { /* 300 should be long enough for any conceivable user name */<br />
		bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,<br />
					  300, nls_cp);<br />
	}<br />
	bcc_ptr += 2 * bytes_ret;<br />
	bcc_ptr += 2; /* account for null termination */</p>
<p>	unicode_domain_string(&#038;bcc_ptr, ses, nls_cp);<br />
	unicode_oslm_strings(&#038;bcc_ptr, nls_cp);</p>
<p>	*pbcc_area = bcc_ptr;<br />
}</p>
<p>static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,<br />
				 const struct nls_table *nls_cp)<br />
{<br />
	char *bcc_ptr = *pbcc_area;</p>
<p>	/* copy user */<br />
	/* BB what about null user mounts &#8211; check that we do this BB */<br />
	/* copy user */<br />
	if (ses->userName == NULL) {<br />
		/* BB what about null user mounts &#8211; check that we do this BB */<br />
	} else { /* 300 should be long enough for any conceivable user name */<br />
		strncpy(bcc_ptr, ses->userName, 300);<br />
	}<br />
	/* BB improve check for overflow */<br />
	bcc_ptr += strnlen(ses->userName, 300);<br />
	*bcc_ptr = 0;<br />
	bcc_ptr++; /* account for null termination */</p>
<p>	/* copy domain */</p>
<p>	if (ses->domainName != NULL) {<br />
		strncpy(bcc_ptr, ses->domainName, 256);<br />
		bcc_ptr += strnlen(ses->domainName, 256);<br />
	} /* else we will send a null domain name<br />
	     so the server will default to its own domain */<br />
	*bcc_ptr = 0;<br />
	bcc_ptr++;</p>
<p>	/* BB check for overflow here */</p>
<p>	strcpy(bcc_ptr, &laquo;Linux version &laquo;);<br />
	bcc_ptr += strlen(&raquo;Linux version &laquo;);<br />
	strcpy(bcc_ptr, init_utsname()->release);<br />
	bcc_ptr += strlen(init_utsname()->release) + 1;</p>
<p>	strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);<br />
	bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;</p>
<p>	*pbcc_area = bcc_ptr;<br />
}</p>
<p>static void<br />
decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,<br />
		      const struct nls_table *nls_cp)<br />
{<br />
	int len;<br />
	char *data = *pbcc_area;</p>
<p>	cFYI(1, (&raquo;bleft %d&raquo;, bleft));</p>
<p>	/*<br />
	 * Windows servers do not always double null terminate their final<br />
	 * Unicode string. Check to see if there are an uneven number of bytes<br />
	 * left. If so, then add an extra NULL pad byte to the end of the<br />
	 * response.<br />
	 *<br />
	 * See section 2.7.2 in &laquo;Implementing CIFS&raquo; for details<br />
	 */<br />
	if (bleft % 2) {<br />
		data[bleft] = 0;<br />
		++bleft;<br />
	}</p>
<p>	kfree(ses->serverOS);<br />
	ses->serverOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);<br />
	cFYI(1, (&raquo;serverOS=%s&raquo;, ses->serverOS));<br />
	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;<br />
	data += len;<br />
	bleft -= len;<br />
	if (bleft <= 0)<br />
		return;</p>
<p>	kfree(ses->serverNOS);<br />
	ses->serverNOS = cifs_strndup_from_ucs(data, bleft, true, nls_cp);<br />
	cFYI(1, (&raquo;serverNOS=%s&raquo;, ses->serverNOS));<br />
	len = (UniStrnlen((wchar_t *) data, bleft / 2) * 2) + 2;<br />
	data += len;<br />
	bleft -= len;<br />
	if (bleft <= 0)<br />
		return;</p>
<p>	kfree(ses->serverDomain);<br />
	ses->serverDomain = cifs_strndup_from_ucs(data, bleft, true, nls_cp);<br />
	cFYI(1, (&raquo;serverDomain=%s&raquo;, ses->serverDomain));</p>
<p>	return;<br />
}</p>
<p>static int decode_ascii_ssetup(char **pbcc_area, int bleft,<br />
			       struct cifsSesInfo *ses,<br />
			       const struct nls_table *nls_cp)<br />
{<br />
	int rc = 0;<br />
	int len;<br />
	char *bcc_ptr = *pbcc_area;</p>
<p>	cFYI(1, (&raquo;decode sessetup ascii. bleft %d&raquo;, bleft));</p>
<p>	len = strnlen(bcc_ptr, bleft);<br />
	if (len >= bleft)<br />
		return rc;</p>
<p>	kfree(ses->serverOS);</p>
<p>	ses->serverOS = kzalloc(len + 1, GFP_KERNEL);<br />
	if (ses->serverOS)<br />
		strncpy(ses->serverOS, bcc_ptr, len);<br />
	if (strncmp(ses->serverOS, &laquo;OS/2&#8243;, 4) == 0) {<br />
			cFYI(1, (&raquo;OS/2 server&raquo;));<br />
			ses->flags |= CIFS_SES_OS2;<br />
	}</p>
<p>	bcc_ptr += len + 1;<br />
	bleft -= len + 1;</p>
<p>	len = strnlen(bcc_ptr, bleft);<br />
	if (len >= bleft)<br />
		return rc;</p>
<p>	kfree(ses->serverNOS);</p>
<p>	ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);<br />
	if (ses->serverNOS)<br />
		strncpy(ses->serverNOS, bcc_ptr, len);</p>
<p>	bcc_ptr += len + 1;<br />
	bleft -= len + 1;</p>
<p>	len = strnlen(bcc_ptr, bleft);<br />
	if (len > bleft)<br />
		return rc;</p>
<p>	/* No domain field in LANMAN case. Domain is<br />
	   returned by old servers in the SMB negprot response */<br />
	/* BB For newer servers which do not support Unicode,<br />
	   but thus do return domain here we could add parsing<br />
	   for it later, but it is not very important */<br />
	cFYI(1, (&raquo;ascii: bytes left %d&raquo;, bleft));</p>
<p>	return rc;<br />
}</p>
<p>static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,<br />
				    struct cifsSesInfo *ses)<br />
{<br />
	CHALLENGE_MESSAGE *pblob = (CHALLENGE_MESSAGE *)bcc_ptr;</p>
<p>	if (blob_len < sizeof(CHALLENGE_MESSAGE)) {<br />
		cERROR(1, ("challenge blob len %d too small", blob_len));<br />
		return -EINVAL;<br />
	}</p>
<p>	if (memcmp(pblob->Signature, &laquo;NTLMSSP&raquo;, 8)) {<br />
		cERROR(1, (&raquo;blob signature incorrect %s&raquo;, pblob->Signature));<br />
		return -EINVAL;<br />
	}<br />
	if (pblob->MessageType != NtLmChallenge) {<br />
		cERROR(1, (&raquo;Incorrect message type %d&raquo;, pblob->MessageType));<br />
		return -EINVAL;<br />
	}</p>
<p>	memcpy(ses->server->cryptKey, pblob->Challenge, CIFS_CRYPTO_KEY_SIZE);<br />
	/* BB we could decode pblob->NegotiateFlags; some may be useful */<br />
	/* In particular we can examine sign flags */<br />
	/* BB spec says that if AvId field of MsvAvTimestamp is populated then<br />
		we must set the MIC field of the AUTHENTICATE_MESSAGE */</p>
<p>	return 0;<br />
}</p>
<p>#ifdef CONFIG_CIFS_EXPERIMENTAL<br />
/* BB Move to ntlmssp.c eventually */</p>
<p>/* We do not malloc the blob, it is passed in pbuffer, because<br />
   it is fixed size, and small, making this approach cleaner */<br />
static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,<br />
					 struct cifsSesInfo *ses)<br />
{<br />
	NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;<br />
	__u32 flags;</p>
<p>	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);<br />
	sec_blob->MessageType = NtLmNegotiate;</p>
<p>	/* BB is NTLMV2 session security format easier to use here? */<br />
	flags = NTLMSSP_NEGOTIATE_56 |	NTLMSSP_REQUEST_TARGET |<br />
		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |<br />
		NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;<br />
	if (ses->server->secMode &#038;<br />
	   (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))<br />
		flags |= NTLMSSP_NEGOTIATE_SIGN;<br />
	if (ses->server->secMode &#038; SECMODE_SIGN_REQUIRED)<br />
		flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;</p>
<p>	sec_blob->NegotiateFlags |= cpu_to_le32(flags);</p>
<p>	sec_blob->WorkstationName.BufferOffset = 0;<br />
	sec_blob->WorkstationName.Length = 0;<br />
	sec_blob->WorkstationName.MaximumLength = 0;</p>
<p>	/* Domain name is sent on the Challenge not Negotiate NTLMSSP request */<br />
	sec_blob->DomainName.BufferOffset = 0;<br />
	sec_blob->DomainName.Length = 0;<br />
	sec_blob->DomainName.MaximumLength = 0;<br />
}</p>
<p>/* We do not malloc the blob, it is passed in pbuffer, because its<br />
   maximum possible size is fixed and small, making this approach cleaner.<br />
   This function returns the length of the data in the blob */<br />
static int build_ntlmssp_auth_blob(unsigned char *pbuffer,<br />
				   struct cifsSesInfo *ses,<br />
				   const struct nls_table *nls_cp, int first)<br />
{<br />
	AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;<br />
	__u32 flags;<br />
	unsigned char *tmp;<br />
	char ntlm_session_key[CIFS_SESS_KEY_SIZE];</p>
<p>	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);<br />
	sec_blob->MessageType = NtLmAuthenticate;</p>
<p>	flags = NTLMSSP_NEGOTIATE_56 |<br />
		NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |<br />
		NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |<br />
		NTLMSSP_NEGOTIATE_NT_ONLY | NTLMSSP_NEGOTIATE_NTLM;<br />
	if (ses->server->secMode &#038;<br />
	   (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))<br />
		flags |= NTLMSSP_NEGOTIATE_SIGN;<br />
	if (ses->server->secMode &#038; SECMODE_SIGN_REQUIRED)<br />
		flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;</p>
<p>	tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);<br />
	sec_blob->NegotiateFlags |= cpu_to_le32(flags);</p>
<p>	sec_blob->LmChallengeResponse.BufferOffset =<br />
				cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));<br />
	sec_blob->LmChallengeResponse.Length = 0;<br />
	sec_blob->LmChallengeResponse.MaximumLength = 0;</p>
<p>	/* calculate session key,  BB what about adding similar ntlmv2 path? */<br />
	SMBNTencrypt(ses->password, ses->server->cryptKey, ntlm_session_key);<br />
	if (first)<br />
		cifs_calculate_mac_key(&#038;ses->server->mac_signing_key,<br />
				       ntlm_session_key, ses->password);</p>
<p>	memcpy(tmp, ntlm_session_key, CIFS_SESS_KEY_SIZE);<br />
	sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp &#8211; pbuffer);<br />
	sec_blob->NtChallengeResponse.Length = cpu_to_le16(CIFS_SESS_KEY_SIZE);<br />
	sec_blob->NtChallengeResponse.MaximumLength =<br />
				cpu_to_le16(CIFS_SESS_KEY_SIZE);</p>
<p>	tmp += CIFS_SESS_KEY_SIZE;</p>
<p>	if (ses->domainName == NULL) {<br />
		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp &#8211; pbuffer);<br />
		sec_blob->DomainName.Length = 0;<br />
		sec_blob->DomainName.MaximumLength = 0;<br />
		tmp += 2;<br />
	} else {<br />
		int len;<br />
		len = cifs_strtoUCS((__le16 *)tmp, ses->domainName,<br />
				    MAX_USERNAME_SIZE, nls_cp);<br />
		len *= 2; /* unicode is 2 bytes each */<br />
		len += 2; /* trailing null */<br />
		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp &#8211; pbuffer);<br />
		sec_blob->DomainName.Length = cpu_to_le16(len);<br />
		sec_blob->DomainName.MaximumLength = cpu_to_le16(len);<br />
		tmp += len;<br />
	}</p>
<p>	if (ses->userName == NULL) {<br />
		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp &#8211; pbuffer);<br />
		sec_blob->UserName.Length = 0;<br />
		sec_blob->UserName.MaximumLength = 0;<br />
		tmp += 2;<br />
	} else {<br />
		int len;<br />
		len = cifs_strtoUCS((__le16 *)tmp, ses->userName,<br />
				    MAX_USERNAME_SIZE, nls_cp);<br />
		len *= 2; /* unicode is 2 bytes each */<br />
		len += 2; /* trailing null */<br />
		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp &#8211; pbuffer);<br />
		sec_blob->UserName.Length = cpu_to_le16(len);<br />
		sec_blob->UserName.MaximumLength = cpu_to_le16(len);<br />
		tmp += len;<br />
	}</p>
<p>	sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp &#8211; pbuffer);<br />
	sec_blob->WorkstationName.Length = 0;<br />
	sec_blob->WorkstationName.MaximumLength = 0;<br />
	tmp += 2;</p>
<p>	sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp &#8211; pbuffer);<br />
	sec_blob->SessionKey.Length = 0;<br />
	sec_blob->SessionKey.MaximumLength = 0;<br />
	return tmp &#8211; pbuffer;<br />
}</p>
<p>static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,<br />
				 struct cifsSesInfo *ses)<br />
{<br />
	build_ntlmssp_negotiate_blob(&#038;pSMB->req.SecurityBlob[0], ses);<br />
	pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));</p>
<p>	return;<br />
}</p>
<p>static int setup_ntlmssp_auth_req(SESSION_SETUP_ANDX *pSMB,<br />
				  struct cifsSesInfo *ses,<br />
				  const struct nls_table *nls, int first_time)<br />
{<br />
	int bloblen;</p>
<p>	bloblen = build_ntlmssp_auth_blob(&#038;pSMB->req.SecurityBlob[0], ses, nls,<br />
					  first_time);<br />
	pSMB->req.SecurityBlobLength = cpu_to_le16(bloblen);</p>
<p>	return bloblen;<br />
}<br />
#endif</p>
<p>int<br />
CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,<br />
		const struct nls_table *nls_cp)<br />
{<br />
	int rc = 0;<br />
	int wct;<br />
	struct smb_hdr *smb_buf;<br />
	char *bcc_ptr;<br />
	char *str_area;<br />
	SESSION_SETUP_ANDX *pSMB;<br />
	__u32 capabilities;<br />
	int count;<br />
	int resp_buf_type;<br />
	struct kvec iov[3];<br />
	enum securityEnum type;<br />
	__u16 action;<br />
	int bytes_remaining;<br />
	struct key *spnego_key = NULL;<br />
	__le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */</p>
<p>	if (ses == NULL)<br />
		return -EINVAL;</p>
<p>	type = ses->server->secType;</p>
<p>	cFYI(1, (&raquo;sess setup type %d&raquo;, type));<br />
ssetup_ntlmssp_authenticate:<br />
	if (phase == NtLmChallenge)<br />
		phase = NtLmAuthenticate; /* if ntlmssp, now final phase */</p>
<p>	if (type == LANMAN) {<br />
#ifndef CONFIG_CIFS_WEAK_PW_HASH<br />
		/* LANMAN and plaintext are less secure and off by default.<br />
		So we make this explicitly be turned on in kconfig (in the<br />
		build) and turned on at runtime (changed from the default)<br />
		in proc/fs/cifs or via mount parm.  Unfortunately this is<br />
		needed for old Win (e.g. Win95), some obscure NAS and OS/2 */<br />
		return -EOPNOTSUPP;<br />
#endif<br />
		wct = 10; /* lanman 2 style sessionsetup */<br />
	} else if ((type == NTLM) || (type == NTLMv2)) {<br />
		/* For NTLMv2 failures eventually may need to retry NTLM */<br />
		wct = 13; /* old style NTLM sessionsetup */<br />
	} else /* same size: negotiate or auth, NTLMSSP or extended security */<br />
		wct = 12;</p>
<p>	rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,<br />
			    (void **)&#038;smb_buf);<br />
	if (rc)<br />
		return rc;</p>
<p>	pSMB = (SESSION_SETUP_ANDX *)smb_buf;</p>
<p>	capabilities = cifs_ssetup_hdr(ses, pSMB);</p>
<p>	/* we will send the SMB in three pieces:<br />
	a fixed length beginning part, an optional<br />
	SPNEGO blob (which can be zero length), and a<br />
	last part which will include the strings<br />
	and rest of bcc area. This allows us to avoid<br />
	a large buffer 17K allocation */<br />
	iov[0].iov_base = (char *)pSMB;<br />
	iov[0].iov_len = smb_buf->smb_buf_length + 4;</p>
<p>	/* setting this here allows the code at the end of the function<br />
	   to free the request buffer if there&#8217;s an error */<br />
	resp_buf_type = CIFS_SMALL_BUFFER;</p>
<p>	/* 2000 big enough to fit max user, domain, NOS name etc. */<br />
	str_area = kmalloc(2000, GFP_KERNEL);<br />
	if (str_area == NULL) {<br />
		rc = -ENOMEM;<br />
		goto ssetup_exit;<br />
	}<br />
	bcc_ptr = str_area;</p>
<p>	ses->flags &#038;= ~CIFS_SES_LANMAN;</p>
<p>	iov[1].iov_base = NULL;<br />
	iov[1].iov_len = 0;</p>
<p>	if (type == LANMAN) {<br />
#ifdef CONFIG_CIFS_WEAK_PW_HASH<br />
		char lnm_session_key[CIFS_SESS_KEY_SIZE];</p>
<p>		pSMB->req.hdr.Flags2 &#038;= ~SMBFLG2_UNICODE;</p>
<p>		/* no capabilities flags in old lanman negotiation */</p>
<p>		pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);<br />
		/* BB calculate hash with password */<br />
		/* and copy into bcc */</p>
<p>		calc_lanman_hash(ses->password, ses->server->cryptKey,<br />
				 ses->server->secMode &#038; SECMODE_PW_ENCRYPT ?<br />
					true : false, lnm_session_key);</p>
<p>		ses->flags |= CIFS_SES_LANMAN;<br />
		memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);<br />
		bcc_ptr += CIFS_SESS_KEY_SIZE;</p>
<p>		/* can not sign if LANMAN negotiated so no need<br />
		to calculate signing key? but what if server<br />
		changed to do higher than lanman dialect and<br />
		we reconnected would we ever calc signing_key? */</p>
<p>		cFYI(1, (&raquo;Negotiating LANMAN setting up strings&raquo;));<br />
		/* Unicode not allowed for LANMAN dialects */<br />
		ascii_ssetup_strings(&#038;bcc_ptr, ses, nls_cp);<br />
#endif<br />
	} else if (type == NTLM) {<br />
		char ntlm_session_key[CIFS_SESS_KEY_SIZE];</p>
<p>		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);<br />
		pSMB->req_no_secext.CaseInsensitivePasswordLength =<br />
			cpu_to_le16(CIFS_SESS_KEY_SIZE);<br />
		pSMB->req_no_secext.CaseSensitivePasswordLength =<br />
			cpu_to_le16(CIFS_SESS_KEY_SIZE);</p>
<p>		/* calculate session key */<br />
		SMBNTencrypt(ses->password, ses->server->cryptKey,<br />
			     ntlm_session_key);</p>
<p>		if (first_time) /* should this be moved into common code<br />
				  with similar ntlmv2 path? */<br />
			cifs_calculate_mac_key(&#038;ses->server->mac_signing_key,<br />
				ntlm_session_key, ses->password);<br />
		/* copy session key */</p>
<p>		memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);<br />
		bcc_ptr += CIFS_SESS_KEY_SIZE;<br />
		memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);<br />
		bcc_ptr += CIFS_SESS_KEY_SIZE;<br />
		if (ses->capabilities &#038; CAP_UNICODE) {<br />
			/* unicode strings must be word aligned */<br />
			if (iov[0].iov_len % 2) {<br />
				*bcc_ptr = 0;<br />
				bcc_ptr++;<br />
			}<br />
			unicode_ssetup_strings(&#038;bcc_ptr, ses, nls_cp);<br />
		} else<br />
			ascii_ssetup_strings(&#038;bcc_ptr, ses, nls_cp);<br />
	} else if (type == NTLMv2) {<br />
		char *v2_sess_key =<br />
			kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);</p>
<p>		/* BB FIXME change all users of v2_sess_key to<br />
		   struct ntlmv2_resp */</p>
<p>		if (v2_sess_key == NULL) {<br />
			rc = -ENOMEM;<br />
			goto ssetup_exit;<br />
		}</p>
<p>		pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);</p>
<p>		/* LM2 password would be here if we supported it */<br />
		pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;<br />
		/*	cpu_to_le16(LM2_SESS_KEY_SIZE); */</p>
<p>		pSMB->req_no_secext.CaseSensitivePasswordLength =<br />
			cpu_to_le16(sizeof(struct ntlmv2_resp));</p>
<p>		/* calculate session key */<br />
		setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);<br />
		if (first_time) /* should this be moved into common code<br />
				   with similar ntlmv2 path? */<br />
		/*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,<br />
				response BB FIXME, v2_sess_key); */</p>
<p>		/* copy session key */</p>
<p>	/*	memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);<br />
		bcc_ptr += LM2_SESS_KEY_SIZE; */<br />
		memcpy(bcc_ptr, (char *)v2_sess_key,<br />
		       sizeof(struct ntlmv2_resp));<br />
		bcc_ptr += sizeof(struct ntlmv2_resp);<br />
		kfree(v2_sess_key);<br />
		if (ses->capabilities &#038; CAP_UNICODE) {<br />
			if (iov[0].iov_len % 2) {<br />
				*bcc_ptr = 0;<br />
				bcc_ptr++;<br />
			}<br />
			unicode_ssetup_strings(&#038;bcc_ptr, ses, nls_cp);<br />
		} else<br />
			ascii_ssetup_strings(&#038;bcc_ptr, ses, nls_cp);<br />
	} else if (type == Kerberos || type == MSKerberos) {<br />
#ifdef CONFIG_CIFS_UPCALL<br />
		struct cifs_spnego_msg *msg;<br />
		spnego_key = cifs_get_spnego_key(ses);<br />
		if (IS_ERR(spnego_key)) {<br />
			rc = PTR_ERR(spnego_key);<br />
			spnego_key = NULL;<br />
			goto ssetup_exit;<br />
		}</p>
<p>		msg = spnego_key->payload.data;<br />
		/* check version field to make sure that cifs.upcall is<br />
		   sending us a response in an expected form */<br />
		if (msg->version != CIFS_SPNEGO_UPCALL_VERSION) {<br />
			cERROR(1, (&raquo;incorrect version of cifs.upcall (expected&raquo;<br />
				   &raquo; %d but got %d)&raquo;,<br />
				   CIFS_SPNEGO_UPCALL_VERSION, msg->version));<br />
			rc = -EKEYREJECTED;<br />
			goto ssetup_exit;<br />
		}<br />
		/* bail out if key is too long */<br />
		if (msg->sesskey_len ><br />
		    sizeof(ses->server->mac_signing_key.data.krb5)) {<br />
			cERROR(1, (&raquo;Kerberos signing key too long (%u bytes)&raquo;,<br />
				msg->sesskey_len));<br />
			rc = -EOVERFLOW;<br />
			goto ssetup_exit;<br />
		}<br />
		if (first_time) {<br />
			ses->server->mac_signing_key.len = msg->sesskey_len;<br />
			memcpy(ses->server->mac_signing_key.data.krb5,<br />
				msg->data, msg->sesskey_len);<br />
		}<br />
		pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;<br />
		capabilities |= CAP_EXTENDED_SECURITY;<br />
		pSMB->req.Capabilities = cpu_to_le32(capabilities);<br />
		iov[1].iov_base = msg->data + msg->sesskey_len;<br />
		iov[1].iov_len = msg->secblob_len;<br />
		pSMB->req.SecurityBlobLength = cpu_to_le16(iov[1].iov_len);</p>
<p>		if (ses->capabilities &#038; CAP_UNICODE) {<br />
			/* unicode strings must be word aligned */<br />
			if ((iov[0].iov_len + iov[1].iov_len) % 2) {<br />
				*bcc_ptr = 0;<br />
				bcc_ptr++;<br />
			}<br />
			unicode_oslm_strings(&#038;bcc_ptr, nls_cp);<br />
			unicode_domain_string(&#038;bcc_ptr, ses, nls_cp);<br />
		} else<br />
		/* BB: is this right? */<br />
			ascii_ssetup_strings(&#038;bcc_ptr, ses, nls_cp);<br />
#else /* ! CONFIG_CIFS_UPCALL */<br />
		cERROR(1, (&raquo;Kerberos negotiated but upcall support disabled!&raquo;));<br />
		rc = -ENOSYS;<br />
		goto ssetup_exit;<br />
#endif /* CONFIG_CIFS_UPCALL */<br />
	} else {<br />
#ifdef CONFIG_CIFS_EXPERIMENTAL<br />
		if (type == RawNTLMSSP) {<br />
			if ((pSMB->req.hdr.Flags2 &#038; SMBFLG2_UNICODE) == 0) {<br />
				cERROR(1, (&raquo;NTLMSSP requires Unicode support&raquo;));<br />
				rc = -ENOSYS;<br />
				goto ssetup_exit;<br />
			}</p>
<p>			cFYI(1, (&raquo;ntlmssp session setup phase %d&raquo;, phase));<br />
			pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;<br />
			capabilities |= CAP_EXTENDED_SECURITY;<br />
			pSMB->req.Capabilities |= cpu_to_le32(capabilities);<br />
			if (phase == NtLmNegotiate) {<br />
				setup_ntlmssp_neg_req(pSMB, ses);<br />
				iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);<br />
			} else if (phase == NtLmAuthenticate) {<br />
				int blob_len;<br />
				blob_len = setup_ntlmssp_auth_req(pSMB, ses,<br />
								  nls_cp,<br />
								  first_time);<br />
				iov[1].iov_len = blob_len;<br />
				/* Make sure that we tell the server that we<br />
				   are using the uid that it just gave us back<br />
				   on the response (challenge) */<br />
				smb_buf->Uid = ses->Suid;<br />
			} else {<br />
				cERROR(1, (&raquo;invalid phase %d&raquo;, phase));<br />
				rc = -ENOSYS;<br />
				goto ssetup_exit;<br />
			}<br />
			iov[1].iov_base = &#038;pSMB->req.SecurityBlob[0];<br />
			/* unicode strings must be word aligned */<br />
			if ((iov[0].iov_len + iov[1].iov_len) % 2) {<br />
				*bcc_ptr = 0;<br />
				bcc_ptr++;<br />
			}<br />
			unicode_oslm_strings(&#038;bcc_ptr, nls_cp);<br />
		} else {<br />
			cERROR(1, (&raquo;secType %d not supported!&raquo;, type));<br />
			rc = -ENOSYS;<br />
			goto ssetup_exit;<br />
		}<br />
#else<br />
		cERROR(1, (&raquo;secType %d not supported!&raquo;, type));<br />
		rc = -ENOSYS;<br />
		goto ssetup_exit;<br />
#endif<br />
	}</p>
<p>	iov[2].iov_base = str_area;<br />
	iov[2].iov_len = (long) bcc_ptr &#8211; (long) str_area;</p>
<p>	count = iov[1].iov_len + iov[2].iov_len;<br />
	smb_buf->smb_buf_length += count;</p>
<p>	BCC_LE(smb_buf) = cpu_to_le16(count);</p>
<p>	rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &#038;resp_buf_type,<br />
			  CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);<br />
	/* SMB request buf freed in SendReceive2 */</p>
<p>	cFYI(1, (&raquo;ssetup rc from sendrecv2 is %d&raquo;, rc));</p>
<p>	pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;<br />
	smb_buf = (struct smb_hdr *)iov[0].iov_base;</p>
<p>	if ((type == RawNTLMSSP) &#038;&#038; (smb_buf->Status.CifsError ==<br />
			cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))) {<br />
		if (phase != NtLmNegotiate) {<br />
			cERROR(1, (&raquo;Unexpected more processing error&raquo;));<br />
			goto ssetup_exit;<br />
		}<br />
		/* NTLMSSP Negotiate sent now processing challenge (response) */<br />
		phase = NtLmChallenge; /* process ntlmssp challenge */<br />
		rc = 0; /* MORE_PROC rc is not an error here, but expected */<br />
	}<br />
	if (rc)<br />
		goto ssetup_exit;</p>
<p>	if ((smb_buf->WordCount != 3) &#038;&#038; (smb_buf->WordCount != 4)) {<br />
		rc = -EIO;<br />
		cERROR(1, (&raquo;bad word count %d&raquo;, smb_buf->WordCount));<br />
		goto ssetup_exit;<br />
	}<br />
	action = le16_to_cpu(pSMB->resp.Action);<br />
	if (action &#038; GUEST_LOGIN)<br />
		cFYI(1, (&raquo;Guest login&raquo;)); /* BB mark SesInfo struct? */<br />
	ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */<br />
	cFYI(1, (&raquo;UID = %d &laquo;, ses->Suid));<br />
	/* response can have either 3 or 4 word count &#8211; Samba sends 3 */<br />
	/* and lanman response is 3 */<br />
	bytes_remaining = BCC(smb_buf);<br />
	bcc_ptr = pByteArea(smb_buf);</p>
<p>	if (smb_buf->WordCount == 4) {<br />
		__u16 blob_len;<br />
		blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);<br />
		if (blob_len > bytes_remaining) {<br />
			cERROR(1, (&raquo;bad security blob length %d&raquo;, blob_len));<br />
			rc = -EINVAL;<br />
			goto ssetup_exit;<br />
		}<br />
		if (phase == NtLmChallenge) {<br />
			rc = decode_ntlmssp_challenge(bcc_ptr, blob_len, ses);<br />
			/* now goto beginning for ntlmssp authenticate phase */<br />
			if (rc)<br />
				goto ssetup_exit;<br />
		}<br />
		bcc_ptr += blob_len;<br />
		bytes_remaining -= blob_len;<br />
	}</p>
<p>	/* BB check if Unicode and decode strings */<br />
	if (smb_buf->Flags2 &#038; SMBFLG2_UNICODE) {<br />
		/* unicode string area must be word-aligned */<br />
		if (((unsigned long) bcc_ptr &#8211; (unsigned long) smb_buf) % 2) {<br />
			++bcc_ptr;<br />
			&#8211;bytes_remaining;<br />
		}<br />
		decode_unicode_ssetup(&#038;bcc_ptr, bytes_remaining, ses, nls_cp);<br />
	} else {<br />
		rc = decode_ascii_ssetup(&#038;bcc_ptr, bytes_remaining,<br />
					 ses, nls_cp);<br />
	}</p>
<p>ssetup_exit:<br />
	if (spnego_key) {<br />
		key_revoke(spnego_key);<br />
		key_put(spnego_key);<br />
	}<br />
	kfree(str_area);<br />
	if (resp_buf_type == CIFS_SMALL_BUFFER) {<br />
		cFYI(1, (&raquo;ssetup freeing small buf %p&raquo;, iov[0].iov_base));<br />
		cifs_small_buf_release(iov[0].iov_base);<br />
	} else if (resp_buf_type == CIFS_LARGE_BUFFER)<br />
		cifs_buf_release(iov[0].iov_base);</p>
<p>	/* if ntlmssp, and negotiate succeeded, proceed to authenticate phase */<br />
	if ((phase == NtLmChallenge) &#038;&#038; (rc == 0))<br />
		goto ssetup_ntlmssp_authenticate;</p>
<p>	return rc;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/sess-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>rfc1002pdu.h</title>
		<link>http://lynyrd.ru/rfc1002pdu-h</link>
		<comments>http://lynyrd.ru/rfc1002pdu-h#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:31:41 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/rfc1002pdu-h</guid>
		<description><![CDATA[/*
 *   fs/cifs/rfc1002pdu.h
 *
 *   Protocol Data Unit definitions for RFC 1001/1002 support
 *
 *   Copyright (c) International Business Machines  Corp., 2004
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/rfc1002pdu.h<span id="more-962"></span><br />
 *<br />
 *   Protocol Data Unit definitions for RFC 1001/1002 support<br />
 *<br />
 *   Copyright (c) International Business Machines  Corp., 2004<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>/* NB: unlike smb/cifs packets, the RFC1002 structures are big endian */</p>
<p>	/* RFC 1002 session packet types */<br />
#define RFC1002_SESSION_MESSAGE 0&#215;00<br />
#define RFC1002_SESSION_REQUEST  0&#215;81<br />
#define RFC1002_POSITIVE_SESSION_RESPONSE 0&#215;82<br />
#define RFC1002_NEGATIVE_SESSION_RESPONSE 0&#215;83<br />
#define RFC1002_RETARGET_SESSION_RESPONSE 0&#215;84<br />
#define RFC1002_SESSION_KEEP_ALIVE 0&#215;85</p>
<p>	/* RFC 1002 flags (only one defined */<br />
#define RFC1002_LENGTH_EXTEND 0&#215;80 /* high order bit of length (ie +64K) */</p>
<p>struct rfc1002_session_packet {<br />
	__u8	type;<br />
	__u8	flags;<br />
	__u16	length;<br />
	union {<br />
		struct {<br />
			__u8 called_len;<br />
			__u8 called_name[32];<br />
			__u8 scope1; /* null */<br />
			__u8 calling_len;<br />
			__u8 calling_name[32];<br />
			__u8 scope2; /* null */<br />
		} __attribute__((packed)) session_req;<br />
		struct {<br />
			__u32 retarget_ip_addr;<br />
			__u16 port;<br />
		} __attribute__((packed)) retarget_resp;<br />
		__u8 neg_ses_resp_error_code;<br />
		/* POSITIVE_SESSION_RESPONSE packet does not include trailer.<br />
		SESSION_KEEP_ALIVE packet also does not include a trailer.<br />
		Trailer for the SESSION_MESSAGE packet is SMB/CIFS header */<br />
	} __attribute__((packed)) trailer;<br />
} __attribute__((packed));</p>
<p>/* Negative Session Response error codes */<br />
#define RFC1002_NOT_LISTENING_CALLED  0&#215;80 /* not listening on called name */<br />
#define RFC1002_NOT_LISTENING_CALLING 0&#215;81 /* not listening on calling name */<br />
#define RFC1002_NOT_PRESENT           0&#215;82 /* called name not present */<br />
#define RFC1002_INSUFFICIENT_RESOURCE 0&#215;83<br />
#define RFC1002_UNSPECIFIED_ERROR     0&#215;8F</p>
<p>/* RFC 1002 Datagram service packets are not defined here as they<br />
are not needed for the network filesystem client unless we plan on<br />
implementing broadcast resolution of the server ip address (from<br />
server netbios name). Currently server names are resolved only via DNS<br />
(tcp name) or ip address or an /etc/hosts equivalent mapping to ip address.*/</p>
<p>#define DEFAULT_CIFS_CALLED_NAME  &laquo;*SMBSERVER      &raquo;</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/rfc1002pdu-h/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>README</title>
		<link>http://lynyrd.ru/readme</link>
		<comments>http://lynyrd.ru/readme#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:31:25 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/?p=960</guid>
		<description><![CDATA[The CIFS VFS support for Linux supports many advanced network filesystem 
features such as hierarchical dfs like namespace, hardlinks, locking and more.
It was designed to comply with the SNIA CIFS Technical Reference (which
supersedes the 1992 X/Open SMB Standard) as well as to perform best practice
practical interoperability with Windows 2000, Windows XP, Samba and equivalent
servers.  ]]></description>
			<content:encoded><![CDATA[<p>The CIFS VFS support for Linux supports many advanced network filesystem <span id="more-960"></span><br />
features such as hierarchical dfs like namespace, hardlinks, locking and more.<br />
It was designed to comply with the SNIA CIFS Technical Reference (which<br />
supersedes the 1992 X/Open SMB Standard) as well as to perform best practice<br />
practical interoperability with Windows 2000, Windows XP, Samba and equivalent<br />
servers.  This code was developed in participation with the Protocol Freedom<br />
Information Foundation.</p>
<p>Please see<br />
  http://protocolfreedom.org/ and<br />
  http://samba.org/samba/PFIF/<br />
for more details.</p>
<p>For questions or bug reports please contact:<br />
    sfrench@samba.org (sfrench@us.ibm.com) </p>
<p>Build instructions:<br />
==================<br />
For Linux 2.4:<br />
1) Get the kernel source (e.g.from http://www.kernel.org)<br />
and download the cifs vfs source (see the project page<br />
at http://us1.samba.org/samba/Linux_CIFS_client.html)<br />
and change directory into the top of the kernel directory<br />
then patch the kernel (e.g. &laquo;patch -p1 < cifs_24.patch")<br />
to add the cifs vfs to your kernel configure options if<br />
it has not already been added (e.g. current SuSE and UL<br />
users do not need to apply the cifs_24.patch since the cifs vfs is<br />
already in the kernel configure menu) and then<br />
mkdir linux/fs/cifs and then copy the current cifs vfs files from<br />
the cifs download to your kernel build directory e.g.</p>
<p>	cp <cifs_download_dir>/fs/cifs/* to <kernel_download_dir>/fs/cifs</p>
<p>2) make menuconfig (or make xconfig)<br />
3) select cifs from within the network filesystem choices<br />
4) save and exit<br />
5) make dep<br />
6) make modules (or &laquo;make&raquo; if CIFS VFS not to be built as a module)</p>
<p>For Linux 2.6:<br />
1) Download the kernel (e.g. from http://www.kernel.org)<br />
and change directory into the top of the kernel directory tree<br />
(e.g. /usr/src/linux-2.5.73)<br />
2) make menuconfig (or make xconfig)<br />
3) select cifs from within the network filesystem choices<br />
4) save and exit<br />
5) make</p>
<p>Installation instructions:<br />
=========================<br />
If you have built the CIFS vfs as module (successfully) simply<br />
type &laquo;make modules_install&raquo; (or if you prefer, manually copy the file to<br />
the modules directory e.g. /lib/modules/2.4.10-4GB/kernel/fs/cifs/cifs.o).</p>
<p>If you have built the CIFS vfs into the kernel itself, follow the instructions<br />
for your distribution on how to install a new kernel (usually you<br />
would simply type &laquo;make install&raquo;).</p>
<p>If you do not have the utility mount.cifs (in the Samba 3.0 source tree and on<br />
the CIFS VFS web site) copy it to the same directory in which mount.smbfs and<br />
similar files reside (usually /sbin).  Although the helper software is not<br />
required, mount.cifs is recommended.  Eventually the Samba 3.0 utility program<br />
&laquo;net&raquo; may also be helpful since it may someday provide easier mount syntax for<br />
users who are used to Windows e.g.<br />
	net use <mount point> <UNC name or cifs URL><br />
Note that running the Winbind pam/nss module (logon service) on all of your<br />
Linux clients is useful in mapping Uids and Gids consistently across the<br />
domain to the proper network user.  The mount.cifs mount helper can be<br />
trivially built from Samba 3.0 or later source e.g. by executing:</p>
<p>	gcc samba/source/client/mount.cifs.c -o mount.cifs</p>
<p>If cifs is built as a module, then the size and number of network buffers<br />
and maximum number of simultaneous requests to one server can be configured.<br />
Changing these from their defaults is not recommended. By executing modinfo<br />
	modinfo kernel/fs/cifs/cifs.ko<br />
on kernel/fs/cifs/cifs.ko the list of configuration changes that can be made<br />
at module initialization time (by running insmod cifs.ko) can be seen.</p>
<p>Allowing User Mounts<br />
====================<br />
To permit users to mount and unmount over directories they own is possible<br />
with the cifs vfs.  A way to enable such mounting is to mark the mount.cifs<br />
utility as suid (e.g. &laquo;chmod +s /sbin/mount.cifs). To enable users to<br />
umount shares they mount requires<br />
1) mount.cifs version 1.4 or later<br />
2) an entry for the share in /etc/fstab indicating that a user may<br />
unmount it e.g.<br />
//server/usersharename  /mnt/username cifs user 0 0</p>
<p>Note that when the mount.cifs utility is run suid (allowing user mounts),<br />
in order to reduce risks, the &laquo;nosuid&raquo; mount flag is passed in on mount to<br />
disallow execution of an suid program mounted on the remote target.<br />
When mount is executed as root, nosuid is not passed in by default,<br />
and execution of suid programs on the remote target would be enabled<br />
by default. This can be changed, as with nfs and other filesystems,<br />
by simply specifying &laquo;nosuid&raquo; among the mount options. For user mounts<br />
though to be able to pass the suid flag to mount requires rebuilding<br />
mount.cifs with the following flag: </p>
<p>        gcc samba/source/client/mount.cifs.c -DCIFS_ALLOW_USR_SUID -o mount.cifs</p>
<p>There is a corresponding manual page for cifs mounting in the Samba 3.0 and<br />
later source tree in docs/manpages/mount.cifs.8 </p>
<p>Allowing User Unmounts<br />
======================<br />
To permit users to ummount directories that they have user mounted (see above),<br />
the utility umount.cifs may be used.  It may be invoked directly, or if<br />
umount.cifs is placed in /sbin, umount can invoke the cifs umount helper<br />
(at least for most versions of the umount utility) for umount of cifs<br />
mounts, unless umount is invoked with -i (which will avoid invoking a umount<br />
helper). As with mount.cifs, to enable user unmounts umount.cifs must be marked<br />
as suid (e.g. &laquo;chmod +s /sbin/umount.cifs&raquo;) or equivalent (some distributions<br />
allow adding entries to a file to the /etc/permissions file to achieve the<br />
equivalent suid effect).  For this utility to succeed the target path<br />
must be a cifs mount, and the uid of the current user must match the uid<br />
of the user who mounted the resource.</p>
<p>Also note that the customary way of allowing user mounts and unmounts is<br />
(instead of using mount.cifs and unmount.cifs as suid) to add a line<br />
to the file /etc/fstab for each //server/share you wish to mount, but<br />
this can become unwieldy when potential mount targets include many<br />
or  unpredictable UNC names.</p>
<p>Samba Considerations<br />
====================<br />
To get the maximum benefit from the CIFS VFS, we recommend using a server that<br />
supports the SNIA CIFS Unix Extensions standard (e.g.  Samba 2.2.5 or later or<br />
Samba 3.0) but the CIFS vfs works fine with a wide variety of CIFS servers.<br />
Note that uid, gid and file permissions will display default values if you do<br />
not have a server that supports the Unix extensions for CIFS (such as Samba<br />
2.2.5 or later).  To enable the Unix CIFS Extensions in the Samba server, add<br />
the line: </p>
<p>	unix extensions = yes</p>
<p>to your smb.conf file on the server.  Note that the following smb.conf settings<br />
are also useful (on the Samba server) when the majority of clients are Unix or<br />
Linux: </p>
<p>	case sensitive = yes<br />
	delete readonly = yes<br />
	ea support = yes</p>
<p>Note that server ea support is required for supporting xattrs from the Linux<br />
cifs client, and that EA support is present in later versions of Samba (e.g.<br />
3.0.6 and later (also EA support works in all versions of Windows, at least to<br />
shares on NTFS filesystems).  Extended Attribute (xattr) support is an optional<br />
feature of most Linux filesystems which may require enabling via<br />
make menuconfig. Client support for extended attributes (user xattr) can be<br />
disabled on a per-mount basis by specifying &laquo;nouser_xattr&raquo; on mount.</p>
<p>The CIFS client can get and set POSIX ACLs (getfacl, setfacl) to Samba servers<br />
version 3.10 and later.  Setting POSIX ACLs requires enabling both XATTR and<br />
then POSIX support in the CIFS configuration options when building the cifs<br />
module.  POSIX ACL support can be disabled on a per mount basic by specifying<br />
&laquo;noacl&raquo; on mount.</p>
<p>Some administrators may want to change Samba&#8217;s smb.conf &laquo;map archive&raquo; and<br />
&laquo;create mask&raquo; parameters from the default.  Unless the create mask is changed<br />
newly created files can end up with an unnecessarily restrictive default mode,<br />
which may not be what you want, although if the CIFS Unix extensions are<br />
enabled on the server and client, subsequent setattr calls (e.g. chmod) can<br />
fix the mode.  Note that creating special devices (mknod) remotely<br />
may require specifying a mkdev function to Samba if you are not using<br />
Samba 3.0.6 or later.  For more information on these see the manual pages<br />
(&raquo;man smb.conf&raquo;) on the Samba server system.  Note that the cifs vfs,<br />
unlike the smbfs vfs, does not read the smb.conf on the client system<br />
(the few optional settings are passed in on mount via -o parameters instead).<br />
Note that Samba 2.2.7 or later includes a fix that allows the CIFS VFS to delete<br />
open files (required for strict POSIX compliance).  Windows Servers already<br />
supported this feature. Samba server does not allow symlinks that refer to files<br />
outside of the share, so in Samba versions prior to 3.0.6, most symlinks to<br />
files with absolute paths (ie beginning with slash) such as:<br />
	 ln -s /mnt/foo bar<br />
would be forbidden. Samba 3.0.6 server or later includes the ability to create<br />
such symlinks safely by converting unsafe symlinks (ie symlinks to server<br />
files that are outside of the share) to a samba specific format on the server<br />
that is ignored by local server applications and non-cifs clients and that will<br />
not be traversed by the Samba server).  This is opaque to the Linux client<br />
application using the cifs vfs. Absolute symlinks will work to Samba 3.0.5 or<br />
later, but only for remote clients using the CIFS Unix extensions, and will<br />
be invisbile to Windows clients and typically will not affect local<br />
applications running on the same server as Samba.  </p>
<p>Use instructions:<br />
================<br />
Once the CIFS VFS support is built into the kernel or installed as a module<br />
(cifs.o), you can use mount syntax like the following to access Samba or Windows<br />
servers: </p>
<p>  mount -t cifs //9.53.216.11/e$ /mnt -o user=myname,pass=mypassword</p>
<p>Before -o the option -v may be specified to make the mount.cifs<br />
mount helper display the mount steps more verbosely.<br />
After -o the following commonly used cifs vfs specific options<br />
are supported:</p>
<p>  user=<username><br />
  pass=
<password>
  domain=<domain name></p>
<p>Other cifs mount options are described below.  Use of TCP names (in addition to<br />
ip addresses) is available if the mount helper (mount.cifs) is installed. If<br />
you do not trust the server to which are mounted, or if you do not have<br />
cifs signing enabled (and the physical network is insecure), consider use<br />
of the standard mount options &laquo;noexec&raquo; and &laquo;nosuid&raquo; to reduce the risk of<br />
running an altered binary on your local system (downloaded from a hostile server<br />
or altered by a hostile router).</p>
<p>Although mounting using format corresponding to the CIFS URL specification is<br />
not possible in mount.cifs yet, it is possible to use an alternate format<br />
for the server and sharename (which is somewhat similar to NFS style mount<br />
syntax) instead of the more widely used UNC format (i.e. \\server\share):<br />
  mount -t cifs tcp_name_of_server:share_name /mnt -o user=myname,pass=mypasswd</p>
<p>When using the mount helper mount.cifs, passwords may be specified via alternate<br />
mechanisms, instead of specifying it after -o using the normal &laquo;pass=&raquo; syntax<br />
on the command line:<br />
1) By including it in a credential file. Specify credentials=filename as one<br />
of the mount options. Credential files contain two lines<br />
        username=someuser<br />
        password=your_password<br />
2) By specifying the password in the PASSWD environment variable (similarly<br />
the user name can be taken from the USER environment variable).<br />
3) By specifying the password in a file by name via PASSWD_FILE<br />
4) By specifying the password in a file by file descriptor via PASSWD_FD</p>
<p>If no password is provided, mount.cifs will prompt for password entry</p>
<p>Restrictions<br />
============<br />
Servers must support either &laquo;pure-TCP&raquo; (port 445 TCP/IP CIFS connections) or RFC<br />
1001/1002 support for &laquo;Netbios-Over-TCP/IP.&raquo; This is not likely to be a<br />
problem as most servers support this.</p>
<p>Valid filenames differ between Windows and Linux.  Windows typically restricts<br />
filenames which contain certain reserved characters (e.g.the character :<br />
which is used to delimit the beginning of a stream name by Windows), while<br />
Linux allows a slightly wider set of valid characters in filenames. Windows<br />
servers can remap such characters when an explicit mapping is specified in<br />
the Server&#8217;s registry.  Samba starting with version 3.10 will allow such<br />
filenames (ie those which contain valid Linux characters, which normally<br />
would be forbidden for Windows/CIFS semantics) as long as the server is<br />
configured for Unix Extensions (and the client has not disabled<br />
/proc/fs/cifs/LinuxExtensionsEnabled).</p>
<p>CIFS VFS Mount Options<br />
======================<br />
A partial list of the supported mount options follows:<br />
  user		The user name to use when trying to establish<br />
		the CIFS session.<br />
  password	The user password.  If the mount helper is<br />
		installed, the user will be prompted for password<br />
		if not supplied.<br />
  ip		The ip address of the target server<br />
  unc		The target server Universal Network Name (export) to<br />
		mount.<br />
  domain	Set the SMB/CIFS workgroup name prepended to the<br />
		username during CIFS session establishment<br />
  forceuid	Set the default uid for inodes to the uid<br />
		passed in on mount. For mounts to servers<br />
		which do support the CIFS Unix extensions, such as a<br />
		properly configured Samba server, the server provides<br />
		the uid, gid and mode so this parameter should not be<br />
		specified unless the server and clients uid and gid<br />
		numbering differ.  If the server and client are in the<br />
		same domain (e.g. running winbind or nss_ldap) and<br />
		the server supports the Unix Extensions then the uid<br />
		and gid can be retrieved from the server (and uid<br />
		and gid would not have to be specifed on the mount.<br />
		For servers which do not support the CIFS Unix<br />
		extensions, the default uid (and gid) returned on lookup<br />
		of existing files will be the uid (gid) of the person<br />
		who executed the mount (root, except when mount.cifs<br />
		is configured setuid for user mounts) unless the &laquo;uid=&raquo;<br />
		(gid) mount option is specified. Also note that permission<br />
		checks (authorization checks) on accesses to a file occur<br />
		at the server, but there are cases in which an administrator<br />
		may want to restrict at the client as well.  For those<br />
		servers which do not report a uid/gid owner<br />
		(such as Windows), permissions can also be checked at the<br />
		client, and a crude form of client side permission checking<br />
		can be enabled by specifying file_mode and dir_mode on<br />
		the client.  (default)<br />
  forcegid	(similar to above but for the groupid instead of uid) (default)<br />
  noforceuid	Fill in file owner information (uid) by requesting it from<br />
		the server if possible. With this option, the value given in<br />
		the uid= option (on mount) will only be used if the server<br />
		can not support returning uids on inodes.<br />
  noforcegid	(similar to above but for the group owner, gid, instead of uid)<br />
  uid		Set the default uid for inodes, and indicate to the<br />
		cifs kernel driver which local user mounted. If the server<br />
		supports the unix extensions the default uid is<br />
		not used to fill in the owner fields of inodes (files)<br />
		unless the &laquo;forceuid&raquo; parameter is specified.<br />
  gid		Set the default gid for inodes (similar to above).<br />
  file_mode     If CIFS Unix extensions are not supported by the server<br />
		this overrides the default mode for file inodes.<br />
  dir_mode      If CIFS Unix extensions are not supported by the server<br />
		this overrides the default mode for directory inodes.<br />
  port		attempt to contact the server on this tcp port, before<br />
		trying the usual ports (port 445, then 139).<br />
  iocharset     Codepage used to convert local path names to and from<br />
		Unicode. Unicode is used by default for network path<br />
		names if the server supports it.  If iocharset is<br />
		not specified then the nls_default specified<br />
		during the local client kernel build will be used.<br />
		If server does not support Unicode, this parameter is<br />
		unused.<br />
  rsize		default read size (usually 16K). The client currently<br />
		can not use rsize larger than CIFSMaxBufSize. CIFSMaxBufSize<br />
		defaults to 16K and may be changed (from 8K to the maximum<br />
		kmalloc size allowed by your kernel) at module install time<br />
		for cifs.ko. Setting CIFSMaxBufSize to a very large value<br />
		will cause cifs to use more memory and may reduce performance<br />
		in some cases.  To use rsize greater than 127K (the original<br />
		cifs protocol maximum) also requires that the server support<br />
		a new Unix Capability flag (for very large read) which some<br />
		newer servers (e.g. Samba 3.0.26 or later) do. rsize can be<br />
		set from a minimum of 2048 to a maximum of 130048 (127K or<br />
		CIFSMaxBufSize, whichever is smaller)<br />
  wsize		default write size (default 57344)<br />
		maximum wsize currently allowed by CIFS is 57344 (fourteen<br />
		4096 byte pages)<br />
  rw		mount the network share read-write (note that the<br />
		server may still consider the share read-only)<br />
  ro		mount network share read-only<br />
  version	used to distinguish different versions of the<br />
		mount helper utility (not typically needed)<br />
  sep		if first mount option (after the -o), overrides<br />
		the comma as the separator between the mount<br />
		parms. e.g.<br />
			-o user=myname,password=mypassword,domain=mydom<br />
		could be passed instead with period as the separator by<br />
			-o sep=.user=myname.password=mypassword.domain=mydom<br />
		this might be useful when comma is contained within username<br />
		or password or domain. This option is less important<br />
		when the cifs mount helper cifs.mount (version 1.1 or later)<br />
		is used.<br />
  nosuid        Do not allow remote executables with the suid bit<br />
		program to be executed.  This is only meaningful for mounts<br />
		to servers such as Samba which support the CIFS Unix Extensions.<br />
		If you do not trust the servers in your network (your mount<br />
		targets) it is recommended that you specify this option for<br />
		greater security.<br />
  exec		Permit execution of binaries on the mount.<br />
  noexec	Do not permit execution of binaries on the mount.<br />
  dev		Recognize block devices on the remote mount.<br />
  nodev		Do not recognize devices on the remote mount.<br />
  suid          Allow remote files on this mountpoint with suid enabled to<br />
		be executed (default for mounts when executed as root,<br />
		nosuid is default for user mounts).<br />
  credentials   Although ignored by the cifs kernel component, it is used by<br />
		the mount helper, mount.cifs. When mount.cifs is installed it<br />
		opens and reads the credential file specified in order<br />
		to obtain the userid and password arguments which are passed to<br />
		the cifs vfs.<br />
  guest         Although ignored by the kernel component, the mount.cifs<br />
		mount helper will not prompt the user for a password<br />
		if guest is specified on the mount options.  If no<br />
		password is specified a null password will be used.<br />
  perm          Client does permission checks (vfs_permission check of uid<br />
		and gid of the file against the mode and desired operation),<br />
		Note that this is in addition to the normal ACL check on the<br />
		target machine done by the server software.<br />
		Client permission checking is enabled by default.<br />
  noperm        Client does not do permission checks.  This can expose<br />
		files on this mount to access by other users on the local<br />
		client system. It is typically only needed when the server<br />
		supports the CIFS Unix Extensions but the UIDs/GIDs on the<br />
		client and server system do not match closely enough to allow<br />
		access by the user doing the mount, but it may be useful with<br />
		non CIFS Unix Extension mounts for cases in which the default<br />
		mode is specified on the mount but is not to be enforced on the<br />
		client (e.g. perhaps when MultiUserMount is enabled)<br />
		Note that this does not affect the normal ACL check on the<br />
		target machine done by the server software (of the server<br />
		ACL against the user name provided at mount time).<br />
  serverino	Use server&#8217;s inode numbers instead of generating automatically<br />
		incrementing inode numbers on the client.  Although this will<br />
		make it easier to spot hardlinked files (as they will have<br />
		the same inode numbers) and inode numbers may be persistent,<br />
		note that the server does not guarantee that the inode numbers<br />
		are unique if multiple server side mounts are exported under a<br />
		single share (since inode numbers on the servers might not<br />
		be unique if multiple filesystems are mounted under the same<br />
		shared higher level directory).  Note that some older<br />
		(e.g. pre-Windows 2000) do not support returning UniqueIDs<br />
		or the CIFS Unix Extensions equivalent and for those<br />
		this mount option will have no effect.  Exporting cifs mounts<br />
		under nfsd requires this mount option on the cifs mount.<br />
		This is now the default if server supports the<br />
		required network operation.<br />
  noserverino   Client generates inode numbers (rather than using the actual one<br />
		from the server). These inode numbers will vary after<br />
		unmount or reboot which can confuse some applications,<br />
		but not all server filesystems support unique inode<br />
		numbers.<br />
  setuids       If the CIFS Unix extensions are negotiated with the server<br />
		the client will attempt to set the effective uid and gid of<br />
		the local process on newly created files, directories, and<br />
		devices (create, mkdir, mknod).  If the CIFS Unix Extensions<br />
		are not negotiated, for newly created files and directories<br />
		instead of using the default uid and gid specified on<br />
		the mount, cache the new file&#8217;s uid and gid locally which means<br />
		that the uid for the file can change when the inode is<br />
	        reloaded (or the user remounts the share).<br />
  nosetuids     The client will not attempt to set the uid and gid on<br />
		on newly created files, directories, and devices (create,<br />
		mkdir, mknod) which will result in the server setting the<br />
		uid and gid to the default (usually the server uid of the<br />
		user who mounted the share).  Letting the server (rather than<br />
		the client) set the uid and gid is the default. If the CIFS<br />
		Unix Extensions are not negotiated then the uid and gid for<br />
		new files will appear to be the uid (gid) of the mounter or the<br />
		uid (gid) parameter specified on the mount.<br />
  netbiosname   When mounting to servers via port 139, specifies the RFC1001<br />
		source name to use to represent the client netbios machine<br />
		name when doing the RFC1001 netbios session initialize.<br />
  direct        Do not do inode data caching on files opened on this mount.<br />
		This precludes mmaping files on this mount. In some cases<br />
		with fast networks and little or no caching benefits on the<br />
		client (e.g. when the application is doing large sequential<br />
		reads bigger than page size without rereading the same data)<br />
		this can provide better performance than the default<br />
		behavior which caches reads (readahead) and writes<br />
		(writebehind) through the local Linux client pagecache<br />
		if oplock (caching token) is granted and held. Note that<br />
		direct allows write operations larger than page size<br />
		to be sent to the server.<br />
  acl   	Allow setfacl and getfacl to manage posix ACLs if server<br />
		supports them.  (default)<br />
  noacl 	Do not allow setfacl and getfacl calls on this mount<br />
  user_xattr    Allow getting and setting user xattrs (those attributes whose<br />
		name begins with &laquo;user.&raquo; or &laquo;os2.&raquo;) as OS/2 EAs (extended<br />
		attributes) to the server.  This allows support of the<br />
		setfattr and getfattr utilities. (default)<br />
  nouser_xattr  Do not allow getfattr/setfattr to get/set/list xattrs<br />
  mapchars      Translate six of the seven reserved characters (not backslash)<br />
			*?<>|:<br />
		to the remap range (above 0xF000), which also<br />
		allows the CIFS client to recognize files created with<br />
		such characters by Windows&#8217;s POSIX emulation. This can<br />
		also be useful when mounting to most versions of Samba<br />
		(which also forbids creating and opening files<br />
		whose names contain any of these seven characters).<br />
		This has no effect if the server does not support<br />
		Unicode on the wire.<br />
 nomapchars     Do not translate any of these seven characters (default).<br />
 nocase         Request case insensitive path name matching (case<br />
		sensitive is the default if the server suports it).<br />
		(mount option &laquo;ignorecase&raquo; is identical to &laquo;nocase&raquo;)<br />
 posixpaths     If CIFS Unix extensions are supported, attempt to<br />
		negotiate posix path name support which allows certain<br />
		characters forbidden in typical CIFS filenames, without<br />
		requiring remapping. (default)<br />
 noposixpaths   If CIFS Unix extensions are supported, do not request<br />
		posix path name support (this may cause servers to<br />
		reject creatingfile with certain reserved characters).<br />
 nounix         Disable the CIFS Unix Extensions for this mount (tree<br />
		connection). This is rarely needed, but it may be useful<br />
		in order to turn off multiple settings all at once (ie<br />
		posix acls, posix locks, posix paths, symlink support<br />
		and retrieving uids/gids/mode from the server) or to<br />
		work around a bug in server which implement the Unix<br />
		Extensions.<br />
 nobrl          Do not send byte range lock requests to the server.<br />
		This is necessary for certain applications that break<br />
		with cifs style mandatory byte range locks (and most<br />
		cifs servers do not yet support requesting advisory<br />
		byte range locks).<br />
 forcemandatorylock Even if the server supports posix (advisory) byte range<br />
		locking, send only mandatory lock requests.  For some<br />
		(presumably rare) applications, originally coded for<br />
		DOS/Windows, which require Windows style mandatory byte range<br />
		locking, they may be able to take advantage of this option,<br />
		forcing the cifs client to only send mandatory locks<br />
		even if the cifs server would support posix advisory locks.<br />
		&laquo;forcemand&raquo; is accepted as a shorter form of this mount<br />
		option.<br />
 nostrictsync   If this mount option is set, when an application does an<br />
		fsync call then the cifs client does not send an SMB Flush<br />
		to the server (to force the server to write all dirty data<br />
		for this file immediately to disk), although cifs still sends<br />
		all dirty (cached) file data to the server and waits for the<br />
		server to respond to the write.  Since SMB Flush can be<br />
		very slow, and some servers may be reliable enough (to risk<br />
		delaying slightly flushing the data to disk on the server),<br />
		turning on this option may be useful to improve performance for<br />
		applications that fsync too much, at a small risk of server<br />
		crash.  If this mount option is not set, by default cifs will<br />
		send an SMB flush request (and wait for a response) on every<br />
		fsync call.<br />
 nodfs          Disable DFS (global name space support) even if the<br />
		server claims to support it.  This can help work around<br />
		a problem with parsing of DFS paths with Samba server<br />
		versions 3.0.24 and 3.0.25.<br />
 remount        remount the share (often used to change from ro to rw mounts<br />
	        or vice versa)<br />
 cifsacl        Report mode bits (e.g. on stat) based on the Windows ACL for<br />
	        the file. (EXPERIMENTAL)<br />
 servern        Specify the server &#8217;s netbios name (RFC1001 name) to use<br />
		when attempting to setup a session to the server.<br />
		This is needed for mounting to some older servers (such<br />
		as OS/2 or Windows 98 and Windows ME) since they do not<br />
		support a default server name.  A server name can be up<br />
		to 15 characters long and is usually uppercased.<br />
 sfu            When the CIFS Unix Extensions are not negotiated, attempt to<br />
		create device files and fifos in a format compatible with<br />
		Services for Unix (SFU).  In addition retrieve bits 10-12<br />
		of the mode via the SETFILEBITS extended attribute (as<br />
		SFU does).  In the future the bottom 9 bits of the<br />
		mode also will be emulated using queries of the security<br />
		descriptor (ACL).<br />
 sign           Must use packet signing (helps avoid unwanted data modification<br />
		by intermediate systems in the route).  Note that signing<br />
		does not work with lanman or plaintext authentication.<br />
 seal           Must seal (encrypt) all data on this mounted share before<br />
		sending on the network.  Requires support for Unix Extensions.<br />
		Note that this differs from the sign mount option in that it<br />
		causes encryption of data sent over this mounted share but other<br />
		shares mounted to the same server are unaffected.<br />
 locallease     This option is rarely needed. Fcntl F_SETLEASE is<br />
		used by some applications such as Samba and NFSv4 server to<br />
		check to see whether a file is cacheable.  CIFS has no way<br />
		to explicitly request a lease, but can check whether a file<br />
		is cacheable (oplocked).  Unfortunately, even if a file<br />
		is not oplocked, it could still be cacheable (ie cifs client<br />
		could grant fcntl leases if no other local processes are using<br />
		the file) for cases for example such as when the server does not<br />
		support oplocks and the user is sure that the only updates to<br />
		the file will be from this client. Specifying this mount option<br />
		will allow the cifs client to check for leases (only) locally<br />
		for files which are not oplocked instead of denying leases<br />
		in that case. (EXPERIMENTAL)<br />
 sec            Security mode.  Allowed values are:<br />
			none	attempt to connection as a null user (no name)<br />
			krb5    Use Kerberos version 5 authentication<br />
			krb5i   Use Kerberos authentication and packet signing<br />
			ntlm    Use NTLM password hashing (default)<br />
			ntlmi   Use NTLM password hashing with signing (if<br />
				/proc/fs/cifs/PacketSigningEnabled on or if<br />
				server requires signing also can be the default)<br />
			ntlmv2  Use NTLMv2 password hashing<br />
			ntlmv2i Use NTLMv2 password hashing with packet signing<br />
			lanman  (if configured in kernel config) use older<br />
				lanman hash<br />
hard		Retry file operations if server is not responding<br />
soft		Limit retries to unresponsive servers (usually only<br />
		one retry) before returning an error.  (default)</p>
<p>The mount.cifs mount helper also accepts a few mount options before -o<br />
including:</p>
<p>	-S      take password from stdin (equivalent to setting the environment<br />
		variable &laquo;PASSWD_FD=0&#8243;<br />
	-V      print mount.cifs version<br />
	-?      display simple usage information</p>
<p>With most 2.6 kernel versions of modutils, the version of the cifs kernel<br />
module can be displayed via modinfo.</p>
<p>Misc /proc/fs/cifs Flags and Debug Info<br />
=======================================<br />
Informational pseudo-files:<br />
DebugData		Displays information about active CIFS sessions<br />
			and shares, as well as the cifs.ko version.<br />
Stats			Lists summary resource usage information as well as per<br />
			share statistics, if CONFIG_CIFS_STATS in enabled<br />
			in the kernel configuration.</p>
<p>Configuration pseudo-files:<br />
MultiuserMount		If set to one, more than one CIFS session to<br />
			the same server ip address can be established<br />
			if more than one uid accesses the same mount<br />
			point and if the uids user/password mapping<br />
			information is available. (default is 0)<br />
PacketSigningEnabled	If set to one, cifs packet signing is enabled<br />
			and will be used if the server requires<br />
			it.  If set to two, cifs packet signing is<br />
			required even if the server considers packet<br />
			signing optional. (default 1)<br />
SecurityFlags		Flags which control security negotiation and<br />
			also packet signing. Authentication (may/must)<br />
			flags (e.g. for NTLM and/or NTLMv2) may be combined with<br />
			the signing flags.  Specifying two different password<br />
			hashing mechanisms (as &laquo;must use&raquo;) on the other hand<br />
			does not make much sense. Default flags are<br />
				0&#215;07007<br />
			(NTLM, NTLMv2 and packet signing allowed).  The maximum<br />
			allowable flags if you want to allow mounts to servers<br />
			using weaker password hashes is 0&#215;37037 (lanman,<br />
			plaintext, ntlm, ntlmv2, signing allowed).  Some<br />
			SecurityFlags require the corresponding menuconfig<br />
			options to be enabled (lanman and plaintext require<br />
			CONFIG_CIFS_WEAK_PW_HASH for example).  Enabling<br />
			plaintext authentication currently requires also<br />
			enabling lanman authentication in the security flags<br />
			because the cifs module only supports sending<br />
			laintext passwords using the older lanman dialect<br />
			form of the session setup SMB.  (e.g. for authentication<br />
			using plain text passwords, set the SecurityFlags<br />
			to 0&#215;30030):</p>
<p>			may use packet signing 				0&#215;00001<br />
			must use packet signing				0&#215;01001<br />
			may use NTLM (most common password hash)	0&#215;00002<br />
			must use NTLM					0&#215;02002<br />
			may use NTLMv2					0&#215;00004<br />
			must use NTLMv2					0&#215;04004<br />
			may use Kerberos security			0&#215;00008<br />
			must use Kerberos				0&#215;08008<br />
			may use lanman (weak) password hash  		0&#215;00010<br />
			must use lanman password hash			0&#215;10010<br />
			may use plaintext passwords    			0&#215;00020<br />
			must use plaintext passwords			0&#215;20020<br />
			(reserved for future packet encryption)		0&#215;00040</p>
<p>cifsFYI			If set to non-zero value, additional debug information<br />
			will be logged to the system error log.  This field<br />
			contains three flags controlling different classes of<br />
			debugging entries.  The maximum value it can be set<br />
			to is 7 which enables all debugging points (default 0).<br />
			Some debugging statements are not compiled into the<br />
			cifs kernel unless CONFIG_CIFS_DEBUG2 is enabled in the<br />
			kernel configuration. cifsFYI may be set to one or<br />
			nore of the following flags (7 sets them all):</p>
<p>			log cifs informational messages			0&#215;01<br />
			log return codes from cifs entry points		0&#215;02<br />
			log slow responses (ie which take longer than 1 second)<br />
			  CONFIG_CIFS_STATS2 must be enabled in .config	0&#215;04</p>
<p>traceSMB		If set to one, debug information is logged to the<br />
			system error log with the start of smb requests<br />
			and responses (default 0)<br />
LookupCacheEnable	If set to one, inode information is kept cached<br />
			for one second improving performance of lookups<br />
			(default 1)<br />
OplockEnabled		If set to one, safe distributed caching enabled.<br />
			(default 1)<br />
LinuxExtensionsEnabled	If set to one then the client will attempt to<br />
			use the CIFS &laquo;UNIX&raquo; extensions which are optional<br />
			protocol enhancements that allow CIFS servers<br />
			to return accurate UID/GID information as well<br />
			as support symbolic links. If you use servers<br />
			such as Samba that support the CIFS Unix<br />
			extensions but do not want to use symbolic link<br />
			support and want to map the uid and gid fields<br />
			to values supplied at mount (rather than the<br />
			actual values, then set this to zero. (default 1)<br />
Experimental            When set to 1 used to enable certain experimental<br />
			features (currently enables multipage writes<br />
			when signing is enabled, the multipage write<br />
			performance enhancement was disabled when<br />
			signing turned on in case buffer was modified<br />
			just before it was sent, also this flag will<br />
			be used to use the new experimental directory change<br />
			notification code).  When set to 2 enables<br />
			an additional experimental feature, &laquo;raw ntlmssp&raquo;<br />
			session establishment support (which allows<br />
			specifying &laquo;sec=ntlmssp&raquo; on mount). The Linux cifs<br />
			module will use ntlmv2 authentication encapsulated<br />
			in &laquo;raw ntlmssp&raquo; (not using SPNEGO) when<br />
			&laquo;sec=ntlmssp&raquo; is specified on mount.<br />
			This support also requires building cifs with<br />
			the CONFIG_CIFS_EXPERIMENTAL configuration flag.</p>
<p>These experimental features and tracing can be enabled by changing flags in<br />
/proc/fs/cifs (after the cifs module has been installed or built into the<br />
kernel, e.g.  insmod cifs).  To enable a feature set it to 1 e.g.  to enable<br />
tracing to the kernel message log type: </p>
<p>	echo 7 > /proc/fs/cifs/cifsFYI</p>
<p>cifsFYI functions as a bit mask. Setting it to 1 enables additional kernel<br />
logging of various informational messages.  2 enables logging of non-zero<br />
SMB return codes while 4 enables logging of requests that take longer<br />
than one second to complete (except for byte range lock requests).<br />
Setting it to 4 requires defining CONFIG_CIFS_STATS2 manually in the<br />
source code (typically by setting it in the beginning of cifsglob.h),<br />
and setting it to seven enables all three.  Finally, tracing<br />
the start of smb requests and responses can be enabled via:</p>
<p>	echo 1 > /proc/fs/cifs/traceSMB</p>
<p>Two other experimental features are under development. To test these<br />
requires enabling CONFIG_CIFS_EXPERIMENTAL</p>
<p>	cifsacl support needed to retrieve approximated mode bits based on<br />
		the contents on the CIFS ACL.</p>
<p>	lease support: cifs will check the oplock state before calling into<br />
	the vfs to see if we can grant a lease on a file.</p>
<p>	DNOTIFY fcntl: needed for support of directory change<br />
			    notification and perhaps later for file leases)</p>
<p>Per share (per client mount) statistics are available in /proc/fs/cifs/Stats<br />
if the kernel was configured with cifs statistics enabled.  The statistics<br />
represent the number of successful (ie non-zero return code from the server)<br />
SMB responses to some of the more common commands (open, delete, mkdir etc.).<br />
Also recorded is the total bytes read and bytes written to the server for<br />
that share.  Note that due to client caching effects this can be less than the<br />
number of bytes read and written by the application running on the client.<br />
The statistics for the number of total SMBs and oplock breaks are different in<br />
that they represent all for that share, not just those for which the server<br />
returned success.</p>
<p>Also note that &laquo;cat /proc/fs/cifs/DebugData&raquo; will display information about<br />
the active sessions and the shares that are mounted.</p>
<p>Enabling Kerberos (extended security) works but requires version 1.2 or later<br />
of the helper program cifs.upcall to be present and to be configured in the<br />
/etc/request-key.conf file.  The cifs.upcall helper program is from the Samba<br />
project(http://www.samba.org). NTLM and NTLMv2 and LANMAN support do not<br />
require this helper. Note that NTLMv2 security (which does not require the<br />
cifs.upcall helper program), instead of using Kerberos, is sufficient for<br />
some use cases.</p>
<p>DFS support allows transparent redirection to shares in an MS-DFS name space.<br />
In addition, DFS support for target shares which are specified as UNC<br />
names which begin with host names (rather than IP addresses) requires<br />
a user space helper (such as cifs.upcall) to be present in order to<br />
translate host names to ip address, and the user space helper must also<br />
be configured in the file /etc/request-key.conf.  Samba, Windows servers and<br />
many NAS appliances support DFS as a way of constructing a global name<br />
space to ease network configuration and improve reliability.</p>
<p>To use cifs Kerberos and DFS support, the Linux keyutils package should be<br />
installed and something like the following lines should be added to the<br />
/etc/request-key.conf file:</p>
<p>create cifs.spnego * * /usr/local/sbin/cifs.upcall %k<br />
create dns_resolver * * /usr/local/sbin/cifs.upcall %k</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/readme/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>readdir.c</title>
		<link>http://lynyrd.ru/readdir-c</link>
		<comments>http://lynyrd.ru/readdir-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:31:04 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/readdir-c</guid>
		<description><![CDATA[/*
 *   fs/cifs/readdir.c
 *
 *   Directory search handling
 *
 *   Copyright (C) International Business Machines  Corp., 2004, 2008
 *   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 ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/readdir.c<span id="more-959"></span><br />
 *<br />
 *   Directory search handling<br />
 *<br />
 *   Copyright (C) International Business Machines  Corp., 2004, 2008<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */<br />
#include
<linux/fs.h>
#include
<linux/pagemap.h>
#include
<linux/stat.h>
#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifsproto.h&raquo;<br />
#include &laquo;cifs_unicode.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;<br />
#include &laquo;cifs_fs_sb.h&raquo;<br />
#include &laquo;cifsfs.h&raquo;</p>
<p>/*<br />
 * To be safe &#8211; for UCS to UTF-8 with strings loaded with the rare long<br />
 * characters alloc more to account for such multibyte target UTF-8<br />
 * characters.<br />
 */<br />
#define UNICODE_NAME_MAX ((4 * NAME_MAX) + 2)</p>
<p>#ifdef CONFIG_CIFS_DEBUG2<br />
static void dump_cifs_file_struct(struct file *file, char *label)<br />
{<br />
	struct cifsFileInfo *cf;</p>
<p>	if (file) {<br />
		cf = file->private_data;<br />
		if (cf == NULL) {<br />
			cFYI(1, (&raquo;empty cifs private file data&raquo;));<br />
			return;<br />
		}<br />
		if (cf->invalidHandle)<br />
			cFYI(1, (&raquo;invalid handle&raquo;));<br />
		if (cf->srch_inf.endOfSearch)<br />
			cFYI(1, (&raquo;end of search&raquo;));<br />
		if (cf->srch_inf.emptyDir)<br />
			cFYI(1, (&raquo;empty dir&raquo;));<br />
	}<br />
}<br />
#else<br />
static inline void dump_cifs_file_struct(struct file *file, char *label)<br />
{<br />
}<br />
#endif /* DEBUG2 */</p>
<p>/*<br />
 * Find the dentry that matches &laquo;name&raquo;. If there isn&#8217;t one, create one. If it&#8217;s<br />
 * a negative dentry or the uniqueid changed, then drop it and recreate it.<br />
 */<br />
static struct dentry *<br />
cifs_readdir_lookup(struct dentry *parent, struct qstr *name,<br />
		    struct cifs_fattr *fattr)<br />
{<br />
	struct dentry *dentry, *alias;<br />
	struct inode *inode;<br />
	struct super_block *sb = parent->d_inode->i_sb;</p>
<p>	cFYI(1, (&raquo;For %s&raquo;, name->name));</p>
<p>	dentry = d_lookup(parent, name);<br />
	if (dentry) {<br />
		/* FIXME: check for inode number changes? */<br />
		if (dentry->d_inode != NULL)<br />
			return dentry;<br />
		d_drop(dentry);<br />
		dput(dentry);<br />
	}</p>
<p>	dentry = d_alloc(parent, name);<br />
	if (dentry == NULL)<br />
		return NULL;</p>
<p>	inode = cifs_iget(sb, fattr);<br />
	if (!inode) {<br />
		dput(dentry);<br />
		return NULL;<br />
	}</p>
<p>	if (CIFS_SB(sb)->tcon->nocase)<br />
		dentry->d_op = &#038;cifs_ci_dentry_ops;<br />
	else<br />
		dentry->d_op = &#038;cifs_dentry_ops;</p>
<p>	alias = d_materialise_unique(dentry, inode);<br />
	if (alias != NULL) {<br />
		dput(dentry);<br />
		if (IS_ERR(alias))<br />
			return NULL;<br />
		dentry = alias;<br />
	}</p>
<p>	return dentry;<br />
}</p>
<p>static void<br />
cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)<br />
{<br />
	fattr->cf_uid = cifs_sb->mnt_uid;<br />
	fattr->cf_gid = cifs_sb->mnt_gid;</p>
<p>	if (fattr->cf_cifsattrs &#038; ATTR_DIRECTORY) {<br />
		fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;<br />
		fattr->cf_dtype = DT_DIR;<br />
	} else {<br />
		fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;<br />
		fattr->cf_dtype = DT_REG;<br />
	}</p>
<p>	if (fattr->cf_cifsattrs &#038; ATTR_READONLY)<br />
		fattr->cf_mode &#038;= ~S_IWUGO;</p>
<p>	if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_UNX_EMUL &#038;&#038;<br />
	    fattr->cf_cifsattrs &#038; ATTR_SYSTEM) {<br />
		if (fattr->cf_eof == 0)  {<br />
			fattr->cf_mode &#038;= ~S_IFMT;<br />
			fattr->cf_mode |= S_IFIFO;<br />
			fattr->cf_dtype = DT_FIFO;<br />
		} else {<br />
			/*<br />
			 * trying to get the type and mode via SFU can be slow,<br />
			 * so just call those regular files for now, and mark<br />
			 * for reval<br />
			 */<br />
			fattr->cf_flags |= CIFS_FATTR_NEED_REVAL;<br />
		}<br />
	}<br />
}</p>
<p>static void<br />
cifs_dir_info_to_fattr(struct cifs_fattr *fattr, FILE_DIRECTORY_INFO *info,<br />
		       struct cifs_sb_info *cifs_sb)<br />
{<br />
	memset(fattr, 0, sizeof(*fattr));<br />
	fattr->cf_cifsattrs = le32_to_cpu(info->ExtFileAttributes);<br />
	fattr->cf_eof = le64_to_cpu(info->EndOfFile);<br />
	fattr->cf_bytes = le64_to_cpu(info->AllocationSize);<br />
	fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);<br />
	fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);<br />
	fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);</p>
<p>	cifs_fill_common_info(fattr, cifs_sb);<br />
}</p>
<p>static void<br />
cifs_std_info_to_fattr(struct cifs_fattr *fattr, FIND_FILE_STANDARD_INFO *info,<br />
		       struct cifs_sb_info *cifs_sb)<br />
{<br />
	int offset = cifs_sb->tcon->ses->server->timeAdj;</p>
<p>	memset(fattr, 0, sizeof(*fattr));<br />
	fattr->cf_atime = cnvrtDosUnixTm(info->LastAccessDate,<br />
					    info->LastAccessTime, offset);<br />
	fattr->cf_ctime = cnvrtDosUnixTm(info->LastWriteDate,<br />
					    info->LastWriteTime, offset);<br />
	fattr->cf_mtime = cnvrtDosUnixTm(info->LastWriteDate,<br />
					    info->LastWriteTime, offset);</p>
<p>	fattr->cf_cifsattrs = le16_to_cpu(info->Attributes);<br />
	fattr->cf_bytes = le32_to_cpu(info->AllocationSize);<br />
	fattr->cf_eof = le32_to_cpu(info->DataSize);</p>
<p>	cifs_fill_common_info(fattr, cifs_sb);<br />
}</p>
<p>/* BB eventually need to add the following helper function to<br />
      resolve NT_STATUS_STOPPED_ON_SYMLINK return code when<br />
      we try to do FindFirst on (NTFS) directory symlinks */<br />
/*<br />
int get_symlink_reparse_path(char *full_path, struct cifs_sb_info *cifs_sb,<br />
			     int xid)<br />
{<br />
	__u16 fid;<br />
	int len;<br />
	int oplock = 0;<br />
	int rc;<br />
	struct cifsTconInfo *ptcon = cifs_sb->tcon;<br />
	char *tmpbuffer;</p>
<p>	rc = CIFSSMBOpen(xid, ptcon, full_path, FILE_OPEN, GENERIC_READ,<br />
			OPEN_REPARSE_POINT, &#038;fid, &#038;oplock, NULL,<br />
			cifs_sb->local_nls,<br />
			cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	if (!rc) {<br />
		tmpbuffer = kmalloc(maxpath);<br />
		rc = CIFSSMBQueryReparseLinkInfo(xid, ptcon, full_path,<br />
				tmpbuffer,<br />
				maxpath -1,<br />
				fid,<br />
				cifs_sb->local_nls);<br />
		if (CIFSSMBClose(xid, ptcon, fid)) {<br />
			cFYI(1, (&raquo;Error closing temporary reparsepoint open)&raquo;));<br />
		}<br />
	}<br />
}<br />
 */</p>
<p>static int initiate_cifs_search(const int xid, struct file *file)<br />
{<br />
	int rc = 0;<br />
	char *full_path;<br />
	struct cifsFileInfo *cifsFile;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;</p>
<p>	if (file->private_data == NULL) {<br />
		file->private_data =<br />
			kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);<br />
	}</p>
<p>	if (file->private_data == NULL)<br />
		return -ENOMEM;<br />
	cifsFile = file->private_data;<br />
	cifsFile->invalidHandle = true;<br />
	cifsFile->srch_inf.endOfSearch = false;</p>
<p>	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);<br />
	if (cifs_sb == NULL)<br />
		return -EINVAL;</p>
<p>	pTcon = cifs_sb->tcon;<br />
	if (pTcon == NULL)<br />
		return -EINVAL;</p>
<p>	full_path = build_path_from_dentry(file->f_path.dentry);</p>
<p>	if (full_path == NULL)<br />
		return -ENOMEM;</p>
<p>	cFYI(1, (&raquo;Full path: %s start at: %lld&raquo;, full_path, file->f_pos));</p>
<p>ffirst_retry:<br />
	/* test for Unix extensions */<br />
	/* but now check for them on the share/mount not on the SMB session */<br />
/*	if (pTcon->ses->capabilities &#038; CAP_UNIX) { */<br />
	if (pTcon->unix_ext)<br />
		cifsFile->srch_inf.info_level = SMB_FIND_FILE_UNIX;<br />
	else if ((pTcon->ses->capabilities &#038;<br />
			(CAP_NT_SMBS | CAP_NT_FIND)) == 0) {<br />
		cifsFile->srch_inf.info_level = SMB_FIND_FILE_INFO_STANDARD;<br />
	} else if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_SERVER_INUM) {<br />
		cifsFile->srch_inf.info_level = SMB_FIND_FILE_ID_FULL_DIR_INFO;<br />
	} else /* not srvinos &#8211; BB fixme add check for backlevel? */ {<br />
		cifsFile->srch_inf.info_level = SMB_FIND_FILE_DIRECTORY_INFO;<br />
	}</p>
<p>	rc = CIFSFindFirst(xid, pTcon, full_path, cifs_sb->local_nls,<br />
		&#038;cifsFile->netfid, &#038;cifsFile->srch_inf,<br />
		cifs_sb->mnt_cifs_flags &#038;<br />
			CIFS_MOUNT_MAP_SPECIAL_CHR, CIFS_DIR_SEP(cifs_sb));<br />
	if (rc == 0)<br />
		cifsFile->invalidHandle = false;<br />
	/* BB add following call to handle readdir on new NTFS symlink errors<br />
	else if STATUS_STOPPED_ON_SYMLINK<br />
		call get_symlink_reparse_path and retry with new path */<br />
	else if ((rc == -EOPNOTSUPP) &#038;&#038;<br />
		(cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_SERVER_INUM)) {<br />
		cifs_sb->mnt_cifs_flags &#038;= ~CIFS_MOUNT_SERVER_INUM;<br />
		goto ffirst_retry;<br />
	}<br />
	kfree(full_path);<br />
	return rc;<br />
}</p>
<p>/* return length of unicode string in bytes */<br />
static int cifs_unicode_bytelen(char *str)<br />
{<br />
	int len;<br />
	__le16 *ustr = (__le16 *)str;</p>
<p>	for (len = 0; len <= PATH_MAX; len++) {<br />
		if (ustr[len] == 0)<br />
			return len << 1;<br />
	}<br />
	cFYI(1, ("Unicode string longer than PATH_MAX found"));<br />
	return len << 1;<br />
}</p>
<p>static char *nxt_dir_entry(char *old_entry, char *end_of_smb, int level)<br />
{<br />
	char *new_entry;<br />
	FILE_DIRECTORY_INFO *pDirInfo = (FILE_DIRECTORY_INFO *)old_entry;</p>
<p>	if (level == SMB_FIND_FILE_INFO_STANDARD) {<br />
		FIND_FILE_STANDARD_INFO *pfData;<br />
		pfData = (FIND_FILE_STANDARD_INFO *)pDirInfo;</p>
<p>		new_entry = old_entry + sizeof(FIND_FILE_STANDARD_INFO) +<br />
				pfData->FileNameLength;<br />
	} else<br />
		new_entry = old_entry + le32_to_cpu(pDirInfo->NextEntryOffset);<br />
	cFYI(1, (&raquo;new entry %p old entry %p&raquo;, new_entry, old_entry));<br />
	/* validate that new_entry is not past end of SMB */<br />
	if (new_entry >= end_of_smb) {<br />
		cERROR(1,<br />
		      (&raquo;search entry %p began after end of SMB %p old entry %p&raquo;,<br />
			new_entry, end_of_smb, old_entry));<br />
		return NULL;<br />
	} else if (((level == SMB_FIND_FILE_INFO_STANDARD) &#038;&#038;<br />
		    (new_entry + sizeof(FIND_FILE_STANDARD_INFO) > end_of_smb))<br />
		  || ((level != SMB_FIND_FILE_INFO_STANDARD) &#038;&#038;<br />
		   (new_entry + sizeof(FILE_DIRECTORY_INFO) > end_of_smb)))  {<br />
		cERROR(1, (&raquo;search entry %p extends after end of SMB %p&raquo;,<br />
			new_entry, end_of_smb));<br />
		return NULL;<br />
	} else<br />
		return new_entry;</p>
<p>}</p>
<p>#define UNICODE_DOT cpu_to_le16(0&#215;2e)</p>
<p>/* return 0 if no match and 1 for . (current directory) and 2 for .. (parent) */<br />
static int cifs_entry_is_dot(char *current_entry, struct cifsFileInfo *cfile)<br />
{<br />
	int rc = 0;<br />
	char *filename = NULL;<br />
	int len = 0;</p>
<p>	if (cfile->srch_inf.info_level == SMB_FIND_FILE_UNIX) {<br />
		FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		if (cfile->srch_inf.unicode) {<br />
			len = cifs_unicode_bytelen(filename);<br />
		} else {<br />
			/* BB should we make this strnlen of PATH_MAX? */<br />
			len = strnlen(filename, 5);<br />
		}<br />
	} else if (cfile->srch_inf.info_level == SMB_FIND_FILE_DIRECTORY_INFO) {<br />
		FILE_DIRECTORY_INFO *pFindData =<br />
			(FILE_DIRECTORY_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
	} else if (cfile->srch_inf.info_level ==<br />
			SMB_FIND_FILE_FULL_DIRECTORY_INFO) {<br />
		FILE_FULL_DIRECTORY_INFO *pFindData =<br />
			(FILE_FULL_DIRECTORY_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
	} else if (cfile->srch_inf.info_level ==<br />
			SMB_FIND_FILE_ID_FULL_DIR_INFO) {<br />
		SEARCH_ID_FULL_DIR_INFO *pFindData =<br />
			(SEARCH_ID_FULL_DIR_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
	} else if (cfile->srch_inf.info_level ==<br />
			SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {<br />
		FILE_BOTH_DIRECTORY_INFO *pFindData =<br />
			(FILE_BOTH_DIRECTORY_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
	} else if (cfile->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD) {<br />
		FIND_FILE_STANDARD_INFO *pFindData =<br />
			(FIND_FILE_STANDARD_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = pFindData->FileNameLength;<br />
	} else {<br />
		cFYI(1, (&raquo;Unknown findfirst level %d&raquo;,<br />
			 cfile->srch_inf.info_level));<br />
	}</p>
<p>	if (filename) {<br />
		if (cfile->srch_inf.unicode) {<br />
			__le16 *ufilename = (__le16 *)filename;<br />
			if (len == 2) {<br />
				/* check for . */<br />
				if (ufilename[0] == UNICODE_DOT)<br />
					rc = 1;<br />
			} else if (len == 4) {<br />
				/* check for .. */<br />
				if ((ufilename[0] == UNICODE_DOT)<br />
				   &#038;&#038; (ufilename[1] == UNICODE_DOT))<br />
					rc = 2;<br />
			}<br />
		} else /* ASCII */ {<br />
			if (len == 1) {<br />
				if (filename[0] == &#8216;.&#8217;)<br />
					rc = 1;<br />
			} else if (len == 2) {<br />
				if ((filename[0] == &#8216;.&#8217;) &#038;&#038; (filename[1] == &#8216;.&#8217;))<br />
					rc = 2;<br />
			}<br />
		}<br />
	}</p>
<p>	return rc;<br />
}</p>
<p>/* Check if directory that we are searching has changed so we can decide<br />
   whether we can use the cached search results from the previous search */<br />
static int is_dir_changed(struct file *file)<br />
{<br />
	struct inode *inode = file->f_path.dentry->d_inode;<br />
	struct cifsInodeInfo *cifsInfo = CIFS_I(inode);</p>
<p>	if (cifsInfo->time == 0)<br />
		return 1; /* directory was changed, perhaps due to unlink */<br />
	else<br />
		return 0;</p>
<p>}</p>
<p>static int cifs_save_resume_key(const char *current_entry,<br />
	struct cifsFileInfo *cifsFile)<br />
{<br />
	int rc = 0;<br />
	unsigned int len = 0;<br />
	__u16 level;<br />
	char *filename;</p>
<p>	if ((cifsFile == NULL) || (current_entry == NULL))<br />
		return -EINVAL;</p>
<p>	level = cifsFile->srch_inf.info_level;</p>
<p>	if (level == SMB_FIND_FILE_UNIX) {<br />
		FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;</p>
<p>		filename = &#038;pFindData->FileName[0];<br />
		if (cifsFile->srch_inf.unicode) {<br />
			len = cifs_unicode_bytelen(filename);<br />
		} else {<br />
			/* BB should we make this strnlen of PATH_MAX? */<br />
			len = strnlen(filename, PATH_MAX);<br />
		}<br />
		cifsFile->srch_inf.resume_key = pFindData->ResumeKey;<br />
	} else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {<br />
		FILE_DIRECTORY_INFO *pFindData =<br />
			(FILE_DIRECTORY_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
		cifsFile->srch_inf.resume_key = pFindData->FileIndex;<br />
	} else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {<br />
		FILE_FULL_DIRECTORY_INFO *pFindData =<br />
			(FILE_FULL_DIRECTORY_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
		cifsFile->srch_inf.resume_key = pFindData->FileIndex;<br />
	} else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {<br />
		SEARCH_ID_FULL_DIR_INFO *pFindData =<br />
			(SEARCH_ID_FULL_DIR_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
		cifsFile->srch_inf.resume_key = pFindData->FileIndex;<br />
	} else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {<br />
		FILE_BOTH_DIRECTORY_INFO *pFindData =<br />
			(FILE_BOTH_DIRECTORY_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
		cifsFile->srch_inf.resume_key = pFindData->FileIndex;<br />
	} else if (level == SMB_FIND_FILE_INFO_STANDARD) {<br />
		FIND_FILE_STANDARD_INFO *pFindData =<br />
			(FIND_FILE_STANDARD_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		/* one byte length, no name conversion */<br />
		len = (unsigned int)pFindData->FileNameLength;<br />
		cifsFile->srch_inf.resume_key = pFindData->ResumeKey;<br />
	} else {<br />
		cFYI(1, (&raquo;Unknown findfirst level %d&raquo;, level));<br />
		return -EINVAL;<br />
	}<br />
	cifsFile->srch_inf.resume_name_len = len;<br />
	cifsFile->srch_inf.presume_name = filename;<br />
	return rc;<br />
}</p>
<p>/* find the corresponding entry in the search */<br />
/* Note that the SMB server returns search entries for . and .. which<br />
   complicates logic here if we choose to parse for them and we do not<br />
   assume that they are located in the findfirst return buffer.*/<br />
/* We start counting in the buffer with entry 2 and increment for every<br />
   entry (do not increment for . or .. entry) */<br />
static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,<br />
	struct file *file, char **ppCurrentEntry, int *num_to_ret)<br />
{<br />
	int rc = 0;<br />
	int pos_in_buf = 0;<br />
	loff_t first_entry_in_buffer;<br />
	loff_t index_to_find = file->f_pos;<br />
	struct cifsFileInfo *cifsFile = file->private_data;<br />
	/* check if index in the buffer */</p>
<p>	if ((cifsFile == NULL) || (ppCurrentEntry == NULL) ||<br />
	   (num_to_ret == NULL))<br />
		return -ENOENT;</p>
<p>	*ppCurrentEntry = NULL;<br />
	first_entry_in_buffer =<br />
		cifsFile->srch_inf.index_of_last_entry -<br />
			cifsFile->srch_inf.entries_in_buffer;</p>
<p>	/* if first entry in buf is zero then is first buffer<br />
	in search response data which means it is likely . and ..<br />
	will be in this buffer, although some servers do not return<br />
	. and .. for the root of a drive and for those we need<br />
	to start two entries earlier */</p>
<p>	dump_cifs_file_struct(file, &laquo;In fce &laquo;);<br />
	if (((index_to_find < cifsFile->srch_inf.index_of_last_entry) &#038;&#038;<br />
	     is_dir_changed(file)) ||<br />
	   (index_to_find < first_entry_in_buffer)) {<br />
		/* close and restart search */<br />
		cFYI(1, ("search backing up - close and restart search"));<br />
		write_lock(&#038;GlobalSMBSeslock);<br />
		if (!cifsFile->srch_inf.endOfSearch &#038;&#038;<br />
		    !cifsFile->invalidHandle) {<br />
			cifsFile->invalidHandle = true;<br />
			write_unlock(&#038;GlobalSMBSeslock);<br />
			CIFSFindClose(xid, pTcon, cifsFile->netfid);<br />
		} else<br />
			write_unlock(&#038;GlobalSMBSeslock);<br />
		if (cifsFile->srch_inf.ntwrk_buf_start) {<br />
			cFYI(1, (&raquo;freeing SMB ff cache buf on search rewind&raquo;));<br />
			if (cifsFile->srch_inf.smallBuf)<br />
				cifs_small_buf_release(cifsFile->srch_inf.<br />
						ntwrk_buf_start);<br />
			else<br />
				cifs_buf_release(cifsFile->srch_inf.<br />
						ntwrk_buf_start);<br />
			cifsFile->srch_inf.ntwrk_buf_start = NULL;<br />
		}<br />
		rc = initiate_cifs_search(xid, file);<br />
		if (rc) {<br />
			cFYI(1, (&raquo;error %d reinitiating a search on rewind&raquo;,<br />
				 rc));<br />
			return rc;<br />
		}<br />
		cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);<br />
	}</p>
<p>	while ((index_to_find >= cifsFile->srch_inf.index_of_last_entry) &#038;&#038;<br />
	      (rc == 0) &#038;&#038; !cifsFile->srch_inf.endOfSearch) {<br />
		cFYI(1, (&raquo;calling findnext2&#8243;));<br />
		rc = CIFSFindNext(xid, pTcon, cifsFile->netfid,<br />
				  &#038;cifsFile->srch_inf);<br />
		cifs_save_resume_key(cifsFile->srch_inf.last_entry, cifsFile);<br />
		if (rc)<br />
			return -ENOENT;<br />
	}<br />
	if (index_to_find < cifsFile->srch_inf.index_of_last_entry) {<br />
		/* we found the buffer that contains the entry */<br />
		/* scan and find it */<br />
		int i;<br />
		char *current_entry;<br />
		char *end_of_smb = cifsFile->srch_inf.ntwrk_buf_start +<br />
			smbCalcSize((struct smb_hdr *)<br />
				cifsFile->srch_inf.ntwrk_buf_start);</p>
<p>		current_entry = cifsFile->srch_inf.srch_entries_start;<br />
		first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry<br />
					- cifsFile->srch_inf.entries_in_buffer;<br />
		pos_in_buf = index_to_find &#8211; first_entry_in_buffer;<br />
		cFYI(1, (&raquo;found entry &#8211; pos_in_buf %d&raquo;, pos_in_buf));</p>
<p>		for (i = 0; (i < (pos_in_buf)) &#038;&#038; (current_entry != NULL); i++) {<br />
			/* go entry by entry figuring out which is first */<br />
			current_entry = nxt_dir_entry(current_entry, end_of_smb,<br />
						cifsFile->srch_inf.info_level);<br />
		}<br />
		if ((current_entry == NULL) &#038;&#038; (i < pos_in_buf)) {<br />
			/* BB fixme - check if we should flag this error */<br />
			cERROR(1, ("reached end of buf searching for pos in buf"<br />
			  " %d index to find %lld rc %d",<br />
			  pos_in_buf, index_to_find, rc));<br />
		}<br />
		rc = 0;<br />
		*ppCurrentEntry = current_entry;<br />
	} else {<br />
		cFYI(1, ("index not in buffer - could not findnext into it"));<br />
		return 0;<br />
	}</p>
<p>	if (pos_in_buf >= cifsFile->srch_inf.entries_in_buffer) {<br />
		cFYI(1, (&raquo;can not return entries pos_in_buf beyond last&raquo;));<br />
		*num_to_ret = 0;<br />
	} else<br />
		*num_to_ret = cifsFile->srch_inf.entries_in_buffer &#8211; pos_in_buf;</p>
<p>	return rc;<br />
}</p>
<p>/* inode num, inode type and filename returned */<br />
static int cifs_get_name_from_search_buf(struct qstr *pqst,<br />
	char *current_entry, __u16 level, unsigned int unicode,<br />
	struct cifs_sb_info *cifs_sb, unsigned int max_len, __u64 *pinum)<br />
{<br />
	int rc = 0;<br />
	unsigned int len = 0;<br />
	char *filename;<br />
	struct nls_table *nlt = cifs_sb->local_nls;</p>
<p>	*pinum = 0;</p>
<p>	if (level == SMB_FIND_FILE_UNIX) {<br />
		FILE_UNIX_INFO *pFindData = (FILE_UNIX_INFO *)current_entry;</p>
<p>		filename = &#038;pFindData->FileName[0];<br />
		if (unicode) {<br />
			len = cifs_unicode_bytelen(filename);<br />
		} else {<br />
			/* BB should we make this strnlen of PATH_MAX? */<br />
			len = strnlen(filename, PATH_MAX);<br />
		}</p>
<p>		*pinum = le64_to_cpu(pFindData->basic.UniqueId);<br />
	} else if (level == SMB_FIND_FILE_DIRECTORY_INFO) {<br />
		FILE_DIRECTORY_INFO *pFindData =<br />
			(FILE_DIRECTORY_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
	} else if (level == SMB_FIND_FILE_FULL_DIRECTORY_INFO) {<br />
		FILE_FULL_DIRECTORY_INFO *pFindData =<br />
			(FILE_FULL_DIRECTORY_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
	} else if (level == SMB_FIND_FILE_ID_FULL_DIR_INFO) {<br />
		SEARCH_ID_FULL_DIR_INFO *pFindData =<br />
			(SEARCH_ID_FULL_DIR_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
		*pinum = le64_to_cpu(pFindData->UniqueId);<br />
	} else if (level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) {<br />
		FILE_BOTH_DIRECTORY_INFO *pFindData =<br />
			(FILE_BOTH_DIRECTORY_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		len = le32_to_cpu(pFindData->FileNameLength);<br />
	} else if (level == SMB_FIND_FILE_INFO_STANDARD) {<br />
		FIND_FILE_STANDARD_INFO *pFindData =<br />
			(FIND_FILE_STANDARD_INFO *)current_entry;<br />
		filename = &#038;pFindData->FileName[0];<br />
		/* one byte length, no name conversion */<br />
		len = (unsigned int)pFindData->FileNameLength;<br />
	} else {<br />
		cFYI(1, (&raquo;Unknown findfirst level %d&raquo;, level));<br />
		return -EINVAL;<br />
	}</p>
<p>	if (len > max_len) {<br />
		cERROR(1, (&raquo;bad search response length %d past smb end&raquo;, len));<br />
		return -EINVAL;<br />
	}</p>
<p>	if (unicode) {<br />
		pqst->len = cifs_from_ucs2((char *) pqst->name,<br />
					   (__le16 *) filename,<br />
					   UNICODE_NAME_MAX,<br />
					   min(len, max_len), nlt,<br />
					   cifs_sb->mnt_cifs_flags &#038;<br />
						CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	} else {<br />
		pqst->name = filename;<br />
		pqst->len = len;<br />
	}<br />
	pqst->hash = full_name_hash(pqst->name, pqst->len);<br />
/*	cFYI(1, (&raquo;filldir on %s&raquo;,pqst->name));  */<br />
	return rc;<br />
}</p>
<p>static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,<br />
			void *direntry, char *scratch_buf, unsigned int max_len)<br />
{<br />
	int rc = 0;<br />
	struct qstr qstring;<br />
	struct cifsFileInfo *pCifsF;<br />
	u64    inum;<br />
	ino_t  ino;<br />
	struct super_block *sb;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct dentry *tmp_dentry;<br />
	struct cifs_fattr fattr;</p>
<p>	/* get filename and len into qstring */<br />
	/* get dentry */<br />
	/* decide whether to create and populate ionde */<br />
	if ((direntry == NULL) || (file == NULL))<br />
		return -EINVAL;</p>
<p>	pCifsF = file->private_data;</p>
<p>	if ((scratch_buf == NULL) || (pfindEntry == NULL) || (pCifsF == NULL))<br />
		return -ENOENT;</p>
<p>	rc = cifs_entry_is_dot(pfindEntry, pCifsF);<br />
	/* skip . and .. since we added them first */<br />
	if (rc != 0)<br />
		return 0;</p>
<p>	sb = file->f_path.dentry->d_sb;<br />
	cifs_sb = CIFS_SB(sb);</p>
<p>	qstring.name = scratch_buf;<br />
	rc = cifs_get_name_from_search_buf(&#038;qstring, pfindEntry,<br />
			pCifsF->srch_inf.info_level,<br />
			pCifsF->srch_inf.unicode, cifs_sb,<br />
			max_len, &#038;inum /* returned */);</p>
<p>	if (rc)<br />
		return rc;</p>
<p>	if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_UNIX)<br />
		cifs_unix_basic_to_fattr(&#038;fattr,<br />
				 &#038;((FILE_UNIX_INFO *) pfindEntry)->basic,<br />
				 cifs_sb);<br />
	else if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_INFO_STANDARD)<br />
		cifs_std_info_to_fattr(&#038;fattr, (FIND_FILE_STANDARD_INFO *)<br />
					pfindEntry, cifs_sb);<br />
	else<br />
		cifs_dir_info_to_fattr(&#038;fattr, (FILE_DIRECTORY_INFO *)<br />
					pfindEntry, cifs_sb);</p>
<p>	if (inum &#038;&#038; (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_SERVER_INUM)) {<br />
		fattr.cf_uniqueid = inum;<br />
	} else {<br />
		fattr.cf_uniqueid = iunique(sb, ROOT_I);<br />
		cifs_autodisable_serverino(cifs_sb);<br />
	}</p>
<p>	ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);<br />
	tmp_dentry = cifs_readdir_lookup(file->f_dentry, &#038;qstring, &#038;fattr);</p>
<p>	rc = filldir(direntry, qstring.name, qstring.len, file->f_pos,<br />
		     ino, fattr.cf_dtype);</p>
<p>	/*<br />
	 * we can not return filldir errors to the caller since they are<br />
	 * &laquo;normal&raquo; when the stat blocksize is too small &#8211; we return remapped<br />
	 * error instead<br />
	 *<br />
	 * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above<br />
	 * case already. Why should we be clobbering other errors from it?<br />
	 */<br />
	if (rc) {<br />
		cFYI(1, (&raquo;filldir rc = %d&raquo;, rc));<br />
		rc = -EOVERFLOW;<br />
	}<br />
	dput(tmp_dentry);<br />
	return rc;<br />
}</p>
<p>int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)<br />
{<br />
	int rc = 0;<br />
	int xid, i;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	struct cifsFileInfo *cifsFile = NULL;<br />
	char *current_entry;<br />
	int num_to_fill = 0;<br />
	char *tmp_buf = NULL;<br />
	char *end_of_smb;<br />
	unsigned int max_len;</p>
<p>	xid = GetXid();</p>
<p>	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);<br />
	pTcon = cifs_sb->tcon;<br />
	if (pTcon == NULL)<br />
		return -EINVAL;</p>
<p>	switch ((int) file->f_pos) {<br />
	case 0:<br />
		if (filldir(direntry, &laquo;.&raquo;, 1, file->f_pos,<br />
		     file->f_path.dentry->d_inode->i_ino, DT_DIR) < 0) {<br />
			cERROR(1, ("Filldir for current dir failed"));<br />
			rc = -ENOMEM;<br />
			break;<br />
		}<br />
		file->f_pos++;<br />
	case 1:<br />
		if (filldir(direntry, &laquo;..&raquo;, 2, file->f_pos,<br />
		     file->f_path.dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {<br />
			cERROR(1, ("Filldir for parent dir failed"));<br />
			rc = -ENOMEM;<br />
			break;<br />
		}<br />
		file->f_pos++;<br />
	default:<br />
		/* 1) If search is active,<br />
			is in current search buffer?<br />
			if it before then restart search<br />
			if after then keep searching till find it */</p>
<p>		if (file->private_data == NULL) {<br />
			rc = initiate_cifs_search(xid, file);<br />
			cFYI(1, (&raquo;initiate cifs search rc %d&raquo;, rc));<br />
			if (rc) {<br />
				FreeXid(xid);<br />
				return rc;<br />
			}<br />
		}<br />
		if (file->private_data == NULL) {<br />
			rc = -EINVAL;<br />
			FreeXid(xid);<br />
			return rc;<br />
		}<br />
		cifsFile = file->private_data;<br />
		if (cifsFile->srch_inf.endOfSearch) {<br />
			if (cifsFile->srch_inf.emptyDir) {<br />
				cFYI(1, (&raquo;End of search, empty dir&raquo;));<br />
				rc = 0;<br />
				break;<br />
			}<br />
		} /* else {<br />
			cifsFile->invalidHandle = true;<br />
			CIFSFindClose(xid, pTcon, cifsFile->netfid);<br />
		} */</p>
<p>		rc = find_cifs_entry(xid, pTcon, file,<br />
				&#038;current_entry, &#038;num_to_fill);<br />
		if (rc) {<br />
			cFYI(1, (&raquo;fce error %d&raquo;, rc));<br />
			goto rddir2_exit;<br />
		} else if (current_entry != NULL) {<br />
			cFYI(1, (&raquo;entry %lld found&raquo;, file->f_pos));<br />
		} else {<br />
			cFYI(1, (&raquo;could not find entry&raquo;));<br />
			goto rddir2_exit;<br />
		}<br />
		cFYI(1, (&raquo;loop through %d times filling dir for net buf %p&raquo;,<br />
			num_to_fill, cifsFile->srch_inf.ntwrk_buf_start));<br />
		max_len = smbCalcSize((struct smb_hdr *)<br />
				cifsFile->srch_inf.ntwrk_buf_start);<br />
		end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + max_len;</p>
<p>		tmp_buf = kmalloc(UNICODE_NAME_MAX, GFP_KERNEL);<br />
		for (i = 0; (i < num_to_fill) &#038;&#038; (rc == 0); i++) {<br />
			if (current_entry == NULL) {<br />
				/* evaluate whether this case is an error */<br />
				cERROR(1, ("past SMB end,  num to fill %d i %d",<br />
					  num_to_fill, i));<br />
				break;<br />
			}<br />
			/* if buggy server returns . and .. late do<br />
			we want to check for that here? */<br />
			rc = cifs_filldir(current_entry, file,<br />
					filldir, direntry, tmp_buf, max_len);<br />
			if (rc == -EOVERFLOW) {<br />
				rc = 0;<br />
				break;<br />
			}</p>
<p>			file->f_pos++;<br />
			if (file->f_pos ==<br />
				cifsFile->srch_inf.index_of_last_entry) {<br />
				cFYI(1, (&raquo;last entry in buf at pos %lld %s&raquo;,<br />
					file->f_pos, tmp_buf));<br />
				cifs_save_resume_key(current_entry, cifsFile);<br />
				break;<br />
			} else<br />
				current_entry =<br />
					nxt_dir_entry(current_entry, end_of_smb,<br />
						cifsFile->srch_inf.info_level);<br />
		}<br />
		kfree(tmp_buf);<br />
		break;<br />
	} /* end switch */</p>
<p>rddir2_exit:<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/readdir-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ntlmssp.h</title>
		<link>http://lynyrd.ru/ntlmssp-h</link>
		<comments>http://lynyrd.ru/ntlmssp-h#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:30:45 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/ntlmssp-h</guid>
		<description><![CDATA[/*
 *   fs/cifs/ntlmssp.h
 *
 *   Copyright (c) International Business Machines  Corp., 2002,2007
 *   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
 ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/ntlmssp.h<span id="more-958"></span><br />
 *<br />
 *   Copyright (c) International Business Machines  Corp., 2002,2007<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>#define NTLMSSP_SIGNATURE &laquo;NTLMSSP&raquo;<br />
/* Message Types */<br />
#define NtLmNegotiate     cpu_to_le32(1)<br />
#define NtLmChallenge     cpu_to_le32(2)<br />
#define NtLmAuthenticate  cpu_to_le32(3)<br />
#define UnknownMessage    cpu_to_le32(8)</p>
<p>/* Negotiate Flags */<br />
#define NTLMSSP_NEGOTIATE_UNICODE         0&#215;01 /* Text strings are unicode */<br />
#define NTLMSSP_NEGOTIATE_OEM             0&#215;02 /* Text strings are in OEM */<br />
#define NTLMSSP_REQUEST_TARGET            0&#215;04 /* Srv returns its auth realm */<br />
/* define reserved9                       0&#215;08 */<br />
#define NTLMSSP_NEGOTIATE_SIGN          0&#215;0010 /* Request signing capability */<br />
#define NTLMSSP_NEGOTIATE_SEAL          0&#215;0020 /* Request confidentiality */<br />
#define NTLMSSP_NEGOTIATE_DGRAM         0&#215;0040<br />
#define NTLMSSP_NEGOTIATE_LM_KEY        0&#215;0080 /* Use LM session key */<br />
/* defined reserved 8                   0&#215;0100 */<br />
#define NTLMSSP_NEGOTIATE_NTLM          0&#215;0200 /* NTLM authentication */<br />
#define NTLMSSP_NEGOTIATE_NT_ONLY       0&#215;0400 /* Lanman not allowed */<br />
#define NTLMSSP_ANONYMOUS               0&#215;0800<br />
#define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0&#215;1000 /* reserved6 */<br />
#define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0&#215;2000<br />
#define NTLMSSP_NEGOTIATE_LOCAL_CALL    0&#215;4000 /* client/server same machine */<br />
#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN   0&#215;8000 /* Sign. All security levels  */<br />
#define NTLMSSP_TARGET_TYPE_DOMAIN     0&#215;10000<br />
#define NTLMSSP_TARGET_TYPE_SERVER     0&#215;20000<br />
#define NTLMSSP_TARGET_TYPE_SHARE      0&#215;40000<br />
#define NTLMSSP_NEGOTIATE_EXTENDED_SEC 0&#215;80000 /* NB:not related to NTLMv2 pwd*/<br />
/* #define NTLMSSP_REQUEST_INIT_RESP     0&#215;100000 */<br />
#define NTLMSSP_NEGOTIATE_IDENTIFY    0&#215;100000<br />
#define NTLMSSP_REQUEST_ACCEPT_RESP   0&#215;200000 /* reserved5 */<br />
#define NTLMSSP_REQUEST_NON_NT_KEY    0&#215;400000<br />
#define NTLMSSP_NEGOTIATE_TARGET_INFO 0&#215;800000<br />
/* #define reserved4                 0&#215;1000000 */<br />
#define NTLMSSP_NEGOTIATE_VERSION    0&#215;2000000 /* we do not set */<br />
/* #define reserved3                 0&#215;4000000 */<br />
/* #define reserved2                 0&#215;8000000 */<br />
/* #define reserved1                0&#215;10000000 */<br />
#define NTLMSSP_NEGOTIATE_128       0&#215;20000000<br />
#define NTLMSSP_NEGOTIATE_KEY_XCH   0&#215;40000000<br />
#define NTLMSSP_NEGOTIATE_56        0&#215;80000000</p>
<p>/* Although typedefs are not commonly used for structure definitions */<br />
/* in the Linux kernel, in this particular case they are useful      */<br />
/* to more closely match the standards document for NTLMSSP from     */<br />
/* OpenGroup and to make the code more closely match the standard in */<br />
/* appearance */</p>
<p>typedef struct _SECURITY_BUFFER {<br />
	__le16 Length;<br />
	__le16 MaximumLength;<br />
	__le32 BufferOffset;	/* offset to buffer */<br />
} __attribute__((packed)) SECURITY_BUFFER;</p>
<p>typedef struct _NEGOTIATE_MESSAGE {<br />
	__u8 Signature[sizeof(NTLMSSP_SIGNATURE)];<br />
	__le32 MessageType;     /* NtLmNegotiate = 1 */<br />
	__le32 NegotiateFlags;<br />
	SECURITY_BUFFER DomainName;	/* RFC 1001 style and ASCII */<br />
	SECURITY_BUFFER WorkstationName;	/* RFC 1001 and ASCII */<br />
	/* SECURITY_BUFFER for version info not present since we<br />
	   do not set the version is present flag */<br />
	char DomainString[0];<br />
	/* followed by WorkstationString */<br />
} __attribute__((packed)) NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;</p>
<p>typedef struct _CHALLENGE_MESSAGE {<br />
	__u8 Signature[sizeof(NTLMSSP_SIGNATURE)];<br />
	__le32 MessageType;   /* NtLmChallenge = 2 */<br />
	SECURITY_BUFFER TargetName;<br />
	__le32 NegotiateFlags;<br />
	__u8 Challenge[CIFS_CRYPTO_KEY_SIZE];<br />
	__u8 Reserved[8];<br />
	SECURITY_BUFFER TargetInfoArray;<br />
	/* SECURITY_BUFFER for version info not present since we<br />
	   do not set the version is present flag */<br />
} __attribute__((packed)) CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;</p>
<p>typedef struct _AUTHENTICATE_MESSAGE {<br />
	__u8 Signature[sizeof(NTLMSSP_SIGNATURE)];<br />
	__le32 MessageType;  /* NtLmsAuthenticate = 3 */<br />
	SECURITY_BUFFER LmChallengeResponse;<br />
	SECURITY_BUFFER NtChallengeResponse;<br />
	SECURITY_BUFFER DomainName;<br />
	SECURITY_BUFFER UserName;<br />
	SECURITY_BUFFER WorkstationName;<br />
	SECURITY_BUFFER SessionKey;<br />
	__le32 NegotiateFlags;<br />
	/* SECURITY_BUFFER for version info not present since we<br />
	   do not set the version is present flag */<br />
	char UserString[0];<br />
} __attribute__((packed)) AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/ntlmssp-h/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>nterr.h</title>
		<link>http://lynyrd.ru/nterr-h</link>
		<comments>http://lynyrd.ru/nterr-h#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:30:28 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/nterr-h</guid>
		<description><![CDATA[/*
   Unix SMB/Netbios implementation.
   Version 1.9.
   NT error code constants
   Copyright (C) Andrew Tridgell              1992-2000
   Copyright (C) John H Terpstra             ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
   Unix SMB/Netbios implementation.<span id="more-957"></span><br />
   Version 1.9.<br />
   NT error code constants<br />
   Copyright (C) Andrew Tridgell              1992-2000<br />
   Copyright (C) John H Terpstra              1996-2000<br />
   Copyright (C) Luke Kenneth Casson Leighton 1996-2000<br />
   Copyright (C) Paul Ashton                  1998-2000</p>
<p>   This program is free software; you can redistribute it and/or modify<br />
   it under the terms of the GNU General Public License as published by<br />
   the Free Software Foundation; either version 2 of the License, or<br />
   (at your option) any later version.</p>
<p>   This program is distributed in the hope that it will be useful,<br />
   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
   GNU General Public License for more details.</p>
<p>   You should have received a copy of the GNU General Public License<br />
   along with this program; if not, write to the Free Software<br />
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br />
*/</p>
<p>#ifndef _NTERR_H<br />
#define _NTERR_H</p>
<p>struct nt_err_code_struct {<br />
	char *nt_errstr;<br />
	__u32 nt_errcode;<br />
};</p>
<p>extern const struct nt_err_code_struct nt_errs[];</p>
<p>/* Win32 Status codes. */<br />
#define STATUS_MORE_ENTRIES               0&#215;0105<br />
#define ERROR_INVALID_PARAMETER		  0&#215;0057<br />
#define ERROR_INSUFFICIENT_BUFFER	  0&#215;007a<br />
#define STATUS_1804	                  0&#215;070c<br />
#define STATUS_NOTIFY_ENUM_DIR            0&#215;010c</p>
<p>/* Win32 Error codes extracted using a loop in smbclient then printing a<br />
   netmon sniff to a file. */</p>
<p>#define NT_STATUS_OK 0&#215;0000<br />
#define STATUS_SOME_UNMAPPED       0&#215;0107<br />
#define STATUS_BUFFER_OVERFLOW     0&#215;80000005<br />
#define NT_STATUS_NO_MORE_ENTRIES  0&#215;8000001a<br />
#define NT_STATUS_MEDIA_CHANGED    0&#215;8000001c<br />
#define NT_STATUS_END_OF_MEDIA     0&#215;8000001e<br />
#define NT_STATUS_MEDIA_CHECK      0&#215;80000020<br />
#define NT_STATUS_NO_DATA_DETECTED 0&#215;8000001c<br />
#define NT_STATUS_STOPPED_ON_SYMLINK 0&#215;8000002d<br />
#define NT_STATUS_DEVICE_REQUIRES_CLEANING 0&#215;80000288<br />
#define NT_STATUS_DEVICE_DOOR_OPEN 0&#215;80000288<br />
#define NT_STATUS_UNSUCCESSFUL 0xC0000000 | 0&#215;0001<br />
#define NT_STATUS_NOT_IMPLEMENTED 0xC0000000 | 0&#215;0002<br />
#define NT_STATUS_INVALID_INFO_CLASS 0xC0000000 | 0&#215;0003<br />
#define NT_STATUS_INFO_LENGTH_MISMATCH 0xC0000000 | 0&#215;0004<br />
#define NT_STATUS_ACCESS_VIOLATION 0xC0000000 | 0&#215;0005<br />
#define NT_STATUS_IN_PAGE_ERROR 0xC0000000 | 0&#215;0006<br />
#define NT_STATUS_PAGEFILE_QUOTA 0xC0000000 | 0&#215;0007<br />
#define NT_STATUS_INVALID_HANDLE 0xC0000000 | 0&#215;0008<br />
#define NT_STATUS_BAD_INITIAL_STACK 0xC0000000 | 0&#215;0009<br />
#define NT_STATUS_BAD_INITIAL_PC 0xC0000000 | 0&#215;000a<br />
#define NT_STATUS_INVALID_CID 0xC0000000 | 0&#215;000b<br />
#define NT_STATUS_TIMER_NOT_CANCELED 0xC0000000 | 0&#215;000c<br />
#define NT_STATUS_INVALID_PARAMETER 0xC0000000 | 0&#215;000d<br />
#define NT_STATUS_NO_SUCH_DEVICE 0xC0000000 | 0&#215;000e<br />
#define NT_STATUS_NO_SUCH_FILE 0xC0000000 | 0&#215;000f<br />
#define NT_STATUS_INVALID_DEVICE_REQUEST 0xC0000000 | 0&#215;0010<br />
#define NT_STATUS_END_OF_FILE 0xC0000000 | 0&#215;0011<br />
#define NT_STATUS_WRONG_VOLUME 0xC0000000 | 0&#215;0012<br />
#define NT_STATUS_NO_MEDIA_IN_DEVICE 0xC0000000 | 0&#215;0013<br />
#define NT_STATUS_UNRECOGNIZED_MEDIA 0xC0000000 | 0&#215;0014<br />
#define NT_STATUS_NONEXISTENT_SECTOR 0xC0000000 | 0&#215;0015<br />
#define NT_STATUS_MORE_PROCESSING_REQUIRED 0xC0000000 | 0&#215;0016<br />
#define NT_STATUS_NO_MEMORY 0xC0000000 | 0&#215;0017<br />
#define NT_STATUS_CONFLICTING_ADDRESSES 0xC0000000 | 0&#215;0018<br />
#define NT_STATUS_NOT_MAPPED_VIEW 0xC0000000 | 0&#215;0019<br />
#define NT_STATUS_UNABLE_TO_FREE_VM 0&#215;80000000 | 0&#215;001a<br />
#define NT_STATUS_UNABLE_TO_DELETE_SECTION 0xC0000000 | 0&#215;001b<br />
#define NT_STATUS_INVALID_SYSTEM_SERVICE 0xC0000000 | 0&#215;001c<br />
#define NT_STATUS_ILLEGAL_INSTRUCTION 0xC0000000 | 0&#215;001d<br />
#define NT_STATUS_INVALID_LOCK_SEQUENCE 0xC0000000 | 0&#215;001e<br />
#define NT_STATUS_INVALID_VIEW_SIZE 0xC0000000 | 0&#215;001f<br />
#define NT_STATUS_INVALID_FILE_FOR_SECTION 0xC0000000 | 0&#215;0020<br />
#define NT_STATUS_ALREADY_COMMITTED 0xC0000000 | 0&#215;0021<br />
#define NT_STATUS_ACCESS_DENIED 0xC0000000 | 0&#215;0022<br />
#define NT_STATUS_BUFFER_TOO_SMALL 0xC0000000 | 0&#215;0023<br />
#define NT_STATUS_OBJECT_TYPE_MISMATCH 0xC0000000 | 0&#215;0024<br />
#define NT_STATUS_NONCONTINUABLE_EXCEPTION 0xC0000000 | 0&#215;0025<br />
#define NT_STATUS_INVALID_DISPOSITION 0xC0000000 | 0&#215;0026<br />
#define NT_STATUS_UNWIND 0xC0000000 | 0&#215;0027<br />
#define NT_STATUS_BAD_STACK 0xC0000000 | 0&#215;0028<br />
#define NT_STATUS_INVALID_UNWIND_TARGET 0xC0000000 | 0&#215;0029<br />
#define NT_STATUS_NOT_LOCKED 0xC0000000 | 0&#215;002a<br />
#define NT_STATUS_PARITY_ERROR 0xC0000000 | 0&#215;002b<br />
#define NT_STATUS_UNABLE_TO_DECOMMIT_VM 0xC0000000 | 0&#215;002c<br />
#define NT_STATUS_NOT_COMMITTED 0xC0000000 | 0&#215;002d<br />
#define NT_STATUS_INVALID_PORT_ATTRIBUTES 0xC0000000 | 0&#215;002e<br />
#define NT_STATUS_PORT_MESSAGE_TOO_LONG 0xC0000000 | 0&#215;002f<br />
#define NT_STATUS_INVALID_PARAMETER_MIX 0xC0000000 | 0&#215;0030<br />
#define NT_STATUS_INVALID_QUOTA_LOWER 0xC0000000 | 0&#215;0031<br />
#define NT_STATUS_DISK_CORRUPT_ERROR 0xC0000000 | 0&#215;0032<br />
#define NT_STATUS_OBJECT_NAME_INVALID 0xC0000000 | 0&#215;0033<br />
#define NT_STATUS_OBJECT_NAME_NOT_FOUND 0xC0000000 | 0&#215;0034<br />
#define NT_STATUS_OBJECT_NAME_COLLISION 0xC0000000 | 0&#215;0035<br />
#define NT_STATUS_HANDLE_NOT_WAITABLE 0xC0000000 | 0&#215;0036<br />
#define NT_STATUS_PORT_DISCONNECTED 0xC0000000 | 0&#215;0037<br />
#define NT_STATUS_DEVICE_ALREADY_ATTACHED 0xC0000000 | 0&#215;0038<br />
#define NT_STATUS_OBJECT_PATH_INVALID 0xC0000000 | 0&#215;0039<br />
#define NT_STATUS_OBJECT_PATH_NOT_FOUND 0xC0000000 | 0&#215;003a<br />
#define NT_STATUS_OBJECT_PATH_SYNTAX_BAD 0xC0000000 | 0&#215;003b<br />
#define NT_STATUS_DATA_OVERRUN 0xC0000000 | 0&#215;003c<br />
#define NT_STATUS_DATA_LATE_ERROR 0xC0000000 | 0&#215;003d<br />
#define NT_STATUS_DATA_ERROR 0xC0000000 | 0&#215;003e<br />
#define NT_STATUS_CRC_ERROR 0xC0000000 | 0&#215;003f<br />
#define NT_STATUS_SECTION_TOO_BIG 0xC0000000 | 0&#215;0040<br />
#define NT_STATUS_PORT_CONNECTION_REFUSED 0xC0000000 | 0&#215;0041<br />
#define NT_STATUS_INVALID_PORT_HANDLE 0xC0000000 | 0&#215;0042<br />
#define NT_STATUS_SHARING_VIOLATION 0xC0000000 | 0&#215;0043<br />
#define NT_STATUS_QUOTA_EXCEEDED 0xC0000000 | 0&#215;0044<br />
#define NT_STATUS_INVALID_PAGE_PROTECTION 0xC0000000 | 0&#215;0045<br />
#define NT_STATUS_MUTANT_NOT_OWNED 0xC0000000 | 0&#215;0046<br />
#define NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED 0xC0000000 | 0&#215;0047<br />
#define NT_STATUS_PORT_ALREADY_SET 0xC0000000 | 0&#215;0048<br />
#define NT_STATUS_SECTION_NOT_IMAGE 0xC0000000 | 0&#215;0049<br />
#define NT_STATUS_SUSPEND_COUNT_EXCEEDED 0xC0000000 | 0&#215;004a<br />
#define NT_STATUS_THREAD_IS_TERMINATING 0xC0000000 | 0&#215;004b<br />
#define NT_STATUS_BAD_WORKING_SET_LIMIT 0xC0000000 | 0&#215;004c<br />
#define NT_STATUS_INCOMPATIBLE_FILE_MAP 0xC0000000 | 0&#215;004d<br />
#define NT_STATUS_SECTION_PROTECTION 0xC0000000 | 0&#215;004e<br />
#define NT_STATUS_EAS_NOT_SUPPORTED 0xC0000000 | 0&#215;004f<br />
#define NT_STATUS_EA_TOO_LARGE 0xC0000000 | 0&#215;0050<br />
#define NT_STATUS_NONEXISTENT_EA_ENTRY 0xC0000000 | 0&#215;0051<br />
#define NT_STATUS_NO_EAS_ON_FILE 0xC0000000 | 0&#215;0052<br />
#define NT_STATUS_EA_CORRUPT_ERROR 0xC0000000 | 0&#215;0053<br />
#define NT_STATUS_FILE_LOCK_CONFLICT 0xC0000000 | 0&#215;0054<br />
#define NT_STATUS_LOCK_NOT_GRANTED 0xC0000000 | 0&#215;0055<br />
#define NT_STATUS_DELETE_PENDING 0xC0000000 | 0&#215;0056<br />
#define NT_STATUS_CTL_FILE_NOT_SUPPORTED 0xC0000000 | 0&#215;0057<br />
#define NT_STATUS_UNKNOWN_REVISION 0xC0000000 | 0&#215;0058<br />
#define NT_STATUS_REVISION_MISMATCH 0xC0000000 | 0&#215;0059<br />
#define NT_STATUS_INVALID_OWNER 0xC0000000 | 0&#215;005a<br />
#define NT_STATUS_INVALID_PRIMARY_GROUP 0xC0000000 | 0&#215;005b<br />
#define NT_STATUS_NO_IMPERSONATION_TOKEN 0xC0000000 | 0&#215;005c<br />
#define NT_STATUS_CANT_DISABLE_MANDATORY 0xC0000000 | 0&#215;005d<br />
#define NT_STATUS_NO_LOGON_SERVERS 0xC0000000 | 0&#215;005e<br />
#define NT_STATUS_NO_SUCH_LOGON_SESSION 0xC0000000 | 0&#215;005f<br />
#define NT_STATUS_NO_SUCH_PRIVILEGE 0xC0000000 | 0&#215;0060<br />
#define NT_STATUS_PRIVILEGE_NOT_HELD 0xC0000000 | 0&#215;0061<br />
#define NT_STATUS_INVALID_ACCOUNT_NAME 0xC0000000 | 0&#215;0062<br />
#define NT_STATUS_USER_EXISTS 0xC0000000 | 0&#215;0063<br />
#define NT_STATUS_NO_SUCH_USER 0xC0000000 | 0&#215;0064<br />
#define NT_STATUS_GROUP_EXISTS 0xC0000000 | 0&#215;0065<br />
#define NT_STATUS_NO_SUCH_GROUP 0xC0000000 | 0&#215;0066<br />
#define NT_STATUS_MEMBER_IN_GROUP 0xC0000000 | 0&#215;0067<br />
#define NT_STATUS_MEMBER_NOT_IN_GROUP 0xC0000000 | 0&#215;0068<br />
#define NT_STATUS_LAST_ADMIN 0xC0000000 | 0&#215;0069<br />
#define NT_STATUS_WRONG_PASSWORD 0xC0000000 | 0&#215;006a<br />
#define NT_STATUS_ILL_FORMED_PASSWORD 0xC0000000 | 0&#215;006b<br />
#define NT_STATUS_PASSWORD_RESTRICTION 0xC0000000 | 0&#215;006c<br />
#define NT_STATUS_LOGON_FAILURE 0xC0000000 | 0&#215;006d<br />
#define NT_STATUS_ACCOUNT_RESTRICTION 0xC0000000 | 0&#215;006e<br />
#define NT_STATUS_INVALID_LOGON_HOURS 0xC0000000 | 0&#215;006f<br />
#define NT_STATUS_INVALID_WORKSTATION 0xC0000000 | 0&#215;0070<br />
#define NT_STATUS_PASSWORD_EXPIRED 0xC0000000 | 0&#215;0071<br />
#define NT_STATUS_ACCOUNT_DISABLED 0xC0000000 | 0&#215;0072<br />
#define NT_STATUS_NONE_MAPPED 0xC0000000 | 0&#215;0073<br />
#define NT_STATUS_TOO_MANY_LUIDS_REQUESTED 0xC0000000 | 0&#215;0074<br />
#define NT_STATUS_LUIDS_EXHAUSTED 0xC0000000 | 0&#215;0075<br />
#define NT_STATUS_INVALID_SUB_AUTHORITY 0xC0000000 | 0&#215;0076<br />
#define NT_STATUS_INVALID_ACL 0xC0000000 | 0&#215;0077<br />
#define NT_STATUS_INVALID_SID 0xC0000000 | 0&#215;0078<br />
#define NT_STATUS_INVALID_SECURITY_DESCR 0xC0000000 | 0&#215;0079<br />
#define NT_STATUS_PROCEDURE_NOT_FOUND 0xC0000000 | 0&#215;007a<br />
#define NT_STATUS_INVALID_IMAGE_FORMAT 0xC0000000 | 0&#215;007b<br />
#define NT_STATUS_NO_TOKEN 0xC0000000 | 0&#215;007c<br />
#define NT_STATUS_BAD_INHERITANCE_ACL 0xC0000000 | 0&#215;007d<br />
#define NT_STATUS_RANGE_NOT_LOCKED 0xC0000000 | 0&#215;007e<br />
#define NT_STATUS_DISK_FULL 0xC0000000 | 0&#215;007f<br />
#define NT_STATUS_SERVER_DISABLED 0xC0000000 | 0&#215;0080<br />
#define NT_STATUS_SERVER_NOT_DISABLED 0xC0000000 | 0&#215;0081<br />
#define NT_STATUS_TOO_MANY_GUIDS_REQUESTED 0xC0000000 | 0&#215;0082<br />
#define NT_STATUS_GUIDS_EXHAUSTED 0xC0000000 | 0&#215;0083<br />
#define NT_STATUS_INVALID_ID_AUTHORITY 0xC0000000 | 0&#215;0084<br />
#define NT_STATUS_AGENTS_EXHAUSTED 0xC0000000 | 0&#215;0085<br />
#define NT_STATUS_INVALID_VOLUME_LABEL 0xC0000000 | 0&#215;0086<br />
#define NT_STATUS_SECTION_NOT_EXTENDED 0xC0000000 | 0&#215;0087<br />
#define NT_STATUS_NOT_MAPPED_DATA 0xC0000000 | 0&#215;0088<br />
#define NT_STATUS_RESOURCE_DATA_NOT_FOUND 0xC0000000 | 0&#215;0089<br />
#define NT_STATUS_RESOURCE_TYPE_NOT_FOUND 0xC0000000 | 0&#215;008a<br />
#define NT_STATUS_RESOURCE_NAME_NOT_FOUND 0xC0000000 | 0&#215;008b<br />
#define NT_STATUS_ARRAY_BOUNDS_EXCEEDED 0xC0000000 | 0&#215;008c<br />
#define NT_STATUS_FLOAT_DENORMAL_OPERAND 0xC0000000 | 0&#215;008d<br />
#define NT_STATUS_FLOAT_DIVIDE_BY_ZERO 0xC0000000 | 0&#215;008e<br />
#define NT_STATUS_FLOAT_INEXACT_RESULT 0xC0000000 | 0&#215;008f<br />
#define NT_STATUS_FLOAT_INVALID_OPERATION 0xC0000000 | 0&#215;0090<br />
#define NT_STATUS_FLOAT_OVERFLOW 0xC0000000 | 0&#215;0091<br />
#define NT_STATUS_FLOAT_STACK_CHECK 0xC0000000 | 0&#215;0092<br />
#define NT_STATUS_FLOAT_UNDERFLOW 0xC0000000 | 0&#215;0093<br />
#define NT_STATUS_INTEGER_DIVIDE_BY_ZERO 0xC0000000 | 0&#215;0094<br />
#define NT_STATUS_INTEGER_OVERFLOW 0xC0000000 | 0&#215;0095<br />
#define NT_STATUS_PRIVILEGED_INSTRUCTION 0xC0000000 | 0&#215;0096<br />
#define NT_STATUS_TOO_MANY_PAGING_FILES 0xC0000000 | 0&#215;0097<br />
#define NT_STATUS_FILE_INVALID 0xC0000000 | 0&#215;0098<br />
#define NT_STATUS_ALLOTTED_SPACE_EXCEEDED 0xC0000000 | 0&#215;0099<br />
#define NT_STATUS_INSUFFICIENT_RESOURCES 0xC0000000 | 0&#215;009a<br />
#define NT_STATUS_DFS_EXIT_PATH_FOUND 0xC0000000 | 0&#215;009b<br />
#define NT_STATUS_DEVICE_DATA_ERROR 0xC0000000 | 0&#215;009c<br />
#define NT_STATUS_DEVICE_NOT_CONNECTED 0xC0000000 | 0&#215;009d<br />
#define NT_STATUS_DEVICE_POWER_FAILURE 0xC0000000 | 0&#215;009e<br />
#define NT_STATUS_FREE_VM_NOT_AT_BASE 0xC0000000 | 0&#215;009f<br />
#define NT_STATUS_MEMORY_NOT_ALLOCATED 0xC0000000 | 0&#215;00a0<br />
#define NT_STATUS_WORKING_SET_QUOTA 0xC0000000 | 0&#215;00a1<br />
#define NT_STATUS_MEDIA_WRITE_PROTECTED 0xC0000000 | 0&#215;00a2<br />
#define NT_STATUS_DEVICE_NOT_READY 0xC0000000 | 0&#215;00a3<br />
#define NT_STATUS_INVALID_GROUP_ATTRIBUTES 0xC0000000 | 0&#215;00a4<br />
#define NT_STATUS_BAD_IMPERSONATION_LEVEL 0xC0000000 | 0&#215;00a5<br />
#define NT_STATUS_CANT_OPEN_ANONYMOUS 0xC0000000 | 0&#215;00a6<br />
#define NT_STATUS_BAD_VALIDATION_CLASS 0xC0000000 | 0&#215;00a7<br />
#define NT_STATUS_BAD_TOKEN_TYPE 0xC0000000 | 0&#215;00a8<br />
#define NT_STATUS_BAD_MASTER_BOOT_RECORD 0xC0000000 | 0&#215;00a9<br />
#define NT_STATUS_INSTRUCTION_MISALIGNMENT 0xC0000000 | 0&#215;00aa<br />
#define NT_STATUS_INSTANCE_NOT_AVAILABLE 0xC0000000 | 0&#215;00ab<br />
#define NT_STATUS_PIPE_NOT_AVAILABLE 0xC0000000 | 0&#215;00ac<br />
#define NT_STATUS_INVALID_PIPE_STATE 0xC0000000 | 0&#215;00ad<br />
#define NT_STATUS_PIPE_BUSY 0xC0000000 | 0&#215;00ae<br />
#define NT_STATUS_ILLEGAL_FUNCTION 0xC0000000 | 0&#215;00af<br />
#define NT_STATUS_PIPE_DISCONNECTED 0xC0000000 | 0&#215;00b0<br />
#define NT_STATUS_PIPE_CLOSING 0xC0000000 | 0&#215;00b1<br />
#define NT_STATUS_PIPE_CONNECTED 0xC0000000 | 0&#215;00b2<br />
#define NT_STATUS_PIPE_LISTENING 0xC0000000 | 0&#215;00b3<br />
#define NT_STATUS_INVALID_READ_MODE 0xC0000000 | 0&#215;00b4<br />
#define NT_STATUS_IO_TIMEOUT 0xC0000000 | 0&#215;00b5<br />
#define NT_STATUS_FILE_FORCED_CLOSED 0xC0000000 | 0&#215;00b6<br />
#define NT_STATUS_PROFILING_NOT_STARTED 0xC0000000 | 0&#215;00b7<br />
#define NT_STATUS_PROFILING_NOT_STOPPED 0xC0000000 | 0&#215;00b8<br />
#define NT_STATUS_COULD_NOT_INTERPRET 0xC0000000 | 0&#215;00b9<br />
#define NT_STATUS_FILE_IS_A_DIRECTORY 0xC0000000 | 0&#215;00ba<br />
#define NT_STATUS_NOT_SUPPORTED 0xC0000000 | 0&#215;00bb<br />
#define NT_STATUS_REMOTE_NOT_LISTENING 0xC0000000 | 0&#215;00bc<br />
#define NT_STATUS_DUPLICATE_NAME 0xC0000000 | 0&#215;00bd<br />
#define NT_STATUS_BAD_NETWORK_PATH 0xC0000000 | 0&#215;00be<br />
#define NT_STATUS_NETWORK_BUSY 0xC0000000 | 0&#215;00bf<br />
#define NT_STATUS_DEVICE_DOES_NOT_EXIST 0xC0000000 | 0&#215;00c0<br />
#define NT_STATUS_TOO_MANY_COMMANDS 0xC0000000 | 0&#215;00c1<br />
#define NT_STATUS_ADAPTER_HARDWARE_ERROR 0xC0000000 | 0&#215;00c2<br />
#define NT_STATUS_INVALID_NETWORK_RESPONSE 0xC0000000 | 0&#215;00c3<br />
#define NT_STATUS_UNEXPECTED_NETWORK_ERROR 0xC0000000 | 0&#215;00c4<br />
#define NT_STATUS_BAD_REMOTE_ADAPTER 0xC0000000 | 0&#215;00c5<br />
#define NT_STATUS_PRINT_QUEUE_FULL 0xC0000000 | 0&#215;00c6<br />
#define NT_STATUS_NO_SPOOL_SPACE 0xC0000000 | 0&#215;00c7<br />
#define NT_STATUS_PRINT_CANCELLED 0xC0000000 | 0&#215;00c8<br />
#define NT_STATUS_NETWORK_NAME_DELETED 0xC0000000 | 0&#215;00c9<br />
#define NT_STATUS_NETWORK_ACCESS_DENIED 0xC0000000 | 0&#215;00ca<br />
#define NT_STATUS_BAD_DEVICE_TYPE 0xC0000000 | 0&#215;00cb<br />
#define NT_STATUS_BAD_NETWORK_NAME 0xC0000000 | 0&#215;00cc<br />
#define NT_STATUS_TOO_MANY_NAMES 0xC0000000 | 0&#215;00cd<br />
#define NT_STATUS_TOO_MANY_SESSIONS 0xC0000000 | 0&#215;00ce<br />
#define NT_STATUS_SHARING_PAUSED 0xC0000000 | 0&#215;00cf<br />
#define NT_STATUS_REQUEST_NOT_ACCEPTED 0xC0000000 | 0&#215;00d0<br />
#define NT_STATUS_REDIRECTOR_PAUSED 0xC0000000 | 0&#215;00d1<br />
#define NT_STATUS_NET_WRITE_FAULT 0xC0000000 | 0&#215;00d2<br />
#define NT_STATUS_PROFILING_AT_LIMIT 0xC0000000 | 0&#215;00d3<br />
#define NT_STATUS_NOT_SAME_DEVICE 0xC0000000 | 0&#215;00d4<br />
#define NT_STATUS_FILE_RENAMED 0xC0000000 | 0&#215;00d5<br />
#define NT_STATUS_VIRTUAL_CIRCUIT_CLOSED 0xC0000000 | 0&#215;00d6<br />
#define NT_STATUS_NO_SECURITY_ON_OBJECT 0xC0000000 | 0&#215;00d7<br />
#define NT_STATUS_CANT_WAIT 0xC0000000 | 0&#215;00d8<br />
#define NT_STATUS_PIPE_EMPTY 0xC0000000 | 0&#215;00d9<br />
#define NT_STATUS_CANT_ACCESS_DOMAIN_INFO 0xC0000000 | 0&#215;00da<br />
#define NT_STATUS_CANT_TERMINATE_SELF 0xC0000000 | 0&#215;00db<br />
#define NT_STATUS_INVALID_SERVER_STATE 0xC0000000 | 0&#215;00dc<br />
#define NT_STATUS_INVALID_DOMAIN_STATE 0xC0000000 | 0&#215;00dd<br />
#define NT_STATUS_INVALID_DOMAIN_ROLE 0xC0000000 | 0&#215;00de<br />
#define NT_STATUS_NO_SUCH_DOMAIN 0xC0000000 | 0&#215;00df<br />
#define NT_STATUS_DOMAIN_EXISTS 0xC0000000 | 0&#215;00e0<br />
#define NT_STATUS_DOMAIN_LIMIT_EXCEEDED 0xC0000000 | 0&#215;00e1<br />
#define NT_STATUS_OPLOCK_NOT_GRANTED 0xC0000000 | 0&#215;00e2<br />
#define NT_STATUS_INVALID_OPLOCK_PROTOCOL 0xC0000000 | 0&#215;00e3<br />
#define NT_STATUS_INTERNAL_DB_CORRUPTION 0xC0000000 | 0&#215;00e4<br />
#define NT_STATUS_INTERNAL_ERROR 0xC0000000 | 0&#215;00e5<br />
#define NT_STATUS_GENERIC_NOT_MAPPED 0xC0000000 | 0&#215;00e6<br />
#define NT_STATUS_BAD_DESCRIPTOR_FORMAT 0xC0000000 | 0&#215;00e7<br />
#define NT_STATUS_INVALID_USER_BUFFER 0xC0000000 | 0&#215;00e8<br />
#define NT_STATUS_UNEXPECTED_IO_ERROR 0xC0000000 | 0&#215;00e9<br />
#define NT_STATUS_UNEXPECTED_MM_CREATE_ERR 0xC0000000 | 0&#215;00ea<br />
#define NT_STATUS_UNEXPECTED_MM_MAP_ERROR 0xC0000000 | 0&#215;00eb<br />
#define NT_STATUS_UNEXPECTED_MM_EXTEND_ERR 0xC0000000 | 0&#215;00ec<br />
#define NT_STATUS_NOT_LOGON_PROCESS 0xC0000000 | 0&#215;00ed<br />
#define NT_STATUS_LOGON_SESSION_EXISTS 0xC0000000 | 0&#215;00ee<br />
#define NT_STATUS_INVALID_PARAMETER_1 0xC0000000 | 0&#215;00ef<br />
#define NT_STATUS_INVALID_PARAMETER_2 0xC0000000 | 0&#215;00f0<br />
#define NT_STATUS_INVALID_PARAMETER_3 0xC0000000 | 0&#215;00f1<br />
#define NT_STATUS_INVALID_PARAMETER_4 0xC0000000 | 0&#215;00f2<br />
#define NT_STATUS_INVALID_PARAMETER_5 0xC0000000 | 0&#215;00f3<br />
#define NT_STATUS_INVALID_PARAMETER_6 0xC0000000 | 0&#215;00f4<br />
#define NT_STATUS_INVALID_PARAMETER_7 0xC0000000 | 0&#215;00f5<br />
#define NT_STATUS_INVALID_PARAMETER_8 0xC0000000 | 0&#215;00f6<br />
#define NT_STATUS_INVALID_PARAMETER_9 0xC0000000 | 0&#215;00f7<br />
#define NT_STATUS_INVALID_PARAMETER_10 0xC0000000 | 0&#215;00f8<br />
#define NT_STATUS_INVALID_PARAMETER_11 0xC0000000 | 0&#215;00f9<br />
#define NT_STATUS_INVALID_PARAMETER_12 0xC0000000 | 0&#215;00fa<br />
#define NT_STATUS_REDIRECTOR_NOT_STARTED 0xC0000000 | 0&#215;00fb<br />
#define NT_STATUS_REDIRECTOR_STARTED 0xC0000000 | 0&#215;00fc<br />
#define NT_STATUS_STACK_OVERFLOW 0xC0000000 | 0&#215;00fd<br />
#define NT_STATUS_NO_SUCH_PACKAGE 0xC0000000 | 0&#215;00fe<br />
#define NT_STATUS_BAD_FUNCTION_TABLE 0xC0000000 | 0&#215;00ff<br />
#define NT_STATUS_DIRECTORY_NOT_EMPTY 0xC0000000 | 0&#215;0101<br />
#define NT_STATUS_FILE_CORRUPT_ERROR 0xC0000000 | 0&#215;0102<br />
#define NT_STATUS_NOT_A_DIRECTORY 0xC0000000 | 0&#215;0103<br />
#define NT_STATUS_BAD_LOGON_SESSION_STATE 0xC0000000 | 0&#215;0104<br />
#define NT_STATUS_LOGON_SESSION_COLLISION 0xC0000000 | 0&#215;0105<br />
#define NT_STATUS_NAME_TOO_LONG 0xC0000000 | 0&#215;0106<br />
#define NT_STATUS_FILES_OPEN 0xC0000000 | 0&#215;0107<br />
#define NT_STATUS_CONNECTION_IN_USE 0xC0000000 | 0&#215;0108<br />
#define NT_STATUS_MESSAGE_NOT_FOUND 0xC0000000 | 0&#215;0109<br />
#define NT_STATUS_PROCESS_IS_TERMINATING 0xC0000000 | 0&#215;010a<br />
#define NT_STATUS_INVALID_LOGON_TYPE 0xC0000000 | 0&#215;010b<br />
#define NT_STATUS_NO_GUID_TRANSLATION 0xC0000000 | 0&#215;010c<br />
#define NT_STATUS_CANNOT_IMPERSONATE 0xC0000000 | 0&#215;010d<br />
#define NT_STATUS_IMAGE_ALREADY_LOADED 0xC0000000 | 0&#215;010e<br />
#define NT_STATUS_ABIOS_NOT_PRESENT 0xC0000000 | 0&#215;010f<br />
#define NT_STATUS_ABIOS_LID_NOT_EXIST 0xC0000000 | 0&#215;0110<br />
#define NT_STATUS_ABIOS_LID_ALREADY_OWNED 0xC0000000 | 0&#215;0111<br />
#define NT_STATUS_ABIOS_NOT_LID_OWNER 0xC0000000 | 0&#215;0112<br />
#define NT_STATUS_ABIOS_INVALID_COMMAND 0xC0000000 | 0&#215;0113<br />
#define NT_STATUS_ABIOS_INVALID_LID 0xC0000000 | 0&#215;0114<br />
#define NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE 0xC0000000 | 0&#215;0115<br />
#define NT_STATUS_ABIOS_INVALID_SELECTOR 0xC0000000 | 0&#215;0116<br />
#define NT_STATUS_NO_LDT 0xC0000000 | 0&#215;0117<br />
#define NT_STATUS_INVALID_LDT_SIZE 0xC0000000 | 0&#215;0118<br />
#define NT_STATUS_INVALID_LDT_OFFSET 0xC0000000 | 0&#215;0119<br />
#define NT_STATUS_INVALID_LDT_DESCRIPTOR 0xC0000000 | 0&#215;011a<br />
#define NT_STATUS_INVALID_IMAGE_NE_FORMAT 0xC0000000 | 0&#215;011b<br />
#define NT_STATUS_RXACT_INVALID_STATE 0xC0000000 | 0&#215;011c<br />
#define NT_STATUS_RXACT_COMMIT_FAILURE 0xC0000000 | 0&#215;011d<br />
#define NT_STATUS_MAPPED_FILE_SIZE_ZERO 0xC0000000 | 0&#215;011e<br />
#define NT_STATUS_TOO_MANY_OPENED_FILES 0xC0000000 | 0&#215;011f<br />
#define NT_STATUS_CANCELLED 0xC0000000 | 0&#215;0120<br />
#define NT_STATUS_CANNOT_DELETE 0xC0000000 | 0&#215;0121<br />
#define NT_STATUS_INVALID_COMPUTER_NAME 0xC0000000 | 0&#215;0122<br />
#define NT_STATUS_FILE_DELETED 0xC0000000 | 0&#215;0123<br />
#define NT_STATUS_SPECIAL_ACCOUNT 0xC0000000 | 0&#215;0124<br />
#define NT_STATUS_SPECIAL_GROUP 0xC0000000 | 0&#215;0125<br />
#define NT_STATUS_SPECIAL_USER 0xC0000000 | 0&#215;0126<br />
#define NT_STATUS_MEMBERS_PRIMARY_GROUP 0xC0000000 | 0&#215;0127<br />
#define NT_STATUS_FILE_CLOSED 0xC0000000 | 0&#215;0128<br />
#define NT_STATUS_TOO_MANY_THREADS 0xC0000000 | 0&#215;0129<br />
#define NT_STATUS_THREAD_NOT_IN_PROCESS 0xC0000000 | 0&#215;012a<br />
#define NT_STATUS_TOKEN_ALREADY_IN_USE 0xC0000000 | 0&#215;012b<br />
#define NT_STATUS_PAGEFILE_QUOTA_EXCEEDED 0xC0000000 | 0&#215;012c<br />
#define NT_STATUS_COMMITMENT_LIMIT 0xC0000000 | 0&#215;012d<br />
#define NT_STATUS_INVALID_IMAGE_LE_FORMAT 0xC0000000 | 0&#215;012e<br />
#define NT_STATUS_INVALID_IMAGE_NOT_MZ 0xC0000000 | 0&#215;012f<br />
#define NT_STATUS_INVALID_IMAGE_PROTECT 0xC0000000 | 0&#215;0130<br />
#define NT_STATUS_INVALID_IMAGE_WIN_16 0xC0000000 | 0&#215;0131<br />
#define NT_STATUS_LOGON_SERVER_CONFLICT 0xC0000000 | 0&#215;0132<br />
#define NT_STATUS_TIME_DIFFERENCE_AT_DC 0xC0000000 | 0&#215;0133<br />
#define NT_STATUS_SYNCHRONIZATION_REQUIRED 0xC0000000 | 0&#215;0134<br />
#define NT_STATUS_DLL_NOT_FOUND 0xC0000000 | 0&#215;0135<br />
#define NT_STATUS_OPEN_FAILED 0xC0000000 | 0&#215;0136<br />
#define NT_STATUS_IO_PRIVILEGE_FAILED 0xC0000000 | 0&#215;0137<br />
#define NT_STATUS_ORDINAL_NOT_FOUND 0xC0000000 | 0&#215;0138<br />
#define NT_STATUS_ENTRYPOINT_NOT_FOUND 0xC0000000 | 0&#215;0139<br />
#define NT_STATUS_CONTROL_C_EXIT 0xC0000000 | 0&#215;013a<br />
#define NT_STATUS_LOCAL_DISCONNECT 0xC0000000 | 0&#215;013b<br />
#define NT_STATUS_REMOTE_DISCONNECT 0xC0000000 | 0&#215;013c<br />
#define NT_STATUS_REMOTE_RESOURCES 0xC0000000 | 0&#215;013d<br />
#define NT_STATUS_LINK_FAILED 0xC0000000 | 0&#215;013e<br />
#define NT_STATUS_LINK_TIMEOUT 0xC0000000 | 0&#215;013f<br />
#define NT_STATUS_INVALID_CONNECTION 0xC0000000 | 0&#215;0140<br />
#define NT_STATUS_INVALID_ADDRESS 0xC0000000 | 0&#215;0141<br />
#define NT_STATUS_DLL_INIT_FAILED 0xC0000000 | 0&#215;0142<br />
#define NT_STATUS_MISSING_SYSTEMFILE 0xC0000000 | 0&#215;0143<br />
#define NT_STATUS_UNHANDLED_EXCEPTION 0xC0000000 | 0&#215;0144<br />
#define NT_STATUS_APP_INIT_FAILURE 0xC0000000 | 0&#215;0145<br />
#define NT_STATUS_PAGEFILE_CREATE_FAILED 0xC0000000 | 0&#215;0146<br />
#define NT_STATUS_NO_PAGEFILE 0xC0000000 | 0&#215;0147<br />
#define NT_STATUS_INVALID_LEVEL 0xC0000000 | 0&#215;0148<br />
#define NT_STATUS_WRONG_PASSWORD_CORE 0xC0000000 | 0&#215;0149<br />
#define NT_STATUS_ILLEGAL_FLOAT_CONTEXT 0xC0000000 | 0&#215;014a<br />
#define NT_STATUS_PIPE_BROKEN 0xC0000000 | 0&#215;014b<br />
#define NT_STATUS_REGISTRY_CORRUPT 0xC0000000 | 0&#215;014c<br />
#define NT_STATUS_REGISTRY_IO_FAILED 0xC0000000 | 0&#215;014d<br />
#define NT_STATUS_NO_EVENT_PAIR 0xC0000000 | 0&#215;014e<br />
#define NT_STATUS_UNRECOGNIZED_VOLUME 0xC0000000 | 0&#215;014f<br />
#define NT_STATUS_SERIAL_NO_DEVICE_INITED 0xC0000000 | 0&#215;0150<br />
#define NT_STATUS_NO_SUCH_ALIAS 0xC0000000 | 0&#215;0151<br />
#define NT_STATUS_MEMBER_NOT_IN_ALIAS 0xC0000000 | 0&#215;0152<br />
#define NT_STATUS_MEMBER_IN_ALIAS 0xC0000000 | 0&#215;0153<br />
#define NT_STATUS_ALIAS_EXISTS 0xC0000000 | 0&#215;0154<br />
#define NT_STATUS_LOGON_NOT_GRANTED 0xC0000000 | 0&#215;0155<br />
#define NT_STATUS_TOO_MANY_SECRETS 0xC0000000 | 0&#215;0156<br />
#define NT_STATUS_SECRET_TOO_LONG 0xC0000000 | 0&#215;0157<br />
#define NT_STATUS_INTERNAL_DB_ERROR 0xC0000000 | 0&#215;0158<br />
#define NT_STATUS_FULLSCREEN_MODE 0xC0000000 | 0&#215;0159<br />
#define NT_STATUS_TOO_MANY_CONTEXT_IDS 0xC0000000 | 0&#215;015a<br />
#define NT_STATUS_LOGON_TYPE_NOT_GRANTED 0xC0000000 | 0&#215;015b<br />
#define NT_STATUS_NOT_REGISTRY_FILE 0xC0000000 | 0&#215;015c<br />
#define NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED 0xC0000000 | 0&#215;015d<br />
#define NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR 0xC0000000 | 0&#215;015e<br />
#define NT_STATUS_FT_MISSING_MEMBER 0xC0000000 | 0&#215;015f<br />
#define NT_STATUS_ILL_FORMED_SERVICE_ENTRY 0xC0000000 | 0&#215;0160<br />
#define NT_STATUS_ILLEGAL_CHARACTER 0xC0000000 | 0&#215;0161<br />
#define NT_STATUS_UNMAPPABLE_CHARACTER 0xC0000000 | 0&#215;0162<br />
#define NT_STATUS_UNDEFINED_CHARACTER 0xC0000000 | 0&#215;0163<br />
#define NT_STATUS_FLOPPY_VOLUME 0xC0000000 | 0&#215;0164<br />
#define NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND 0xC0000000 | 0&#215;0165<br />
#define NT_STATUS_FLOPPY_WRONG_CYLINDER 0xC0000000 | 0&#215;0166<br />
#define NT_STATUS_FLOPPY_UNKNOWN_ERROR 0xC0000000 | 0&#215;0167<br />
#define NT_STATUS_FLOPPY_BAD_REGISTERS 0xC0000000 | 0&#215;0168<br />
#define NT_STATUS_DISK_RECALIBRATE_FAILED 0xC0000000 | 0&#215;0169<br />
#define NT_STATUS_DISK_OPERATION_FAILED 0xC0000000 | 0&#215;016a<br />
#define NT_STATUS_DISK_RESET_FAILED 0xC0000000 | 0&#215;016b<br />
#define NT_STATUS_SHARED_IRQ_BUSY 0xC0000000 | 0&#215;016c<br />
#define NT_STATUS_FT_ORPHANING 0xC0000000 | 0&#215;016d<br />
#define NT_STATUS_PARTITION_FAILURE 0xC0000000 | 0&#215;0172<br />
#define NT_STATUS_INVALID_BLOCK_LENGTH 0xC0000000 | 0&#215;0173<br />
#define NT_STATUS_DEVICE_NOT_PARTITIONED 0xC0000000 | 0&#215;0174<br />
#define NT_STATUS_UNABLE_TO_LOCK_MEDIA 0xC0000000 | 0&#215;0175<br />
#define NT_STATUS_UNABLE_TO_UNLOAD_MEDIA 0xC0000000 | 0&#215;0176<br />
#define NT_STATUS_EOM_OVERFLOW 0xC0000000 | 0&#215;0177<br />
#define NT_STATUS_NO_MEDIA 0xC0000000 | 0&#215;0178<br />
#define NT_STATUS_NO_SUCH_MEMBER 0xC0000000 | 0&#215;017a<br />
#define NT_STATUS_INVALID_MEMBER 0xC0000000 | 0&#215;017b<br />
#define NT_STATUS_KEY_DELETED 0xC0000000 | 0&#215;017c<br />
#define NT_STATUS_NO_LOG_SPACE 0xC0000000 | 0&#215;017d<br />
#define NT_STATUS_TOO_MANY_SIDS 0xC0000000 | 0&#215;017e<br />
#define NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED 0xC0000000 | 0&#215;017f<br />
#define NT_STATUS_KEY_HAS_CHILDREN 0xC0000000 | 0&#215;0180<br />
#define NT_STATUS_CHILD_MUST_BE_VOLATILE 0xC0000000 | 0&#215;0181<br />
#define NT_STATUS_DEVICE_CONFIGURATION_ERROR 0xC0000000 | 0&#215;0182<br />
#define NT_STATUS_DRIVER_INTERNAL_ERROR 0xC0000000 | 0&#215;0183<br />
#define NT_STATUS_INVALID_DEVICE_STATE 0xC0000000 | 0&#215;0184<br />
#define NT_STATUS_IO_DEVICE_ERROR 0xC0000000 | 0&#215;0185<br />
#define NT_STATUS_DEVICE_PROTOCOL_ERROR 0xC0000000 | 0&#215;0186<br />
#define NT_STATUS_BACKUP_CONTROLLER 0xC0000000 | 0&#215;0187<br />
#define NT_STATUS_LOG_FILE_FULL 0xC0000000 | 0&#215;0188<br />
#define NT_STATUS_TOO_LATE 0xC0000000 | 0&#215;0189<br />
#define NT_STATUS_NO_TRUST_LSA_SECRET 0xC0000000 | 0&#215;018a<br />
#define NT_STATUS_NO_TRUST_SAM_ACCOUNT 0xC0000000 | 0&#215;018b<br />
#define NT_STATUS_TRUSTED_DOMAIN_FAILURE 0xC0000000 | 0&#215;018c<br />
#define NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE 0xC0000000 | 0&#215;018d<br />
#define NT_STATUS_EVENTLOG_FILE_CORRUPT 0xC0000000 | 0&#215;018e<br />
#define NT_STATUS_EVENTLOG_CANT_START 0xC0000000 | 0&#215;018f<br />
#define NT_STATUS_TRUST_FAILURE 0xC0000000 | 0&#215;0190<br />
#define NT_STATUS_MUTANT_LIMIT_EXCEEDED 0xC0000000 | 0&#215;0191<br />
#define NT_STATUS_NETLOGON_NOT_STARTED 0xC0000000 | 0&#215;0192<br />
#define NT_STATUS_ACCOUNT_EXPIRED 0xC0000000 | 0&#215;0193<br />
#define NT_STATUS_POSSIBLE_DEADLOCK 0xC0000000 | 0&#215;0194<br />
#define NT_STATUS_NETWORK_CREDENTIAL_CONFLICT 0xC0000000 | 0&#215;0195<br />
#define NT_STATUS_REMOTE_SESSION_LIMIT 0xC0000000 | 0&#215;0196<br />
#define NT_STATUS_EVENTLOG_FILE_CHANGED 0xC0000000 | 0&#215;0197<br />
#define NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT 0xC0000000 | 0&#215;0198<br />
#define NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT 0xC0000000 | 0&#215;0199<br />
#define NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT 0xC0000000 | 0&#215;019a<br />
#define NT_STATUS_DOMAIN_TRUST_INCONSISTENT 0xC0000000 | 0&#215;019b<br />
#define NT_STATUS_FS_DRIVER_REQUIRED 0xC0000000 | 0&#215;019c<br />
#define NT_STATUS_NO_USER_SESSION_KEY 0xC0000000 | 0&#215;0202<br />
#define NT_STATUS_USER_SESSION_DELETED 0xC0000000 | 0&#215;0203<br />
#define NT_STATUS_RESOURCE_LANG_NOT_FOUND 0xC0000000 | 0&#215;0204<br />
#define NT_STATUS_INSUFF_SERVER_RESOURCES 0xC0000000 | 0&#215;0205<br />
#define NT_STATUS_INVALID_BUFFER_SIZE 0xC0000000 | 0&#215;0206<br />
#define NT_STATUS_INVALID_ADDRESS_COMPONENT 0xC0000000 | 0&#215;0207<br />
#define NT_STATUS_INVALID_ADDRESS_WILDCARD 0xC0000000 | 0&#215;0208<br />
#define NT_STATUS_TOO_MANY_ADDRESSES 0xC0000000 | 0&#215;0209<br />
#define NT_STATUS_ADDRESS_ALREADY_EXISTS 0xC0000000 | 0&#215;020a<br />
#define NT_STATUS_ADDRESS_CLOSED 0xC0000000 | 0&#215;020b<br />
#define NT_STATUS_CONNECTION_DISCONNECTED 0xC0000000 | 0&#215;020c<br />
#define NT_STATUS_CONNECTION_RESET 0xC0000000 | 0&#215;020d<br />
#define NT_STATUS_TOO_MANY_NODES 0xC0000000 | 0&#215;020e<br />
#define NT_STATUS_TRANSACTION_ABORTED 0xC0000000 | 0&#215;020f<br />
#define NT_STATUS_TRANSACTION_TIMED_OUT 0xC0000000 | 0&#215;0210<br />
#define NT_STATUS_TRANSACTION_NO_RELEASE 0xC0000000 | 0&#215;0211<br />
#define NT_STATUS_TRANSACTION_NO_MATCH 0xC0000000 | 0&#215;0212<br />
#define NT_STATUS_TRANSACTION_RESPONDED 0xC0000000 | 0&#215;0213<br />
#define NT_STATUS_TRANSACTION_INVALID_ID 0xC0000000 | 0&#215;0214<br />
#define NT_STATUS_TRANSACTION_INVALID_TYPE 0xC0000000 | 0&#215;0215<br />
#define NT_STATUS_NOT_SERVER_SESSION 0xC0000000 | 0&#215;0216<br />
#define NT_STATUS_NOT_CLIENT_SESSION 0xC0000000 | 0&#215;0217<br />
#define NT_STATUS_CANNOT_LOAD_REGISTRY_FILE 0xC0000000 | 0&#215;0218<br />
#define NT_STATUS_DEBUG_ATTACH_FAILED 0xC0000000 | 0&#215;0219<br />
#define NT_STATUS_SYSTEM_PROCESS_TERMINATED 0xC0000000 | 0&#215;021a<br />
#define NT_STATUS_DATA_NOT_ACCEPTED 0xC0000000 | 0&#215;021b<br />
#define NT_STATUS_NO_BROWSER_SERVERS_FOUND 0xC0000000 | 0&#215;021c<br />
#define NT_STATUS_VDM_HARD_ERROR 0xC0000000 | 0&#215;021d<br />
#define NT_STATUS_DRIVER_CANCEL_TIMEOUT 0xC0000000 | 0&#215;021e<br />
#define NT_STATUS_REPLY_MESSAGE_MISMATCH 0xC0000000 | 0&#215;021f<br />
#define NT_STATUS_MAPPED_ALIGNMENT 0xC0000000 | 0&#215;0220<br />
#define NT_STATUS_IMAGE_CHECKSUM_MISMATCH 0xC0000000 | 0&#215;0221<br />
#define NT_STATUS_LOST_WRITEBEHIND_DATA 0xC0000000 | 0&#215;0222<br />
#define NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID 0xC0000000 | 0&#215;0223<br />
#define NT_STATUS_PASSWORD_MUST_CHANGE 0xC0000000 | 0&#215;0224<br />
#define NT_STATUS_NOT_FOUND 0xC0000000 | 0&#215;0225<br />
#define NT_STATUS_NOT_TINY_STREAM 0xC0000000 | 0&#215;0226<br />
#define NT_STATUS_RECOVERY_FAILURE 0xC0000000 | 0&#215;0227<br />
#define NT_STATUS_STACK_OVERFLOW_READ 0xC0000000 | 0&#215;0228<br />
#define NT_STATUS_FAIL_CHECK 0xC0000000 | 0&#215;0229<br />
#define NT_STATUS_DUPLICATE_OBJECTID 0xC0000000 | 0&#215;022a<br />
#define NT_STATUS_OBJECTID_EXISTS 0xC0000000 | 0&#215;022b<br />
#define NT_STATUS_CONVERT_TO_LARGE 0xC0000000 | 0&#215;022c<br />
#define NT_STATUS_RETRY 0xC0000000 | 0&#215;022d<br />
#define NT_STATUS_FOUND_OUT_OF_SCOPE 0xC0000000 | 0&#215;022e<br />
#define NT_STATUS_ALLOCATE_BUCKET 0xC0000000 | 0&#215;022f<br />
#define NT_STATUS_PROPSET_NOT_FOUND 0xC0000000 | 0&#215;0230<br />
#define NT_STATUS_MARSHALL_OVERFLOW 0xC0000000 | 0&#215;0231<br />
#define NT_STATUS_INVALID_VARIANT 0xC0000000 | 0&#215;0232<br />
#define NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND 0xC0000000 | 0&#215;0233<br />
#define NT_STATUS_ACCOUNT_LOCKED_OUT 0xC0000000 | 0&#215;0234<br />
#define NT_STATUS_HANDLE_NOT_CLOSABLE 0xC0000000 | 0&#215;0235<br />
#define NT_STATUS_CONNECTION_REFUSED 0xC0000000 | 0&#215;0236<br />
#define NT_STATUS_GRACEFUL_DISCONNECT 0xC0000000 | 0&#215;0237<br />
#define NT_STATUS_ADDRESS_ALREADY_ASSOCIATED 0xC0000000 | 0&#215;0238<br />
#define NT_STATUS_ADDRESS_NOT_ASSOCIATED 0xC0000000 | 0&#215;0239<br />
#define NT_STATUS_CONNECTION_INVALID 0xC0000000 | 0&#215;023a<br />
#define NT_STATUS_CONNECTION_ACTIVE 0xC0000000 | 0&#215;023b<br />
#define NT_STATUS_NETWORK_UNREACHABLE 0xC0000000 | 0&#215;023c<br />
#define NT_STATUS_HOST_UNREACHABLE 0xC0000000 | 0&#215;023d<br />
#define NT_STATUS_PROTOCOL_UNREACHABLE 0xC0000000 | 0&#215;023e<br />
#define NT_STATUS_PORT_UNREACHABLE 0xC0000000 | 0&#215;023f<br />
#define NT_STATUS_REQUEST_ABORTED 0xC0000000 | 0&#215;0240<br />
#define NT_STATUS_CONNECTION_ABORTED 0xC0000000 | 0&#215;0241<br />
#define NT_STATUS_BAD_COMPRESSION_BUFFER 0xC0000000 | 0&#215;0242<br />
#define NT_STATUS_USER_MAPPED_FILE 0xC0000000 | 0&#215;0243<br />
#define NT_STATUS_AUDIT_FAILED 0xC0000000 | 0&#215;0244<br />
#define NT_STATUS_TIMER_RESOLUTION_NOT_SET 0xC0000000 | 0&#215;0245<br />
#define NT_STATUS_CONNECTION_COUNT_LIMIT 0xC0000000 | 0&#215;0246<br />
#define NT_STATUS_LOGIN_TIME_RESTRICTION 0xC0000000 | 0&#215;0247<br />
#define NT_STATUS_LOGIN_WKSTA_RESTRICTION 0xC0000000 | 0&#215;0248<br />
#define NT_STATUS_IMAGE_MP_UP_MISMATCH 0xC0000000 | 0&#215;0249<br />
#define NT_STATUS_INSUFFICIENT_LOGON_INFO 0xC0000000 | 0&#215;0250<br />
#define NT_STATUS_BAD_DLL_ENTRYPOINT 0xC0000000 | 0&#215;0251<br />
#define NT_STATUS_BAD_SERVICE_ENTRYPOINT 0xC0000000 | 0&#215;0252<br />
#define NT_STATUS_LPC_REPLY_LOST 0xC0000000 | 0&#215;0253<br />
#define NT_STATUS_IP_ADDRESS_CONFLICT1 0xC0000000 | 0&#215;0254<br />
#define NT_STATUS_IP_ADDRESS_CONFLICT2 0xC0000000 | 0&#215;0255<br />
#define NT_STATUS_REGISTRY_QUOTA_LIMIT 0xC0000000 | 0&#215;0256<br />
#define NT_STATUS_PATH_NOT_COVERED 0xC0000000 | 0&#215;0257<br />
#define NT_STATUS_NO_CALLBACK_ACTIVE 0xC0000000 | 0&#215;0258<br />
#define NT_STATUS_LICENSE_QUOTA_EXCEEDED 0xC0000000 | 0&#215;0259<br />
#define NT_STATUS_PWD_TOO_SHORT 0xC0000000 | 0&#215;025a<br />
#define NT_STATUS_PWD_TOO_RECENT 0xC0000000 | 0&#215;025b<br />
#define NT_STATUS_PWD_HISTORY_CONFLICT 0xC0000000 | 0&#215;025c<br />
#define NT_STATUS_PLUGPLAY_NO_DEVICE 0xC0000000 | 0&#215;025e<br />
#define NT_STATUS_UNSUPPORTED_COMPRESSION 0xC0000000 | 0&#215;025f<br />
#define NT_STATUS_INVALID_HW_PROFILE 0xC0000000 | 0&#215;0260<br />
#define NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH 0xC0000000 | 0&#215;0261<br />
#define NT_STATUS_DRIVER_ORDINAL_NOT_FOUND 0xC0000000 | 0&#215;0262<br />
#define NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND 0xC0000000 | 0&#215;0263<br />
#define NT_STATUS_RESOURCE_NOT_OWNED 0xC0000000 | 0&#215;0264<br />
#define NT_STATUS_TOO_MANY_LINKS 0xC0000000 | 0&#215;0265<br />
#define NT_STATUS_QUOTA_LIST_INCONSISTENT 0xC0000000 | 0&#215;0266<br />
#define NT_STATUS_FILE_IS_OFFLINE 0xC0000000 | 0&#215;0267<br />
#define NT_STATUS_NO_SUCH_JOB 0xC0000000 | 0xEDE	/* scheduler */</p>
<p>#endif				/* _NTERR_H */</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/nterr-h/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>nterr.c</title>
		<link>http://lynyrd.ru/nterr-c</link>
		<comments>http://lynyrd.ru/nterr-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:30:11 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/?p=955</guid>
		<description><![CDATA[/*
 *  Unix SMB/Netbios implementation.
 *  Version 1.9.
 *  RPC Pipe client / server routines
 *  Copyright (C) Luke Kenneth Casson Leighton 1997-2001.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *  Unix SMB/Netbios implementation.<span id="more-955"></span><br />
 *  Version 1.9.<br />
 *  RPC Pipe client / server routines<br />
 *  Copyright (C) Luke Kenneth Casson Leighton 1997-2001.<br />
 *<br />
 *  This program is free software; you can redistribute it and/or modify<br />
 *  it under the terms of the GNU General Public License as published by<br />
 *  the Free Software Foundation; either version 2 of the License, or<br />
 *  (at your option) any later version.<br />
 *<br />
 *  This program is distributed in the hope that it will be useful,<br />
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
 *  GNU General Public License for more details.<br />
 *<br />
 *  You should have received a copy of the GNU General Public License<br />
 *  along with this program; if not, write to the Free Software<br />
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br />
 */</p>
<p>/* NT error codes &#8211; see nterr.h */<br />
#include
<linux/types.h>
#include
<linux/fs.h>
#include &laquo;nterr.h&raquo;</p>
<p>const struct nt_err_code_struct nt_errs[] = {<br />
	{&raquo;NT_STATUS_OK&raquo;, NT_STATUS_OK},<br />
	{&raquo;NT_STATUS_UNSUCCESSFUL&raquo;, NT_STATUS_UNSUCCESSFUL},<br />
	{&raquo;NT_STATUS_NOT_IMPLEMENTED&raquo;, NT_STATUS_NOT_IMPLEMENTED},<br />
	{&raquo;NT_STATUS_INVALID_INFO_CLASS&raquo;, NT_STATUS_INVALID_INFO_CLASS},<br />
	{&raquo;NT_STATUS_INFO_LENGTH_MISMATCH&raquo;, NT_STATUS_INFO_LENGTH_MISMATCH},<br />
	{&raquo;NT_STATUS_ACCESS_VIOLATION&raquo;, NT_STATUS_ACCESS_VIOLATION},<br />
	{&raquo;STATUS_BUFFER_OVERFLOW&raquo;, STATUS_BUFFER_OVERFLOW},<br />
	{&raquo;NT_STATUS_IN_PAGE_ERROR&raquo;, NT_STATUS_IN_PAGE_ERROR},<br />
	{&raquo;NT_STATUS_PAGEFILE_QUOTA&raquo;, NT_STATUS_PAGEFILE_QUOTA},<br />
	{&raquo;NT_STATUS_INVALID_HANDLE&raquo;, NT_STATUS_INVALID_HANDLE},<br />
	{&raquo;NT_STATUS_BAD_INITIAL_STACK&raquo;, NT_STATUS_BAD_INITIAL_STACK},<br />
	{&raquo;NT_STATUS_BAD_INITIAL_PC&raquo;, NT_STATUS_BAD_INITIAL_PC},<br />
	{&raquo;NT_STATUS_INVALID_CID&raquo;, NT_STATUS_INVALID_CID},<br />
	{&raquo;NT_STATUS_TIMER_NOT_CANCELED&raquo;, NT_STATUS_TIMER_NOT_CANCELED},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER&raquo;, NT_STATUS_INVALID_PARAMETER},<br />
	{&raquo;NT_STATUS_NO_SUCH_DEVICE&raquo;, NT_STATUS_NO_SUCH_DEVICE},<br />
	{&raquo;NT_STATUS_NO_SUCH_FILE&raquo;, NT_STATUS_NO_SUCH_FILE},<br />
	{&raquo;NT_STATUS_INVALID_DEVICE_REQUEST&raquo;,<br />
	 NT_STATUS_INVALID_DEVICE_REQUEST},<br />
	{&raquo;NT_STATUS_END_OF_FILE&raquo;, NT_STATUS_END_OF_FILE},<br />
	{&raquo;NT_STATUS_WRONG_VOLUME&raquo;, NT_STATUS_WRONG_VOLUME},<br />
	{&raquo;NT_STATUS_NO_MEDIA_IN_DEVICE&raquo;, NT_STATUS_NO_MEDIA_IN_DEVICE},<br />
	{&raquo;NT_STATUS_UNRECOGNIZED_MEDIA&raquo;, NT_STATUS_UNRECOGNIZED_MEDIA},<br />
	{&raquo;NT_STATUS_NONEXISTENT_SECTOR&raquo;, NT_STATUS_NONEXISTENT_SECTOR},<br />
	{&raquo;NT_STATUS_MORE_PROCESSING_REQUIRED&raquo;,<br />
	 NT_STATUS_MORE_PROCESSING_REQUIRED},<br />
	{&raquo;NT_STATUS_NO_MEMORY&raquo;, NT_STATUS_NO_MEMORY},<br />
	{&raquo;NT_STATUS_CONFLICTING_ADDRESSES&raquo;,<br />
	 NT_STATUS_CONFLICTING_ADDRESSES},<br />
	{&raquo;NT_STATUS_NOT_MAPPED_VIEW&raquo;, NT_STATUS_NOT_MAPPED_VIEW},<br />
	{&raquo;NT_STATUS_UNABLE_TO_FREE_VM&raquo;, NT_STATUS_UNABLE_TO_FREE_VM},<br />
	{&raquo;NT_STATUS_UNABLE_TO_DELETE_SECTION&raquo;,<br />
	 NT_STATUS_UNABLE_TO_DELETE_SECTION},<br />
	{&raquo;NT_STATUS_INVALID_SYSTEM_SERVICE&raquo;,<br />
	 NT_STATUS_INVALID_SYSTEM_SERVICE},<br />
	{&raquo;NT_STATUS_ILLEGAL_INSTRUCTION&raquo;, NT_STATUS_ILLEGAL_INSTRUCTION},<br />
	{&raquo;NT_STATUS_INVALID_LOCK_SEQUENCE&raquo;,<br />
	 NT_STATUS_INVALID_LOCK_SEQUENCE},<br />
	{&raquo;NT_STATUS_INVALID_VIEW_SIZE&raquo;, NT_STATUS_INVALID_VIEW_SIZE},<br />
	{&raquo;NT_STATUS_INVALID_FILE_FOR_SECTION&raquo;,<br />
	 NT_STATUS_INVALID_FILE_FOR_SECTION},<br />
	{&raquo;NT_STATUS_ALREADY_COMMITTED&raquo;, NT_STATUS_ALREADY_COMMITTED},<br />
	{&raquo;NT_STATUS_ACCESS_DENIED&raquo;, NT_STATUS_ACCESS_DENIED},<br />
	{&raquo;NT_STATUS_BUFFER_TOO_SMALL&raquo;, NT_STATUS_BUFFER_TOO_SMALL},<br />
	{&raquo;NT_STATUS_OBJECT_TYPE_MISMATCH&raquo;, NT_STATUS_OBJECT_TYPE_MISMATCH},<br />
	{&raquo;NT_STATUS_NONCONTINUABLE_EXCEPTION&raquo;,<br />
	 NT_STATUS_NONCONTINUABLE_EXCEPTION},<br />
	{&raquo;NT_STATUS_INVALID_DISPOSITION&raquo;, NT_STATUS_INVALID_DISPOSITION},<br />
	{&raquo;NT_STATUS_UNWIND&raquo;, NT_STATUS_UNWIND},<br />
	{&raquo;NT_STATUS_BAD_STACK&raquo;, NT_STATUS_BAD_STACK},<br />
	{&raquo;NT_STATUS_INVALID_UNWIND_TARGET&raquo;,<br />
	 NT_STATUS_INVALID_UNWIND_TARGET},<br />
	{&raquo;NT_STATUS_NOT_LOCKED&raquo;, NT_STATUS_NOT_LOCKED},<br />
	{&raquo;NT_STATUS_PARITY_ERROR&raquo;, NT_STATUS_PARITY_ERROR},<br />
	{&raquo;NT_STATUS_UNABLE_TO_DECOMMIT_VM&raquo;,<br />
	 NT_STATUS_UNABLE_TO_DECOMMIT_VM},<br />
	{&raquo;NT_STATUS_NOT_COMMITTED&raquo;, NT_STATUS_NOT_COMMITTED},<br />
	{&raquo;NT_STATUS_INVALID_PORT_ATTRIBUTES&raquo;,<br />
	 NT_STATUS_INVALID_PORT_ATTRIBUTES},<br />
	{&raquo;NT_STATUS_PORT_MESSAGE_TOO_LONG&raquo;,<br />
	 NT_STATUS_PORT_MESSAGE_TOO_LONG},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_MIX&raquo;,<br />
	 NT_STATUS_INVALID_PARAMETER_MIX},<br />
	{&raquo;NT_STATUS_INVALID_QUOTA_LOWER&raquo;, NT_STATUS_INVALID_QUOTA_LOWER},<br />
	{&raquo;NT_STATUS_DISK_CORRUPT_ERROR&raquo;, NT_STATUS_DISK_CORRUPT_ERROR},<br />
	{&raquo;NT_STATUS_OBJECT_NAME_INVALID&raquo;, NT_STATUS_OBJECT_NAME_INVALID},<br />
	{&raquo;NT_STATUS_OBJECT_NAME_NOT_FOUND&raquo;,<br />
	 NT_STATUS_OBJECT_NAME_NOT_FOUND},<br />
	{&raquo;NT_STATUS_OBJECT_NAME_COLLISION&raquo;,<br />
	 NT_STATUS_OBJECT_NAME_COLLISION},<br />
	{&raquo;NT_STATUS_HANDLE_NOT_WAITABLE&raquo;, NT_STATUS_HANDLE_NOT_WAITABLE},<br />
	{&raquo;NT_STATUS_PORT_DISCONNECTED&raquo;, NT_STATUS_PORT_DISCONNECTED},<br />
	{&raquo;NT_STATUS_DEVICE_ALREADY_ATTACHED&raquo;,<br />
	 NT_STATUS_DEVICE_ALREADY_ATTACHED},<br />
	{&raquo;NT_STATUS_OBJECT_PATH_INVALID&raquo;, NT_STATUS_OBJECT_PATH_INVALID},<br />
	{&raquo;NT_STATUS_OBJECT_PATH_NOT_FOUND&raquo;,<br />
	 NT_STATUS_OBJECT_PATH_NOT_FOUND},<br />
	{&raquo;NT_STATUS_OBJECT_PATH_SYNTAX_BAD&raquo;,<br />
	 NT_STATUS_OBJECT_PATH_SYNTAX_BAD},<br />
	{&raquo;NT_STATUS_DATA_OVERRUN&raquo;, NT_STATUS_DATA_OVERRUN},<br />
	{&raquo;NT_STATUS_DATA_LATE_ERROR&raquo;, NT_STATUS_DATA_LATE_ERROR},<br />
	{&raquo;NT_STATUS_DATA_ERROR&raquo;, NT_STATUS_DATA_ERROR},<br />
	{&raquo;NT_STATUS_CRC_ERROR&raquo;, NT_STATUS_CRC_ERROR},<br />
	{&raquo;NT_STATUS_SECTION_TOO_BIG&raquo;, NT_STATUS_SECTION_TOO_BIG},<br />
	{&raquo;NT_STATUS_PORT_CONNECTION_REFUSED&raquo;,<br />
	 NT_STATUS_PORT_CONNECTION_REFUSED},<br />
	{&raquo;NT_STATUS_INVALID_PORT_HANDLE&raquo;, NT_STATUS_INVALID_PORT_HANDLE},<br />
	{&raquo;NT_STATUS_SHARING_VIOLATION&raquo;, NT_STATUS_SHARING_VIOLATION},<br />
	{&raquo;NT_STATUS_QUOTA_EXCEEDED&raquo;, NT_STATUS_QUOTA_EXCEEDED},<br />
	{&raquo;NT_STATUS_INVALID_PAGE_PROTECTION&raquo;,<br />
	 NT_STATUS_INVALID_PAGE_PROTECTION},<br />
	{&raquo;NT_STATUS_MUTANT_NOT_OWNED&raquo;, NT_STATUS_MUTANT_NOT_OWNED},<br />
	{&raquo;NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED&raquo;,<br />
	 NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED},<br />
	{&raquo;NT_STATUS_PORT_ALREADY_SET&raquo;, NT_STATUS_PORT_ALREADY_SET},<br />
	{&raquo;NT_STATUS_SECTION_NOT_IMAGE&raquo;, NT_STATUS_SECTION_NOT_IMAGE},<br />
	{&raquo;NT_STATUS_SUSPEND_COUNT_EXCEEDED&raquo;,<br />
	 NT_STATUS_SUSPEND_COUNT_EXCEEDED},<br />
	{&raquo;NT_STATUS_THREAD_IS_TERMINATING&raquo;,<br />
	 NT_STATUS_THREAD_IS_TERMINATING},<br />
	{&raquo;NT_STATUS_BAD_WORKING_SET_LIMIT&raquo;,<br />
	 NT_STATUS_BAD_WORKING_SET_LIMIT},<br />
	{&raquo;NT_STATUS_INCOMPATIBLE_FILE_MAP&raquo;,<br />
	 NT_STATUS_INCOMPATIBLE_FILE_MAP},<br />
	{&raquo;NT_STATUS_SECTION_PROTECTION&raquo;, NT_STATUS_SECTION_PROTECTION},<br />
	{&raquo;NT_STATUS_EAS_NOT_SUPPORTED&raquo;, NT_STATUS_EAS_NOT_SUPPORTED},<br />
	{&raquo;NT_STATUS_EA_TOO_LARGE&raquo;, NT_STATUS_EA_TOO_LARGE},<br />
	{&raquo;NT_STATUS_NONEXISTENT_EA_ENTRY&raquo;, NT_STATUS_NONEXISTENT_EA_ENTRY},<br />
	{&raquo;NT_STATUS_NO_EAS_ON_FILE&raquo;, NT_STATUS_NO_EAS_ON_FILE},<br />
	{&raquo;NT_STATUS_EA_CORRUPT_ERROR&raquo;, NT_STATUS_EA_CORRUPT_ERROR},<br />
	{&raquo;NT_STATUS_FILE_LOCK_CONFLICT&raquo;, NT_STATUS_FILE_LOCK_CONFLICT},<br />
	{&raquo;NT_STATUS_LOCK_NOT_GRANTED&raquo;, NT_STATUS_LOCK_NOT_GRANTED},<br />
	{&raquo;NT_STATUS_DELETE_PENDING&raquo;, NT_STATUS_DELETE_PENDING},<br />
	{&raquo;NT_STATUS_CTL_FILE_NOT_SUPPORTED&raquo;,<br />
	 NT_STATUS_CTL_FILE_NOT_SUPPORTED},<br />
	{&raquo;NT_STATUS_UNKNOWN_REVISION&raquo;, NT_STATUS_UNKNOWN_REVISION},<br />
	{&raquo;NT_STATUS_REVISION_MISMATCH&raquo;, NT_STATUS_REVISION_MISMATCH},<br />
	{&raquo;NT_STATUS_INVALID_OWNER&raquo;, NT_STATUS_INVALID_OWNER},<br />
	{&raquo;NT_STATUS_INVALID_PRIMARY_GROUP&raquo;,<br />
	 NT_STATUS_INVALID_PRIMARY_GROUP},<br />
	{&raquo;NT_STATUS_NO_IMPERSONATION_TOKEN&raquo;,<br />
	 NT_STATUS_NO_IMPERSONATION_TOKEN},<br />
	{&raquo;NT_STATUS_CANT_DISABLE_MANDATORY&raquo;,<br />
	 NT_STATUS_CANT_DISABLE_MANDATORY},<br />
	{&raquo;NT_STATUS_NO_LOGON_SERVERS&raquo;, NT_STATUS_NO_LOGON_SERVERS},<br />
	{&raquo;NT_STATUS_NO_SUCH_LOGON_SESSION&raquo;,<br />
	 NT_STATUS_NO_SUCH_LOGON_SESSION},<br />
	{&raquo;NT_STATUS_NO_SUCH_PRIVILEGE&raquo;, NT_STATUS_NO_SUCH_PRIVILEGE},<br />
	{&raquo;NT_STATUS_PRIVILEGE_NOT_HELD&raquo;, NT_STATUS_PRIVILEGE_NOT_HELD},<br />
	{&raquo;NT_STATUS_INVALID_ACCOUNT_NAME&raquo;, NT_STATUS_INVALID_ACCOUNT_NAME},<br />
	{&raquo;NT_STATUS_USER_EXISTS&raquo;, NT_STATUS_USER_EXISTS},<br />
	{&raquo;NT_STATUS_NO_SUCH_USER&raquo;, NT_STATUS_NO_SUCH_USER},<br />
	{&raquo;NT_STATUS_GROUP_EXISTS&raquo;, NT_STATUS_GROUP_EXISTS},<br />
	{&raquo;NT_STATUS_NO_SUCH_GROUP&raquo;, NT_STATUS_NO_SUCH_GROUP},<br />
	{&raquo;NT_STATUS_MEMBER_IN_GROUP&raquo;, NT_STATUS_MEMBER_IN_GROUP},<br />
	{&raquo;NT_STATUS_MEMBER_NOT_IN_GROUP&raquo;, NT_STATUS_MEMBER_NOT_IN_GROUP},<br />
	{&raquo;NT_STATUS_LAST_ADMIN&raquo;, NT_STATUS_LAST_ADMIN},<br />
	{&raquo;NT_STATUS_WRONG_PASSWORD&raquo;, NT_STATUS_WRONG_PASSWORD},<br />
	{&raquo;NT_STATUS_ILL_FORMED_PASSWORD&raquo;, NT_STATUS_ILL_FORMED_PASSWORD},<br />
	{&raquo;NT_STATUS_PASSWORD_RESTRICTION&raquo;, NT_STATUS_PASSWORD_RESTRICTION},<br />
	{&raquo;NT_STATUS_LOGON_FAILURE&raquo;, NT_STATUS_LOGON_FAILURE},<br />
	{&raquo;NT_STATUS_ACCOUNT_RESTRICTION&raquo;, NT_STATUS_ACCOUNT_RESTRICTION},<br />
	{&raquo;NT_STATUS_INVALID_LOGON_HOURS&raquo;, NT_STATUS_INVALID_LOGON_HOURS},<br />
	{&raquo;NT_STATUS_INVALID_WORKSTATION&raquo;, NT_STATUS_INVALID_WORKSTATION},<br />
	{&raquo;NT_STATUS_PASSWORD_EXPIRED&raquo;, NT_STATUS_PASSWORD_EXPIRED},<br />
	{&raquo;NT_STATUS_ACCOUNT_DISABLED&raquo;, NT_STATUS_ACCOUNT_DISABLED},<br />
	{&raquo;NT_STATUS_NONE_MAPPED&raquo;, NT_STATUS_NONE_MAPPED},<br />
	{&raquo;NT_STATUS_TOO_MANY_LUIDS_REQUESTED&raquo;,<br />
	 NT_STATUS_TOO_MANY_LUIDS_REQUESTED},<br />
	{&raquo;NT_STATUS_LUIDS_EXHAUSTED&raquo;, NT_STATUS_LUIDS_EXHAUSTED},<br />
	{&raquo;NT_STATUS_INVALID_SUB_AUTHORITY&raquo;,<br />
	 NT_STATUS_INVALID_SUB_AUTHORITY},<br />
	{&raquo;NT_STATUS_INVALID_ACL&raquo;, NT_STATUS_INVALID_ACL},<br />
	{&raquo;NT_STATUS_INVALID_SID&raquo;, NT_STATUS_INVALID_SID},<br />
	{&raquo;NT_STATUS_INVALID_SECURITY_DESCR&raquo;,<br />
	 NT_STATUS_INVALID_SECURITY_DESCR},<br />
	{&raquo;NT_STATUS_PROCEDURE_NOT_FOUND&raquo;, NT_STATUS_PROCEDURE_NOT_FOUND},<br />
	{&raquo;NT_STATUS_INVALID_IMAGE_FORMAT&raquo;, NT_STATUS_INVALID_IMAGE_FORMAT},<br />
	{&raquo;NT_STATUS_NO_TOKEN&raquo;, NT_STATUS_NO_TOKEN},<br />
	{&raquo;NT_STATUS_BAD_INHERITANCE_ACL&raquo;, NT_STATUS_BAD_INHERITANCE_ACL},<br />
	{&raquo;NT_STATUS_RANGE_NOT_LOCKED&raquo;, NT_STATUS_RANGE_NOT_LOCKED},<br />
	{&raquo;NT_STATUS_DISK_FULL&raquo;, NT_STATUS_DISK_FULL},<br />
	{&raquo;NT_STATUS_SERVER_DISABLED&raquo;, NT_STATUS_SERVER_DISABLED},<br />
	{&raquo;NT_STATUS_SERVER_NOT_DISABLED&raquo;, NT_STATUS_SERVER_NOT_DISABLED},<br />
	{&raquo;NT_STATUS_TOO_MANY_GUIDS_REQUESTED&raquo;,<br />
	 NT_STATUS_TOO_MANY_GUIDS_REQUESTED},<br />
	{&raquo;NT_STATUS_GUIDS_EXHAUSTED&raquo;, NT_STATUS_GUIDS_EXHAUSTED},<br />
	{&raquo;NT_STATUS_INVALID_ID_AUTHORITY&raquo;, NT_STATUS_INVALID_ID_AUTHORITY},<br />
	{&raquo;NT_STATUS_AGENTS_EXHAUSTED&raquo;, NT_STATUS_AGENTS_EXHAUSTED},<br />
	{&raquo;NT_STATUS_INVALID_VOLUME_LABEL&raquo;, NT_STATUS_INVALID_VOLUME_LABEL},<br />
	{&raquo;NT_STATUS_SECTION_NOT_EXTENDED&raquo;, NT_STATUS_SECTION_NOT_EXTENDED},<br />
	{&raquo;NT_STATUS_NOT_MAPPED_DATA&raquo;, NT_STATUS_NOT_MAPPED_DATA},<br />
	{&raquo;NT_STATUS_RESOURCE_DATA_NOT_FOUND&raquo;,<br />
	 NT_STATUS_RESOURCE_DATA_NOT_FOUND},<br />
	{&raquo;NT_STATUS_RESOURCE_TYPE_NOT_FOUND&raquo;,<br />
	 NT_STATUS_RESOURCE_TYPE_NOT_FOUND},<br />
	{&raquo;NT_STATUS_RESOURCE_NAME_NOT_FOUND&raquo;,<br />
	 NT_STATUS_RESOURCE_NAME_NOT_FOUND},<br />
	{&raquo;NT_STATUS_ARRAY_BOUNDS_EXCEEDED&raquo;,<br />
	 NT_STATUS_ARRAY_BOUNDS_EXCEEDED},<br />
	{&raquo;NT_STATUS_FLOAT_DENORMAL_OPERAND&raquo;,<br />
	 NT_STATUS_FLOAT_DENORMAL_OPERAND},<br />
	{&raquo;NT_STATUS_FLOAT_DIVIDE_BY_ZERO&raquo;, NT_STATUS_FLOAT_DIVIDE_BY_ZERO},<br />
	{&raquo;NT_STATUS_FLOAT_INEXACT_RESULT&raquo;, NT_STATUS_FLOAT_INEXACT_RESULT},<br />
	{&raquo;NT_STATUS_FLOAT_INVALID_OPERATION&raquo;,<br />
	 NT_STATUS_FLOAT_INVALID_OPERATION},<br />
	{&raquo;NT_STATUS_FLOAT_OVERFLOW&raquo;, NT_STATUS_FLOAT_OVERFLOW},<br />
	{&raquo;NT_STATUS_FLOAT_STACK_CHECK&raquo;, NT_STATUS_FLOAT_STACK_CHECK},<br />
	{&raquo;NT_STATUS_FLOAT_UNDERFLOW&raquo;, NT_STATUS_FLOAT_UNDERFLOW},<br />
	{&raquo;NT_STATUS_INTEGER_DIVIDE_BY_ZERO&raquo;,<br />
	 NT_STATUS_INTEGER_DIVIDE_BY_ZERO},<br />
	{&raquo;NT_STATUS_INTEGER_OVERFLOW&raquo;, NT_STATUS_INTEGER_OVERFLOW},<br />
	{&raquo;NT_STATUS_PRIVILEGED_INSTRUCTION&raquo;,<br />
	 NT_STATUS_PRIVILEGED_INSTRUCTION},<br />
	{&raquo;NT_STATUS_TOO_MANY_PAGING_FILES&raquo;,<br />
	 NT_STATUS_TOO_MANY_PAGING_FILES},<br />
	{&raquo;NT_STATUS_FILE_INVALID&raquo;, NT_STATUS_FILE_INVALID},<br />
	{&raquo;NT_STATUS_ALLOTTED_SPACE_EXCEEDED&raquo;,<br />
	 NT_STATUS_ALLOTTED_SPACE_EXCEEDED},<br />
	{&raquo;NT_STATUS_INSUFFICIENT_RESOURCES&raquo;,<br />
	 NT_STATUS_INSUFFICIENT_RESOURCES},<br />
	{&raquo;NT_STATUS_DFS_EXIT_PATH_FOUND&raquo;, NT_STATUS_DFS_EXIT_PATH_FOUND},<br />
	{&raquo;NT_STATUS_DEVICE_DATA_ERROR&raquo;, NT_STATUS_DEVICE_DATA_ERROR},<br />
	{&raquo;NT_STATUS_DEVICE_NOT_CONNECTED&raquo;, NT_STATUS_DEVICE_NOT_CONNECTED},<br />
	{&raquo;NT_STATUS_DEVICE_POWER_FAILURE&raquo;, NT_STATUS_DEVICE_POWER_FAILURE},<br />
	{&raquo;NT_STATUS_FREE_VM_NOT_AT_BASE&raquo;, NT_STATUS_FREE_VM_NOT_AT_BASE},<br />
	{&raquo;NT_STATUS_MEMORY_NOT_ALLOCATED&raquo;, NT_STATUS_MEMORY_NOT_ALLOCATED},<br />
	{&raquo;NT_STATUS_WORKING_SET_QUOTA&raquo;, NT_STATUS_WORKING_SET_QUOTA},<br />
	{&raquo;NT_STATUS_MEDIA_WRITE_PROTECTED&raquo;,<br />
	 NT_STATUS_MEDIA_WRITE_PROTECTED},<br />
	{&raquo;NT_STATUS_DEVICE_NOT_READY&raquo;, NT_STATUS_DEVICE_NOT_READY},<br />
	{&raquo;NT_STATUS_INVALID_GROUP_ATTRIBUTES&raquo;,<br />
	 NT_STATUS_INVALID_GROUP_ATTRIBUTES},<br />
	{&raquo;NT_STATUS_BAD_IMPERSONATION_LEVEL&raquo;,<br />
	 NT_STATUS_BAD_IMPERSONATION_LEVEL},<br />
	{&raquo;NT_STATUS_CANT_OPEN_ANONYMOUS&raquo;, NT_STATUS_CANT_OPEN_ANONYMOUS},<br />
	{&raquo;NT_STATUS_BAD_VALIDATION_CLASS&raquo;, NT_STATUS_BAD_VALIDATION_CLASS},<br />
	{&raquo;NT_STATUS_BAD_TOKEN_TYPE&raquo;, NT_STATUS_BAD_TOKEN_TYPE},<br />
	{&raquo;NT_STATUS_BAD_MASTER_BOOT_RECORD&raquo;,<br />
	 NT_STATUS_BAD_MASTER_BOOT_RECORD},<br />
	{&raquo;NT_STATUS_INSTRUCTION_MISALIGNMENT&raquo;,<br />
	 NT_STATUS_INSTRUCTION_MISALIGNMENT},<br />
	{&raquo;NT_STATUS_INSTANCE_NOT_AVAILABLE&raquo;,<br />
	 NT_STATUS_INSTANCE_NOT_AVAILABLE},<br />
	{&raquo;NT_STATUS_PIPE_NOT_AVAILABLE&raquo;, NT_STATUS_PIPE_NOT_AVAILABLE},<br />
	{&raquo;NT_STATUS_INVALID_PIPE_STATE&raquo;, NT_STATUS_INVALID_PIPE_STATE},<br />
	{&raquo;NT_STATUS_PIPE_BUSY&raquo;, NT_STATUS_PIPE_BUSY},<br />
	{&raquo;NT_STATUS_ILLEGAL_FUNCTION&raquo;, NT_STATUS_ILLEGAL_FUNCTION},<br />
	{&raquo;NT_STATUS_PIPE_DISCONNECTED&raquo;, NT_STATUS_PIPE_DISCONNECTED},<br />
	{&raquo;NT_STATUS_PIPE_CLOSING&raquo;, NT_STATUS_PIPE_CLOSING},<br />
	{&raquo;NT_STATUS_PIPE_CONNECTED&raquo;, NT_STATUS_PIPE_CONNECTED},<br />
	{&raquo;NT_STATUS_PIPE_LISTENING&raquo;, NT_STATUS_PIPE_LISTENING},<br />
	{&raquo;NT_STATUS_INVALID_READ_MODE&raquo;, NT_STATUS_INVALID_READ_MODE},<br />
	{&raquo;NT_STATUS_IO_TIMEOUT&raquo;, NT_STATUS_IO_TIMEOUT},<br />
	{&raquo;NT_STATUS_FILE_FORCED_CLOSED&raquo;, NT_STATUS_FILE_FORCED_CLOSED},<br />
	{&raquo;NT_STATUS_PROFILING_NOT_STARTED&raquo;,<br />
	 NT_STATUS_PROFILING_NOT_STARTED},<br />
	{&raquo;NT_STATUS_PROFILING_NOT_STOPPED&raquo;,<br />
	 NT_STATUS_PROFILING_NOT_STOPPED},<br />
	{&raquo;NT_STATUS_COULD_NOT_INTERPRET&raquo;, NT_STATUS_COULD_NOT_INTERPRET},<br />
	{&raquo;NT_STATUS_FILE_IS_A_DIRECTORY&raquo;, NT_STATUS_FILE_IS_A_DIRECTORY},<br />
	{&raquo;NT_STATUS_NOT_SUPPORTED&raquo;, NT_STATUS_NOT_SUPPORTED},<br />
	{&raquo;NT_STATUS_REMOTE_NOT_LISTENING&raquo;, NT_STATUS_REMOTE_NOT_LISTENING},<br />
	{&raquo;NT_STATUS_DUPLICATE_NAME&raquo;, NT_STATUS_DUPLICATE_NAME},<br />
	{&raquo;NT_STATUS_BAD_NETWORK_PATH&raquo;, NT_STATUS_BAD_NETWORK_PATH},<br />
	{&raquo;NT_STATUS_NETWORK_BUSY&raquo;, NT_STATUS_NETWORK_BUSY},<br />
	{&raquo;NT_STATUS_DEVICE_DOES_NOT_EXIST&raquo;,<br />
	 NT_STATUS_DEVICE_DOES_NOT_EXIST},<br />
	{&raquo;NT_STATUS_TOO_MANY_COMMANDS&raquo;, NT_STATUS_TOO_MANY_COMMANDS},<br />
	{&raquo;NT_STATUS_ADAPTER_HARDWARE_ERROR&raquo;,<br />
	 NT_STATUS_ADAPTER_HARDWARE_ERROR},<br />
	{&raquo;NT_STATUS_INVALID_NETWORK_RESPONSE&raquo;,<br />
	 NT_STATUS_INVALID_NETWORK_RESPONSE},<br />
	{&raquo;NT_STATUS_UNEXPECTED_NETWORK_ERROR&raquo;,<br />
	 NT_STATUS_UNEXPECTED_NETWORK_ERROR},<br />
	{&raquo;NT_STATUS_BAD_REMOTE_ADAPTER&raquo;, NT_STATUS_BAD_REMOTE_ADAPTER},<br />
	{&raquo;NT_STATUS_PRINT_QUEUE_FULL&raquo;, NT_STATUS_PRINT_QUEUE_FULL},<br />
	{&raquo;NT_STATUS_NO_SPOOL_SPACE&raquo;, NT_STATUS_NO_SPOOL_SPACE},<br />
	{&raquo;NT_STATUS_PRINT_CANCELLED&raquo;, NT_STATUS_PRINT_CANCELLED},<br />
	{&raquo;NT_STATUS_NETWORK_NAME_DELETED&raquo;, NT_STATUS_NETWORK_NAME_DELETED},<br />
	{&raquo;NT_STATUS_NETWORK_ACCESS_DENIED&raquo;,<br />
	 NT_STATUS_NETWORK_ACCESS_DENIED},<br />
	{&raquo;NT_STATUS_BAD_DEVICE_TYPE&raquo;, NT_STATUS_BAD_DEVICE_TYPE},<br />
	{&raquo;NT_STATUS_BAD_NETWORK_NAME&raquo;, NT_STATUS_BAD_NETWORK_NAME},<br />
	{&raquo;NT_STATUS_TOO_MANY_NAMES&raquo;, NT_STATUS_TOO_MANY_NAMES},<br />
	{&raquo;NT_STATUS_TOO_MANY_SESSIONS&raquo;, NT_STATUS_TOO_MANY_SESSIONS},<br />
	{&raquo;NT_STATUS_SHARING_PAUSED&raquo;, NT_STATUS_SHARING_PAUSED},<br />
	{&raquo;NT_STATUS_REQUEST_NOT_ACCEPTED&raquo;, NT_STATUS_REQUEST_NOT_ACCEPTED},<br />
	{&raquo;NT_STATUS_REDIRECTOR_PAUSED&raquo;, NT_STATUS_REDIRECTOR_PAUSED},<br />
	{&raquo;NT_STATUS_NET_WRITE_FAULT&raquo;, NT_STATUS_NET_WRITE_FAULT},<br />
	{&raquo;NT_STATUS_PROFILING_AT_LIMIT&raquo;, NT_STATUS_PROFILING_AT_LIMIT},<br />
	{&raquo;NT_STATUS_NOT_SAME_DEVICE&raquo;, NT_STATUS_NOT_SAME_DEVICE},<br />
	{&raquo;NT_STATUS_FILE_RENAMED&raquo;, NT_STATUS_FILE_RENAMED},<br />
	{&raquo;NT_STATUS_VIRTUAL_CIRCUIT_CLOSED&raquo;,<br />
	 NT_STATUS_VIRTUAL_CIRCUIT_CLOSED},<br />
	{&raquo;NT_STATUS_NO_SECURITY_ON_OBJECT&raquo;,<br />
	 NT_STATUS_NO_SECURITY_ON_OBJECT},<br />
	{&raquo;NT_STATUS_CANT_WAIT&raquo;, NT_STATUS_CANT_WAIT},<br />
	{&raquo;NT_STATUS_PIPE_EMPTY&raquo;, NT_STATUS_PIPE_EMPTY},<br />
	{&raquo;NT_STATUS_CANT_ACCESS_DOMAIN_INFO&raquo;,<br />
	 NT_STATUS_CANT_ACCESS_DOMAIN_INFO},<br />
	{&raquo;NT_STATUS_CANT_TERMINATE_SELF&raquo;, NT_STATUS_CANT_TERMINATE_SELF},<br />
	{&raquo;NT_STATUS_INVALID_SERVER_STATE&raquo;, NT_STATUS_INVALID_SERVER_STATE},<br />
	{&raquo;NT_STATUS_INVALID_DOMAIN_STATE&raquo;, NT_STATUS_INVALID_DOMAIN_STATE},<br />
	{&raquo;NT_STATUS_INVALID_DOMAIN_ROLE&raquo;, NT_STATUS_INVALID_DOMAIN_ROLE},<br />
	{&raquo;NT_STATUS_NO_SUCH_DOMAIN&raquo;, NT_STATUS_NO_SUCH_DOMAIN},<br />
	{&raquo;NT_STATUS_DOMAIN_EXISTS&raquo;, NT_STATUS_DOMAIN_EXISTS},<br />
	{&raquo;NT_STATUS_DOMAIN_LIMIT_EXCEEDED&raquo;,<br />
	 NT_STATUS_DOMAIN_LIMIT_EXCEEDED},<br />
	{&raquo;NT_STATUS_OPLOCK_NOT_GRANTED&raquo;, NT_STATUS_OPLOCK_NOT_GRANTED},<br />
	{&raquo;NT_STATUS_INVALID_OPLOCK_PROTOCOL&raquo;,<br />
	 NT_STATUS_INVALID_OPLOCK_PROTOCOL},<br />
	{&raquo;NT_STATUS_INTERNAL_DB_CORRUPTION&raquo;,<br />
	 NT_STATUS_INTERNAL_DB_CORRUPTION},<br />
	{&raquo;NT_STATUS_INTERNAL_ERROR&raquo;, NT_STATUS_INTERNAL_ERROR},<br />
	{&raquo;NT_STATUS_GENERIC_NOT_MAPPED&raquo;, NT_STATUS_GENERIC_NOT_MAPPED},<br />
	{&raquo;NT_STATUS_BAD_DESCRIPTOR_FORMAT&raquo;,<br />
	 NT_STATUS_BAD_DESCRIPTOR_FORMAT},<br />
	{&raquo;NT_STATUS_INVALID_USER_BUFFER&raquo;, NT_STATUS_INVALID_USER_BUFFER},<br />
	{&raquo;NT_STATUS_UNEXPECTED_IO_ERROR&raquo;, NT_STATUS_UNEXPECTED_IO_ERROR},<br />
	{&raquo;NT_STATUS_UNEXPECTED_MM_CREATE_ERR&raquo;,<br />
	 NT_STATUS_UNEXPECTED_MM_CREATE_ERR},<br />
	{&raquo;NT_STATUS_UNEXPECTED_MM_MAP_ERROR&raquo;,<br />
	 NT_STATUS_UNEXPECTED_MM_MAP_ERROR},<br />
	{&raquo;NT_STATUS_UNEXPECTED_MM_EXTEND_ERR&raquo;,<br />
	 NT_STATUS_UNEXPECTED_MM_EXTEND_ERR},<br />
	{&raquo;NT_STATUS_NOT_LOGON_PROCESS&raquo;, NT_STATUS_NOT_LOGON_PROCESS},<br />
	{&raquo;NT_STATUS_LOGON_SESSION_EXISTS&raquo;, NT_STATUS_LOGON_SESSION_EXISTS},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_1&#8243;, NT_STATUS_INVALID_PARAMETER_1},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_2&#8243;, NT_STATUS_INVALID_PARAMETER_2},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_3&#8243;, NT_STATUS_INVALID_PARAMETER_3},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_4&#8243;, NT_STATUS_INVALID_PARAMETER_4},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_5&#8243;, NT_STATUS_INVALID_PARAMETER_5},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_6&#8243;, NT_STATUS_INVALID_PARAMETER_6},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_7&#8243;, NT_STATUS_INVALID_PARAMETER_7},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_8&#8243;, NT_STATUS_INVALID_PARAMETER_8},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_9&#8243;, NT_STATUS_INVALID_PARAMETER_9},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_10&#8243;, NT_STATUS_INVALID_PARAMETER_10},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_11&#8243;, NT_STATUS_INVALID_PARAMETER_11},<br />
	{&raquo;NT_STATUS_INVALID_PARAMETER_12&#8243;, NT_STATUS_INVALID_PARAMETER_12},<br />
	{&raquo;NT_STATUS_REDIRECTOR_NOT_STARTED&raquo;,<br />
	 NT_STATUS_REDIRECTOR_NOT_STARTED},<br />
	{&raquo;NT_STATUS_REDIRECTOR_STARTED&raquo;, NT_STATUS_REDIRECTOR_STARTED},<br />
	{&raquo;NT_STATUS_STACK_OVERFLOW&raquo;, NT_STATUS_STACK_OVERFLOW},<br />
	{&raquo;NT_STATUS_NO_SUCH_PACKAGE&raquo;, NT_STATUS_NO_SUCH_PACKAGE},<br />
	{&raquo;NT_STATUS_BAD_FUNCTION_TABLE&raquo;, NT_STATUS_BAD_FUNCTION_TABLE},<br />
	{&raquo;NT_STATUS_DIRECTORY_NOT_EMPTY&raquo;, NT_STATUS_DIRECTORY_NOT_EMPTY},<br />
	{&raquo;NT_STATUS_FILE_CORRUPT_ERROR&raquo;, NT_STATUS_FILE_CORRUPT_ERROR},<br />
	{&raquo;NT_STATUS_NOT_A_DIRECTORY&raquo;, NT_STATUS_NOT_A_DIRECTORY},<br />
	{&raquo;NT_STATUS_BAD_LOGON_SESSION_STATE&raquo;,<br />
	 NT_STATUS_BAD_LOGON_SESSION_STATE},<br />
	{&raquo;NT_STATUS_LOGON_SESSION_COLLISION&raquo;,<br />
	 NT_STATUS_LOGON_SESSION_COLLISION},<br />
	{&raquo;NT_STATUS_NAME_TOO_LONG&raquo;, NT_STATUS_NAME_TOO_LONG},<br />
	{&raquo;NT_STATUS_FILES_OPEN&raquo;, NT_STATUS_FILES_OPEN},<br />
	{&raquo;NT_STATUS_CONNECTION_IN_USE&raquo;, NT_STATUS_CONNECTION_IN_USE},<br />
	{&raquo;NT_STATUS_MESSAGE_NOT_FOUND&raquo;, NT_STATUS_MESSAGE_NOT_FOUND},<br />
	{&raquo;NT_STATUS_PROCESS_IS_TERMINATING&raquo;,<br />
	 NT_STATUS_PROCESS_IS_TERMINATING},<br />
	{&raquo;NT_STATUS_INVALID_LOGON_TYPE&raquo;, NT_STATUS_INVALID_LOGON_TYPE},<br />
	{&raquo;NT_STATUS_NO_GUID_TRANSLATION&raquo;, NT_STATUS_NO_GUID_TRANSLATION},<br />
	{&raquo;NT_STATUS_CANNOT_IMPERSONATE&raquo;, NT_STATUS_CANNOT_IMPERSONATE},<br />
	{&raquo;NT_STATUS_IMAGE_ALREADY_LOADED&raquo;, NT_STATUS_IMAGE_ALREADY_LOADED},<br />
	{&raquo;NT_STATUS_ABIOS_NOT_PRESENT&raquo;, NT_STATUS_ABIOS_NOT_PRESENT},<br />
	{&raquo;NT_STATUS_ABIOS_LID_NOT_EXIST&raquo;, NT_STATUS_ABIOS_LID_NOT_EXIST},<br />
	{&raquo;NT_STATUS_ABIOS_LID_ALREADY_OWNED&raquo;,<br />
	 NT_STATUS_ABIOS_LID_ALREADY_OWNED},<br />
	{&raquo;NT_STATUS_ABIOS_NOT_LID_OWNER&raquo;, NT_STATUS_ABIOS_NOT_LID_OWNER},<br />
	{&raquo;NT_STATUS_ABIOS_INVALID_COMMAND&raquo;,<br />
	 NT_STATUS_ABIOS_INVALID_COMMAND},<br />
	{&raquo;NT_STATUS_ABIOS_INVALID_LID&raquo;, NT_STATUS_ABIOS_INVALID_LID},<br />
	{&raquo;NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE&raquo;,<br />
	 NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE},<br />
	{&raquo;NT_STATUS_ABIOS_INVALID_SELECTOR&raquo;,<br />
	 NT_STATUS_ABIOS_INVALID_SELECTOR},<br />
	{&raquo;NT_STATUS_NO_LDT&raquo;, NT_STATUS_NO_LDT},<br />
	{&raquo;NT_STATUS_INVALID_LDT_SIZE&raquo;, NT_STATUS_INVALID_LDT_SIZE},<br />
	{&raquo;NT_STATUS_INVALID_LDT_OFFSET&raquo;, NT_STATUS_INVALID_LDT_OFFSET},<br />
	{&raquo;NT_STATUS_INVALID_LDT_DESCRIPTOR&raquo;,<br />
	 NT_STATUS_INVALID_LDT_DESCRIPTOR},<br />
	{&raquo;NT_STATUS_INVALID_IMAGE_NE_FORMAT&raquo;,<br />
	 NT_STATUS_INVALID_IMAGE_NE_FORMAT},<br />
	{&raquo;NT_STATUS_RXACT_INVALID_STATE&raquo;, NT_STATUS_RXACT_INVALID_STATE},<br />
	{&raquo;NT_STATUS_RXACT_COMMIT_FAILURE&raquo;, NT_STATUS_RXACT_COMMIT_FAILURE},<br />
	{&raquo;NT_STATUS_MAPPED_FILE_SIZE_ZERO&raquo;,<br />
	 NT_STATUS_MAPPED_FILE_SIZE_ZERO},<br />
	{&raquo;NT_STATUS_TOO_MANY_OPENED_FILES&raquo;,<br />
	 NT_STATUS_TOO_MANY_OPENED_FILES},<br />
	{&raquo;NT_STATUS_CANCELLED&raquo;, NT_STATUS_CANCELLED},<br />
	{&raquo;NT_STATUS_CANNOT_DELETE&raquo;, NT_STATUS_CANNOT_DELETE},<br />
	{&raquo;NT_STATUS_INVALID_COMPUTER_NAME&raquo;,<br />
	 NT_STATUS_INVALID_COMPUTER_NAME},<br />
	{&raquo;NT_STATUS_FILE_DELETED&raquo;, NT_STATUS_FILE_DELETED},<br />
	{&raquo;NT_STATUS_SPECIAL_ACCOUNT&raquo;, NT_STATUS_SPECIAL_ACCOUNT},<br />
	{&raquo;NT_STATUS_SPECIAL_GROUP&raquo;, NT_STATUS_SPECIAL_GROUP},<br />
	{&raquo;NT_STATUS_SPECIAL_USER&raquo;, NT_STATUS_SPECIAL_USER},<br />
	{&raquo;NT_STATUS_MEMBERS_PRIMARY_GROUP&raquo;,<br />
	 NT_STATUS_MEMBERS_PRIMARY_GROUP},<br />
	{&raquo;NT_STATUS_FILE_CLOSED&raquo;, NT_STATUS_FILE_CLOSED},<br />
	{&raquo;NT_STATUS_TOO_MANY_THREADS&raquo;, NT_STATUS_TOO_MANY_THREADS},<br />
	{&raquo;NT_STATUS_THREAD_NOT_IN_PROCESS&raquo;,<br />
	 NT_STATUS_THREAD_NOT_IN_PROCESS},<br />
	{&raquo;NT_STATUS_TOKEN_ALREADY_IN_USE&raquo;, NT_STATUS_TOKEN_ALREADY_IN_USE},<br />
	{&raquo;NT_STATUS_PAGEFILE_QUOTA_EXCEEDED&raquo;,<br />
	 NT_STATUS_PAGEFILE_QUOTA_EXCEEDED},<br />
	{&raquo;NT_STATUS_COMMITMENT_LIMIT&raquo;, NT_STATUS_COMMITMENT_LIMIT},<br />
	{&raquo;NT_STATUS_INVALID_IMAGE_LE_FORMAT&raquo;,<br />
	 NT_STATUS_INVALID_IMAGE_LE_FORMAT},<br />
	{&raquo;NT_STATUS_INVALID_IMAGE_NOT_MZ&raquo;, NT_STATUS_INVALID_IMAGE_NOT_MZ},<br />
	{&raquo;NT_STATUS_INVALID_IMAGE_PROTECT&raquo;,<br />
	 NT_STATUS_INVALID_IMAGE_PROTECT},<br />
	{&raquo;NT_STATUS_INVALID_IMAGE_WIN_16&#8243;, NT_STATUS_INVALID_IMAGE_WIN_16},<br />
	{&raquo;NT_STATUS_LOGON_SERVER_CONFLICT&raquo;,<br />
	 NT_STATUS_LOGON_SERVER_CONFLICT},<br />
	{&raquo;NT_STATUS_TIME_DIFFERENCE_AT_DC&raquo;,<br />
	 NT_STATUS_TIME_DIFFERENCE_AT_DC},<br />
	{&raquo;NT_STATUS_SYNCHRONIZATION_REQUIRED&raquo;,<br />
	 NT_STATUS_SYNCHRONIZATION_REQUIRED},<br />
	{&raquo;NT_STATUS_DLL_NOT_FOUND&raquo;, NT_STATUS_DLL_NOT_FOUND},<br />
	{&raquo;NT_STATUS_OPEN_FAILED&raquo;, NT_STATUS_OPEN_FAILED},<br />
	{&raquo;NT_STATUS_IO_PRIVILEGE_FAILED&raquo;, NT_STATUS_IO_PRIVILEGE_FAILED},<br />
	{&raquo;NT_STATUS_ORDINAL_NOT_FOUND&raquo;, NT_STATUS_ORDINAL_NOT_FOUND},<br />
	{&raquo;NT_STATUS_ENTRYPOINT_NOT_FOUND&raquo;, NT_STATUS_ENTRYPOINT_NOT_FOUND},<br />
	{&raquo;NT_STATUS_CONTROL_C_EXIT&raquo;, NT_STATUS_CONTROL_C_EXIT},<br />
	{&raquo;NT_STATUS_LOCAL_DISCONNECT&raquo;, NT_STATUS_LOCAL_DISCONNECT},<br />
	{&raquo;NT_STATUS_REMOTE_DISCONNECT&raquo;, NT_STATUS_REMOTE_DISCONNECT},<br />
	{&raquo;NT_STATUS_REMOTE_RESOURCES&raquo;, NT_STATUS_REMOTE_RESOURCES},<br />
	{&raquo;NT_STATUS_LINK_FAILED&raquo;, NT_STATUS_LINK_FAILED},<br />
	{&raquo;NT_STATUS_LINK_TIMEOUT&raquo;, NT_STATUS_LINK_TIMEOUT},<br />
	{&raquo;NT_STATUS_INVALID_CONNECTION&raquo;, NT_STATUS_INVALID_CONNECTION},<br />
	{&raquo;NT_STATUS_INVALID_ADDRESS&raquo;, NT_STATUS_INVALID_ADDRESS},<br />
	{&raquo;NT_STATUS_DLL_INIT_FAILED&raquo;, NT_STATUS_DLL_INIT_FAILED},<br />
	{&raquo;NT_STATUS_MISSING_SYSTEMFILE&raquo;, NT_STATUS_MISSING_SYSTEMFILE},<br />
	{&raquo;NT_STATUS_UNHANDLED_EXCEPTION&raquo;, NT_STATUS_UNHANDLED_EXCEPTION},<br />
	{&raquo;NT_STATUS_APP_INIT_FAILURE&raquo;, NT_STATUS_APP_INIT_FAILURE},<br />
	{&raquo;NT_STATUS_PAGEFILE_CREATE_FAILED&raquo;,<br />
	 NT_STATUS_PAGEFILE_CREATE_FAILED},<br />
	{&raquo;NT_STATUS_NO_PAGEFILE&raquo;, NT_STATUS_NO_PAGEFILE},<br />
	{&raquo;NT_STATUS_INVALID_LEVEL&raquo;, NT_STATUS_INVALID_LEVEL},<br />
	{&raquo;NT_STATUS_WRONG_PASSWORD_CORE&raquo;, NT_STATUS_WRONG_PASSWORD_CORE},<br />
	{&raquo;NT_STATUS_ILLEGAL_FLOAT_CONTEXT&raquo;,<br />
	 NT_STATUS_ILLEGAL_FLOAT_CONTEXT},<br />
	{&raquo;NT_STATUS_PIPE_BROKEN&raquo;, NT_STATUS_PIPE_BROKEN},<br />
	{&raquo;NT_STATUS_REGISTRY_CORRUPT&raquo;, NT_STATUS_REGISTRY_CORRUPT},<br />
	{&raquo;NT_STATUS_REGISTRY_IO_FAILED&raquo;, NT_STATUS_REGISTRY_IO_FAILED},<br />
	{&raquo;NT_STATUS_NO_EVENT_PAIR&raquo;, NT_STATUS_NO_EVENT_PAIR},<br />
	{&raquo;NT_STATUS_UNRECOGNIZED_VOLUME&raquo;, NT_STATUS_UNRECOGNIZED_VOLUME},<br />
	{&raquo;NT_STATUS_SERIAL_NO_DEVICE_INITED&raquo;,<br />
	 NT_STATUS_SERIAL_NO_DEVICE_INITED},<br />
	{&raquo;NT_STATUS_NO_SUCH_ALIAS&raquo;, NT_STATUS_NO_SUCH_ALIAS},<br />
	{&raquo;NT_STATUS_MEMBER_NOT_IN_ALIAS&raquo;, NT_STATUS_MEMBER_NOT_IN_ALIAS},<br />
	{&raquo;NT_STATUS_MEMBER_IN_ALIAS&raquo;, NT_STATUS_MEMBER_IN_ALIAS},<br />
	{&raquo;NT_STATUS_ALIAS_EXISTS&raquo;, NT_STATUS_ALIAS_EXISTS},<br />
	{&raquo;NT_STATUS_LOGON_NOT_GRANTED&raquo;, NT_STATUS_LOGON_NOT_GRANTED},<br />
	{&raquo;NT_STATUS_TOO_MANY_SECRETS&raquo;, NT_STATUS_TOO_MANY_SECRETS},<br />
	{&raquo;NT_STATUS_SECRET_TOO_LONG&raquo;, NT_STATUS_SECRET_TOO_LONG},<br />
	{&raquo;NT_STATUS_INTERNAL_DB_ERROR&raquo;, NT_STATUS_INTERNAL_DB_ERROR},<br />
	{&raquo;NT_STATUS_FULLSCREEN_MODE&raquo;, NT_STATUS_FULLSCREEN_MODE},<br />
	{&raquo;NT_STATUS_TOO_MANY_CONTEXT_IDS&raquo;, NT_STATUS_TOO_MANY_CONTEXT_IDS},<br />
	{&raquo;NT_STATUS_LOGON_TYPE_NOT_GRANTED&raquo;,<br />
	 NT_STATUS_LOGON_TYPE_NOT_GRANTED},<br />
	{&raquo;NT_STATUS_NOT_REGISTRY_FILE&raquo;, NT_STATUS_NOT_REGISTRY_FILE},<br />
	{&raquo;NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED&raquo;,<br />
	 NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED},<br />
	{&raquo;NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR&raquo;,<br />
	 NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR},<br />
	{&raquo;NT_STATUS_FT_MISSING_MEMBER&raquo;, NT_STATUS_FT_MISSING_MEMBER},<br />
	{&raquo;NT_STATUS_ILL_FORMED_SERVICE_ENTRY&raquo;,<br />
	 NT_STATUS_ILL_FORMED_SERVICE_ENTRY},<br />
	{&raquo;NT_STATUS_ILLEGAL_CHARACTER&raquo;, NT_STATUS_ILLEGAL_CHARACTER},<br />
	{&raquo;NT_STATUS_UNMAPPABLE_CHARACTER&raquo;, NT_STATUS_UNMAPPABLE_CHARACTER},<br />
	{&raquo;NT_STATUS_UNDEFINED_CHARACTER&raquo;, NT_STATUS_UNDEFINED_CHARACTER},<br />
	{&raquo;NT_STATUS_FLOPPY_VOLUME&raquo;, NT_STATUS_FLOPPY_VOLUME},<br />
	{&raquo;NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND&raquo;,<br />
	 NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND},<br />
	{&raquo;NT_STATUS_FLOPPY_WRONG_CYLINDER&raquo;,<br />
	 NT_STATUS_FLOPPY_WRONG_CYLINDER},<br />
	{&raquo;NT_STATUS_FLOPPY_UNKNOWN_ERROR&raquo;, NT_STATUS_FLOPPY_UNKNOWN_ERROR},<br />
	{&raquo;NT_STATUS_FLOPPY_BAD_REGISTERS&raquo;, NT_STATUS_FLOPPY_BAD_REGISTERS},<br />
	{&raquo;NT_STATUS_DISK_RECALIBRATE_FAILED&raquo;,<br />
	 NT_STATUS_DISK_RECALIBRATE_FAILED},<br />
	{&raquo;NT_STATUS_DISK_OPERATION_FAILED&raquo;,<br />
	 NT_STATUS_DISK_OPERATION_FAILED},<br />
	{&raquo;NT_STATUS_DISK_RESET_FAILED&raquo;, NT_STATUS_DISK_RESET_FAILED},<br />
	{&raquo;NT_STATUS_SHARED_IRQ_BUSY&raquo;, NT_STATUS_SHARED_IRQ_BUSY},<br />
	{&raquo;NT_STATUS_FT_ORPHANING&raquo;, NT_STATUS_FT_ORPHANING},<br />
	{&raquo;NT_STATUS_PARTITION_FAILURE&raquo;, NT_STATUS_PARTITION_FAILURE},<br />
	{&raquo;NT_STATUS_INVALID_BLOCK_LENGTH&raquo;, NT_STATUS_INVALID_BLOCK_LENGTH},<br />
	{&raquo;NT_STATUS_DEVICE_NOT_PARTITIONED&raquo;,<br />
	 NT_STATUS_DEVICE_NOT_PARTITIONED},<br />
	{&raquo;NT_STATUS_UNABLE_TO_LOCK_MEDIA&raquo;, NT_STATUS_UNABLE_TO_LOCK_MEDIA},<br />
	{&raquo;NT_STATUS_UNABLE_TO_UNLOAD_MEDIA&raquo;,<br />
	 NT_STATUS_UNABLE_TO_UNLOAD_MEDIA},<br />
	{&raquo;NT_STATUS_EOM_OVERFLOW&raquo;, NT_STATUS_EOM_OVERFLOW},<br />
	{&raquo;NT_STATUS_NO_MEDIA&raquo;, NT_STATUS_NO_MEDIA},<br />
	{&raquo;NT_STATUS_NO_SUCH_MEMBER&raquo;, NT_STATUS_NO_SUCH_MEMBER},<br />
	{&raquo;NT_STATUS_INVALID_MEMBER&raquo;, NT_STATUS_INVALID_MEMBER},<br />
	{&raquo;NT_STATUS_KEY_DELETED&raquo;, NT_STATUS_KEY_DELETED},<br />
	{&raquo;NT_STATUS_NO_LOG_SPACE&raquo;, NT_STATUS_NO_LOG_SPACE},<br />
	{&raquo;NT_STATUS_TOO_MANY_SIDS&raquo;, NT_STATUS_TOO_MANY_SIDS},<br />
	{&raquo;NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED&raquo;,<br />
	 NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED},<br />
	{&raquo;NT_STATUS_KEY_HAS_CHILDREN&raquo;, NT_STATUS_KEY_HAS_CHILDREN},<br />
	{&raquo;NT_STATUS_CHILD_MUST_BE_VOLATILE&raquo;,<br />
	 NT_STATUS_CHILD_MUST_BE_VOLATILE},<br />
	{&raquo;NT_STATUS_DEVICE_CONFIGURATION_ERROR&raquo;,<br />
	 NT_STATUS_DEVICE_CONFIGURATION_ERROR},<br />
	{&raquo;NT_STATUS_DRIVER_INTERNAL_ERROR&raquo;,<br />
	 NT_STATUS_DRIVER_INTERNAL_ERROR},<br />
	{&raquo;NT_STATUS_INVALID_DEVICE_STATE&raquo;, NT_STATUS_INVALID_DEVICE_STATE},<br />
	{&raquo;NT_STATUS_IO_DEVICE_ERROR&raquo;, NT_STATUS_IO_DEVICE_ERROR},<br />
	{&raquo;NT_STATUS_DEVICE_PROTOCOL_ERROR&raquo;,<br />
	 NT_STATUS_DEVICE_PROTOCOL_ERROR},<br />
	{&raquo;NT_STATUS_BACKUP_CONTROLLER&raquo;, NT_STATUS_BACKUP_CONTROLLER},<br />
	{&raquo;NT_STATUS_LOG_FILE_FULL&raquo;, NT_STATUS_LOG_FILE_FULL},<br />
	{&raquo;NT_STATUS_TOO_LATE&raquo;, NT_STATUS_TOO_LATE},<br />
	{&raquo;NT_STATUS_NO_TRUST_LSA_SECRET&raquo;, NT_STATUS_NO_TRUST_LSA_SECRET},<br />
	{&raquo;NT_STATUS_NO_TRUST_SAM_ACCOUNT&raquo;, NT_STATUS_NO_TRUST_SAM_ACCOUNT},<br />
	{&raquo;NT_STATUS_TRUSTED_DOMAIN_FAILURE&raquo;,<br />
	 NT_STATUS_TRUSTED_DOMAIN_FAILURE},<br />
	{&raquo;NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE&raquo;,<br />
	 NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE},<br />
	{&raquo;NT_STATUS_EVENTLOG_FILE_CORRUPT&raquo;,<br />
	 NT_STATUS_EVENTLOG_FILE_CORRUPT},<br />
	{&raquo;NT_STATUS_EVENTLOG_CANT_START&raquo;, NT_STATUS_EVENTLOG_CANT_START},<br />
	{&raquo;NT_STATUS_TRUST_FAILURE&raquo;, NT_STATUS_TRUST_FAILURE},<br />
	{&raquo;NT_STATUS_MUTANT_LIMIT_EXCEEDED&raquo;,<br />
	 NT_STATUS_MUTANT_LIMIT_EXCEEDED},<br />
	{&raquo;NT_STATUS_NETLOGON_NOT_STARTED&raquo;, NT_STATUS_NETLOGON_NOT_STARTED},<br />
	{&raquo;NT_STATUS_ACCOUNT_EXPIRED&raquo;, NT_STATUS_ACCOUNT_EXPIRED},<br />
	{&raquo;NT_STATUS_POSSIBLE_DEADLOCK&raquo;, NT_STATUS_POSSIBLE_DEADLOCK},<br />
	{&raquo;NT_STATUS_NETWORK_CREDENTIAL_CONFLICT&raquo;,<br />
	 NT_STATUS_NETWORK_CREDENTIAL_CONFLICT},<br />
	{&raquo;NT_STATUS_REMOTE_SESSION_LIMIT&raquo;, NT_STATUS_REMOTE_SESSION_LIMIT},<br />
	{&raquo;NT_STATUS_EVENTLOG_FILE_CHANGED&raquo;,<br />
	 NT_STATUS_EVENTLOG_FILE_CHANGED},<br />
	{&raquo;NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT&raquo;,<br />
	 NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT},<br />
	{&raquo;NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT&raquo;,<br />
	 NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT},<br />
	{&raquo;NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT&raquo;,<br />
	 NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT},<br />
	{&raquo;NT_STATUS_DOMAIN_TRUST_INCONSISTENT&raquo;,<br />
	 NT_STATUS_DOMAIN_TRUST_INCONSISTENT},<br />
	{&raquo;NT_STATUS_FS_DRIVER_REQUIRED&raquo;, NT_STATUS_FS_DRIVER_REQUIRED},<br />
	{&raquo;NT_STATUS_NO_USER_SESSION_KEY&raquo;, NT_STATUS_NO_USER_SESSION_KEY},<br />
	{&raquo;NT_STATUS_USER_SESSION_DELETED&raquo;, NT_STATUS_USER_SESSION_DELETED},<br />
	{&raquo;NT_STATUS_RESOURCE_LANG_NOT_FOUND&raquo;,<br />
	 NT_STATUS_RESOURCE_LANG_NOT_FOUND},<br />
	{&raquo;NT_STATUS_INSUFF_SERVER_RESOURCES&raquo;,<br />
	 NT_STATUS_INSUFF_SERVER_RESOURCES},<br />
	{&raquo;NT_STATUS_INVALID_BUFFER_SIZE&raquo;, NT_STATUS_INVALID_BUFFER_SIZE},<br />
	{&raquo;NT_STATUS_INVALID_ADDRESS_COMPONENT&raquo;,<br />
	 NT_STATUS_INVALID_ADDRESS_COMPONENT},<br />
	{&raquo;NT_STATUS_INVALID_ADDRESS_WILDCARD&raquo;,<br />
	 NT_STATUS_INVALID_ADDRESS_WILDCARD},<br />
	{&raquo;NT_STATUS_TOO_MANY_ADDRESSES&raquo;, NT_STATUS_TOO_MANY_ADDRESSES},<br />
	{&raquo;NT_STATUS_ADDRESS_ALREADY_EXISTS&raquo;,<br />
	 NT_STATUS_ADDRESS_ALREADY_EXISTS},<br />
	{&raquo;NT_STATUS_ADDRESS_CLOSED&raquo;, NT_STATUS_ADDRESS_CLOSED},<br />
	{&raquo;NT_STATUS_CONNECTION_DISCONNECTED&raquo;,<br />
	 NT_STATUS_CONNECTION_DISCONNECTED},<br />
	{&raquo;NT_STATUS_CONNECTION_RESET&raquo;, NT_STATUS_CONNECTION_RESET},<br />
	{&raquo;NT_STATUS_TOO_MANY_NODES&raquo;, NT_STATUS_TOO_MANY_NODES},<br />
	{&raquo;NT_STATUS_TRANSACTION_ABORTED&raquo;, NT_STATUS_TRANSACTION_ABORTED},<br />
	{&raquo;NT_STATUS_TRANSACTION_TIMED_OUT&raquo;,<br />
	 NT_STATUS_TRANSACTION_TIMED_OUT},<br />
	{&raquo;NT_STATUS_TRANSACTION_NO_RELEASE&raquo;,<br />
	 NT_STATUS_TRANSACTION_NO_RELEASE},<br />
	{&raquo;NT_STATUS_TRANSACTION_NO_MATCH&raquo;, NT_STATUS_TRANSACTION_NO_MATCH},<br />
	{&raquo;NT_STATUS_TRANSACTION_RESPONDED&raquo;,<br />
	 NT_STATUS_TRANSACTION_RESPONDED},<br />
	{&raquo;NT_STATUS_TRANSACTION_INVALID_ID&raquo;,<br />
	 NT_STATUS_TRANSACTION_INVALID_ID},<br />
	{&raquo;NT_STATUS_TRANSACTION_INVALID_TYPE&raquo;,<br />
	 NT_STATUS_TRANSACTION_INVALID_TYPE},<br />
	{&raquo;NT_STATUS_NOT_SERVER_SESSION&raquo;, NT_STATUS_NOT_SERVER_SESSION},<br />
	{&raquo;NT_STATUS_NOT_CLIENT_SESSION&raquo;, NT_STATUS_NOT_CLIENT_SESSION},<br />
	{&raquo;NT_STATUS_CANNOT_LOAD_REGISTRY_FILE&raquo;,<br />
	 NT_STATUS_CANNOT_LOAD_REGISTRY_FILE},<br />
	{&raquo;NT_STATUS_DEBUG_ATTACH_FAILED&raquo;, NT_STATUS_DEBUG_ATTACH_FAILED},<br />
	{&raquo;NT_STATUS_SYSTEM_PROCESS_TERMINATED&raquo;,<br />
	 NT_STATUS_SYSTEM_PROCESS_TERMINATED},<br />
	{&raquo;NT_STATUS_DATA_NOT_ACCEPTED&raquo;, NT_STATUS_DATA_NOT_ACCEPTED},<br />
	{&raquo;NT_STATUS_NO_BROWSER_SERVERS_FOUND&raquo;,<br />
	 NT_STATUS_NO_BROWSER_SERVERS_FOUND},<br />
	{&raquo;NT_STATUS_VDM_HARD_ERROR&raquo;, NT_STATUS_VDM_HARD_ERROR},<br />
	{&raquo;NT_STATUS_DRIVER_CANCEL_TIMEOUT&raquo;,<br />
	 NT_STATUS_DRIVER_CANCEL_TIMEOUT},<br />
	{&raquo;NT_STATUS_REPLY_MESSAGE_MISMATCH&raquo;,<br />
	 NT_STATUS_REPLY_MESSAGE_MISMATCH},<br />
	{&raquo;NT_STATUS_MAPPED_ALIGNMENT&raquo;, NT_STATUS_MAPPED_ALIGNMENT},<br />
	{&raquo;NT_STATUS_IMAGE_CHECKSUM_MISMATCH&raquo;,<br />
	 NT_STATUS_IMAGE_CHECKSUM_MISMATCH},<br />
	{&raquo;NT_STATUS_LOST_WRITEBEHIND_DATA&raquo;,<br />
	 NT_STATUS_LOST_WRITEBEHIND_DATA},<br />
	{&raquo;NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID&raquo;,<br />
	 NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID},<br />
	{&raquo;NT_STATUS_PASSWORD_MUST_CHANGE&raquo;, NT_STATUS_PASSWORD_MUST_CHANGE},<br />
	{&raquo;NT_STATUS_NOT_FOUND&raquo;, NT_STATUS_NOT_FOUND},<br />
	{&raquo;NT_STATUS_NOT_TINY_STREAM&raquo;, NT_STATUS_NOT_TINY_STREAM},<br />
	{&raquo;NT_STATUS_RECOVERY_FAILURE&raquo;, NT_STATUS_RECOVERY_FAILURE},<br />
	{&raquo;NT_STATUS_STACK_OVERFLOW_READ&raquo;, NT_STATUS_STACK_OVERFLOW_READ},<br />
	{&raquo;NT_STATUS_FAIL_CHECK&raquo;, NT_STATUS_FAIL_CHECK},<br />
	{&raquo;NT_STATUS_DUPLICATE_OBJECTID&raquo;, NT_STATUS_DUPLICATE_OBJECTID},<br />
	{&raquo;NT_STATUS_OBJECTID_EXISTS&raquo;, NT_STATUS_OBJECTID_EXISTS},<br />
	{&raquo;NT_STATUS_CONVERT_TO_LARGE&raquo;, NT_STATUS_CONVERT_TO_LARGE},<br />
	{&raquo;NT_STATUS_RETRY&raquo;, NT_STATUS_RETRY},<br />
	{&raquo;NT_STATUS_FOUND_OUT_OF_SCOPE&raquo;, NT_STATUS_FOUND_OUT_OF_SCOPE},<br />
	{&raquo;NT_STATUS_ALLOCATE_BUCKET&raquo;, NT_STATUS_ALLOCATE_BUCKET},<br />
	{&raquo;NT_STATUS_PROPSET_NOT_FOUND&raquo;, NT_STATUS_PROPSET_NOT_FOUND},<br />
	{&raquo;NT_STATUS_MARSHALL_OVERFLOW&raquo;, NT_STATUS_MARSHALL_OVERFLOW},<br />
	{&raquo;NT_STATUS_INVALID_VARIANT&raquo;, NT_STATUS_INVALID_VARIANT},<br />
	{&raquo;NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND&raquo;,<br />
	 NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND},<br />
	{&raquo;NT_STATUS_ACCOUNT_LOCKED_OUT&raquo;, NT_STATUS_ACCOUNT_LOCKED_OUT},<br />
	{&raquo;NT_STATUS_HANDLE_NOT_CLOSABLE&raquo;, NT_STATUS_HANDLE_NOT_CLOSABLE},<br />
	{&raquo;NT_STATUS_CONNECTION_REFUSED&raquo;, NT_STATUS_CONNECTION_REFUSED},<br />
	{&raquo;NT_STATUS_GRACEFUL_DISCONNECT&raquo;, NT_STATUS_GRACEFUL_DISCONNECT},<br />
	{&raquo;NT_STATUS_ADDRESS_ALREADY_ASSOCIATED&raquo;,<br />
	 NT_STATUS_ADDRESS_ALREADY_ASSOCIATED},<br />
	{&raquo;NT_STATUS_ADDRESS_NOT_ASSOCIATED&raquo;,<br />
	 NT_STATUS_ADDRESS_NOT_ASSOCIATED},<br />
	{&raquo;NT_STATUS_CONNECTION_INVALID&raquo;, NT_STATUS_CONNECTION_INVALID},<br />
	{&raquo;NT_STATUS_CONNECTION_ACTIVE&raquo;, NT_STATUS_CONNECTION_ACTIVE},<br />
	{&raquo;NT_STATUS_NETWORK_UNREACHABLE&raquo;, NT_STATUS_NETWORK_UNREACHABLE},<br />
	{&raquo;NT_STATUS_HOST_UNREACHABLE&raquo;, NT_STATUS_HOST_UNREACHABLE},<br />
	{&raquo;NT_STATUS_PROTOCOL_UNREACHABLE&raquo;, NT_STATUS_PROTOCOL_UNREACHABLE},<br />
	{&raquo;NT_STATUS_PORT_UNREACHABLE&raquo;, NT_STATUS_PORT_UNREACHABLE},<br />
	{&raquo;NT_STATUS_REQUEST_ABORTED&raquo;, NT_STATUS_REQUEST_ABORTED},<br />
	{&raquo;NT_STATUS_CONNECTION_ABORTED&raquo;, NT_STATUS_CONNECTION_ABORTED},<br />
	{&raquo;NT_STATUS_BAD_COMPRESSION_BUFFER&raquo;,<br />
	 NT_STATUS_BAD_COMPRESSION_BUFFER},<br />
	{&raquo;NT_STATUS_USER_MAPPED_FILE&raquo;, NT_STATUS_USER_MAPPED_FILE},<br />
	{&raquo;NT_STATUS_AUDIT_FAILED&raquo;, NT_STATUS_AUDIT_FAILED},<br />
	{&raquo;NT_STATUS_TIMER_RESOLUTION_NOT_SET&raquo;,<br />
	 NT_STATUS_TIMER_RESOLUTION_NOT_SET},<br />
	{&raquo;NT_STATUS_CONNECTION_COUNT_LIMIT&raquo;,<br />
	 NT_STATUS_CONNECTION_COUNT_LIMIT},<br />
	{&raquo;NT_STATUS_LOGIN_TIME_RESTRICTION&raquo;,<br />
	 NT_STATUS_LOGIN_TIME_RESTRICTION},<br />
	{&raquo;NT_STATUS_LOGIN_WKSTA_RESTRICTION&raquo;,<br />
	 NT_STATUS_LOGIN_WKSTA_RESTRICTION},<br />
	{&raquo;NT_STATUS_IMAGE_MP_UP_MISMATCH&raquo;, NT_STATUS_IMAGE_MP_UP_MISMATCH},<br />
	{&raquo;NT_STATUS_INSUFFICIENT_LOGON_INFO&raquo;,<br />
	 NT_STATUS_INSUFFICIENT_LOGON_INFO},<br />
	{&raquo;NT_STATUS_BAD_DLL_ENTRYPOINT&raquo;, NT_STATUS_BAD_DLL_ENTRYPOINT},<br />
	{&raquo;NT_STATUS_BAD_SERVICE_ENTRYPOINT&raquo;,<br />
	 NT_STATUS_BAD_SERVICE_ENTRYPOINT},<br />
	{&raquo;NT_STATUS_LPC_REPLY_LOST&raquo;, NT_STATUS_LPC_REPLY_LOST},<br />
	{&raquo;NT_STATUS_IP_ADDRESS_CONFLICT1&#8243;, NT_STATUS_IP_ADDRESS_CONFLICT1},<br />
	{&raquo;NT_STATUS_IP_ADDRESS_CONFLICT2&#8243;, NT_STATUS_IP_ADDRESS_CONFLICT2},<br />
	{&raquo;NT_STATUS_REGISTRY_QUOTA_LIMIT&raquo;, NT_STATUS_REGISTRY_QUOTA_LIMIT},<br />
	{&raquo;NT_STATUS_PATH_NOT_COVERED&raquo;, NT_STATUS_PATH_NOT_COVERED},<br />
	{&raquo;NT_STATUS_NO_CALLBACK_ACTIVE&raquo;, NT_STATUS_NO_CALLBACK_ACTIVE},<br />
	{&raquo;NT_STATUS_LICENSE_QUOTA_EXCEEDED&raquo;,<br />
	 NT_STATUS_LICENSE_QUOTA_EXCEEDED},<br />
	{&raquo;NT_STATUS_PWD_TOO_SHORT&raquo;, NT_STATUS_PWD_TOO_SHORT},<br />
	{&raquo;NT_STATUS_PWD_TOO_RECENT&raquo;, NT_STATUS_PWD_TOO_RECENT},<br />
	{&raquo;NT_STATUS_PWD_HISTORY_CONFLICT&raquo;, NT_STATUS_PWD_HISTORY_CONFLICT},<br />
	{&raquo;NT_STATUS_PLUGPLAY_NO_DEVICE&raquo;, NT_STATUS_PLUGPLAY_NO_DEVICE},<br />
	{&raquo;NT_STATUS_UNSUPPORTED_COMPRESSION&raquo;,<br />
	 NT_STATUS_UNSUPPORTED_COMPRESSION},<br />
	{&raquo;NT_STATUS_INVALID_HW_PROFILE&raquo;, NT_STATUS_INVALID_HW_PROFILE},<br />
	{&raquo;NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH&raquo;,<br />
	 NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH},<br />
	{&raquo;NT_STATUS_DRIVER_ORDINAL_NOT_FOUND&raquo;,<br />
	 NT_STATUS_DRIVER_ORDINAL_NOT_FOUND},<br />
	{&raquo;NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND&raquo;,<br />
	 NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND},<br />
	{&raquo;NT_STATUS_RESOURCE_NOT_OWNED&raquo;, NT_STATUS_RESOURCE_NOT_OWNED},<br />
	{&raquo;NT_STATUS_TOO_MANY_LINKS&raquo;, NT_STATUS_TOO_MANY_LINKS},<br />
	{&raquo;NT_STATUS_QUOTA_LIST_INCONSISTENT&raquo;,<br />
	 NT_STATUS_QUOTA_LIST_INCONSISTENT},<br />
	{&raquo;NT_STATUS_FILE_IS_OFFLINE&raquo;, NT_STATUS_FILE_IS_OFFLINE},<br />
	{&raquo;NT_STATUS_NO_MORE_ENTRIES&raquo;, NT_STATUS_NO_MORE_ENTRIES},<br />
	{&raquo;STATUS_MORE_ENTRIES&raquo;, STATUS_MORE_ENTRIES},<br />
	{&raquo;STATUS_SOME_UNMAPPED&raquo;, STATUS_SOME_UNMAPPED},<br />
	{NULL, 0}<br />
};</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/nterr-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>netmisc.c</title>
		<link>http://lynyrd.ru/netmisc-c</link>
		<comments>http://lynyrd.ru/netmisc-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:29:47 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/netmisc-c</guid>
		<description><![CDATA[/*
 *   fs/cifs/netmisc.c
 *
 *   Copyright (c) International Business Machines  Corp., 2002,2008
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   Error mapping routines from Samba libsmb/errormap.c
 *   Copyright (C) Andrew Tridgell 2001
 *
 *   This program is free software;  you can redistribute ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/netmisc.c<span id="more-954"></span><br />
 *<br />
 *   Copyright (c) International Business Machines  Corp., 2002,2008<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   Error mapping routines from Samba libsmb/errormap.c<br />
 *   Copyright (C) Andrew Tridgell 2001<br />
 *<br />
 *   This program is free software;  you can redistribute it and/or modify<br />
 *   it under the terms of the GNU General Public License as published by<br />
 *   the Free Software Foundation; either version 2 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This program is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU General Public License<br />
 *   along with this program;  if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>#include
<linux/net.h>
#include
<linux/string.h>
#include
<linux/in.h>
#include
<linux/ctype.h>
#include
<linux/fs.h>
#include <asm/div64.h><br />
#include <asm/byteorder.h><br />
#include
<linux/inet.h>
#include &laquo;cifsfs.h&raquo;<br />
#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifsproto.h&raquo;<br />
#include &laquo;smberr.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;<br />
#include &laquo;nterr.h&raquo;</p>
<p>struct smb_to_posix_error {<br />
	__u16 smb_err;<br />
	int posix_code;<br />
};</p>
<p>static const struct smb_to_posix_error mapping_table_ERRDOS[] = {<br />
	{ERRbadfunc, -EINVAL},<br />
	{ERRbadfile, -ENOENT},<br />
	{ERRbadpath, -ENOTDIR},<br />
	{ERRnofids, -EMFILE},<br />
	{ERRnoaccess, -EACCES},<br />
	{ERRbadfid, -EBADF},<br />
	{ERRbadmcb, -EIO},<br />
	{ERRnomem, -ENOMEM},<br />
	{ERRbadmem, -EFAULT},<br />
	{ERRbadenv, -EFAULT},<br />
	{ERRbadformat, -EINVAL},<br />
	{ERRbadaccess, -EACCES},<br />
	{ERRbaddata, -EIO},<br />
	{ERRbaddrive, -ENXIO},<br />
	{ERRremcd, -EACCES},<br />
	{ERRdiffdevice, -EXDEV},<br />
	{ERRnofiles, -ENOENT},<br />
	{ERRbadshare, -ETXTBSY},<br />
	{ERRlock, -EACCES},<br />
	{ERRunsup, -EINVAL},<br />
	{ERRnosuchshare, -ENXIO},<br />
	{ERRfilexists, -EEXIST},<br />
	{ERRinvparm, -EINVAL},<br />
	{ERRdiskfull, -ENOSPC},<br />
	{ERRinvname, -ENOENT},<br />
	{ERRinvlevel, -EOPNOTSUPP},<br />
	{ERRdirnotempty, -ENOTEMPTY},<br />
	{ERRnotlocked, -ENOLCK},<br />
	{ERRcancelviolation, -ENOLCK},<br />
	{ERRalreadyexists, -EEXIST},<br />
	{ERRmoredata, -EOVERFLOW},<br />
	{ERReasnotsupported, -EOPNOTSUPP},<br />
	{ErrQuota, -EDQUOT},<br />
	{ErrNotALink, -ENOLINK},<br />
	{ERRnetlogonNotStarted, -ENOPROTOOPT},<br />
	{ERRsymlink, -EOPNOTSUPP},<br />
	{ErrTooManyLinks, -EMLINK},<br />
	{0, 0}<br />
};</p>
<p>static const struct smb_to_posix_error mapping_table_ERRSRV[] = {<br />
	{ERRerror, -EIO},<br />
	{ERRbadpw, -EACCES},  /* was EPERM */<br />
	{ERRbadtype, -EREMOTE},<br />
	{ERRaccess, -EACCES},<br />
	{ERRinvtid, -ENXIO},<br />
	{ERRinvnetname, -ENXIO},<br />
	{ERRinvdevice, -ENXIO},<br />
	{ERRqfull, -ENOSPC},<br />
	{ERRqtoobig, -ENOSPC},<br />
	{ERRqeof, -EIO},<br />
	{ERRinvpfid, -EBADF},<br />
	{ERRsmbcmd, -EBADRQC},<br />
	{ERRsrverror, -EIO},<br />
	{ERRbadBID, -EIO},<br />
	{ERRfilespecs, -EINVAL},<br />
	{ERRbadLink, -EIO},<br />
	{ERRbadpermits, -EINVAL},<br />
	{ERRbadPID, -ESRCH},<br />
	{ERRsetattrmode, -EINVAL},<br />
	{ERRpaused, -EHOSTDOWN},<br />
	{ERRmsgoff, -EHOSTDOWN},<br />
	{ERRnoroom, -ENOSPC},<br />
	{ERRrmuns, -EUSERS},<br />
	{ERRtimeout, -ETIME},<br />
	{ERRnoresource, -ENOBUFS},<br />
	{ERRtoomanyuids, -EUSERS},<br />
	{ERRbaduid, -EACCES},<br />
	{ERRusempx, -EIO},<br />
	{ERRusestd, -EIO},<br />
	{ERR_NOTIFY_ENUM_DIR, -ENOBUFS},<br />
	{ERRnoSuchUser, -EACCES},<br />
/*	{ERRaccountexpired, -EACCES},<br />
	{ERRbadclient, -EACCES},<br />
	{ERRbadLogonTime, -EACCES},<br />
	{ERRpasswordExpired, -EACCES},*/<br />
	{ERRaccountexpired, -EKEYEXPIRED},<br />
	{ERRbadclient, -EACCES},<br />
	{ERRbadLogonTime, -EACCES},<br />
	{ERRpasswordExpired, -EKEYEXPIRED},</p>
<p>	{ERRnosupport, -EINVAL},<br />
	{0, 0}<br />
};</p>
<p>static const struct smb_to_posix_error mapping_table_ERRHRD[] = {<br />
	{0, 0}<br />
};</p>
<p>/*<br />
 * Convert a string containing text IPv4 or IPv6 address to binary form.<br />
 *<br />
 * Returns 0 on failure.<br />
 */<br />
static int<br />
cifs_inet_pton(const int address_family, const char *cp, void *dst)<br />
{<br />
	int ret = 0;</p>
<p>	/* calculate length by finding first slash or NULL */<br />
	if (address_family == AF_INET)<br />
		ret = in4_pton(cp, -1 /* len */, dst, &#8216;\\&#8217;, NULL);<br />
	else if (address_family == AF_INET6)<br />
		ret = in6_pton(cp, -1 /* len */, dst , &#8216;\\&#8217;, NULL);</p>
<p>	cFYI(DBG2, (&raquo;address conversion returned %d for %s&raquo;, ret, cp));<br />
	if (ret > 0)<br />
		ret = 1;<br />
	return ret;<br />
}</p>
<p>/*<br />
 * Try to convert a string to an IPv4 address and then attempt to convert<br />
 * it to an IPv6 address if that fails. Set the family field if either<br />
 * succeeds. If it&#8217;s an IPv6 address and it has a &#8216;%&#8217; sign in it, try to<br />
 * treat the part following it as a numeric sin6_scope_id.<br />
 *<br />
 * Returns 0 on failure.<br />
 */<br />
int<br />
cifs_convert_address(char *src, void *dst)<br />
{<br />
	int rc;<br />
	char *pct, *endp;<br />
	struct sockaddr_in *s4 = (struct sockaddr_in *) dst;<br />
	struct sockaddr_in6 *s6 = (struct sockaddr_in6 *) dst;</p>
<p>	/* IPv4 address */<br />
	if (cifs_inet_pton(AF_INET, src, &#038;s4->sin_addr.s_addr)) {<br />
		s4->sin_family = AF_INET;<br />
		return 1;<br />
	}</p>
<p>	/* temporarily terminate string */<br />
	pct = strchr(src, &#8216;%&#8217;);<br />
	if (pct)<br />
		*pct = &#8216;\0&#8242;;</p>
<p>	rc = cifs_inet_pton(AF_INET6, src, &#038;s6->sin6_addr.s6_addr);</p>
<p>	/* repair temp termination (if any) and make pct point to scopeid */<br />
	if (pct)<br />
		*pct++ = &#8216;%&#8217;;</p>
<p>	if (!rc)<br />
		return rc;</p>
<p>	s6->sin6_family = AF_INET6;<br />
	if (pct) {<br />
		s6->sin6_scope_id = (u32) simple_strtoul(pct, &#038;endp, 0);<br />
		if (!*pct || *endp)<br />
			return 0;<br />
	}</p>
<p>	return rc;<br />
}</p>
<p>/*****************************************************************************<br />
convert a NT status code to a dos class/code<br />
 *****************************************************************************/<br />
/* NT status -> dos error map */<br />
static const struct {<br />
	__u8 dos_class;<br />
	__u16 dos_code;<br />
	__u32 ntstatus;<br />
} ntstatus_to_dos_map[] = {<br />
	{<br />
	ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, {<br />
	ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, {<br />
	ERRDOS, ERRinvlevel, NT_STATUS_INVALID_INFO_CLASS}, {<br />
	ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA}, {<br />
	ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_INITIAL_STACK}, {<br />
	ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_CID}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER}, {<br />
	ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, {<br />
	ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, {<br />
	ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, {<br />
	ERRDOS, 38, NT_STATUS_END_OF_FILE}, {<br />
	ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, {<br />
	ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, {<br />
	ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR},<br />
/*	{ This NT error code was &#8217;sqashed&#8217;<br />
	 from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK<br />
	 during the session setup } */<br />
	{<br />
	ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, {<br />
	ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, {<br />
	ERRDOS, 487, NT_STATUS_NOT_MAPPED_VIEW}, {<br />
	ERRDOS, 87, NT_STATUS_UNABLE_TO_FREE_VM}, {<br />
	ERRDOS, 87, NT_STATUS_UNABLE_TO_DELETE_SECTION}, {<br />
	ERRDOS, 2142, NT_STATUS_INVALID_SYSTEM_SERVICE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_INSTRUCTION}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_INVALID_VIEW_SIZE}, {<br />
	ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED},<br />
/*	{ This NT error code was &#8217;sqashed&#8217;<br />
	 from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE<br />
	 during the session setup }   */<br />
	{<br />
	ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, {<br />
	ERRDOS, 111, NT_STATUS_BUFFER_TOO_SMALL}, {<br />
	ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNWIND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_STACK}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_UNWIND_TARGET}, {<br />
	ERRDOS, 158, NT_STATUS_NOT_LOCKED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PARITY_ERROR}, {<br />
	ERRDOS, 487, NT_STATUS_UNABLE_TO_DECOMMIT_VM}, {<br />
	ERRDOS, 487, NT_STATUS_NOT_COMMITTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_PORT_ATTRIBUTES}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PORT_MESSAGE_TOO_LONG}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, {<br />
	 /* mapping changed since shell does lookup on * expects FileNotFound */<br />
	ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_INVALID}, {<br />
	ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, {<br />
	ERRDOS, ERRalreadyexists, NT_STATUS_OBJECT_NAME_COLLISION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, {<br />
	ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, {<br />
	ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, {<br />
	ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, {<br />
	ERRDOS, 161, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR}, {<br />
	ERRDOS, 23, NT_STATUS_DATA_ERROR}, {<br />
	ERRDOS, 23, NT_STATUS_CRC_ERROR}, {<br />
	ERRDOS, ERRnomem, NT_STATUS_SECTION_TOO_BIG}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_PORT_CONNECTION_REFUSED}, {<br />
	ERRDOS, ERRbadfid, NT_STATUS_INVALID_PORT_HANDLE}, {<br />
	ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_QUOTA_EXCEEDED}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PAGE_PROTECTION}, {<br />
	ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, {<br />
	ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, {<br />
	ERRDOS, 87, NT_STATUS_PORT_ALREADY_SET}, {<br />
	ERRDOS, 87, NT_STATUS_SECTION_NOT_IMAGE}, {<br />
	ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_THREAD_IS_TERMINATING}, {<br />
	ERRDOS, 87, NT_STATUS_BAD_WORKING_SET_LIMIT}, {<br />
	ERRDOS, 87, NT_STATUS_INCOMPATIBLE_FILE_MAP}, {<br />
	ERRDOS, 87, NT_STATUS_SECTION_PROTECTION}, {<br />
	ERRDOS, ERReasnotsupported, NT_STATUS_EAS_NOT_SUPPORTED}, {<br />
	ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NONEXISTENT_EA_ENTRY}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_EAS_ON_FILE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_EA_CORRUPT_ERROR}, {<br />
	ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, {<br />
	ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED}, {<br />
	ERRDOS, ERRbadfile, NT_STATUS_DELETE_PENDING}, {<br />
	ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNKNOWN_REVISION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_REVISION_MISMATCH}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_OWNER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_PRIMARY_GROUP}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_IMPERSONATION_TOKEN}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CANT_DISABLE_MANDATORY}, {<br />
	ERRDOS, 2215, NT_STATUS_NO_LOGON_SERVERS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_LOGON_SESSION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PRIVILEGE}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_PRIVILEGE_NOT_HELD}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS},<br />
/*	{ This NT error code was &#8217;sqashed&#8217;<br />
	 from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE<br />
	 during the session setup } */<br />
	{<br />
	ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { /* could map to 2238 */<br />
	ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN},<br />
/*	{ This NT error code was &#8217;sqashed&#8217;<br />
	 from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE<br />
	 during the session setup } */<br />
	{<br />
	ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_PASSWORD}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {<br />
	ERRSRV, ERRbadLogonTime, NT_STATUS_INVALID_LOGON_HOURS}, {<br />
	ERRSRV, ERRbadclient, NT_STATUS_INVALID_WORKSTATION}, {<br />
	ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, {<br />
	ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_DISABLED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_SUB_AUTHORITY}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACL}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_SID}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_SECURITY_DESCR}, {<br />
	ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, {<br />
	ERRDOS, 193, NT_STATUS_INVALID_IMAGE_FORMAT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_TOKEN}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_INHERITANCE_ACL}, {<br />
	ERRDOS, 158, NT_STATUS_RANGE_NOT_LOCKED}, {<br />
	ERRDOS, 112, NT_STATUS_DISK_FULL}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SERVER_DISABLED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SERVER_NOT_DISABLED}, {<br />
	ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, {<br />
	ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_ID_AUTHORITY}, {<br />
	ERRDOS, 259, NT_STATUS_AGENTS_EXHAUSTED}, {<br />
	ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, {<br />
	ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, {<br />
	ERRDOS, 487, NT_STATUS_NOT_MAPPED_DATA}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_DATA_NOT_FOUND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_NAME_NOT_FOUND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DENORMAL_OPERAND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INEXACT_RESULT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INVALID_OPERATION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOAT_OVERFLOW}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOAT_STACK_CHECK}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOAT_UNDERFLOW}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, {<br />
	ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PRIVILEGED_INSTRUCTION}, {<br />
	ERRDOS, ERRnomem, NT_STATUS_TOO_MANY_PAGING_FILES}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED},<br />
/*	{ This NT error code was &#8217;sqashed&#8217;<br />
	 from NT_STATUS_INSUFFICIENT_RESOURCES to<br />
	 NT_STATUS_INSUFF_SERVER_RESOURCES during the session setup } */<br />
	{<br />
	ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, {<br />
	ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, {<br />
	ERRDOS, 23, NT_STATUS_DEVICE_DATA_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, {<br />
	ERRDOS, 21, NT_STATUS_DEVICE_POWER_FAILURE}, {<br />
	ERRDOS, 487, NT_STATUS_FREE_VM_NOT_AT_BASE}, {<br />
	ERRDOS, 487, NT_STATUS_MEMORY_NOT_ALLOCATED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_WORKING_SET_QUOTA}, {<br />
	ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, {<br />
	ERRDOS, 21, NT_STATUS_DEVICE_NOT_READY}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_GROUP_ATTRIBUTES}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_IMPERSONATION_LEVEL}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CANT_OPEN_ANONYMOUS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_VALIDATION_CLASS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_TOKEN_TYPE}, {<br />
	ERRDOS, 87, NT_STATUS_BAD_MASTER_BOOT_RECORD}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INSTRUCTION_MISALIGNMENT}, {<br />
	ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, {<br />
	ERRDOS, ERRpipebusy, NT_STATUS_PIPE_NOT_AVAILABLE}, {<br />
	ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PIPE_STATE}, {<br />
	ERRDOS, ERRpipebusy, NT_STATUS_PIPE_BUSY}, {<br />
	ERRDOS, ERRbadfunc, NT_STATUS_ILLEGAL_FUNCTION}, {<br />
	ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, {<br />
	ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PIPE_CONNECTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PIPE_LISTENING}, {<br />
	ERRDOS, ERRbadpipe, NT_STATUS_INVALID_READ_MODE}, {<br />
	ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, {<br />
	ERRDOS, 38, NT_STATUS_FILE_FORCED_CLOSED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STARTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STOPPED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_COULD_NOT_INTERPRET}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, {<br />
	ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED}, {<br />
	ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, {<br />
	ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, {<br />
	ERRDOS, 53, NT_STATUS_BAD_NETWORK_PATH}, {<br />
	ERRDOS, 54, NT_STATUS_NETWORK_BUSY}, {<br />
	ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, {<br />
	ERRDOS, 56, NT_STATUS_TOO_MANY_COMMANDS}, {<br />
	ERRDOS, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, {<br />
	ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, {<br />
	ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, {<br />
	ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, {<br />
	ERRDOS, 61, NT_STATUS_PRINT_QUEUE_FULL}, {<br />
	ERRDOS, 62, NT_STATUS_NO_SPOOL_SPACE}, {<br />
	ERRDOS, 63, NT_STATUS_PRINT_CANCELLED}, {<br />
	ERRDOS, 64, NT_STATUS_NETWORK_NAME_DELETED}, {<br />
	ERRDOS, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, {<br />
	ERRDOS, 66, NT_STATUS_BAD_DEVICE_TYPE}, {<br />
	ERRDOS, ERRnosuchshare, NT_STATUS_BAD_NETWORK_NAME}, {<br />
	ERRDOS, 68, NT_STATUS_TOO_MANY_NAMES}, {<br />
	ERRDOS, 69, NT_STATUS_TOO_MANY_SESSIONS}, {<br />
	ERRDOS, 70, NT_STATUS_SHARING_PAUSED}, {<br />
	ERRDOS, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, {<br />
	ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, {<br />
	ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PROFILING_AT_LIMIT}, {<br />
	ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_FILE_RENAMED}, {<br />
	ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_SECURITY_ON_OBJECT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CANT_WAIT}, {<br />
	ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_EMPTY}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CANT_TERMINATE_SELF}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_SERVER_STATE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_STATE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_ROLE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_DOMAIN}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_EXISTS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, {<br />
	ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, {<br />
	ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_CORRUPTION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_GENERIC_NOT_MAPPED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_DESCRIPTOR_FORMAT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_USER_BUFFER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_IO_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_CREATE_ERR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_MAP_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_EXTEND_ERR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NOT_LOGON_PROCESS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_EXISTS}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_1}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_2}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_3}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_4}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_5}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_6}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_7}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_8}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_9}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_10}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_11}, {<br />
	ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_12}, {<br />
	ERRDOS, ERRbadpath, NT_STATUS_REDIRECTOR_NOT_STARTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_REDIRECTOR_STARTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PACKAGE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_FUNCTION_TABLE}, {<br />
	ERRDOS, 203, 0xc0000100}, {<br />
	ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR}, {<br />
	ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION}, {<br />
	ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, {<br />
	ERRDOS, 2401, NT_STATUS_FILES_OPEN}, {<br />
	ERRDOS, 2404, NT_STATUS_CONNECTION_IN_USE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MESSAGE_NOT_FOUND}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_PROCESS_IS_TERMINATING}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_LOGON_TYPE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_GUID_TRANSLATION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CANNOT_IMPERSONATE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_IMAGE_ALREADY_LOADED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_PRESENT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_NOT_EXIST}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_ALREADY_OWNED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_LID_OWNER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_COMMAND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_LID}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_SELECTOR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_LDT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_SIZE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_OFFSET}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_DESCRIPTOR}, {<br />
	ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NE_FORMAT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_RXACT_INVALID_STATE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_RXACT_COMMIT_FAILURE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MAPPED_FILE_SIZE_ZERO}, {<br />
	ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CANCELLED}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_CANNOT_DELETE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_COMPUTER_NAME}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_FILE_DELETED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_ACCOUNT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_GROUP}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_USER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MEMBERS_PRIMARY_GROUP}, {<br />
	ERRDOS, ERRbadfid, NT_STATUS_FILE_CLOSED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_THREADS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_THREAD_NOT_IN_PROCESS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_TOKEN_ALREADY_IN_USE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA_EXCEEDED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_COMMITMENT_LIMIT}, {<br />
	ERRDOS, 193, NT_STATUS_INVALID_IMAGE_LE_FORMAT}, {<br />
	ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NOT_MZ}, {<br />
	ERRDOS, 193, NT_STATUS_INVALID_IMAGE_PROTECT}, {<br />
	ERRDOS, 193, NT_STATUS_INVALID_IMAGE_WIN_16}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LOGON_SERVER_CONFLICT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_TIME_DIFFERENCE_AT_DC}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SYNCHRONIZATION_REQUIRED}, {<br />
	ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_OPEN_FAILED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_IO_PRIVILEGE_FAILED}, {<br />
	ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, {<br />
	ERRDOS, 127, NT_STATUS_ENTRYPOINT_NOT_FOUND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CONTROL_C_EXIT}, {<br />
	ERRDOS, 64, NT_STATUS_LOCAL_DISCONNECT}, {<br />
	ERRDOS, 64, NT_STATUS_REMOTE_DISCONNECT}, {<br />
	ERRDOS, 51, NT_STATUS_REMOTE_RESOURCES}, {<br />
	ERRDOS, 59, NT_STATUS_LINK_FAILED}, {<br />
	ERRDOS, 59, NT_STATUS_LINK_TIMEOUT}, {<br />
	ERRDOS, 59, NT_STATUS_INVALID_CONNECTION}, {<br />
	ERRDOS, 59, NT_STATUS_INVALID_ADDRESS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DLL_INIT_FAILED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MISSING_SYSTEMFILE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNHANDLED_EXCEPTION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_APP_INIT_FAILURE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_CREATE_FAILED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_PAGEFILE}, {<br />
	ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, {<br />
	ERRDOS, 86, NT_STATUS_WRONG_PASSWORD_CORE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_FLOAT_CONTEXT}, {<br />
	ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_CORRUPT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_IO_FAILED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_EVENT_PAIR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_VOLUME}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SERIAL_NO_DEVICE_INITED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_ALIAS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_ALIAS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_ALIAS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ALIAS_EXISTS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LOGON_NOT_GRANTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SECRETS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SECRET_TOO_LONG}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FULLSCREEN_MODE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_CONTEXT_IDS}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_LOGON_TYPE_NOT_GRANTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NOT_REGISTRY_FILE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FT_MISSING_MEMBER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_SERVICE_ENTRY}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_CHARACTER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNMAPPABLE_CHARACTER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNDEFINED_CHARACTER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_VOLUME}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_WRONG_CYLINDER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_UNKNOWN_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_BAD_REGISTERS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DISK_RECALIBRATE_FAILED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DISK_OPERATION_FAILED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DISK_RESET_FAILED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SHARED_IRQ_BUSY}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FT_ORPHANING}, {<br />
	ERRHRD, ERRgeneral, 0xc000016e}, {<br />
	ERRHRD, ERRgeneral, 0xc000016f}, {<br />
	ERRHRD, ERRgeneral, 0xc0000170}, {<br />
	ERRHRD, ERRgeneral, 0xc0000171}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PARTITION_FAILURE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_BLOCK_LENGTH}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_PARTITIONED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_LOCK_MEDIA}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_EOM_OVERFLOW}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_MEDIA}, {<br />
	ERRHRD, ERRgeneral, 0xc0000179}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_MEMBER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_MEMBER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_KEY_DELETED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_LOG_SPACE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SIDS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_KEY_HAS_CHILDREN}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CHILD_MUST_BE_VOLATILE}, {<br />
	ERRDOS, 87, NT_STATUS_DEVICE_CONFIGURATION_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DRIVER_INTERNAL_ERROR}, {<br />
	ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DEVICE_PROTOCOL_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BACKUP_CONTROLLER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LOG_FILE_FULL}, {<br />
	ERRDOS, 19, NT_STATUS_TOO_LATE}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET},<br />
/*	{ This NT error code was &#8217;sqashed&#8217;<br />
	 from NT_STATUS_NO_TRUST_SAM_ACCOUNT to<br />
	 NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE during the session setup } */<br />
	{<br />
	ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CORRUPT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_CANT_START}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, {<br />
	ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, {<br />
	ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_EXPIRED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CHANGED}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT},<br />
/*	{ This NT error code was &#8217;sqashed&#8217;<br />
	 from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE<br />
	 during the session setup }  */<br />
	{<br />
	ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FS_DRIVER_REQUIRED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, {<br />
	ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, {<br />
	ERRDOS, ERRnomem, NT_STATUS_INSUFF_SERVER_RESOURCES}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, {<br />
	ERRDOS, 68, NT_STATUS_TOO_MANY_ADDRESSES}, {<br />
	ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_EXISTS}, {<br />
	ERRDOS, 64, NT_STATUS_ADDRESS_CLOSED}, {<br />
	ERRDOS, 64, NT_STATUS_CONNECTION_DISCONNECTED}, {<br />
	ERRDOS, 64, NT_STATUS_CONNECTION_RESET}, {<br />
	ERRDOS, 68, NT_STATUS_TOO_MANY_NODES}, {<br />
	ERRDOS, 59, NT_STATUS_TRANSACTION_ABORTED}, {<br />
	ERRDOS, 59, NT_STATUS_TRANSACTION_TIMED_OUT}, {<br />
	ERRDOS, 59, NT_STATUS_TRANSACTION_NO_RELEASE}, {<br />
	ERRDOS, 59, NT_STATUS_TRANSACTION_NO_MATCH}, {<br />
	ERRDOS, 59, NT_STATUS_TRANSACTION_RESPONDED}, {<br />
	ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_ID}, {<br />
	ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_TYPE}, {<br />
	ERRDOS, ERRunsup, NT_STATUS_NOT_SERVER_SESSION}, {<br />
	ERRDOS, ERRunsup, NT_STATUS_NOT_CLIENT_SESSION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CANNOT_LOAD_REGISTRY_FILE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DEBUG_ATTACH_FAILED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_SYSTEM_PROCESS_TERMINATED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DATA_NOT_ACCEPTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_VDM_HARD_ERROR}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DRIVER_CANCEL_TIMEOUT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_REPLY_MESSAGE_MISMATCH}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MAPPED_ALIGNMENT}, {<br />
	ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, {<br />
	ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_MUST_CHANGE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW_READ}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FAIL_CHECK}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DUPLICATE_OBJECTID}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_OBJECTID_EXISTS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CONVERT_TO_LARGE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_RETRY}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FOUND_OUT_OF_SCOPE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ALLOCATE_BUCKET}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PROPSET_NOT_FOUND}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_MARSHALL_OVERFLOW}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_VARIANT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, {<br />
	ERRDOS, ERRnoaccess, NT_STATUS_ACCOUNT_LOCKED_OUT}, {<br />
	ERRDOS, ERRbadfid, NT_STATUS_HANDLE_NOT_CLOSABLE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_GRACEFUL_DISCONNECT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_NOT_ASSOCIATED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_INVALID}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ACTIVE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PROTOCOL_UNREACHABLE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PORT_UNREACHABLE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_REQUEST_ABORTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_COMPRESSION_BUFFER}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_USER_MAPPED_FILE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_AUDIT_FAILED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_TIMER_RESOLUTION_NOT_SET}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_COUNT_LIMIT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LOGIN_TIME_RESTRICTION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LOGIN_WKSTA_RESTRICTION}, {<br />
	ERRDOS, 193, NT_STATUS_IMAGE_MP_UP_MISMATCH}, {<br />
	ERRHRD, ERRgeneral, 0xc000024a}, {<br />
	ERRHRD, ERRgeneral, 0xc000024b}, {<br />
	ERRHRD, ERRgeneral, 0xc000024c}, {<br />
	ERRHRD, ERRgeneral, 0xc000024d}, {<br />
	ERRHRD, ERRgeneral, 0xc000024e}, {<br />
	ERRHRD, ERRgeneral, 0xc000024f}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INSUFFICIENT_LOGON_INFO}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_DLL_ENTRYPOINT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_BAD_SERVICE_ENTRYPOINT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LPC_REPLY_LOST}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT1}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT2}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_QUOTA_LIMIT}, {<br />
	ERRSRV, 3, NT_STATUS_PATH_NOT_COVERED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_NO_CALLBACK_ACTIVE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_LICENSE_QUOTA_EXCEEDED}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_SHORT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_RECENT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PWD_HISTORY_CONFLICT}, {<br />
	ERRHRD, ERRgeneral, 0xc000025d}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_PLUGPLAY_NO_DEVICE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_UNSUPPORTED_COMPRESSION}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_HW_PROFILE}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH}, {<br />
	ERRDOS, 182, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, {<br />
	ERRDOS, 127, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, {<br />
	ERRDOS, 288, NT_STATUS_RESOURCE_NOT_OWNED}, {<br />
	ERRDOS, ErrTooManyLinks, NT_STATUS_TOO_MANY_LINKS}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_QUOTA_LIST_INCONSISTENT}, {<br />
	ERRHRD, ERRgeneral, NT_STATUS_FILE_IS_OFFLINE}, {<br />
	ERRDOS, 21, 0xc000026e}, {<br />
	ERRDOS, 161, 0xc0000281}, {<br />
	ERRDOS, ERRnoaccess, 0xc000028a}, {<br />
	ERRDOS, ERRnoaccess, 0xc000028b}, {<br />
	ERRHRD, ERRgeneral, 0xc000028c}, {<br />
	ERRDOS, ERRnoaccess, 0xc000028d}, {<br />
	ERRDOS, ERRnoaccess, 0xc000028e}, {<br />
	ERRDOS, ERRnoaccess, 0xc000028f}, {<br />
	ERRDOS, ERRnoaccess, 0xc0000290}, {<br />
	ERRDOS, ERRbadfunc, 0xc000029c}, {<br />
	ERRDOS, ERRsymlink, NT_STATUS_STOPPED_ON_SYMLINK}, {<br />
	ERRDOS, ERRinvlevel, 0&#215;007c0001}, };</p>
<p>/*****************************************************************************<br />
 Print an error message from the status code<br />
 *****************************************************************************/<br />
static void<br />
cifs_print_status(__u32 status_code)<br />
{<br />
	int idx = 0;</p>
<p>	while (nt_errs[idx].nt_errstr != NULL) {<br />
		if (((nt_errs[idx].nt_errcode) &#038; 0xFFFFFF) ==<br />
		    (status_code &#038; 0xFFFFFF)) {<br />
			printk(KERN_NOTICE &laquo;Status code returned 0x%08x %s\n&raquo;,<br />
				   status_code, nt_errs[idx].nt_errstr);<br />
		}<br />
		idx++;<br />
	}<br />
	return;<br />
}</p>
<p>static void<br />
ntstatus_to_dos(__u32 ntstatus, __u8 *eclass, __u16 *ecode)<br />
{<br />
	int i;<br />
	if (ntstatus == 0) {<br />
		*eclass = 0;<br />
		*ecode = 0;<br />
		return;<br />
	}<br />
	for (i = 0; ntstatus_to_dos_map[i].ntstatus; i++) {<br />
		if (ntstatus == ntstatus_to_dos_map[i].ntstatus) {<br />
			*eclass = ntstatus_to_dos_map[i].dos_class;<br />
			*ecode = ntstatus_to_dos_map[i].dos_code;<br />
			return;<br />
		}<br />
	}<br />
	*eclass = ERRHRD;<br />
	*ecode = ERRgeneral;<br />
}</p>
<p>int<br />
map_smb_to_linux_error(struct smb_hdr *smb, int logErr)<br />
{<br />
	unsigned int i;<br />
	int rc = -EIO;	/* if transport error smb error may not be set */<br />
	__u8 smberrclass;<br />
	__u16 smberrcode;</p>
<p>	/* BB if NT Status codes &#8211; map NT BB */</p>
<p>	/* old style smb error codes */<br />
	if (smb->Status.CifsError == 0)<br />
		return 0;</p>
<p>	if (smb->Flags2 &#038; SMBFLG2_ERR_STATUS) {<br />
		/* translate the newer STATUS codes to old style SMB errors<br />
		 * and then to POSIX errors */<br />
		__u32 err = le32_to_cpu(smb->Status.CifsError);<br />
		if (logErr &#038;&#038; (err != (NT_STATUS_MORE_PROCESSING_REQUIRED)))<br />
			cifs_print_status(err);<br />
		else if (cifsFYI &#038; CIFS_RC)<br />
			cifs_print_status(err);<br />
		ntstatus_to_dos(err, &#038;smberrclass, &#038;smberrcode);<br />
	} else {<br />
		smberrclass = smb->Status.DosError.ErrorClass;<br />
		smberrcode = le16_to_cpu(smb->Status.DosError.Error);<br />
	}</p>
<p>	/* old style errors */</p>
<p>	/* DOS class smb error codes &#8211; map DOS */<br />
	if (smberrclass == ERRDOS) {<br />
		/* 1 byte field no need to byte reverse */<br />
		for (i = 0;<br />
		     i <<br />
		     sizeof(mapping_table_ERRDOS) /<br />
		     sizeof(struct smb_to_posix_error); i++) {<br />
			if (mapping_table_ERRDOS[i].smb_err == 0)<br />
				break;<br />
			else if (mapping_table_ERRDOS[i].smb_err ==<br />
								smberrcode) {<br />
				rc = mapping_table_ERRDOS[i].posix_code;<br />
				break;<br />
			}<br />
			/* else try next error mapping one to see if match */<br />
		}<br />
	} else if (smberrclass == ERRSRV) {<br />
		/* server class of error codes */<br />
		for (i = 0;<br />
		     i <<br />
		     sizeof(mapping_table_ERRSRV) /<br />
		     sizeof(struct smb_to_posix_error); i++) {<br />
			if (mapping_table_ERRSRV[i].smb_err == 0)<br />
				break;<br />
			else if (mapping_table_ERRSRV[i].smb_err ==<br />
								smberrcode) {<br />
				rc = mapping_table_ERRSRV[i].posix_code;<br />
				break;<br />
			}<br />
			/* else try next error mapping to see if match */<br />
		}<br />
	}<br />
	/* else ERRHRD class errors or junk  - return EIO */</p>
<p>	cFYI(1, ("Mapping smb error code %d to POSIX err %d",<br />
		 smberrcode, rc));</p>
<p>	/* generic corrective action e.g. reconnect SMB session on<br />
	 * ERRbaduid could be added */</p>
<p>	return rc;<br />
}</p>
<p>/*<br />
 * calculate the size of the SMB message based on the fixed header<br />
 * portion, the number of word parameters and the data portion of the message<br />
 */<br />
unsigned int<br />
smbCalcSize(struct smb_hdr *ptr)<br />
{<br />
	return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +<br />
		2 /* size of the bcc field */ + BCC(ptr));<br />
}</p>
<p>unsigned int<br />
smbCalcSize_LE(struct smb_hdr *ptr)<br />
{<br />
	return (sizeof(struct smb_hdr) + (2 * ptr->WordCount) +<br />
		2 /* size of the bcc field */ + le16_to_cpu(BCC_LE(ptr)));<br />
}</p>
<p>/* The following are taken from fs/ntfs/util.c */</p>
<p>#define NTFS_TIME_OFFSET ((u64)(369*365 + 89) * 24 * 3600 * 10000000)</p>
<p>/*<br />
 * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units)<br />
 * into Unix UTC (based 1970-01-01, in seconds).<br />
 */<br />
struct timespec<br />
cifs_NTtimeToUnix(__le64 ntutc)<br />
{<br />
	struct timespec ts;<br />
	/* BB what about the timezone? BB */</p>
<p>	/* Subtract the NTFS time offset, then convert to 1s intervals. */<br />
	u64 t;</p>
<p>	t = le64_to_cpu(ntutc) &#8211; NTFS_TIME_OFFSET;<br />
	ts.tv_nsec = do_div(t, 10000000) * 100;<br />
	ts.tv_sec = t;<br />
	return ts;<br />
}</p>
<p>/* Convert the Unix UTC into NT UTC. */<br />
u64<br />
cifs_UnixTimeToNT(struct timespec t)<br />
{<br />
	/* Convert to 100ns intervals and then add the NTFS time offset. */<br />
	return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET;<br />
}</p>
<p>static int total_days_of_prev_months[] =<br />
{0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};</p>
<p>struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)<br />
{<br />
	struct timespec ts;<br />
	int sec, min, days, month, year;<br />
	u16 date = le16_to_cpu(le_date);<br />
	u16 time = le16_to_cpu(le_time);<br />
	SMB_TIME *st = (SMB_TIME *)&time;<br />
	SMB_DATE *sd = (SMB_DATE *)&date;</p>
<p>	cFYI(1, (&raquo;date %d time %d&raquo;, date, time));</p>
<p>	sec = 2 * st->TwoSeconds;<br />
	min = st->Minutes;<br />
	if ((sec > 59) || (min > 59))<br />
		cERROR(1, (&raquo;illegal time min %d sec %d&raquo;, min, sec));<br />
	sec += (min * 60);<br />
	sec += 60 * 60 * st->Hours;<br />
	if (st->Hours > 24)<br />
		cERROR(1, (&raquo;illegal hours %d&raquo;, st->Hours));<br />
	days = sd->Day;<br />
	month = sd->Month;<br />
	if ((days > 31) || (month > 12)) {<br />
		cERROR(1, (&raquo;illegal date, month %d day: %d&raquo;, month, days));<br />
		if (month > 12)<br />
			month = 12;<br />
	}<br />
	month -= 1;<br />
	days += total_days_of_prev_months[month];<br />
	days += 3652; /* account for difference in days between 1980 and 1970 */<br />
	year = sd->Year;<br />
	days += year * 365;<br />
	days += (year/4); /* leap year */<br />
	/* generalized leap year calculation is more complex, ie no leap year<br />
	for years/100 except for years/400, but since the maximum number for DOS<br />
	 year is 2**7, the last year is 1980+127, which means we need only<br />
	 consider 2 special case years, ie the years 2000 and 2100, and only<br />
	 adjust for the lack of leap year for the year 2100, as 2000 was a<br />
	 leap year (divisable by 400) */<br />
	if (year >= 120)  /* the year 2100 */<br />
		days = days &#8211; 1;  /* do not count leap year for the year 2100 */</p>
<p>	/* adjust for leap year where we are still before leap day */<br />
	if (year != 120)<br />
		days -= ((year &#038; 0&#215;03) == 0) &#038;&#038; (month < 2 ? 1 : 0);<br />
	sec += 24 * 60 * 60 * days;</p>
<p>	ts.tv_sec = sec + offset;</p>
<p>	/* cFYI(1,(&raquo;sec after cnvrt dos to unix time %d&raquo;,sec)); */</p>
<p>	ts.tv_nsec = 0;<br />
	return ts;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/netmisc-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>misc.c</title>
		<link>http://lynyrd.ru/misc-c</link>
		<comments>http://lynyrd.ru/misc-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:29:24 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/misc-c</guid>
		<description><![CDATA[/*
 *   fs/cifs/misc.c
 *
 *   Copyright (C) International Business Machines  Corp., 2002,2008
 *   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
 ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/misc.c<span id="more-953"></span><br />
 *<br />
 *   Copyright (C) International Business Machines  Corp., 2002,2008<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>#include
<linux/slab.h>
#include
<linux/ctype.h>
#include
<linux/mempool.h>
#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifsproto.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;<br />
#include &laquo;smberr.h&raquo;<br />
#include &laquo;nterr.h&raquo;<br />
#include &laquo;cifs_unicode.h&raquo;</p>
<p>extern mempool_t *cifs_sm_req_poolp;<br />
extern mempool_t *cifs_req_poolp;</p>
<p>/* The xid serves as a useful identifier for each incoming vfs request,<br />
   in a similar way to the mid which is useful to track each sent smb,<br />
   and CurrentXid can also provide a running counter (although it<br />
   will eventually wrap past zero) of the total vfs operations handled<br />
   since the cifs fs was mounted */</p>
<p>unsigned int<br />
_GetXid(void)<br />
{<br />
	unsigned int xid;</p>
<p>	spin_lock(&#038;GlobalMid_Lock);<br />
	GlobalTotalActiveXid++;</p>
<p>	/* keep high water mark for number of simultaneous ops in filesystem */<br />
	if (GlobalTotalActiveXid > GlobalMaxActiveXid)<br />
		GlobalMaxActiveXid = GlobalTotalActiveXid;<br />
	if (GlobalTotalActiveXid > 65000)<br />
		cFYI(1, (&raquo;warning: more than 65000 requests active&raquo;));<br />
	xid = GlobalCurrentXid++;<br />
	spin_unlock(&#038;GlobalMid_Lock);<br />
	return xid;<br />
}</p>
<p>void<br />
_FreeXid(unsigned int xid)<br />
{<br />
	spin_lock(&#038;GlobalMid_Lock);<br />
	/* if (GlobalTotalActiveXid == 0)<br />
		BUG(); */<br />
	GlobalTotalActiveXid&#8211;;<br />
	spin_unlock(&#038;GlobalMid_Lock);<br />
}</p>
<p>struct cifsSesInfo *<br />
sesInfoAlloc(void)<br />
{<br />
	struct cifsSesInfo *ret_buf;</p>
<p>	ret_buf = kzalloc(sizeof(struct cifsSesInfo), GFP_KERNEL);<br />
	if (ret_buf) {<br />
		atomic_inc(&#038;sesInfoAllocCount);<br />
		ret_buf->status = CifsNew;<br />
		++ret_buf->ses_count;<br />
		INIT_LIST_HEAD(&#038;ret_buf->smb_ses_list);<br />
		INIT_LIST_HEAD(&#038;ret_buf->tcon_list);<br />
		init_MUTEX(&#038;ret_buf->sesSem);<br />
	}<br />
	return ret_buf;<br />
}</p>
<p>void<br />
sesInfoFree(struct cifsSesInfo *buf_to_free)<br />
{<br />
	if (buf_to_free == NULL) {<br />
		cFYI(1, (&raquo;Null buffer passed to sesInfoFree&raquo;));<br />
		return;<br />
	}</p>
<p>	atomic_dec(&#038;sesInfoAllocCount);<br />
	kfree(buf_to_free->serverOS);<br />
	kfree(buf_to_free->serverDomain);<br />
	kfree(buf_to_free->serverNOS);<br />
	if (buf_to_free->password) {<br />
		memset(buf_to_free->password, 0, strlen(buf_to_free->password));<br />
		kfree(buf_to_free->password);<br />
	}<br />
	kfree(buf_to_free->domainName);<br />
	kfree(buf_to_free);<br />
}</p>
<p>struct cifsTconInfo *<br />
tconInfoAlloc(void)<br />
{<br />
	struct cifsTconInfo *ret_buf;<br />
	ret_buf = kzalloc(sizeof(struct cifsTconInfo), GFP_KERNEL);<br />
	if (ret_buf) {<br />
		atomic_inc(&#038;tconInfoAllocCount);<br />
		ret_buf->tidStatus = CifsNew;<br />
		++ret_buf->tc_count;<br />
		INIT_LIST_HEAD(&#038;ret_buf->openFileList);<br />
		INIT_LIST_HEAD(&#038;ret_buf->tcon_list);<br />
#ifdef CONFIG_CIFS_STATS<br />
		spin_lock_init(&#038;ret_buf->stat_lock);<br />
#endif<br />
	}<br />
	return ret_buf;<br />
}</p>
<p>void<br />
tconInfoFree(struct cifsTconInfo *buf_to_free)<br />
{<br />
	if (buf_to_free == NULL) {<br />
		cFYI(1, (&raquo;Null buffer passed to tconInfoFree&raquo;));<br />
		return;<br />
	}<br />
	atomic_dec(&#038;tconInfoAllocCount);<br />
	kfree(buf_to_free->nativeFileSystem);<br />
	if (buf_to_free->password) {<br />
		memset(buf_to_free->password, 0, strlen(buf_to_free->password));<br />
		kfree(buf_to_free->password);<br />
	}<br />
	kfree(buf_to_free);<br />
}</p>
<p>struct smb_hdr *<br />
cifs_buf_get(void)<br />
{<br />
	struct smb_hdr *ret_buf = NULL;</p>
<p>/* We could use negotiated size instead of max_msgsize -<br />
   but it may be more efficient to always alloc same size<br />
   albeit slightly larger than necessary and maxbuffersize<br />
   defaults to this and can not be bigger */<br />
	ret_buf = mempool_alloc(cifs_req_poolp, GFP_NOFS);</p>
<p>	/* clear the first few header bytes */<br />
	/* for most paths, more is cleared in header_assemble */<br />
	if (ret_buf) {<br />
		memset(ret_buf, 0, sizeof(struct smb_hdr) + 3);<br />
		atomic_inc(&#038;bufAllocCount);<br />
#ifdef CONFIG_CIFS_STATS2<br />
		atomic_inc(&#038;totBufAllocCount);<br />
#endif /* CONFIG_CIFS_STATS2 */<br />
	}</p>
<p>	return ret_buf;<br />
}</p>
<p>void<br />
cifs_buf_release(void *buf_to_free)<br />
{<br />
	if (buf_to_free == NULL) {<br />
		/* cFYI(1, (&raquo;Null buffer passed to cifs_buf_release&raquo;));*/<br />
		return;<br />
	}<br />
	mempool_free(buf_to_free, cifs_req_poolp);</p>
<p>	atomic_dec(&#038;bufAllocCount);<br />
	return;<br />
}</p>
<p>struct smb_hdr *<br />
cifs_small_buf_get(void)<br />
{<br />
	struct smb_hdr *ret_buf = NULL;</p>
<p>/* We could use negotiated size instead of max_msgsize -<br />
   but it may be more efficient to always alloc same size<br />
   albeit slightly larger than necessary and maxbuffersize<br />
   defaults to this and can not be bigger */<br />
	ret_buf = mempool_alloc(cifs_sm_req_poolp, GFP_NOFS);<br />
	if (ret_buf) {<br />
	/* No need to clear memory here, cleared in header assemble */<br />
	/*	memset(ret_buf, 0, sizeof(struct smb_hdr) + 27);*/<br />
		atomic_inc(&#038;smBufAllocCount);<br />
#ifdef CONFIG_CIFS_STATS2<br />
		atomic_inc(&#038;totSmBufAllocCount);<br />
#endif /* CONFIG_CIFS_STATS2 */</p>
<p>	}<br />
	return ret_buf;<br />
}</p>
<p>void<br />
cifs_small_buf_release(void *buf_to_free)<br />
{</p>
<p>	if (buf_to_free == NULL) {<br />
		cFYI(1, (&raquo;Null buffer passed to cifs_small_buf_release&raquo;));<br />
		return;<br />
	}<br />
	mempool_free(buf_to_free, cifs_sm_req_poolp);</p>
<p>	atomic_dec(&#038;smBufAllocCount);<br />
	return;<br />
}</p>
<p>/*<br />
	Find a free multiplex id (SMB mid). Otherwise there could be<br />
	mid collisions which might cause problems, demultiplexing the<br />
	wrong response to this request. Multiplex ids could collide if<br />
	one of a series requests takes much longer than the others, or<br />
	if a very large number of long lived requests (byte range<br />
	locks or FindNotify requests) are pending.  No more than<br />
	64K-1 requests can be outstanding at one time.  If no<br />
	mids are available, return zero.  A future optimization<br />
	could make the combination of mids and uid the key we use<br />
	to demultiplex on (rather than mid alone).<br />
	In addition to the above check, the cifs demultiplex<br />
	code already used the command code as a secondary<br />
	check of the frame and if signing is negotiated the<br />
	response would be discarded if the mid were the same<br />
	but the signature was wrong.  Since the mid is not put in the<br />
	pending queue until later (when it is about to be dispatched)<br />
	we do have to limit the number of outstanding requests<br />
	to somewhat less than 64K-1 although it is hard to imagine<br />
	so many threads being in the vfs at one time.<br />
*/<br />
__u16 GetNextMid(struct TCP_Server_Info *server)<br />
{<br />
	__u16 mid = 0;<br />
	__u16 last_mid;<br />
	int   collision;</p>
<p>	if (server == NULL)<br />
		return mid;</p>
<p>	spin_lock(&#038;GlobalMid_Lock);<br />
	last_mid = server->CurrentMid; /* we do not want to loop forever */<br />
	server->CurrentMid++;<br />
	/* This nested loop looks more expensive than it is.<br />
	In practice the list of pending requests is short,<br />
	fewer than 50, and the mids are likely to be unique<br />
	on the first pass through the loop unless some request<br />
	takes longer than the 64 thousand requests before it<br />
	(and it would also have to have been a request that<br />
	 did not time out) */<br />
	while (server->CurrentMid != last_mid) {<br />
		struct list_head *tmp;<br />
		struct mid_q_entry *mid_entry;</p>
<p>		collision = 0;<br />
		if (server->CurrentMid == 0)<br />
			server->CurrentMid++;</p>
<p>		list_for_each(tmp, &#038;server->pending_mid_q) {<br />
			mid_entry = list_entry(tmp, struct mid_q_entry, qhead);</p>
<p>			if ((mid_entry->mid == server->CurrentMid) &#038;&#038;<br />
			    (mid_entry->midState == MID_REQUEST_SUBMITTED)) {<br />
				/* This mid is in use, try a different one */<br />
				collision = 1;<br />
				break;<br />
			}<br />
		}<br />
		if (collision == 0) {<br />
			mid = server->CurrentMid;<br />
			break;<br />
		}<br />
		server->CurrentMid++;<br />
	}<br />
	spin_unlock(&#038;GlobalMid_Lock);<br />
	return mid;<br />
}</p>
<p>/* NB: MID can not be set if treeCon not passed in, in that<br />
   case it is responsbility of caller to set the mid */<br />
void<br />
header_assemble(struct smb_hdr *buffer, char smb_command /* command */ ,<br />
		const struct cifsTconInfo *treeCon, int word_count<br />
		/* length of fixed section (word count) in two byte units  */)<br />
{<br />
	struct list_head *temp_item;<br />
	struct cifsSesInfo *ses;<br />
	char *temp = (char *) buffer;</p>
<p>	memset(temp, 0, 256); /* bigger than MAX_CIFS_HDR_SIZE */</p>
<p>	buffer->smb_buf_length =<br />
	    (2 * word_count) + sizeof(struct smb_hdr) -<br />
	    4 /*  RFC 1001 length field does not count */  +<br />
	    2 /* for bcc field itself */ ;<br />
	/* Note that this is the only network field that has to be converted<br />
	   to big endian and it is done just before we send it */</p>
<p>	buffer->Protocol[0] = 0xFF;<br />
	buffer->Protocol[1] = &#8216;S&#8217;;<br />
	buffer->Protocol[2] = &#8216;M&#8217;;<br />
	buffer->Protocol[3] = &#8216;B&#8217;;<br />
	buffer->Command = smb_command;<br />
	buffer->Flags = 0&#215;00;	/* case sensitive */<br />
	buffer->Flags2 = SMBFLG2_KNOWS_LONG_NAMES;<br />
	buffer->Pid = cpu_to_le16((__u16)current->tgid);<br />
	buffer->PidHigh = cpu_to_le16((__u16)(current->tgid >> 16));<br />
	if (treeCon) {<br />
		buffer->Tid = treeCon->tid;<br />
		if (treeCon->ses) {<br />
			if (treeCon->ses->capabilities &#038; CAP_UNICODE)<br />
				buffer->Flags2 |= SMBFLG2_UNICODE;<br />
			if (treeCon->ses->capabilities &#038; CAP_STATUS32)<br />
				buffer->Flags2 |= SMBFLG2_ERR_STATUS;</p>
<p>			/* Uid is not converted */<br />
			buffer->Uid = treeCon->ses->Suid;<br />
			buffer->Mid = GetNextMid(treeCon->ses->server);<br />
			if (multiuser_mount != 0) {<br />
		/* For the multiuser case, there are few obvious technically  */<br />
		/* possible mechanisms to match the local linux user (uid)    */<br />
		/* to a valid remote smb user (smb_uid):		      */<br />
		/* 	1) Query Winbind (or other local pam/nss daemon       */<br />
		/* 	  for userid/password/logon_domain or credential      */<br />
		/*      2) Query Winbind for uid to sid to username mapping   */<br />
		/* 	   and see if we have a matching password for existing*/<br />
		/*         session for that user perhas getting password by   */<br />
		/*         adding a new pam_cifs module that stores passwords */<br />
		/*         so that the cifs vfs can get at that for all logged*/<br />
		/*	   on users					      */<br />
		/*	3) (Which is the mechanism we have chosen)	      */<br />
		/*	   Search through sessions to the same server for a   */<br />
		/*	   a match on the uid that was passed in on mount     */<br />
		/*         with the current processes uid (or euid?) and use  */<br />
		/* 	   that smb uid.   If no existing smb session for     */<br />
		/* 	   that uid found, use the default smb session ie     */<br />
		/*         the smb session for the volume mounted which is    */<br />
		/* 	   the same as would be used if the multiuser mount   */<br />
		/* 	   flag were disabled.  */</p>
<p>		/*  BB Add support for establishing new tCon and SMB Session  */<br />
		/*      with userid/password pairs found on the smb session   */<br />
		/*	for other target tcp/ip addresses 		BB    */<br />
				if (current_fsuid() != treeCon->ses->linux_uid) {<br />
					cFYI(1, (&raquo;Multiuser mode and UID &raquo;<br />
						 &laquo;did not match tcon uid&raquo;));<br />
					read_lock(&#038;cifs_tcp_ses_lock);<br />
					list_for_each(temp_item, &#038;treeCon->ses->server->smb_ses_list) {<br />
						ses = list_entry(temp_item, struct cifsSesInfo, smb_ses_list);<br />
						if (ses->linux_uid == current_fsuid()) {<br />
							if (ses->server == treeCon->ses->server) {<br />
								cFYI(1, (&raquo;found matching uid substitute right smb_uid&raquo;));<br />
								buffer->Uid = ses->Suid;<br />
								break;<br />
							} else {<br />
				/* BB eventually call cifs_setup_session here */<br />
								cFYI(1, (&raquo;local UID found but no smb sess with this server exists&raquo;));<br />
							}<br />
						}<br />
					}<br />
					read_unlock(&#038;cifs_tcp_ses_lock);<br />
				}<br />
			}<br />
		}<br />
		if (treeCon->Flags &#038; SMB_SHARE_IS_IN_DFS)<br />
			buffer->Flags2 |= SMBFLG2_DFS;<br />
		if (treeCon->nocase)<br />
			buffer->Flags  |= SMBFLG_CASELESS;<br />
		if ((treeCon->ses) &#038;&#038; (treeCon->ses->server))<br />
			if (treeCon->ses->server->secMode &#038;<br />
			  (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))<br />
				buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;<br />
	}</p>
<p>/*  endian conversion of flags is now done just before sending */<br />
	buffer->WordCount = (char) word_count;<br />
	return;<br />
}</p>
<p>static int<br />
checkSMBhdr(struct smb_hdr *smb, __u16 mid)<br />
{<br />
	/* Make sure that this really is an SMB, that it is a response,<br />
	   and that the message ids match */<br />
	if ((*(__le32 *) smb->Protocol == cpu_to_le32(0&#215;424d53ff)) &#038;&#038;<br />
		(mid == smb->Mid)) {<br />
		if (smb->Flags &#038; SMBFLG_RESPONSE)<br />
			return 0;<br />
		else {<br />
		/* only one valid case where server sends us request */<br />
			if (smb->Command == SMB_COM_LOCKING_ANDX)<br />
				return 0;<br />
			else<br />
				cERROR(1, (&raquo;Received Request not response&raquo;));<br />
		}<br />
	} else { /* bad signature or mid */<br />
		if (*(__le32 *) smb->Protocol != cpu_to_le32(0&#215;424d53ff))<br />
			cERROR(1,<br />
			       (&raquo;Bad protocol string signature header %x&raquo;,<br />
				*(unsigned int *) smb->Protocol));<br />
		if (mid != smb->Mid)<br />
			cERROR(1, (&raquo;Mids do not match&raquo;));<br />
	}<br />
	cERROR(1, (&raquo;bad smb detected. The Mid=%d&raquo;, smb->Mid));<br />
	return 1;<br />
}</p>
<p>int<br />
checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length)<br />
{<br />
	__u32 len = smb->smb_buf_length;<br />
	__u32 clc_len;  /* calculated length */<br />
	cFYI(0, (&raquo;checkSMB Length: 0x%x, smb_buf_length: 0x%x&raquo;, length, len));</p>
<p>	if (length < 2 + sizeof(struct smb_hdr)) {<br />
		if ((length >= sizeof(struct smb_hdr) &#8211; 1)<br />
			    &#038;&#038; (smb->Status.CifsError != 0)) {<br />
			smb->WordCount = 0;<br />
			/* some error cases do not return wct and bcc */<br />
			return 0;<br />
		} else if ((length == sizeof(struct smb_hdr) + 1) &#038;&#038;<br />
				(smb->WordCount == 0)) {<br />
			char *tmp = (char *)smb;<br />
			/* Need to work around a bug in two servers here */<br />
			/* First, check if the part of bcc they sent was zero */<br />
			if (tmp[sizeof(struct smb_hdr)] == 0) {<br />
				/* some servers return only half of bcc<br />
				 * on simple responses (wct, bcc both zero)<br />
				 * in particular have seen this on<br />
				 * ulogoffX and FindClose. This leaves<br />
				 * one byte of bcc potentially unitialized<br />
				 */<br />
				/* zero rest of bcc */<br />
				tmp[sizeof(struct smb_hdr)+1] = 0;<br />
				return 0;<br />
			}<br />
			cERROR(1, (&raquo;rcvd invalid byte count (bcc)&raquo;));<br />
		} else {<br />
			cERROR(1, (&raquo;Length less than smb header size&raquo;));<br />
		}<br />
		return 1;<br />
	}<br />
	if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE &#8211; 4) {<br />
		cERROR(1, (&raquo;smb length greater than MaxBufSize, mid=%d&raquo;,<br />
				   smb->Mid));<br />
		return 1;<br />
	}</p>
<p>	if (checkSMBhdr(smb, mid))<br />
		return 1;<br />
	clc_len = smbCalcSize_LE(smb);</p>
<p>	if (4 + len != length) {<br />
		cERROR(1, (&raquo;Length read does not match RFC1001 length %d&raquo;,<br />
			   len));<br />
		return 1;<br />
	}</p>
<p>	if (4 + len != clc_len) {<br />
		/* check if bcc wrapped around for large read responses */<br />
		if ((len > 64 * 1024) &#038;&#038; (len > clc_len)) {<br />
			/* check if lengths match mod 64K */<br />
			if (((4 + len) &#038; 0xFFFF) == (clc_len &#038; 0xFFFF))<br />
				return 0; /* bcc wrapped */<br />
		}<br />
		cFYI(1, (&raquo;Calculated size %d vs length %d mismatch for mid %d&raquo;,<br />
				clc_len, 4 + len, smb->Mid));<br />
		/* Windows XP can return a few bytes too much, presumably<br />
		an illegal pad, at the end of byte range lock responses<br />
		so we allow for that three byte pad, as long as actual<br />
		received length is as long or longer than calculated length */<br />
		/* We have now had to extend this more, since there is a<br />
		case in which it needs to be bigger still to handle a<br />
		malformed response to transact2 findfirst from WinXP when<br />
		access denied is returned and thus bcc and wct are zero<br />
		but server says length is 0&#215;21 bytes too long as if the server<br />
		forget to reset the smb rfc1001 length when it reset the<br />
		wct and bcc to minimum size and drop the t2 parms and data */<br />
		if ((4+len > clc_len) &#038;&#038; (len <= clc_len + 512))<br />
			return 0;<br />
		else {<br />
			cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d",<br />
					len, smb->Mid));<br />
			return 1;<br />
		}<br />
	}<br />
	return 0;<br />
}</p>
<p>bool<br />
is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)<br />
{<br />
	struct smb_com_lock_req *pSMB = (struct smb_com_lock_req *)buf;<br />
	struct list_head *tmp, *tmp1, *tmp2;<br />
	struct cifsSesInfo *ses;<br />
	struct cifsTconInfo *tcon;<br />
	struct cifsInodeInfo *pCifsInode;<br />
	struct cifsFileInfo *netfile;<br />
	int rc;</p>
<p>	cFYI(1, (&raquo;Checking for oplock break or dnotify response&raquo;));<br />
	if ((pSMB->hdr.Command == SMB_COM_NT_TRANSACT) &#038;&#038;<br />
	   (pSMB->hdr.Flags &#038; SMBFLG_RESPONSE)) {<br />
		struct smb_com_transaction_change_notify_rsp *pSMBr =<br />
			(struct smb_com_transaction_change_notify_rsp *)buf;<br />
		struct file_notify_information *pnotify;<br />
		__u32 data_offset = 0;<br />
		if (pSMBr->ByteCount > sizeof(struct file_notify_information)) {<br />
			data_offset = le32_to_cpu(pSMBr->DataOffset);</p>
<p>			pnotify = (struct file_notify_information *)<br />
				((char *)&#038;pSMBr->hdr.Protocol + data_offset);<br />
			cFYI(1, (&raquo;dnotify on %s Action: 0x%x&raquo;,<br />
				 pnotify->FileName, pnotify->Action));<br />
			/*   cifs_dump_mem(&raquo;Rcvd notify Data: &laquo;,buf,<br />
				sizeof(struct smb_hdr)+60); */<br />
			return true;<br />
		}<br />
		if (pSMBr->hdr.Status.CifsError) {<br />
			cFYI(1, (&raquo;notify err 0x%d&raquo;,<br />
				pSMBr->hdr.Status.CifsError));<br />
			return true;<br />
		}<br />
		return false;<br />
	}<br />
	if (pSMB->hdr.Command != SMB_COM_LOCKING_ANDX)<br />
		return false;<br />
	if (pSMB->hdr.Flags &#038; SMBFLG_RESPONSE) {<br />
		/* no sense logging error on invalid handle on oplock<br />
		   break &#8211; harmless race between close request and oplock<br />
		   break response is expected from time to time writing out<br />
		   large dirty files cached on the client */<br />
		if ((NT_STATUS_INVALID_HANDLE) ==<br />
		   le32_to_cpu(pSMB->hdr.Status.CifsError)) {<br />
			cFYI(1, (&raquo;invalid handle on oplock break&raquo;));<br />
			return true;<br />
		} else if (ERRbadfid ==<br />
		   le16_to_cpu(pSMB->hdr.Status.DosError.Error)) {<br />
			return true;<br />
		} else {<br />
			return false; /* on valid oplock brk we get &laquo;request&raquo; */<br />
		}<br />
	}<br />
	if (pSMB->hdr.WordCount != <img src='http://lynyrd.ru/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /><br />
		return false;</p>
<p>	cFYI(1, (&raquo;oplock type 0x%d level 0x%d&raquo;,<br />
		 pSMB->LockType, pSMB->OplockLevel));<br />
	if (!(pSMB->LockType &#038; LOCKING_ANDX_OPLOCK_RELEASE))<br />
		return false;</p>
<p>	/* look up tcon based on tid &#038; uid */<br />
	read_lock(&#038;cifs_tcp_ses_lock);<br />
	list_for_each(tmp, &#038;srv->smb_ses_list) {<br />
		ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);<br />
		list_for_each(tmp1, &#038;ses->tcon_list) {<br />
			tcon = list_entry(tmp1, struct cifsTconInfo, tcon_list);<br />
			if (tcon->tid != buf->Tid)<br />
				continue;</p>
<p>			cifs_stats_inc(&#038;tcon->num_oplock_brks);<br />
			read_lock(&#038;GlobalSMBSeslock);<br />
			list_for_each(tmp2, &#038;tcon->openFileList) {<br />
				netfile = list_entry(tmp2, struct cifsFileInfo,<br />
						     tlist);<br />
				if (pSMB->Fid != netfile->netfid)<br />
					continue;</p>
<p>				/*<br />
				 * don&#8217;t do anything if file is about to be<br />
				 * closed anyway.<br />
				 */<br />
				if (netfile->closePend) {<br />
					read_unlock(&#038;GlobalSMBSeslock);<br />
					read_unlock(&#038;cifs_tcp_ses_lock);<br />
					return true;<br />
				}</p>
<p>				cFYI(1, (&raquo;file id match, oplock break&raquo;));<br />
				pCifsInode = CIFS_I(netfile->pInode);<br />
				pCifsInode->clientCanCacheAll = false;<br />
				if (pSMB->OplockLevel == 0)<br />
					pCifsInode->clientCanCacheRead = false;<br />
				rc = slow_work_enqueue(&#038;netfile->oplock_break);<br />
				if (rc) {<br />
					cERROR(1, (&raquo;failed to enqueue oplock &raquo;<br />
						   &laquo;break: %d\n&raquo;, rc));<br />
				} else {<br />
					netfile->oplock_break_cancelled = false;<br />
				}<br />
				read_unlock(&#038;GlobalSMBSeslock);<br />
				read_unlock(&#038;cifs_tcp_ses_lock);<br />
				return true;<br />
			}<br />
			read_unlock(&#038;GlobalSMBSeslock);<br />
			read_unlock(&#038;cifs_tcp_ses_lock);<br />
			cFYI(1, (&raquo;No matching file for oplock break&raquo;));<br />
			return true;<br />
		}<br />
	}<br />
	read_unlock(&#038;cifs_tcp_ses_lock);<br />
	cFYI(1, (&raquo;Can not process oplock break for non-existent connection&raquo;));<br />
	return true;<br />
}</p>
<p>void<br />
dump_smb(struct smb_hdr *smb_buf, int smb_buf_length)<br />
{<br />
	int i, j;<br />
	char debug_line[17];<br />
	unsigned char *buffer;</p>
<p>	if (traceSMB == 0)<br />
		return;</p>
<p>	buffer = (unsigned char *) smb_buf;<br />
	for (i = 0, j = 0; i < smb_buf_length; i++, j++) {<br />
		if (i % 8 == 0) {<br />
			/* have reached the beginning of line */<br />
			printk(KERN_DEBUG "| ");<br />
			j = 0;<br />
		}<br />
		printk("%0#4x ", buffer[i]);<br />
		debug_line[2 * j] = ' ';<br />
		if (isprint(buffer[i]))<br />
			debug_line[1 + (2 * j)] = buffer[i];<br />
		else<br />
			debug_line[1 + (2 * j)] = '_';</p>
<p>		if (i % 8 == 7) {<br />
			/* reached end of line, time to print ascii */<br />
			debug_line[16] = 0;<br />
			printk(" | %s\n", debug_line);<br />
		}<br />
	}<br />
	for (; j < 8; j++) {<br />
		printk("     ");<br />
		debug_line[2 * j] = ' ';<br />
		debug_line[1 + (2 * j)] = ' ';<br />
	}<br />
	printk(" | %s\n", debug_line);<br />
	return;<br />
}</p>
<p>/* Convert 16 bit Unicode pathname to wire format from string in current code<br />
   page.  Conversion may involve remapping up the seven characters that are<br />
   only legal in POSIX-like OS (if they are present in the string). Path<br />
   names are little endian 16 bit Unicode on the wire */<br />
int<br />
cifsConvertToUCS(__le16 *target, const char *source, int maxlen,<br />
		 const struct nls_table *cp, int mapChars)<br />
{<br />
	int i, j, charlen;<br />
	int len_remaining = maxlen;<br />
	char src_char;<br />
	__u16 temp;</p>
<p>	if (!mapChars)<br />
		return cifs_strtoUCS(target, source, PATH_MAX, cp);</p>
<p>	for (i = 0, j = 0; i < maxlen; j++) {<br />
		src_char = source[i];<br />
		switch (src_char) {<br />
			case 0:<br />
				target[j] = 0;<br />
				goto ctoUCS_out;<br />
			case ':':<br />
				target[j] = cpu_to_le16(UNI_COLON);<br />
				break;<br />
			case '*':<br />
				target[j] = cpu_to_le16(UNI_ASTERIK);<br />
				break;<br />
			case '?':<br />
				target[j] = cpu_to_le16(UNI_QUESTION);<br />
				break;<br />
			case '<':<br />
				target[j] = cpu_to_le16(UNI_LESSTHAN);<br />
				break;<br />
			case '>&#8216;:<br />
				target[j] = cpu_to_le16(UNI_GRTRTHAN);<br />
				break;<br />
			case &#8216;|&#8217;:<br />
				target[j] = cpu_to_le16(UNI_PIPE);<br />
				break;<br />
			/* BB We can not handle remapping slash until<br />
			   all the calls to build_path_from_dentry<br />
			   are modified, as they use slash as separator BB */<br />
			/* case &#8216;\\&#8217;:<br />
				target[j] = cpu_to_le16(UNI_SLASH);<br />
				break;*/<br />
			default:<br />
				charlen = cp->char2uni(source+i,<br />
					len_remaining, &#038;temp);<br />
				/* if no match, use question mark, which<br />
				at least in some cases servers as wild card */<br />
				if (charlen < 1) {<br />
					target[j] = cpu_to_le16(0x003f);<br />
					charlen = 1;<br />
				} else<br />
					target[j] = cpu_to_le16(temp);<br />
				len_remaining -= charlen;<br />
				/* character may take more than one byte in the<br />
				   the source string, but will take exactly two<br />
				   bytes in the target string */<br />
				i += charlen;<br />
				continue;<br />
		}<br />
		i++; /* move to next char in source string */<br />
		len_remaining--;<br />
	}</p>
<p>ctoUCS_out:<br />
	return i;<br />
}</p>
<p>void<br />
cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)<br />
{<br />
	if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_SERVER_INUM) {<br />
		cifs_sb->mnt_cifs_flags &#038;= ~CIFS_MOUNT_SERVER_INUM;<br />
		cERROR(1, (&raquo;Autodisabling the use of server inode numbers on &raquo;<br />
			   &laquo;%s. This server doesn&#8217;t seem to support them &raquo;<br />
			   &laquo;properly. Hardlinks will not be recognized on this &raquo;<br />
			   &laquo;mount. Consider mounting with the \&raquo;noserverino\&raquo; &raquo;<br />
			   &laquo;option to silence this message.&raquo;,<br />
			   cifs_sb->tcon->treeName));<br />
	}<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/misc-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>md5.h</title>
		<link>http://lynyrd.ru/md5-h</link>
		<comments>http://lynyrd.ru/md5-h#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:29:05 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/md5-h</guid>
		<description><![CDATA[#ifndef MD5_H
#define MD5_H
#ifndef HEADER_MD5_H
/* Try to avoid clashes with OpenSSL */
#define HEADER_MD5_H
#endif
struct MD5Context {
	__u32 buf[4];
	__u32 bits[2];
	unsigned char in[64];
};
#endif				/* !MD5_H */
#ifndef _HMAC_MD5_H
struct HMACMD5Context {
	struct MD5Context ctx;
	unsigned char k_ipad[65];
	unsigned char k_opad[65];
};
#endif				/* _HMAC_MD5_H */
void cifs_MD5_init(struct MD5Context *context);
void cifs_MD5_update(struct MD5Context *context, unsigned char const *buf,
			unsigned len);
void cifs_MD5_final(unsigned char digest[16], struct MD5Context *context);
/* The following definitions come from lib/hmacmd5.c  ]]></description>
			<content:encoded><![CDATA[<p>#ifndef MD5_H<br />
#define MD5_H<span id="more-952"></span><br />
#ifndef HEADER_MD5_H<br />
/* Try to avoid clashes with OpenSSL */<br />
#define HEADER_MD5_H<br />
#endif</p>
<p>struct MD5Context {<br />
	__u32 buf[4];<br />
	__u32 bits[2];<br />
	unsigned char in[64];<br />
};<br />
#endif				/* !MD5_H */</p>
<p>#ifndef _HMAC_MD5_H<br />
struct HMACMD5Context {<br />
	struct MD5Context ctx;<br />
	unsigned char k_ipad[65];<br />
	unsigned char k_opad[65];<br />
};<br />
#endif				/* _HMAC_MD5_H */</p>
<p>void cifs_MD5_init(struct MD5Context *context);<br />
void cifs_MD5_update(struct MD5Context *context, unsigned char const *buf,<br />
			unsigned len);<br />
void cifs_MD5_final(unsigned char digest[16], struct MD5Context *context);</p>
<p>/* The following definitions come from lib/hmacmd5.c  */</p>
<p>/* void hmac_md5_init_rfc2104(unsigned char *key, int key_len,<br />
			struct HMACMD5Context *ctx);*/<br />
void hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,<br />
			struct HMACMD5Context *ctx);<br />
void hmac_md5_update(const unsigned char *text, int text_len,<br />
			struct HMACMD5Context *ctx);<br />
void hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx);<br />
/* void hmac_md5(unsigned char key[16], unsigned char *data, int data_len,<br />
			unsigned char *digest);*/</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/md5-h/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>md5.c</title>
		<link>http://lynyrd.ru/md5-c</link>
		<comments>http://lynyrd.ru/md5-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:28:47 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/?p=950</guid>
		<description><![CDATA[/*
 * This code implements the MD5 message-digest algorithm.
 * The algorithm is due to Ron Rivest.  This code was
 * written by Colin Plumb in 1993, no copyright is claimed.
 * This code is in the public domain; do with it what you wish.
 *
 * Equivalent code is available from RSA Data ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 * This code implements the MD5 message-digest algorithm.<span id="more-950"></span><br />
 * The algorithm is due to Ron Rivest.  This code was<br />
 * written by Colin Plumb in 1993, no copyright is claimed.<br />
 * This code is in the public domain; do with it what you wish.<br />
 *<br />
 * Equivalent code is available from RSA Data Security, Inc.<br />
 * This code has been tested against that, and is equivalent,<br />
 * except that you don&#8217;t need to include two pages of legalese<br />
 * with every copy.<br />
 *<br />
 * To compute the message digest of a chunk of bytes, declare an<br />
 * MD5Context structure, pass it to cifs_MD5_init, call cifs_MD5_update as<br />
 * needed on buffers full of bytes, and then call cifs_MD5_final, which<br />
 * will fill a supplied 16-byte array with the digest.<br />
 */</p>
<p>/* This code slightly modified to fit into Samba by<br />
   abartlet@samba.org Jun 2001<br />
   and to fit the cifs vfs by<br />
   Steve French sfrench@us.ibm.com */</p>
<p>#include
<linux/string.h>
#include &laquo;md5.h&raquo;</p>
<p>static void MD5Transform(__u32 buf[4], __u32 const in[16]);</p>
<p>/*<br />
 * Note: this code is harmless on little-endian machines.<br />
 */<br />
static void<br />
byteReverse(unsigned char *buf, unsigned longs)<br />
{<br />
	__u32 t;<br />
	do {<br />
		t = (__u32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |<br />
		    ((unsigned) buf[1] << 8 | buf[0]);<br />
		*(__u32 *) buf = t;<br />
		buf += 4;<br />
	} while (--longs);<br />
}</p>
<p>/*<br />
 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious<br />
 * initialization constants.<br />
 */<br />
void<br />
cifs_MD5_init(struct MD5Context *ctx)<br />
{<br />
	ctx->buf[0] = 0&#215;67452301;<br />
	ctx->buf[1] = 0xefcdab89;<br />
	ctx->buf[2] = 0&#215;98badcfe;<br />
	ctx->buf[3] = 0&#215;10325476;</p>
<p>	ctx->bits[0] = 0;<br />
	ctx->bits[1] = 0;<br />
}</p>
<p>/*<br />
 * Update context to reflect the concatenation of another buffer full<br />
 * of bytes.<br />
 */<br />
void<br />
cifs_MD5_update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)<br />
{<br />
	register __u32 t;</p>
<p>	/* Update bitcount */</p>
<p>	t = ctx->bits[0];<br />
	if ((ctx->bits[0] = t + ((__u32) len << 3)) < t)<br />
		ctx->bits[1]++;	/* Carry from low to high */<br />
	ctx->bits[1] += len >> 29;</p>
<p>	t = (t >> 3) &#038; 0&#215;3f;	/* Bytes already in shsInfo->data */</p>
<p>	/* Handle any leading odd-sized chunks */</p>
<p>	if (t) {<br />
		unsigned char *p = (unsigned char *) ctx->in + t;</p>
<p>		t = 64 &#8211; t;<br />
		if (len < t) {<br />
			memmove(p, buf, len);<br />
			return;<br />
		}<br />
		memmove(p, buf, t);<br />
		byteReverse(ctx->in, 16);<br />
		MD5Transform(ctx->buf, (__u32 *) ctx->in);<br />
		buf += t;<br />
		len -= t;<br />
	}<br />
	/* Process data in 64-byte chunks */</p>
<p>	while (len >= 64) {<br />
		memmove(ctx->in, buf, 64);<br />
		byteReverse(ctx->in, 16);<br />
		MD5Transform(ctx->buf, (__u32 *) ctx->in);<br />
		buf += 64;<br />
		len -= 64;<br />
	}</p>
<p>	/* Handle any remaining bytes of data. */</p>
<p>	memmove(ctx->in, buf, len);<br />
}</p>
<p>/*<br />
 * Final wrapup &#8211; pad to 64-byte boundary with the bit pattern<br />
 * 1 0* (64-bit count of bits processed, MSB-first)<br />
 */<br />
void<br />
cifs_MD5_final(unsigned char digest[16], struct MD5Context *ctx)<br />
{<br />
	unsigned int count;<br />
	unsigned char *p;</p>
<p>	/* Compute number of bytes mod 64 */<br />
	count = (ctx->bits[0] >> 3) &#038; 0&#215;3F;</p>
<p>	/* Set the first char of padding to 0&#215;80.  This is safe since there is<br />
	   always at least one byte free */<br />
	p = ctx->in + count;<br />
	*p++ = 0&#215;80;</p>
<p>	/* Bytes of padding needed to make 64 bytes */<br />
	count = 64 &#8211; 1 &#8211; count;</p>
<p>	/* Pad out to 56 mod 64 */<br />
	if (count < <img src='http://lynyrd.ru/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> {<br />
		/* Two lots of padding:  Pad the first block to 64 bytes */<br />
		memset(p, 0, count);<br />
		byteReverse(ctx->in, 16);<br />
		MD5Transform(ctx->buf, (__u32 *) ctx->in);</p>
<p>		/* Now fill the next block with 56 bytes */<br />
		memset(ctx->in, 0, 56);<br />
	} else {<br />
		/* Pad block to 56 bytes */<br />
		memset(p, 0, count &#8211; 8);<br />
	}<br />
	byteReverse(ctx->in, 14);</p>
<p>	/* Append length in bits and transform */<br />
	((__u32 *) ctx->in)[14] = ctx->bits[0];<br />
	((__u32 *) ctx->in)[15] = ctx->bits[1];</p>
<p>	MD5Transform(ctx->buf, (__u32 *) ctx->in);<br />
	byteReverse((unsigned char *) ctx->buf, 4);<br />
	memmove(digest, ctx->buf, 16);<br />
	memset(ctx, 0, sizeof(*ctx));	/* In case it&#8217;s sensitive */<br />
}</p>
<p>/* The four core functions &#8211; F1 is optimized somewhat */</p>
<p>/* #define F1(x, y, z) (x &#038; y | ~x &#038; z) */<br />
#define F1(x, y, z) (z ^ (x &#038; (y ^ z)))<br />
#define F2(x, y, z) F1(z, x, y)<br />
#define F3(x, y, z) (x ^ y ^ z)<br />
#define F4(x, y, z) (y ^ (x | ~z))</p>
<p>/* This is the central step in the MD5 algorithm. */<br />
#define MD5STEP(f, w, x, y, z, data, s) \<br />
	(w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x)</p>
<p>/*<br />
 * The core of the MD5 algorithm, this alters an existing MD5 hash to<br />
 * reflect the addition of 16 longwords of new data.  cifs_MD5_update blocks<br />
 * the data and converts bytes into longwords for this routine.<br />
 */<br />
static void<br />
MD5Transform(__u32 buf[4], __u32 const in[16])<br />
{<br />
	register __u32 a, b, c, d;</p>
<p>	a = buf[0];<br />
	b = buf[1];<br />
	c = buf[2];<br />
	d = buf[3];</p>
<p>	MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);<br />
	MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);<br />
	MD5STEP(F1, c, d, a, b, in[2] + 0&#215;242070db, 17);<br />
	MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);<br />
	MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);<br />
	MD5STEP(F1, d, a, b, c, in[5] + 0&#215;4787c62a, 12);<br />
	MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);<br />
	MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);<br />
	MD5STEP(F1, a, b, c, d, in[8] + 0&#215;698098d8, 7);<br />
	MD5STEP(F1, d, a, b, c, in[9] + 0&#215;8b44f7af, 12);<br />
	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);<br />
	MD5STEP(F1, b, c, d, a, in[11] + 0&#215;895cd7be, 22);<br />
	MD5STEP(F1, a, b, c, d, in[12] + 0&#215;6b901122, 7);<br />
	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);<br />
	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);<br />
	MD5STEP(F1, b, c, d, a, in[15] + 0&#215;49b40821, 22);</p>
<p>	MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);<br />
	MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);<br />
	MD5STEP(F2, c, d, a, b, in[11] + 0&#215;265e5a51, 14);<br />
	MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);<br />
	MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);<br />
	MD5STEP(F2, d, a, b, c, in[10] + 0&#215;02441453, 9);<br />
	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);<br />
	MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);<br />
	MD5STEP(F2, a, b, c, d, in[9] + 0&#215;21e1cde6, 5);<br />
	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);<br />
	MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);<br />
	MD5STEP(F2, b, c, d, a, in[8] + 0&#215;455a14ed, 20);<br />
	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);<br />
	MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);<br />
	MD5STEP(F2, c, d, a, b, in[7] + 0&#215;676f02d9, 14);<br />
	MD5STEP(F2, b, c, d, a, in[12] + 0&#215;8d2a4c8a, 20);</p>
<p>	MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);<br />
	MD5STEP(F3, d, a, b, c, in[8] + 0&#215;8771f681, 11);<br />
	MD5STEP(F3, c, d, a, b, in[11] + 0&#215;6d9d6122, 16);<br />
	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);<br />
	MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);<br />
	MD5STEP(F3, d, a, b, c, in[4] + 0&#215;4bdecfa9, 11);<br />
	MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);<br />
	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);<br />
	MD5STEP(F3, a, b, c, d, in[13] + 0&#215;289b7ec6, 4);<br />
	MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);<br />
	MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);<br />
	MD5STEP(F3, b, c, d, a, in[6] + 0&#215;04881d05, 23);<br />
	MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);<br />
	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);<br />
	MD5STEP(F3, c, d, a, b, in[15] + 0&#215;1fa27cf8, 16);<br />
	MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);</p>
<p>	MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);<br />
	MD5STEP(F4, d, a, b, c, in[7] + 0&#215;432aff97, 10);<br />
	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);<br />
	MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);<br />
	MD5STEP(F4, a, b, c, d, in[12] + 0&#215;655b59c3, 6);<br />
	MD5STEP(F4, d, a, b, c, in[3] + 0&#215;8f0ccc92, 10);<br />
	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);<br />
	MD5STEP(F4, b, c, d, a, in[1] + 0&#215;85845dd1, 21);<br />
	MD5STEP(F4, a, b, c, d, in[8] + 0&#215;6fa87e4f, 6);<br />
	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);<br />
	MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);<br />
	MD5STEP(F4, b, c, d, a, in[13] + 0&#215;4e0811a1, 21);<br />
	MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);<br />
	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);<br />
	MD5STEP(F4, c, d, a, b, in[2] + 0&#215;2ad7d2bb, 15);<br />
	MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);</p>
<p>	buf[0] += a;<br />
	buf[1] += b;<br />
	buf[2] += c;<br />
	buf[3] += d;<br />
}</p>
<p>#if 0   /* currently unused */<br />
/***********************************************************************<br />
 the rfc 2104 version of hmac_md5 initialisation.<br />
***********************************************************************/<br />
static void<br />
hmac_md5_init_rfc2104(unsigned char *key, int key_len,<br />
		      struct HMACMD5Context *ctx)<br />
{<br />
	int i;</p>
<p>	/* if key is longer than 64 bytes reset it to key=MD5(key) */<br />
	if (key_len > 64) {<br />
		unsigned char tk[16];<br />
		struct MD5Context tctx;</p>
<p>		cifs_MD5_init(&#038;tctx);<br />
		cifs_MD5_update(&#038;tctx, key, key_len);<br />
		cifs_MD5_final(tk, &#038;tctx);</p>
<p>		key = tk;<br />
		key_len = 16;<br />
	}</p>
<p>	/* start out by storing key in pads */<br />
	memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad));<br />
	memset(ctx->k_opad, 0, sizeof(ctx->k_opad));<br />
	memcpy(ctx->k_ipad, key, key_len);<br />
	memcpy(ctx->k_opad, key, key_len);</p>
<p>	/* XOR key with ipad and opad values */<br />
	for (i = 0; i < 64; i++) {<br />
		ctx->k_ipad[i] ^= 0&#215;36;<br />
		ctx->k_opad[i] ^= 0&#215;5c;<br />
	}</p>
<p>	cifs_MD5_init(&#038;ctx->ctx);<br />
	cifs_MD5_update(&#038;ctx->ctx, ctx->k_ipad, 64);<br />
}<br />
#endif</p>
<p>/***********************************************************************<br />
 the microsoft version of hmac_md5 initialisation.<br />
***********************************************************************/<br />
void<br />
hmac_md5_init_limK_to_64(const unsigned char *key, int key_len,<br />
			 struct HMACMD5Context *ctx)<br />
{<br />
	int i;</p>
<p>	/* if key is longer than 64 bytes truncate it */<br />
	if (key_len > 64)<br />
		key_len = 64;</p>
<p>	/* start out by storing key in pads */<br />
	memset(ctx->k_ipad, 0, sizeof(ctx->k_ipad));<br />
	memset(ctx->k_opad, 0, sizeof(ctx->k_opad));<br />
	memcpy(ctx->k_ipad, key, key_len);<br />
	memcpy(ctx->k_opad, key, key_len);</p>
<p>	/* XOR key with ipad and opad values */<br />
	for (i = 0; i < 64; i++) {<br />
		ctx->k_ipad[i] ^= 0&#215;36;<br />
		ctx->k_opad[i] ^= 0&#215;5c;<br />
	}</p>
<p>	cifs_MD5_init(&#038;ctx->ctx);<br />
	cifs_MD5_update(&#038;ctx->ctx, ctx->k_ipad, 64);<br />
}</p>
<p>/***********************************************************************<br />
 update hmac_md5 &laquo;inner&raquo; buffer<br />
***********************************************************************/<br />
void<br />
hmac_md5_update(const unsigned char *text, int text_len,<br />
		struct HMACMD5Context *ctx)<br />
{<br />
	cifs_MD5_update(&#038;ctx->ctx, text, text_len);	/* then text of datagram */<br />
}</p>
<p>/***********************************************************************<br />
 finish off hmac_md5 &laquo;inner&raquo; buffer and generate outer one.<br />
***********************************************************************/<br />
void<br />
hmac_md5_final(unsigned char *digest, struct HMACMD5Context *ctx)<br />
{<br />
	struct MD5Context ctx_o;</p>
<p>	cifs_MD5_final(digest, &#038;ctx->ctx);</p>
<p>	cifs_MD5_init(&#038;ctx_o);<br />
	cifs_MD5_update(&#038;ctx_o, ctx->k_opad, 64);<br />
	cifs_MD5_update(&#038;ctx_o, digest, 16);<br />
	cifs_MD5_final(digest, &#038;ctx_o);<br />
}</p>
<p>/***********************************************************<br />
 single function to calculate an HMAC MD5 digest from data.<br />
 use the microsoft hmacmd5 init method because the key is 16 bytes.<br />
************************************************************/<br />
#if 0 /* currently unused */<br />
static void<br />
hmac_md5(unsigned char key[16], unsigned char *data, int data_len,<br />
	 unsigned char *digest)<br />
{<br />
	struct HMACMD5Context ctx;<br />
	hmac_md5_init_limK_to_64(key, 16, &#038;ctx);<br />
	if (data_len != 0)<br />
		hmac_md5_update(data, data_len, &#038;ctx);</p>
<p>	hmac_md5_final(digest, &#038;ctx);<br />
}<br />
#endif</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/md5-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>md4.c</title>
		<link>http://lynyrd.ru/md4-c</link>
		<comments>http://lynyrd.ru/md4-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:28:24 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/?p=948</guid>
		<description><![CDATA[/*
   Unix SMB/Netbios implementation.
   Version 1.9.
   a implementation of MD4 designed for use in the SMB authentication protocol
   Copyright (C) Andrew Tridgell 1997-1998.
   Modified by Steve French (sfrench@us.ibm.com) 2002-2003
   This program is free software; you can redistribute it and/or modify
   it ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
   Unix SMB/Netbios implementation.<span id="more-948"></span><br />
   Version 1.9.<br />
   a implementation of MD4 designed for use in the SMB authentication protocol<br />
   Copyright (C) Andrew Tridgell 1997-1998.<br />
   Modified by Steve French (sfrench@us.ibm.com) 2002-2003</p>
<p>   This program is free software; you can redistribute it and/or modify<br />
   it under the terms of the GNU General Public License as published by<br />
   the Free Software Foundation; either version 2 of the License, or<br />
   (at your option) any later version.</p>
<p>   This program is distributed in the hope that it will be useful,<br />
   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
   GNU General Public License for more details.</p>
<p>   You should have received a copy of the GNU General Public License<br />
   along with this program; if not, write to the Free Software<br />
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br />
*/<br />
#include
<linux/module.h>
#include
<linux/fs.h>
#include &laquo;cifsencrypt.h&raquo;</p>
<p>/* NOTE: This code makes no attempt to be fast! */</p>
<p>static __u32<br />
F(__u32 X, __u32 Y, __u32 Z)<br />
{<br />
	return (X &#038; Y) | ((~X) &#038; Z);<br />
}</p>
<p>static __u32<br />
G(__u32 X, __u32 Y, __u32 Z)<br />
{<br />
	return (X &#038; Y) | (X &#038; Z) | (Y &#038; Z);<br />
}</p>
<p>static __u32<br />
H(__u32 X, __u32 Y, __u32 Z)<br />
{<br />
	return X ^ Y ^ Z;<br />
}</p>
<p>static __u32<br />
lshift(__u32 x, int s)<br />
{<br />
	x &#038;= 0xFFFFFFFF;<br />
	return ((x << s) &#038; 0xFFFFFFFF) | (x >> (32 &#8211; s));<br />
}</p>
<p>#define ROUND1(a,b,c,d,k,s) (*a) = lshift((*a) + F(*b,*c,*d) + X[k], s)<br />
#define ROUND2(a,b,c,d,k,s) (*a) = lshift((*a) + G(*b,*c,*d) + X[k] + (__u32)0&#215;5A827999,s)<br />
#define ROUND3(a,b,c,d,k,s) (*a) = lshift((*a) + H(*b,*c,*d) + X[k] + (__u32)0&#215;6ED9EBA1,s)</p>
<p>/* this applies md4 to 64 byte chunks */<br />
static void<br />
mdfour64(__u32 *M, __u32 *A, __u32 *B, __u32 *C, __u32 *D)<br />
{<br />
	int j;<br />
	__u32 AA, BB, CC, DD;<br />
	__u32 X[16];</p>
<p>	for (j = 0; j < 16; j++)<br />
		X[j] = M[j];</p>
<p>	AA = *A;<br />
	BB = *B;<br />
	CC = *C;<br />
	DD = *D;</p>
<p>	ROUND1(A, B, C, D, 0, 3);<br />
	ROUND1(D, A, B, C, 1, 7);<br />
	ROUND1(C, D, A, B, 2, 11);<br />
	ROUND1(B, C, D, A, 3, 19);<br />
	ROUND1(A, B, C, D, 4, 3);<br />
	ROUND1(D, A, B, C, 5, 7);<br />
	ROUND1(C, D, A, B, 6, 11);<br />
	ROUND1(B, C, D, A, 7, 19);<br />
	ROUND1(A, B, C, D, 8, 3);<br />
	ROUND1(D, A, B, C, 9, 7);<br />
	ROUND1(C, D, A, B, 10, 11);<br />
	ROUND1(B, C, D, A, 11, 19);<br />
	ROUND1(A, B, C, D, 12, 3);<br />
	ROUND1(D, A, B, C, 13, 7);<br />
	ROUND1(C, D, A, B, 14, 11);<br />
	ROUND1(B, C, D, A, 15, 19);</p>
<p>	ROUND2(A, B, C, D, 0, 3);<br />
	ROUND2(D, A, B, C, 4, 5);<br />
	ROUND2(C, D, A, B, 8, 9);<br />
	ROUND2(B, C, D, A, 12, 13);<br />
	ROUND2(A, B, C, D, 1, 3);<br />
	ROUND2(D, A, B, C, 5, 5);<br />
	ROUND2(C, D, A, B, 9, 9);<br />
	ROUND2(B, C, D, A, 13, 13);<br />
	ROUND2(A, B, C, D, 2, 3);<br />
	ROUND2(D, A, B, C, 6, 5);<br />
	ROUND2(C, D, A, B, 10, 9);<br />
	ROUND2(B, C, D, A, 14, 13);<br />
	ROUND2(A, B, C, D, 3, 3);<br />
	ROUND2(D, A, B, C, 7, 5);<br />
	ROUND2(C, D, A, B, 11, 9);<br />
	ROUND2(B, C, D, A, 15, 13);</p>
<p>	ROUND3(A, B, C, D, 0, 3);<br />
	ROUND3(D, A, B, C, 8, 9);<br />
	ROUND3(C, D, A, B, 4, 11);<br />
	ROUND3(B, C, D, A, 12, 15);<br />
	ROUND3(A, B, C, D, 2, 3);<br />
	ROUND3(D, A, B, C, 10, 9);<br />
	ROUND3(C, D, A, B, 6, 11);<br />
	ROUND3(B, C, D, A, 14, 15);<br />
	ROUND3(A, B, C, D, 1, 3);<br />
	ROUND3(D, A, B, C, 9, 9);<br />
	ROUND3(C, D, A, B, 5, 11);<br />
	ROUND3(B, C, D, A, 13, 15);<br />
	ROUND3(A, B, C, D, 3, 3);<br />
	ROUND3(D, A, B, C, 11, 9);<br />
	ROUND3(C, D, A, B, 7, 11);<br />
	ROUND3(B, C, D, A, 15, 15);</p>
<p>	*A += AA;<br />
	*B += BB;<br />
	*C += CC;<br />
	*D += DD;</p>
<p>	*A &#038;= 0xFFFFFFFF;<br />
	*B &#038;= 0xFFFFFFFF;<br />
	*C &#038;= 0xFFFFFFFF;<br />
	*D &#038;= 0xFFFFFFFF;</p>
<p>	for (j = 0; j < 16; j++)<br />
		X[j] = 0;<br />
}</p>
<p>static void<br />
copy64(__u32 *M, unsigned char *in)<br />
{<br />
	int i;</p>
<p>	for (i = 0; i < 16; i++)<br />
		M[i] = (in[i * 4 + 3] << 24) | (in[i * 4 + 2] << 16) |<br />
		    (in[i * 4 + 1] << <img src='http://lynyrd.ru/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> | (in[i * 4 + 0] << 0);<br />
}</p>
<p>static void<br />
copy4(unsigned char *out, __u32 x)<br />
{<br />
	out[0] = x &#038; 0xFF;<br />
	out[1] = (x >> <img src='http://lynyrd.ru/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> &#038; 0xFF;<br />
	out[2] = (x >> 16) &#038; 0xFF;<br />
	out[3] = (x >> 24) &#038; 0xFF;<br />
}</p>
<p>/* produce a md4 message digest from data of length n bytes */<br />
void<br />
mdfour(unsigned char *out, unsigned char *in, int n)<br />
{<br />
	unsigned char buf[128];<br />
	__u32 M[16];<br />
	__u32 b = n * 8;<br />
	int i;<br />
	__u32 A = 0&#215;67452301;<br />
	__u32 B = 0xefcdab89;<br />
	__u32 C = 0&#215;98badcfe;<br />
	__u32 D = 0&#215;10325476;</p>
<p>	while (n > 64) {<br />
		copy64(M, in);<br />
		mdfour64(M, &#038;A, &#038;B, &#038;C, &#038;D);<br />
		in += 64;<br />
		n -= 64;<br />
	}</p>
<p>	for (i = 0; i < 128; i++)<br />
		buf[i] = 0;<br />
	memcpy(buf, in, n);<br />
	buf[n] = 0&#215;80;</p>
<p>	if (n <= 55) {<br />
		copy4(buf + 56, b);<br />
		copy64(M, buf);<br />
		mdfour64(M, &#038;A, &#038;B, &#038;C, &#038;D);<br />
	} else {<br />
		copy4(buf + 120, b);<br />
		copy64(M, buf);<br />
		mdfour64(M, &#038;A, &#038;B, &#038;C, &#038;D);<br />
		copy64(M, buf + 64);<br />
		mdfour64(M, &#038;A, &#038;B, &#038;C, &#038;D);<br />
	}</p>
<p>	for (i = 0; i < 128; i++)<br />
		buf[i] = 0;<br />
	copy64(M, buf);</p>
<p>	copy4(out, A);<br />
	copy4(out + 4, B);<br />
	copy4(out + 8, C);<br />
	copy4(out + 12, D);</p>
<p>	A = B = C = D = 0;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/md4-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Makefile</title>
		<link>http://lynyrd.ru/makefile-10</link>
		<comments>http://lynyrd.ru/makefile-10#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:28:03 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/makefile-10</guid>
		<description><![CDATA[#
# Makefile for Linux CIFS VFS client 
#
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 \
	  md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \
	  readdir.o ioctl.o sess.o export.o cifsacl.o
cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o
]]></description>
			<content:encoded><![CDATA[<p>#<br />
# Makefile for Linux CIFS VFS client <span id="more-947"></span><br />
#<br />
obj-$(CONFIG_CIFS) += cifs.o</p>
<p>cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \<br />
	  link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \<br />
	  md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \<br />
	  readdir.o ioctl.o sess.o export.o cifsacl.o</p>
<p>cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o</p>
<p>cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/makefile-10/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>link.c</title>
		<link>http://lynyrd.ru/link-c</link>
		<comments>http://lynyrd.ru/link-c#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:27:48 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/link-c</guid>
		<description><![CDATA[/*
 *   fs/cifs/link.c
 *
 *   Copyright (C) International Business Machines  Corp., 2002,2008
 *   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
 ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/link.c<span id="more-946"></span><br />
 *<br />
 *   Copyright (C) International Business Machines  Corp., 2002,2008<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */<br />
#include
<linux/fs.h>
#include
<linux/stat.h>
#include
<linux/namei.h>
#include &laquo;cifsfs.h&raquo;<br />
#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifsproto.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;<br />
#include &laquo;cifs_fs_sb.h&raquo;</p>
<p>int<br />
cifs_hardlink(struct dentry *old_file, struct inode *inode,<br />
	      struct dentry *direntry)<br />
{<br />
	int rc = -EACCES;<br />
	int xid;<br />
	char *fromName = NULL;<br />
	char *toName = NULL;<br />
	struct cifs_sb_info *cifs_sb_target;<br />
	struct cifsTconInfo *pTcon;<br />
	struct cifsInodeInfo *cifsInode;</p>
<p>	xid = GetXid();</p>
<p>	cifs_sb_target = CIFS_SB(inode->i_sb);<br />
	pTcon = cifs_sb_target->tcon;</p>
<p>/* No need to check for cross device links since server will do that<br />
   BB note DFS case in future though (when we may have to check) */</p>
<p>	fromName = build_path_from_dentry(old_file);<br />
	toName = build_path_from_dentry(direntry);<br />
	if ((fromName == NULL) || (toName == NULL)) {<br />
		rc = -ENOMEM;<br />
		goto cifs_hl_exit;<br />
	}</p>
<p>/*	if (cifs_sb_target->tcon->ses->capabilities &#038; CAP_UNIX)*/<br />
	if (pTcon->unix_ext)<br />
		rc = CIFSUnixCreateHardLink(xid, pTcon, fromName, toName,<br />
					    cifs_sb_target->local_nls,<br />
					    cifs_sb_target->mnt_cifs_flags &#038;<br />
						CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	else {<br />
		rc = CIFSCreateHardLink(xid, pTcon, fromName, toName,<br />
					cifs_sb_target->local_nls,<br />
					cifs_sb_target->mnt_cifs_flags &#038;<br />
						CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
		if ((rc == -EIO) || (rc == -EINVAL))<br />
			rc = -EOPNOTSUPP;<br />
	}</p>
<p>	d_drop(direntry);	/* force new lookup from server of target */</p>
<p>	/* if source file is cached (oplocked) revalidate will not go to server<br />
	   until the file is closed or oplock broken so update nlinks locally */<br />
	if (old_file->d_inode) {<br />
		cifsInode = CIFS_I(old_file->d_inode);<br />
		if (rc == 0) {<br />
			old_file->d_inode->i_nlink++;<br />
/* BB should we make this contingent on superblock flag NOATIME? */<br />
/*			old_file->d_inode->i_ctime = CURRENT_TIME;*/<br />
			/* parent dir timestamps will update from srv<br />
			within a second, would it really be worth it<br />
			to set the parent dir cifs inode time to zero<br />
			to force revalidate (faster) for it too? */<br />
		}<br />
		/* if not oplocked will force revalidate to get info<br />
		   on source file from srv */<br />
		cifsInode->time = 0;</p>
<p>		/* Will update parent dir timestamps from srv within a second.<br />
		   Would it really be worth it to set the parent dir (cifs<br />
		   inode) time field to zero to force revalidate on parent<br />
		   directory faster ie<br />
			CIFS_I(inode)->time = 0;  */<br />
	}</p>
<p>cifs_hl_exit:<br />
	kfree(fromName);<br />
	kfree(toName);<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>void *<br />
cifs_follow_link(struct dentry *direntry, struct nameidata *nd)<br />
{<br />
	struct inode *inode = direntry->d_inode;<br />
	int rc = -ENOMEM;<br />
	int xid;<br />
	char *full_path = NULL;<br />
	char *target_path = NULL;<br />
	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);<br />
	struct cifsTconInfo *tcon = cifs_sb->tcon;</p>
<p>	xid = GetXid();</p>
<p>	/*<br />
	 * For now, we just handle symlinks with unix extensions enabled.<br />
	 * Eventually we should handle NTFS reparse points, and MacOS<br />
	 * symlink support. For instance&#8230;<br />
	 *<br />
	 * rc = CIFSSMBQueryReparseLinkInfo(&#8230;)<br />
	 *<br />
	 * For now, just return -EACCES when the server doesn&#8217;t support posix<br />
	 * extensions. Note that we still allow querying symlinks when posix<br />
	 * extensions are manually disabled. We could disable these as well<br />
	 * but there doesn&#8217;t seem to be any harm in allowing the client to<br />
	 * read them.<br />
	 */<br />
	if (!(tcon->ses->capabilities &#038; CAP_UNIX)) {<br />
		rc = -EACCES;<br />
		goto out;<br />
	}</p>
<p>	full_path = build_path_from_dentry(direntry);<br />
	if (!full_path)<br />
		goto out;</p>
<p>	cFYI(1, (&raquo;Full path: %s inode = 0x%p&raquo;, full_path, inode));</p>
<p>	rc = CIFSSMBUnixQuerySymLink(xid, tcon, full_path, &#038;target_path,<br />
				     cifs_sb->local_nls);<br />
	kfree(full_path);<br />
out:<br />
	if (rc != 0) {<br />
		kfree(target_path);<br />
		target_path = ERR_PTR(rc);<br />
	}</p>
<p>	FreeXid(xid);<br />
	nd_set_link(nd, target_path);<br />
	return NULL;<br />
}</p>
<p>int<br />
cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)<br />
{<br />
	int rc = -EOPNOTSUPP;<br />
	int xid;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	char *full_path = NULL;<br />
	struct inode *newinode = NULL;</p>
<p>	xid = GetXid();</p>
<p>	cifs_sb = CIFS_SB(inode->i_sb);<br />
	pTcon = cifs_sb->tcon;</p>
<p>	full_path = build_path_from_dentry(direntry);</p>
<p>	if (full_path == NULL) {<br />
		rc = -ENOMEM;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}</p>
<p>	cFYI(1, (&raquo;Full path: %s&raquo;, full_path));<br />
	cFYI(1, (&raquo;symname is %s&raquo;, symname));</p>
<p>	/* BB what if DFS and this volume is on different share? BB */<br />
	if (pTcon->unix_ext)<br />
		rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,<br />
					   cifs_sb->local_nls);<br />
	/* else<br />
	   rc = CIFSCreateReparseSymLink(xid, pTcon, fromName, toName,<br />
					cifs_sb_target->local_nls); */</p>
<p>	if (rc == 0) {<br />
		if (pTcon->unix_ext)<br />
			rc = cifs_get_inode_info_unix(&#038;newinode, full_path,<br />
						      inode->i_sb, xid);<br />
		else<br />
			rc = cifs_get_inode_info(&#038;newinode, full_path, NULL,<br />
						 inode->i_sb, xid, NULL);</p>
<p>		if (rc != 0) {<br />
			cFYI(1, (&raquo;Create symlink ok, getinodeinfo fail rc = %d&raquo;,<br />
			      rc));<br />
		} else {<br />
			if (pTcon->nocase)<br />
				direntry->d_op = &#038;cifs_ci_dentry_ops;<br />
			else<br />
				direntry->d_op = &#038;cifs_dentry_ops;<br />
			d_instantiate(direntry, newinode);<br />
		}<br />
	}</p>
<p>	kfree(full_path);<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie)<br />
{<br />
	char *p = nd_get_link(nd);<br />
	if (!IS_ERR(p))<br />
		kfree(p);<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/link-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kconfig</title>
		<link>http://lynyrd.ru/kconfig-10</link>
		<comments>http://lynyrd.ru/kconfig-10#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:27:23 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/?p=944</guid>
		<description><![CDATA[config CIFS
	tristate &#171;CIFS support (advanced network filesystem, SMBFS successor)&#187;
	depends on INET
	select NLS
	select SLOW_WORK
	help
	  This is the client VFS module for the Common Internet File System
	  (CIFS) protocol which is the successor to the Server Message Block
	  (SMB) protocol, the native file sharing mechanism for most early
	  PC operating systems.  The ]]></description>
			<content:encoded><![CDATA[<p>config CIFS<br />
	tristate &laquo;CIFS support (advanced network filesystem, SMBFS <span id="more-944"></span>successor)&raquo;<br />
	depends on INET<br />
	select NLS<br />
	select SLOW_WORK<br />
	help<br />
	  This is the client VFS module for the Common Internet File System<br />
	  (CIFS) protocol which is the successor to the Server Message Block<br />
	  (SMB) protocol, the native file sharing mechanism for most early<br />
	  PC operating systems.  The CIFS protocol is fully supported by<br />
	  file servers such as Windows 2000 (including Windows 2003, NT 4<br />
	  and Windows XP) as well by Samba (which provides excellent CIFS<br />
	  server support for Linux and many other operating systems). Limited<br />
	  support for OS/2 and Windows ME and similar servers is provided as<br />
	  well.</p>
<p>	  The cifs module provides an advanced network file system<br />
	  client for mounting to CIFS compliant servers.  It includes<br />
	  support for DFS (hierarchical name space), secure per-user<br />
	  session establishment via Kerberos or NTLM or NTLMv2,<br />
	  safe distributed caching (oplock), optional packet<br />
	  signing, Unicode and other internationalization improvements.<br />
	  If you need to mount to Samba or Windows from this machine, say Y.</p>
<p>config CIFS_STATS<br />
        bool &laquo;CIFS statistics&raquo;<br />
        depends on CIFS<br />
        help<br />
          Enabling this option will cause statistics for each server share<br />
	  mounted by the cifs client to be displayed in /proc/fs/cifs/Stats</p>
<p>config CIFS_STATS2<br />
	bool &laquo;Extended statistics&raquo;<br />
	depends on CIFS_STATS<br />
	help<br />
	  Enabling this option will allow more detailed statistics on SMB<br />
	  request timing to be displayed in /proc/fs/cifs/DebugData and also<br />
	  allow optional logging of slow responses to dmesg (depending on the<br />
	  value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details).<br />
	  These additional statistics may have a minor effect on performance<br />
	  and memory utilization.</p>
<p>	  Unless you are a developer or are doing network performance analysis<br />
	  or tuning, say N.</p>
<p>config CIFS_WEAK_PW_HASH<br />
	bool &laquo;Support legacy servers which use weaker LANMAN security&raquo;<br />
	depends on CIFS<br />
	help<br />
	  Modern CIFS servers including Samba and most Windows versions<br />
	  (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)<br />
	  security mechanisms. These hash the password more securely<br />
	  than the mechanisms used in the older LANMAN version of the<br />
	  SMB protocol but LANMAN based authentication is needed to<br />
	  establish sessions with some old SMB servers.</p>
<p>	  Enabling this option allows the cifs module to mount to older<br />
	  LANMAN based servers such as OS/2 and Windows 95, but such<br />
	  mounts may be less secure than mounts using NTLM or more recent<br />
	  security mechanisms if you are on a public network.  Unless you<br />
	  have a need to access old SMB servers (and are on a private<br />
	  network) you probably want to say N.  Even if this support<br />
	  is enabled in the kernel build, LANMAN authentication will not be<br />
	  used automatically. At runtime LANMAN mounts are disabled but<br />
	  can be set to required (or optional) either in<br />
	  /proc/fs/cifs (see fs/cifs/README for more detail) or via an<br />
	  option on the mount command. This support is disabled by<br />
	  default in order to reduce the possibility of a downgrade<br />
	  attack.</p>
<p>	  If unsure, say N.</p>
<p>config CIFS_UPCALL<br />
	  bool &laquo;Kerberos/SPNEGO advanced session setup&raquo;<br />
	  depends on CIFS &#038;&#038; KEYS<br />
	  help<br />
	    Enables an upcall mechanism for CIFS which accesses<br />
	    userspace helper utilities to provide SPNEGO packaged (RFC 4178)<br />
	    Kerberos tickets which are needed to mount to certain secure servers<br />
	    (for which more secure Kerberos authentication is required). If<br />
	    unsure, say N.</p>
<p>config CIFS_XATTR<br />
        bool &laquo;CIFS extended attributes&raquo;<br />
        depends on CIFS<br />
        help<br />
          Extended attributes are name:value pairs associated with inodes by<br />
          the kernel or by users (see the attr(5) manual page, or visit<br />
          <http://acl.bestbits.at/> for details).  CIFS maps the name of<br />
          extended attributes beginning with the user namespace prefix<br />
          to SMB/CIFS EAs. EAs are stored on Windows servers without the<br />
          user namespace prefix, but their names are seen by Linux cifs clients<br />
          prefaced by the user namespace prefix. The system namespace<br />
          (used by some filesystems to store ACLs) is not supported at<br />
          this time.</p>
<p>          If unsure, say N.</p>
<p>config CIFS_POSIX<br />
        bool &laquo;CIFS POSIX Extensions&raquo;<br />
        depends on CIFS_XATTR<br />
        help<br />
          Enabling this option will cause the cifs client to attempt to<br />
	  negotiate a newer dialect with servers, such as Samba 3.0.5<br />
	  or later, that optionally can handle more POSIX like (rather<br />
	  than Windows like) file behavior.  It also enables<br />
	  support for POSIX ACLs (getfacl and setfacl) to servers<br />
	  (such as Samba 3.10 and later) which can negotiate<br />
	  CIFS POSIX ACL support.  If unsure, say N.</p>
<p>config CIFS_DEBUG2<br />
	bool &laquo;Enable additional CIFS debugging routines&raquo;<br />
	depends on CIFS<br />
	help<br />
	   Enabling this option adds a few more debugging routines<br />
	   to the cifs code which slightly increases the size of<br />
	   the cifs module and can cause additional logging of debug<br />
	   messages in some error paths, slowing performance. This<br />
	   option can be turned off unless you are debugging<br />
	   cifs problems.  If unsure, say N.</p>
<p>config CIFS_DFS_UPCALL<br />
	  bool &laquo;DFS feature support&raquo;<br />
	  depends on CIFS &#038;&#038; KEYS<br />
	  help<br />
	    Distributed File System (DFS) support is used to access shares<br />
	    transparently in an enterprise name space, even if the share<br />
	    moves to a different server.  This feature also enables<br />
	    an upcall mechanism for CIFS which contacts userspace helper<br />
	    utilities to provide server name resolution (host names to<br />
	    IP addresses) which is needed for implicit mounts of DFS junction<br />
	    points. If unsure, say N.</p>
<p>config CIFS_EXPERIMENTAL<br />
	  bool &laquo;CIFS Experimental Features (EXPERIMENTAL)&raquo;<br />
	  depends on CIFS &#038;&#038; EXPERIMENTAL<br />
	  help<br />
	    Enables cifs features under testing. These features are<br />
	    experimental and currently include DFS support and directory<br />
	    change notification ie fcntl(F_DNOTIFY), as well as the upcall<br />
	    mechanism which will be used for Kerberos session negotiation<br />
	    and uid remapping.  Some of these features also may depend on<br />
	    setting a value of 1 to the pseudo-file /proc/fs/cifs/Experimental<br />
	    (which is disabled by default). See the file fs/cifs/README<br />
	    for more details.  If unsure, say N.</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/kconfig-10/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ioctl.c</title>
		<link>http://lynyrd.ru/ioctl-c-2</link>
		<comments>http://lynyrd.ru/ioctl-c-2#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:26:57 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/?p=942</guid>
		<description><![CDATA[/*
 *   fs/cifs/ioctl.c
 *
 *   vfs operations that deal with io control
 *
 *   Copyright (C) International Business Machines  Corp., 2005,2007
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/ioctl.c<span id="more-942"></span><br />
 *<br />
 *   vfs operations that deal with io control<br />
 *<br />
 *   Copyright (C) International Business Machines  Corp., 2005,2007<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p>#include
<linux/fs.h>
#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifsproto.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;<br />
#include &laquo;cifsfs.h&raquo;</p>
<p>#define CIFS_IOC_CHECKUMOUNT _IO(0xCF, 2)</p>
<p>long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg)<br />
{<br />
	struct inode *inode = filep->f_dentry->d_inode;<br />
	int rc = -ENOTTY; /* strange error &#8211; but the precedent */<br />
	int xid;<br />
	struct cifs_sb_info *cifs_sb;<br />
#ifdef CONFIG_CIFS_POSIX<br />
	__u64	ExtAttrBits = 0;<br />
	__u64	ExtAttrMask = 0;<br />
	__u64   caps;<br />
	struct cifsTconInfo *tcon;<br />
	struct cifsFileInfo *pSMBFile =<br />
		(struct cifsFileInfo *)filep->private_data;<br />
#endif /* CONFIG_CIFS_POSIX */</p>
<p>	xid = GetXid();</p>
<p>	cFYI(1, (&raquo;ioctl file %p  cmd %u  arg %lu&raquo;, filep, command, arg));</p>
<p>	cifs_sb = CIFS_SB(inode->i_sb);</p>
<p>#ifdef CONFIG_CIFS_POSIX<br />
	tcon = cifs_sb->tcon;<br />
	if (tcon)<br />
		caps = le64_to_cpu(tcon->fsUnixInfo.Capability);<br />
	else {<br />
		rc = -EIO;<br />
		FreeXid(xid);<br />
		return -EIO;<br />
	}<br />
#endif /* CONFIG_CIFS_POSIX */</p>
<p>	switch (command) {<br />
		case CIFS_IOC_CHECKUMOUNT:<br />
			cFYI(1, (&raquo;User unmount attempted&raquo;));<br />
			if (cifs_sb->mnt_uid == current_uid())<br />
				rc = 0;<br />
			else {<br />
				rc = -EACCES;<br />
				cFYI(1, (&raquo;uids do not match&raquo;));<br />
			}<br />
			break;<br />
#ifdef CONFIG_CIFS_POSIX<br />
		case FS_IOC_GETFLAGS:<br />
			if (CIFS_UNIX_EXTATTR_CAP &#038; caps) {<br />
				if (pSMBFile == NULL)<br />
					break;<br />
				rc = CIFSGetExtAttr(xid, tcon, pSMBFile->netfid,<br />
					&#038;ExtAttrBits, &#038;ExtAttrMask);<br />
				if (rc == 0)<br />
					rc = put_user(ExtAttrBits &#038;<br />
						FS_FL_USER_VISIBLE,<br />
						(int __user *)arg);<br />
			}<br />
			break;</p>
<p>		case FS_IOC_SETFLAGS:<br />
			if (CIFS_UNIX_EXTATTR_CAP &#038; caps) {<br />
				if (get_user(ExtAttrBits, (int __user *)arg)) {<br />
					rc = -EFAULT;<br />
					break;<br />
				}<br />
				if (pSMBFile == NULL)<br />
					break;<br />
				/* rc= CIFSGetExtAttr(xid,tcon,pSMBFile->netfid,<br />
					extAttrBits, &#038;ExtAttrMask);*/<br />
			}<br />
			cFYI(1, (&raquo;set flags not implemented yet&raquo;));<br />
			break;<br />
#endif /* CONFIG_CIFS_POSIX */<br />
		default:<br />
			cFYI(1, (&raquo;unsupported ioctl&raquo;));<br />
			break;<br />
	}</p>
<p>	FreeXid(xid);<br />
	return rc;<br />
}</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/ioctl-c-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>file.c</title>
		<link>http://lynyrd.ru/file-c-7</link>
		<comments>http://lynyrd.ru/file-c-7#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:26:22 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/file-c-7</guid>
		<description><![CDATA[/*
 *   fs/cifs/file.c
 *
 *   vfs operations that deal with files
 *
 *   Copyright (C) International Business Machines  Corp., 2002,2007
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *              Jeremy Allison (jra@samba.org)
 *
 *   ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/file.c<span id="more-939"></span><br />
 *<br />
 *   vfs operations that deal with files<br />
 *<br />
 *   Copyright (C) International Business Machines  Corp., 2002,2007<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *              Jeremy Allison (jra@samba.org)<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */<br />
#include
<linux/fs.h>
#include
<linux/backing-dev.h>
#include
<linux/stat.h>
#include
<linux/fcntl.h>
#include
<linux/pagemap.h>
#include
<linux/pagevec.h>
#include
<linux/writeback.h>
#include
<linux/task_io_accounting_ops.h>
#include
<linux/delay.h>
#include
<linux/mount.h>
#include <asm/div64.h><br />
#include &laquo;cifsfs.h&raquo;<br />
#include &laquo;cifspdu.h&raquo;<br />
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifsproto.h&raquo;<br />
#include &laquo;cifs_unicode.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;<br />
#include &laquo;cifs_fs_sb.h&raquo;</p>
<p>static inline int cifs_convert_flags(unsigned int flags)<br />
{<br />
	if ((flags &#038; O_ACCMODE) == O_RDONLY)<br />
		return GENERIC_READ;<br />
	else if ((flags &#038; O_ACCMODE) == O_WRONLY)<br />
		return GENERIC_WRITE;<br />
	else if ((flags &#038; O_ACCMODE) == O_RDWR) {<br />
		/* GENERIC_ALL is too much permission to request<br />
		   can cause unnecessary access denied on create */<br />
		/* return GENERIC_ALL; */<br />
		return (GENERIC_READ | GENERIC_WRITE);<br />
	}</p>
<p>	return (READ_CONTROL | FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES |<br />
		FILE_WRITE_EA | FILE_APPEND_DATA | FILE_WRITE_DATA |<br />
		FILE_READ_DATA);<br />
}</p>
<p>static inline fmode_t cifs_posix_convert_flags(unsigned int flags)<br />
{<br />
	fmode_t posix_flags = 0;</p>
<p>	if ((flags &#038; O_ACCMODE) == O_RDONLY)<br />
		posix_flags = FMODE_READ;<br />
	else if ((flags &#038; O_ACCMODE) == O_WRONLY)<br />
		posix_flags = FMODE_WRITE;<br />
	else if ((flags &#038; O_ACCMODE) == O_RDWR) {<br />
		/* GENERIC_ALL is too much permission to request<br />
		   can cause unnecessary access denied on create */<br />
		/* return GENERIC_ALL; */<br />
		posix_flags = FMODE_READ | FMODE_WRITE;<br />
	}<br />
	/* can not map O_CREAT or O_EXCL or O_TRUNC flags when<br />
	   reopening a file.  They had their effect on the original open */<br />
	if (flags &#038; O_APPEND)<br />
		posix_flags |= (fmode_t)O_APPEND;<br />
	if (flags &#038; O_SYNC)<br />
		posix_flags |= (fmode_t)O_SYNC;<br />
	if (flags &#038; O_DIRECTORY)<br />
		posix_flags |= (fmode_t)O_DIRECTORY;<br />
	if (flags &#038; O_NOFOLLOW)<br />
		posix_flags |= (fmode_t)O_NOFOLLOW;<br />
	if (flags &#038; O_DIRECT)<br />
		posix_flags |= (fmode_t)O_DIRECT;</p>
<p>	return posix_flags;<br />
}</p>
<p>static inline int cifs_get_disposition(unsigned int flags)<br />
{<br />
	if ((flags &#038; (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))<br />
		return FILE_CREATE;<br />
	else if ((flags &#038; (O_CREAT | O_TRUNC)) == (O_CREAT | O_TRUNC))<br />
		return FILE_OVERWRITE_IF;<br />
	else if ((flags &#038; O_CREAT) == O_CREAT)<br />
		return FILE_OPEN_IF;<br />
	else if ((flags &#038; O_TRUNC) == O_TRUNC)<br />
		return FILE_OVERWRITE;<br />
	else<br />
		return FILE_OPEN;<br />
}</p>
<p>/* all arguments to this function must be checked for validity in caller */<br />
static inline int<br />
cifs_posix_open_inode_helper(struct inode *inode, struct file *file,<br />
			     struct cifsInodeInfo *pCifsInode,<br />
			     struct cifsFileInfo *pCifsFile, __u32 oplock,<br />
			     u16 netfid)<br />
{</p>
<p>	write_lock(&#038;GlobalSMBSeslock);</p>
<p>	pCifsInode = CIFS_I(file->f_path.dentry->d_inode);<br />
	if (pCifsInode == NULL) {<br />
		write_unlock(&#038;GlobalSMBSeslock);<br />
		return -EINVAL;<br />
	}</p>
<p>	if (pCifsInode->clientCanCacheRead) {<br />
		/* we have the inode open somewhere else<br />
		   no need to discard cache data */<br />
		goto psx_client_can_cache;<br />
	}</p>
<p>	/* BB FIXME need to fix this check to move it earlier into posix_open<br />
	   BB  fIX following section BB FIXME */</p>
<p>	/* if not oplocked, invalidate inode pages if mtime or file<br />
	   size changed */<br />
/*	temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));<br />
	if (timespec_equal(&#038;file->f_path.dentry->d_inode->i_mtime, &#038;temp) &#038;&#038;<br />
			   (file->f_path.dentry->d_inode->i_size ==<br />
			    (loff_t)le64_to_cpu(buf->EndOfFile))) {<br />
		cFYI(1, (&raquo;inode unchanged on server&raquo;));<br />
	} else {<br />
		if (file->f_path.dentry->d_inode->i_mapping) {<br />
			rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);<br />
			if (rc != 0)<br />
				CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;<br />
		}<br />
		cFYI(1, (&raquo;invalidating remote inode since open detected it &raquo;<br />
			 &laquo;changed&raquo;));<br />
		invalidate_remote_inode(file->f_path.dentry->d_inode);<br />
	} */</p>
<p>psx_client_can_cache:<br />
	if ((oplock &#038; 0xF) == OPLOCK_EXCLUSIVE) {<br />
		pCifsInode->clientCanCacheAll = true;<br />
		pCifsInode->clientCanCacheRead = true;<br />
		cFYI(1, (&raquo;Exclusive Oplock granted on inode %p&raquo;,<br />
			 file->f_path.dentry->d_inode));<br />
	} else if ((oplock &#038; 0xF) == OPLOCK_READ)<br />
		pCifsInode->clientCanCacheRead = true;</p>
<p>	/* will have to change the unlock if we reenable the<br />
	   filemap_fdatawrite (which does not seem necessary */<br />
	write_unlock(&#038;GlobalSMBSeslock);<br />
	return 0;<br />
}</p>
<p>static struct cifsFileInfo *<br />
cifs_fill_filedata(struct file *file)<br />
{<br />
	struct list_head *tmp;<br />
	struct cifsFileInfo *pCifsFile = NULL;<br />
	struct cifsInodeInfo *pCifsInode = NULL;</p>
<p>	/* search inode for this file and fill in file->private_data */<br />
	pCifsInode = CIFS_I(file->f_path.dentry->d_inode);<br />
	read_lock(&#038;GlobalSMBSeslock);<br />
	list_for_each(tmp, &#038;pCifsInode->openFileList) {<br />
		pCifsFile = list_entry(tmp, struct cifsFileInfo, flist);<br />
		if ((pCifsFile->pfile == NULL) &#038;&#038;<br />
		    (pCifsFile->pid == current->tgid)) {<br />
			/* mode set in cifs_create */</p>
<p>			/* needed for writepage */<br />
			pCifsFile->pfile = file;<br />
			file->private_data = pCifsFile;<br />
			break;<br />
		}<br />
	}<br />
	read_unlock(&#038;GlobalSMBSeslock);</p>
<p>	if (file->private_data != NULL) {<br />
		return pCifsFile;<br />
	} else if ((file->f_flags &#038; O_CREAT) &#038;&#038; (file->f_flags &#038; O_EXCL))<br />
			cERROR(1, (&raquo;could not find file instance for &raquo;<br />
				   &laquo;new file %p&raquo;, file));<br />
	return NULL;<br />
}</p>
<p>/* all arguments to this function must be checked for validity in caller */<br />
static inline int cifs_open_inode_helper(struct inode *inode, struct file *file,<br />
	struct cifsInodeInfo *pCifsInode, struct cifsFileInfo *pCifsFile,<br />
	struct cifsTconInfo *pTcon, int *oplock, FILE_ALL_INFO *buf,<br />
	char *full_path, int xid)<br />
{<br />
	struct timespec temp;<br />
	int rc;</p>
<p>	if (pCifsInode->clientCanCacheRead) {<br />
		/* we have the inode open somewhere else<br />
		   no need to discard cache data */<br />
		goto client_can_cache;<br />
	}</p>
<p>	/* BB need same check in cifs_create too? */<br />
	/* if not oplocked, invalidate inode pages if mtime or file<br />
	   size changed */<br />
	temp = cifs_NTtimeToUnix(buf->LastWriteTime);<br />
	if (timespec_equal(&#038;file->f_path.dentry->d_inode->i_mtime, &#038;temp) &#038;&#038;<br />
			   (file->f_path.dentry->d_inode->i_size ==<br />
			    (loff_t)le64_to_cpu(buf->EndOfFile))) {<br />
		cFYI(1, (&raquo;inode unchanged on server&raquo;));<br />
	} else {<br />
		if (file->f_path.dentry->d_inode->i_mapping) {<br />
		/* BB no need to lock inode until after invalidate<br />
		   since namei code should already have it locked? */<br />
			rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);<br />
			if (rc != 0)<br />
				CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;<br />
		}<br />
		cFYI(1, (&raquo;invalidating remote inode since open detected it &raquo;<br />
			 &laquo;changed&raquo;));<br />
		invalidate_remote_inode(file->f_path.dentry->d_inode);<br />
	}</p>
<p>client_can_cache:<br />
	if (pTcon->unix_ext)<br />
		rc = cifs_get_inode_info_unix(&#038;file->f_path.dentry->d_inode,<br />
			full_path, inode->i_sb, xid);<br />
	else<br />
		rc = cifs_get_inode_info(&#038;file->f_path.dentry->d_inode,<br />
			full_path, buf, inode->i_sb, xid, NULL);</p>
<p>	if ((*oplock &#038; 0xF) == OPLOCK_EXCLUSIVE) {<br />
		pCifsInode->clientCanCacheAll = true;<br />
		pCifsInode->clientCanCacheRead = true;<br />
		cFYI(1, (&raquo;Exclusive Oplock granted on inode %p&raquo;,<br />
			 file->f_path.dentry->d_inode));<br />
	} else if ((*oplock &#038; 0xF) == OPLOCK_READ)<br />
		pCifsInode->clientCanCacheRead = true;</p>
<p>	return rc;<br />
}</p>
<p>int cifs_open(struct inode *inode, struct file *file)<br />
{<br />
	int rc = -EACCES;<br />
	int xid;<br />
	__u32 oplock;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *tcon;<br />
	struct cifsFileInfo *pCifsFile;<br />
	struct cifsInodeInfo *pCifsInode;<br />
	char *full_path = NULL;<br />
	int desiredAccess;<br />
	int disposition;<br />
	__u16 netfid;<br />
	FILE_ALL_INFO *buf = NULL;</p>
<p>	xid = GetXid();</p>
<p>	cifs_sb = CIFS_SB(inode->i_sb);<br />
	tcon = cifs_sb->tcon;</p>
<p>	pCifsInode = CIFS_I(file->f_path.dentry->d_inode);<br />
	pCifsFile = cifs_fill_filedata(file);<br />
	if (pCifsFile) {<br />
		rc = 0;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}</p>
<p>	full_path = build_path_from_dentry(file->f_path.dentry);<br />
	if (full_path == NULL) {<br />
		rc = -ENOMEM;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}</p>
<p>	cFYI(1, (&raquo;inode = 0x%p file flags are 0x%x for %s&raquo;,<br />
		 inode, file->f_flags, full_path));</p>
<p>	if (oplockEnabled)<br />
		oplock = REQ_OPLOCK;<br />
	else<br />
		oplock = 0;</p>
<p>	if (!tcon->broken_posix_open &#038;&#038; tcon->unix_ext &#038;&#038;<br />
	    (tcon->ses->capabilities &#038; CAP_UNIX) &#038;&#038;<br />
	    (CIFS_UNIX_POSIX_PATH_OPS_CAP &#038;<br />
			le64_to_cpu(tcon->fsUnixInfo.Capability))) {<br />
		int oflags = (int) cifs_posix_convert_flags(file->f_flags);<br />
		/* can not refresh inode info since size could be stale */<br />
		rc = cifs_posix_open(full_path, &#038;inode, file->f_path.mnt,<br />
				     cifs_sb->mnt_file_mode /* ignored */,<br />
				     oflags, &#038;oplock, &#038;netfid, xid);<br />
		if (rc == 0) {<br />
			cFYI(1, (&raquo;posix open succeeded&raquo;));<br />
			/* no need for special case handling of setting mode<br />
			   on read only files needed here */</p>
<p>			pCifsFile = cifs_fill_filedata(file);<br />
			cifs_posix_open_inode_helper(inode, file, pCifsInode,<br />
						     pCifsFile, oplock, netfid);<br />
			goto out;<br />
		} else if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {<br />
			if (tcon->ses->serverNOS)<br />
				cERROR(1, (&raquo;server %s of type %s returned&raquo;<br />
					   &raquo; unexpected error on SMB posix open&raquo;<br />
					   &laquo;, disabling posix open support.&raquo;<br />
					   &raquo; Check if server update available.&raquo;,<br />
					   tcon->ses->serverName,<br />
					   tcon->ses->serverNOS));<br />
			tcon->broken_posix_open = true;<br />
		} else if ((rc != -EIO) &#038;&#038; (rc != -EREMOTE) &#038;&#038;<br />
			 (rc != -EOPNOTSUPP)) /* path not found or net err */<br />
			goto out;<br />
		/* else fallthrough to retry open the old way on network i/o<br />
		   or DFS errors */<br />
	}</p>
<p>	desiredAccess = cifs_convert_flags(file->f_flags);</p>
<p>/*********************************************************************<br />
 *  open flag mapping table:<br />
 *<br />
 *	POSIX Flag            CIFS Disposition<br />
 *	&#8212;&#8212;&#8212;-            &#8212;&#8212;&#8212;&#8212;&#8212;-<br />
 *	O_CREAT               FILE_OPEN_IF<br />
 *	O_CREAT | O_EXCL      FILE_CREATE<br />
 *	O_CREAT | O_TRUNC     FILE_OVERWRITE_IF<br />
 *	O_TRUNC               FILE_OVERWRITE<br />
 *	none of the above     FILE_OPEN<br />
 *<br />
 *	Note that there is not a direct match between disposition<br />
 *	FILE_SUPERSEDE (ie create whether or not file exists although<br />
 *	O_CREAT | O_TRUNC is similar but truncates the existing<br />
 *	file rather than creating a new file as FILE_SUPERSEDE does<br />
 *	(which uses the attributes / metadata passed in on open call)<br />
 *?<br />
 *?  O_SYNC is a reasonable match to CIFS writethrough flag<br />
 *?  and the read write flags match reasonably.  O_LARGEFILE<br />
 *?  is irrelevant because largefile support is always used<br />
 *?  by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,<br />
 *	 O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation<br />
 *********************************************************************/</p>
<p>	disposition = cifs_get_disposition(file->f_flags);</p>
<p>	/* BB pass O_SYNC flag through on file attributes .. BB */</p>
<p>	/* Also refresh inode by passing in file_info buf returned by SMBOpen<br />
	   and calling get_inode_info with returned buf (at least helps<br />
	   non-Unix server case) */</p>
<p>	/* BB we can not do this if this is the second open of a file<br />
	   and the first handle has writebehind data, we might be<br />
	   able to simply do a filemap_fdatawrite/filemap_fdatawait first */<br />
	buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);<br />
	if (!buf) {<br />
		rc = -ENOMEM;<br />
		goto out;<br />
	}</p>
<p>	if (cifs_sb->tcon->ses->capabilities &#038; CAP_NT_SMBS)<br />
		rc = CIFSSMBOpen(xid, tcon, full_path, disposition,<br />
			 desiredAccess, CREATE_NOT_DIR, &#038;netfid, &#038;oplock, buf,<br />
			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags<br />
				 &#038; CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	else<br />
		rc = -EIO; /* no NT SMB support fall into legacy open below */</p>
<p>	if (rc == -EIO) {<br />
		/* Old server, try legacy style OpenX */<br />
		rc = SMBLegacyOpen(xid, tcon, full_path, disposition,<br />
			desiredAccess, CREATE_NOT_DIR, &#038;netfid, &#038;oplock, buf,<br />
			cifs_sb->local_nls, cifs_sb->mnt_cifs_flags<br />
				&#038; CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	}<br />
	if (rc) {<br />
		cFYI(1, (&raquo;cifs_open returned 0x%x&raquo;, rc));<br />
		goto out;<br />
	}</p>
<p>	pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt,<br />
					file->f_flags);<br />
	file->private_data = pCifsFile;<br />
	if (file->private_data == NULL) {<br />
		rc = -ENOMEM;<br />
		goto out;<br />
	}</p>
<p>	rc = cifs_open_inode_helper(inode, file, pCifsInode, pCifsFile, tcon,<br />
				    &#038;oplock, buf, full_path, xid);</p>
<p>	if (oplock &#038; CIFS_CREATE_ACTION) {<br />
		/* time to set mode which we can not set earlier due to<br />
		   problems creating new read-only files */<br />
		if (tcon->unix_ext) {<br />
			struct cifs_unix_set_info_args args = {<br />
				.mode	= inode->i_mode,<br />
				.uid	= NO_CHANGE_64,<br />
				.gid	= NO_CHANGE_64,<br />
				.ctime	= NO_CHANGE_64,<br />
				.atime	= NO_CHANGE_64,<br />
				.mtime	= NO_CHANGE_64,<br />
				.device	= 0,<br />
			};<br />
			CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &#038;args,<br />
					       cifs_sb->local_nls,<br />
					       cifs_sb->mnt_cifs_flags &#038;<br />
						CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
		}<br />
	}</p>
<p>out:<br />
	kfree(buf);<br />
	kfree(full_path);<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>/* Try to reacquire byte range locks that were released when session */<br />
/* to server was lost */<br />
static int cifs_relock_file(struct cifsFileInfo *cifsFile)<br />
{<br />
	int rc = 0;</p>
<p>/* BB list all locks open on this file and relock */</p>
<p>	return rc;<br />
}</p>
<p>static int cifs_reopen_file(struct file *file, bool can_flush)<br />
{<br />
	int rc = -EACCES;<br />
	int xid;<br />
	__u32 oplock;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *tcon;<br />
	struct cifsFileInfo *pCifsFile;<br />
	struct cifsInodeInfo *pCifsInode;<br />
	struct inode *inode;<br />
	char *full_path = NULL;<br />
	int desiredAccess;<br />
	int disposition = FILE_OPEN;<br />
	__u16 netfid;</p>
<p>	if (file->private_data)<br />
		pCifsFile = (struct cifsFileInfo *)file->private_data;<br />
	else<br />
		return -EBADF;</p>
<p>	xid = GetXid();<br />
	mutex_lock(&#038;pCifsFile->fh_mutex);<br />
	if (!pCifsFile->invalidHandle) {<br />
		mutex_unlock(&#038;pCifsFile->fh_mutex);<br />
		rc = 0;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}</p>
<p>	if (file->f_path.dentry == NULL) {<br />
		cERROR(1, (&raquo;no valid name if dentry freed&raquo;));<br />
		dump_stack();<br />
		rc = -EBADF;<br />
		goto reopen_error_exit;<br />
	}</p>
<p>	inode = file->f_path.dentry->d_inode;<br />
	if (inode == NULL) {<br />
		cERROR(1, (&raquo;inode not valid&raquo;));<br />
		dump_stack();<br />
		rc = -EBADF;<br />
		goto reopen_error_exit;<br />
	}</p>
<p>	cifs_sb = CIFS_SB(inode->i_sb);<br />
	tcon = cifs_sb->tcon;</p>
<p>/* can not grab rename sem here because various ops, including<br />
   those that already have the rename sem can end up causing writepage<br />
   to get called and if the server was down that means we end up here,<br />
   and we can never tell if the caller already has the rename_sem */<br />
	full_path = build_path_from_dentry(file->f_path.dentry);<br />
	if (full_path == NULL) {<br />
		rc = -ENOMEM;<br />
reopen_error_exit:<br />
		mutex_unlock(&#038;pCifsFile->fh_mutex);<br />
		FreeXid(xid);<br />
		return rc;<br />
	}</p>
<p>	cFYI(1, (&raquo;inode = 0x%p file flags 0x%x for %s&raquo;,<br />
		 inode, file->f_flags, full_path));</p>
<p>	if (oplockEnabled)<br />
		oplock = REQ_OPLOCK;<br />
	else<br />
		oplock = 0;</p>
<p>	if (tcon->unix_ext &#038;&#038; (tcon->ses->capabilities &#038; CAP_UNIX) &#038;&#038;<br />
	    (CIFS_UNIX_POSIX_PATH_OPS_CAP &#038;<br />
			le64_to_cpu(tcon->fsUnixInfo.Capability))) {<br />
		int oflags = (int) cifs_posix_convert_flags(file->f_flags);<br />
		/* can not refresh inode info since size could be stale */<br />
		rc = cifs_posix_open(full_path, NULL, file->f_path.mnt,<br />
				     cifs_sb->mnt_file_mode /* ignored */,<br />
				     oflags, &#038;oplock, &#038;netfid, xid);<br />
		if (rc == 0) {<br />
			cFYI(1, (&raquo;posix reopen succeeded&raquo;));<br />
			goto reopen_success;<br />
		}<br />
		/* fallthrough to retry open the old way on errors, especially<br />
		   in the reconnect path it is important to retry hard */<br />
	}</p>
<p>	desiredAccess = cifs_convert_flags(file->f_flags);</p>
<p>	/* Can not refresh inode by passing in file_info buf to be returned<br />
	   by SMBOpen and then calling get_inode_info with returned buf<br />
	   since file might have write behind data that needs to be flushed<br />
	   and server version of file size can be stale. If we knew for sure<br />
	   that inode was not dirty locally we could do this */</p>
<p>	rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess,<br />
			 CREATE_NOT_DIR, &#038;netfid, &#038;oplock, NULL,<br />
			 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &#038;<br />
				CIFS_MOUNT_MAP_SPECIAL_CHR);<br />
	if (rc) {<br />
		mutex_unlock(&#038;pCifsFile->fh_mutex);<br />
		cFYI(1, (&raquo;cifs_open returned 0x%x&raquo;, rc));<br />
		cFYI(1, (&raquo;oplock: %d&raquo;, oplock));<br />
	} else {<br />
reopen_success:<br />
		pCifsFile->netfid = netfid;<br />
		pCifsFile->invalidHandle = false;<br />
		mutex_unlock(&#038;pCifsFile->fh_mutex);<br />
		pCifsInode = CIFS_I(inode);<br />
		if (pCifsInode) {<br />
			if (can_flush) {<br />
				rc = filemap_write_and_wait(inode->i_mapping);<br />
				if (rc != 0)<br />
					CIFS_I(inode)->write_behind_rc = rc;<br />
			/* temporarily disable caching while we<br />
			   go to server to get inode info */<br />
				pCifsInode->clientCanCacheAll = false;<br />
				pCifsInode->clientCanCacheRead = false;<br />
				if (tcon->unix_ext)<br />
					rc = cifs_get_inode_info_unix(&#038;inode,<br />
						full_path, inode->i_sb, xid);<br />
				else<br />
					rc = cifs_get_inode_info(&#038;inode,<br />
						full_path, NULL, inode->i_sb,<br />
						xid, NULL);<br />
			} /* else we are writing out data to server already<br />
			     and could deadlock if we tried to flush data, and<br />
			     since we do not know if we have data that would<br />
			     invalidate the current end of file on the server<br />
			     we can not go to the server to get the new inod<br />
			     info */<br />
			if ((oplock &#038; 0xF) == OPLOCK_EXCLUSIVE) {<br />
				pCifsInode->clientCanCacheAll = true;<br />
				pCifsInode->clientCanCacheRead = true;<br />
				cFYI(1, (&raquo;Exclusive Oplock granted on inode %p&raquo;,<br />
					 file->f_path.dentry->d_inode));<br />
			} else if ((oplock &#038; 0xF) == OPLOCK_READ) {<br />
				pCifsInode->clientCanCacheRead = true;<br />
				pCifsInode->clientCanCacheAll = false;<br />
			} else {<br />
				pCifsInode->clientCanCacheRead = false;<br />
				pCifsInode->clientCanCacheAll = false;<br />
			}<br />
			cifs_relock_file(pCifsFile);<br />
		}<br />
	}<br />
	kfree(full_path);<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>int cifs_close(struct inode *inode, struct file *file)<br />
{<br />
	int rc = 0;<br />
	int xid, timeout;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	struct cifsFileInfo *pSMBFile =<br />
		(struct cifsFileInfo *)file->private_data;</p>
<p>	xid = GetXid();</p>
<p>	cifs_sb = CIFS_SB(inode->i_sb);<br />
	pTcon = cifs_sb->tcon;<br />
	if (pSMBFile) {<br />
		struct cifsLockInfo *li, *tmp;<br />
		write_lock(&#038;GlobalSMBSeslock);<br />
		pSMBFile->closePend = true;<br />
		if (pTcon) {<br />
			/* no sense reconnecting to close a file that is<br />
			   already closed */<br />
			if (!pTcon->need_reconnect) {<br />
				write_unlock(&#038;GlobalSMBSeslock);<br />
				timeout = 2;<br />
				while ((atomic_read(&#038;pSMBFile->count) != 1)<br />
					&#038;&#038; (timeout <= 2048)) {<br />
					/* Give write a better chance to get to<br />
					server ahead of the close.  We do not<br />
					want to add a wait_q here as it would<br />
					increase the memory utilization as<br />
					the struct would be in each open file,<br />
					but this should give enough time to<br />
					clear the socket */<br />
					cFYI(DBG2,<br />
						("close delay, write pending"));<br />
					msleep(timeout);<br />
					timeout *= 4;<br />
				}<br />
				if (!pTcon->need_reconnect &#038;&#038;<br />
				    !pSMBFile->invalidHandle)<br />
					rc = CIFSSMBClose(xid, pTcon,<br />
						  pSMBFile->netfid);<br />
			} else<br />
				write_unlock(&#038;GlobalSMBSeslock);<br />
		} else<br />
			write_unlock(&#038;GlobalSMBSeslock);</p>
<p>		/* Delete any outstanding lock records.<br />
		   We&#8217;ll lose them when the file is closed anyway. */<br />
		mutex_lock(&#038;pSMBFile->lock_mutex);<br />
		list_for_each_entry_safe(li, tmp, &#038;pSMBFile->llist, llist) {<br />
			list_del(&#038;li->llist);<br />
			kfree(li);<br />
		}<br />
		mutex_unlock(&#038;pSMBFile->lock_mutex);</p>
<p>		write_lock(&#038;GlobalSMBSeslock);<br />
		list_del(&#038;pSMBFile->flist);<br />
		list_del(&#038;pSMBFile->tlist);<br />
		write_unlock(&#038;GlobalSMBSeslock);<br />
		cifsFileInfo_put(file->private_data);<br />
		file->private_data = NULL;<br />
	} else<br />
		rc = -EBADF;</p>
<p>	read_lock(&#038;GlobalSMBSeslock);<br />
	if (list_empty(&#038;(CIFS_I(inode)->openFileList))) {<br />
		cFYI(1, (&raquo;closing last open instance for inode %p&raquo;, inode));<br />
		/* if the file is not open we do not know if we can cache info<br />
		   on this inode, much less write behind and read ahead */<br />
		CIFS_I(inode)->clientCanCacheRead = false;<br />
		CIFS_I(inode)->clientCanCacheAll  = false;<br />
	}<br />
	read_unlock(&#038;GlobalSMBSeslock);<br />
	if ((rc == 0) &#038;&#038; CIFS_I(inode)->write_behind_rc)<br />
		rc = CIFS_I(inode)->write_behind_rc;<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>int cifs_closedir(struct inode *inode, struct file *file)<br />
{<br />
	int rc = 0;<br />
	int xid;<br />
	struct cifsFileInfo *pCFileStruct =<br />
	    (struct cifsFileInfo *)file->private_data;<br />
	char *ptmp;</p>
<p>	cFYI(1, (&raquo;Closedir inode = 0x%p&raquo;, inode));</p>
<p>	xid = GetXid();</p>
<p>	if (pCFileStruct) {<br />
		struct cifsTconInfo *pTcon;<br />
		struct cifs_sb_info *cifs_sb =<br />
			CIFS_SB(file->f_path.dentry->d_sb);</p>
<p>		pTcon = cifs_sb->tcon;</p>
<p>		cFYI(1, (&raquo;Freeing private data in close dir&raquo;));<br />
		write_lock(&#038;GlobalSMBSeslock);<br />
		if (!pCFileStruct->srch_inf.endOfSearch &#038;&#038;<br />
		    !pCFileStruct->invalidHandle) {<br />
			pCFileStruct->invalidHandle = true;<br />
			write_unlock(&#038;GlobalSMBSeslock);<br />
			rc = CIFSFindClose(xid, pTcon, pCFileStruct->netfid);<br />
			cFYI(1, (&raquo;Closing uncompleted readdir with rc %d&raquo;,<br />
				 rc));<br />
			/* not much we can do if it fails anyway, ignore rc */<br />
			rc = 0;<br />
		} else<br />
			write_unlock(&#038;GlobalSMBSeslock);<br />
		ptmp = pCFileStruct->srch_inf.ntwrk_buf_start;<br />
		if (ptmp) {<br />
			cFYI(1, (&raquo;closedir free smb buf in srch struct&raquo;));<br />
			pCFileStruct->srch_inf.ntwrk_buf_start = NULL;<br />
			if (pCFileStruct->srch_inf.smallBuf)<br />
				cifs_small_buf_release(ptmp);<br />
			else<br />
				cifs_buf_release(ptmp);<br />
		}<br />
		kfree(file->private_data);<br />
		file->private_data = NULL;<br />
	}<br />
	/* BB can we lock the filestruct while this is going on? */<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>static int store_file_lock(struct cifsFileInfo *fid, __u64 len,<br />
				__u64 offset, __u8 lockType)<br />
{<br />
	struct cifsLockInfo *li =<br />
		kmalloc(sizeof(struct cifsLockInfo), GFP_KERNEL);<br />
	if (li == NULL)<br />
		return -ENOMEM;<br />
	li->offset = offset;<br />
	li->length = len;<br />
	li->type = lockType;<br />
	mutex_lock(&#038;fid->lock_mutex);<br />
	list_add(&#038;li->llist, &#038;fid->llist);<br />
	mutex_unlock(&#038;fid->lock_mutex);<br />
	return 0;<br />
}</p>
<p>int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)<br />
{<br />
	int rc, xid;<br />
	__u32 numLock = 0;<br />
	__u32 numUnlock = 0;<br />
	__u64 length;<br />
	bool wait_flag = false;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *tcon;<br />
	__u16 netfid;<br />
	__u8 lockType = LOCKING_ANDX_LARGE_FILES;<br />
	bool posix_locking = 0;</p>
<p>	length = 1 + pfLock->fl_end &#8211; pfLock->fl_start;<br />
	rc = -EACCES;<br />
	xid = GetXid();</p>
<p>	cFYI(1, (&raquo;Lock parm: 0x%x flockflags: &raquo;<br />
		 &laquo;0x%x flocktype: 0x%x start: %lld end: %lld&raquo;,<br />
		cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,<br />
		pfLock->fl_end));</p>
<p>	if (pfLock->fl_flags &#038; FL_POSIX)<br />
		cFYI(1, (&raquo;Posix&raquo;));<br />
	if (pfLock->fl_flags &#038; FL_FLOCK)<br />
		cFYI(1, (&raquo;Flock&raquo;));<br />
	if (pfLock->fl_flags &#038; FL_SLEEP) {<br />
		cFYI(1, (&raquo;Blocking lock&raquo;));<br />
		wait_flag = true;<br />
	}<br />
	if (pfLock->fl_flags &#038; FL_ACCESS)<br />
		cFYI(1, (&raquo;Process suspended by mandatory locking &#8211; &raquo;<br />
			 &laquo;not implemented yet&raquo;));<br />
	if (pfLock->fl_flags &#038; FL_LEASE)<br />
		cFYI(1, (&raquo;Lease on file &#8211; not implemented yet&raquo;));<br />
	if (pfLock->fl_flags &#038;<br />
	    (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))<br />
		cFYI(1, (&raquo;Unknown lock flags 0x%x&raquo;, pfLock->fl_flags));</p>
<p>	if (pfLock->fl_type == F_WRLCK) {<br />
		cFYI(1, (&raquo;F_WRLCK &laquo;));<br />
		numLock = 1;<br />
	} else if (pfLock->fl_type == F_UNLCK) {<br />
		cFYI(1, (&raquo;F_UNLCK&raquo;));<br />
		numUnlock = 1;<br />
		/* Check if unlock includes more than<br />
		one lock range */<br />
	} else if (pfLock->fl_type == F_RDLCK) {<br />
		cFYI(1, (&raquo;F_RDLCK&raquo;));<br />
		lockType |= LOCKING_ANDX_SHARED_LOCK;<br />
		numLock = 1;<br />
	} else if (pfLock->fl_type == F_EXLCK) {<br />
		cFYI(1, (&raquo;F_EXLCK&raquo;));<br />
		numLock = 1;<br />
	} else if (pfLock->fl_type == F_SHLCK) {<br />
		cFYI(1, (&raquo;F_SHLCK&raquo;));<br />
		lockType |= LOCKING_ANDX_SHARED_LOCK;<br />
		numLock = 1;<br />
	} else<br />
		cFYI(1, (&raquo;Unknown type of lock&raquo;));</p>
<p>	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);<br />
	tcon = cifs_sb->tcon;</p>
<p>	if (file->private_data == NULL) {<br />
		rc = -EBADF;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}<br />
	netfid = ((struct cifsFileInfo *)file->private_data)->netfid;</p>
<p>	if ((tcon->ses->capabilities &#038; CAP_UNIX) &#038;&#038;<br />
	    (CIFS_UNIX_FCNTL_CAP &#038; le64_to_cpu(tcon->fsUnixInfo.Capability)) &#038;&#038;<br />
	    ((cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_NOPOSIXBRL) == 0))<br />
		posix_locking = 1;<br />
	/* BB add code here to normalize offset and length to<br />
	account for negative length which we can not accept over the<br />
	wire */<br />
	if (IS_GETLK(cmd)) {<br />
		if (posix_locking) {<br />
			int posix_lock_type;<br />
			if (lockType &#038; LOCKING_ANDX_SHARED_LOCK)<br />
				posix_lock_type = CIFS_RDLCK;<br />
			else<br />
				posix_lock_type = CIFS_WRLCK;<br />
			rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,<br />
					length,	pfLock,<br />
					posix_lock_type, wait_flag);<br />
			FreeXid(xid);<br />
			return rc;<br />
		}</p>
<p>		/* BB we could chain these into one lock request BB */<br />
		rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start,<br />
				 0, 1, lockType, 0 /* wait flag */ );<br />
		if (rc == 0) {<br />
			rc = CIFSSMBLock(xid, tcon, netfid, length,<br />
					 pfLock->fl_start, 1 /* numUnlock */ ,<br />
					 0 /* numLock */ , lockType,<br />
					 0 /* wait flag */ );<br />
			pfLock->fl_type = F_UNLCK;<br />
			if (rc != 0)<br />
				cERROR(1, (&raquo;Error unlocking previously locked &raquo;<br />
					   &laquo;range %d during test of lock&raquo;, rc));<br />
			rc = 0;</p>
<p>		} else {<br />
			/* if rc == ERR_SHARING_VIOLATION ? */<br />
			rc = 0;	/* do not change lock type to unlock<br />
				   since range in use */<br />
		}</p>
<p>		FreeXid(xid);<br />
		return rc;<br />
	}</p>
<p>	if (!numLock &#038;&#038; !numUnlock) {<br />
		/* if no lock or unlock then nothing<br />
		to do since we do not know what it is */<br />
		FreeXid(xid);<br />
		return -EOPNOTSUPP;<br />
	}</p>
<p>	if (posix_locking) {<br />
		int posix_lock_type;<br />
		if (lockType &#038; LOCKING_ANDX_SHARED_LOCK)<br />
			posix_lock_type = CIFS_RDLCK;<br />
		else<br />
			posix_lock_type = CIFS_WRLCK;</p>
<p>		if (numUnlock == 1)<br />
			posix_lock_type = CIFS_UNLCK;</p>
<p>		rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,<br />
				      length, pfLock,<br />
				      posix_lock_type, wait_flag);<br />
	} else {<br />
		struct cifsFileInfo *fid =<br />
			(struct cifsFileInfo *)file->private_data;</p>
<p>		if (numLock) {<br />
			rc = CIFSSMBLock(xid, tcon, netfid, length,<br />
					pfLock->fl_start,<br />
					0, numLock, lockType, wait_flag);</p>
<p>			if (rc == 0) {<br />
				/* For Windows locks we must store them. */<br />
				rc = store_file_lock(fid, length,<br />
						pfLock->fl_start, lockType);<br />
			}<br />
		} else if (numUnlock) {<br />
			/* For each stored lock that this unlock overlaps<br />
			   completely, unlock it. */<br />
			int stored_rc = 0;<br />
			struct cifsLockInfo *li, *tmp;</p>
<p>			rc = 0;<br />
			mutex_lock(&#038;fid->lock_mutex);<br />
			list_for_each_entry_safe(li, tmp, &#038;fid->llist, llist) {<br />
				if (pfLock->fl_start <= li->offset &#038;&#038;<br />
						(pfLock->fl_start + length) >=<br />
						(li->offset + li->length)) {<br />
					stored_rc = CIFSSMBLock(xid, tcon,<br />
							netfid,<br />
							li->length, li->offset,<br />
							1, 0, li->type, false);<br />
					if (stored_rc)<br />
						rc = stored_rc;</p>
<p>					list_del(&#038;li->llist);<br />
					kfree(li);<br />
				}<br />
			}<br />
			mutex_unlock(&#038;fid->lock_mutex);<br />
		}<br />
	}</p>
<p>	if (pfLock->fl_flags &#038; FL_POSIX)<br />
		posix_lock_file_wait(file, pfLock);<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>/*<br />
 * Set the timeout on write requests past EOF. For some servers (Windows)<br />
 * these calls can be very long.<br />
 *<br />
 * If we&#8217;re writing >10M past the EOF we give a 180s timeout. Anything less<br />
 * than that gets a 45s timeout. Writes not past EOF get 15s timeouts.<br />
 * The 10M cutoff is totally arbitrary. A better scheme for this would be<br />
 * welcome if someone wants to suggest one.<br />
 *<br />
 * We may be able to do a better job with this if there were some way to<br />
 * declare that a file should be sparse.<br />
 */<br />
static int<br />
cifs_write_timeout(struct cifsInodeInfo *cifsi, loff_t offset)<br />
{<br />
	if (offset <= cifsi->server_eof)<br />
		return CIFS_STD_OP;<br />
	else if (offset > (cifsi->server_eof + (10 * 1024 * 1024)))<br />
		return CIFS_VLONG_OP;<br />
	else<br />
		return CIFS_LONG_OP;<br />
}</p>
<p>/* update the file size (if needed) after a write */<br />
static void<br />
cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,<br />
		      unsigned int bytes_written)<br />
{<br />
	loff_t end_of_write = offset + bytes_written;</p>
<p>	if (end_of_write > cifsi->server_eof)<br />
		cifsi->server_eof = end_of_write;<br />
}</p>
<p>ssize_t cifs_user_write(struct file *file, const char __user *write_data,<br />
	size_t write_size, loff_t *poffset)<br />
{<br />
	int rc = 0;<br />
	unsigned int bytes_written = 0;<br />
	unsigned int total_written;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	int xid, long_op;<br />
	struct cifsFileInfo *open_file;<br />
	struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode);</p>
<p>	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);</p>
<p>	pTcon = cifs_sb->tcon;</p>
<p>	/* cFYI(1,<br />
	   (&raquo; write %d bytes to offset %lld of %s&raquo;, write_size,<br />
	   *poffset, file->f_path.dentry->d_name.name)); */</p>
<p>	if (file->private_data == NULL)<br />
		return -EBADF;<br />
	open_file = (struct cifsFileInfo *) file->private_data;</p>
<p>	rc = generic_write_checks(file, poffset, &#038;write_size, 0);<br />
	if (rc)<br />
		return rc;</p>
<p>	xid = GetXid();</p>
<p>	long_op = cifs_write_timeout(cifsi, *poffset);<br />
	for (total_written = 0; write_size > total_written;<br />
	     total_written += bytes_written) {<br />
		rc = -EAGAIN;<br />
		while (rc == -EAGAIN) {<br />
			if (file->private_data == NULL) {<br />
				/* file has been closed on us */<br />
				FreeXid(xid);<br />
			/* if we have gotten here we have written some data<br />
			   and blocked, and the file has been freed on us while<br />
			   we blocked so return what we managed to write */<br />
				return total_written;<br />
			}<br />
			if (open_file->closePend) {<br />
				FreeXid(xid);<br />
				if (total_written)<br />
					return total_written;<br />
				else<br />
					return -EBADF;<br />
			}<br />
			if (open_file->invalidHandle) {<br />
				/* we could deadlock if we called<br />
				   filemap_fdatawait from here so tell<br />
				   reopen_file not to flush data to server<br />
				   now */<br />
				rc = cifs_reopen_file(file, false);<br />
				if (rc != 0)<br />
					break;<br />
			}</p>
<p>			rc = CIFSSMBWrite(xid, pTcon,<br />
				open_file->netfid,<br />
				min_t(const int, cifs_sb->wsize,<br />
				      write_size &#8211; total_written),<br />
				*poffset, &#038;bytes_written,<br />
				NULL, write_data + total_written, long_op);<br />
		}<br />
		if (rc || (bytes_written == 0)) {<br />
			if (total_written)<br />
				break;<br />
			else {<br />
				FreeXid(xid);<br />
				return rc;<br />
			}<br />
		} else {<br />
			cifs_update_eof(cifsi, *poffset, bytes_written);<br />
			*poffset += bytes_written;<br />
		}<br />
		long_op = CIFS_STD_OP; /* subsequent writes fast -<br />
				    15 seconds is plenty */<br />
	}</p>
<p>	cifs_stats_bytes_written(pTcon, total_written);</p>
<p>	/* since the write may have blocked check these pointers again */<br />
	if ((file->f_path.dentry) &#038;&#038; (file->f_path.dentry->d_inode)) {<br />
		struct inode *inode = file->f_path.dentry->d_inode;<br />
/* Do not update local mtime &#8211; server will set its actual value on write<br />
 *		inode->i_ctime = inode->i_mtime =<br />
 * 			current_fs_time(inode->i_sb);*/<br />
		if (total_written > 0) {<br />
			spin_lock(&#038;inode->i_lock);<br />
			if (*poffset > file->f_path.dentry->d_inode->i_size)<br />
				i_size_write(file->f_path.dentry->d_inode,<br />
					*poffset);<br />
			spin_unlock(&#038;inode->i_lock);<br />
		}<br />
		mark_inode_dirty_sync(file->f_path.dentry->d_inode);<br />
	}<br />
	FreeXid(xid);<br />
	return total_written;<br />
}</p>
<p>static ssize_t cifs_write(struct file *file, const char *write_data,<br />
			  size_t write_size, loff_t *poffset)<br />
{<br />
	int rc = 0;<br />
	unsigned int bytes_written = 0;<br />
	unsigned int total_written;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	int xid, long_op;<br />
	struct cifsFileInfo *open_file;<br />
	struct cifsInodeInfo *cifsi = CIFS_I(file->f_path.dentry->d_inode);</p>
<p>	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);</p>
<p>	pTcon = cifs_sb->tcon;</p>
<p>	cFYI(1, (&raquo;write %zd bytes to offset %lld of %s&raquo;, write_size,<br />
	   *poffset, file->f_path.dentry->d_name.name));</p>
<p>	if (file->private_data == NULL)<br />
		return -EBADF;<br />
	open_file = (struct cifsFileInfo *)file->private_data;</p>
<p>	xid = GetXid();</p>
<p>	long_op = cifs_write_timeout(cifsi, *poffset);<br />
	for (total_written = 0; write_size > total_written;<br />
	     total_written += bytes_written) {<br />
		rc = -EAGAIN;<br />
		while (rc == -EAGAIN) {<br />
			if (file->private_data == NULL) {<br />
				/* file has been closed on us */<br />
				FreeXid(xid);<br />
			/* if we have gotten here we have written some data<br />
			   and blocked, and the file has been freed on us<br />
			   while we blocked so return what we managed to<br />
			   write */<br />
				return total_written;<br />
			}<br />
			if (open_file->closePend) {<br />
				FreeXid(xid);<br />
				if (total_written)<br />
					return total_written;<br />
				else<br />
					return -EBADF;<br />
			}<br />
			if (open_file->invalidHandle) {<br />
				/* we could deadlock if we called<br />
				   filemap_fdatawait from here so tell<br />
				   reopen_file not to flush data to<br />
				   server now */<br />
				rc = cifs_reopen_file(file, false);<br />
				if (rc != 0)<br />
					break;<br />
			}<br />
			if (experimEnabled || (pTcon->ses->server &#038;&#038;<br />
				((pTcon->ses->server->secMode &#038;<br />
				(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))<br />
				== 0))) {<br />
				struct kvec iov[2];<br />
				unsigned int len;</p>
<p>				len = min((size_t)cifs_sb->wsize,<br />
					  write_size &#8211; total_written);<br />
				/* iov[0] is reserved for smb header */<br />
				iov[1].iov_base = (char *)write_data +<br />
						  total_written;<br />
				iov[1].iov_len = len;<br />
				rc = CIFSSMBWrite2(xid, pTcon,<br />
						open_file->netfid, len,<br />
						*poffset, &#038;bytes_written,<br />
						iov, 1, long_op);<br />
			} else<br />
				rc = CIFSSMBWrite(xid, pTcon,<br />
					 open_file->netfid,<br />
					 min_t(const int, cifs_sb->wsize,<br />
					       write_size &#8211; total_written),<br />
					 *poffset, &#038;bytes_written,<br />
					 write_data + total_written,<br />
					 NULL, long_op);<br />
		}<br />
		if (rc || (bytes_written == 0)) {<br />
			if (total_written)<br />
				break;<br />
			else {<br />
				FreeXid(xid);<br />
				return rc;<br />
			}<br />
		} else {<br />
			cifs_update_eof(cifsi, *poffset, bytes_written);<br />
			*poffset += bytes_written;<br />
		}<br />
		long_op = CIFS_STD_OP; /* subsequent writes fast -<br />
				    15 seconds is plenty */<br />
	}</p>
<p>	cifs_stats_bytes_written(pTcon, total_written);</p>
<p>	/* since the write may have blocked check these pointers again */<br />
	if ((file->f_path.dentry) &#038;&#038; (file->f_path.dentry->d_inode)) {<br />
/*BB We could make this contingent on superblock ATIME flag too */<br />
/*		file->f_path.dentry->d_inode->i_ctime =<br />
		file->f_path.dentry->d_inode->i_mtime = CURRENT_TIME;*/<br />
		if (total_written > 0) {<br />
			spin_lock(&#038;file->f_path.dentry->d_inode->i_lock);<br />
			if (*poffset > file->f_path.dentry->d_inode->i_size)<br />
				i_size_write(file->f_path.dentry->d_inode,<br />
					     *poffset);<br />
			spin_unlock(&#038;file->f_path.dentry->d_inode->i_lock);<br />
		}<br />
		mark_inode_dirty_sync(file->f_path.dentry->d_inode);<br />
	}<br />
	FreeXid(xid);<br />
	return total_written;<br />
}</p>
<p>#ifdef CONFIG_CIFS_EXPERIMENTAL<br />
struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode)<br />
{<br />
	struct cifsFileInfo *open_file = NULL;</p>
<p>	read_lock(&#038;GlobalSMBSeslock);<br />
	/* we could simply get the first_list_entry since write-only entries<br />
	   are always at the end of the list but since the first entry might<br />
	   have a close pending, we go through the whole list */<br />
	list_for_each_entry(open_file, &#038;cifs_inode->openFileList, flist) {<br />
		if (open_file->closePend)<br />
			continue;<br />
		if (open_file->pfile &#038;&#038; ((open_file->pfile->f_flags &#038; O_RDWR) ||<br />
		    (open_file->pfile->f_flags &#038; O_RDONLY))) {<br />
			if (!open_file->invalidHandle) {<br />
				/* found a good file */<br />
				/* lock it so it will not be closed on us */<br />
				cifsFileInfo_get(open_file);<br />
				read_unlock(&#038;GlobalSMBSeslock);<br />
				return open_file;<br />
			} /* else might as well continue, and look for<br />
			     another, or simply have the caller reopen it<br />
			     again rather than trying to fix this handle */<br />
		} else /* write only file */<br />
			break; /* write only files are last so must be done */<br />
	}<br />
	read_unlock(&#038;GlobalSMBSeslock);<br />
	return NULL;<br />
}<br />
#endif</p>
<p>struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)<br />
{<br />
	struct cifsFileInfo *open_file;<br />
	bool any_available = false;<br />
	int rc;</p>
<p>	/* Having a null inode here (because mapping->host was set to zero by<br />
	the VFS or MM) should not happen but we had reports of on oops (due to<br />
	it being zero) during stress testcases so we need to check for it */</p>
<p>	if (cifs_inode == NULL) {<br />
		cERROR(1, (&raquo;Null inode passed to cifs_writeable_file&raquo;));<br />
		dump_stack();<br />
		return NULL;<br />
	}</p>
<p>	read_lock(&#038;GlobalSMBSeslock);<br />
refind_writable:<br />
	list_for_each_entry(open_file, &#038;cifs_inode->openFileList, flist) {<br />
		if (open_file->closePend ||<br />
		    (!any_available &#038;&#038; open_file->pid != current->tgid))<br />
			continue;</p>
<p>		if (open_file->pfile &#038;&#038;<br />
		    ((open_file->pfile->f_flags &#038; O_RDWR) ||<br />
		     (open_file->pfile->f_flags &#038; O_WRONLY))) {<br />
			cifsFileInfo_get(open_file);</p>
<p>			if (!open_file->invalidHandle) {<br />
				/* found a good writable file */<br />
				read_unlock(&#038;GlobalSMBSeslock);<br />
				return open_file;<br />
			}</p>
<p>			read_unlock(&#038;GlobalSMBSeslock);<br />
			/* Had to unlock since following call can block */<br />
			rc = cifs_reopen_file(open_file->pfile, false);<br />
			if (!rc) {<br />
				if (!open_file->closePend)<br />
					return open_file;<br />
				else { /* start over in case this was deleted */<br />
				       /* since the list could be modified */<br />
					read_lock(&#038;GlobalSMBSeslock);<br />
					cifsFileInfo_put(open_file);<br />
					goto refind_writable;<br />
				}<br />
			}</p>
<p>			/* if it fails, try another handle if possible -<br />
			(we can not do this if closePending since<br />
			loop could be modified &#8211; in which case we<br />
			have to start at the beginning of the list<br />
			again. Note that it would be bad<br />
			to hold up writepages here (rather than<br />
			in caller) with continuous retries */<br />
			cFYI(1, (&raquo;wp failed on reopen file&raquo;));<br />
			read_lock(&#038;GlobalSMBSeslock);<br />
			/* can not use this handle, no write<br />
			   pending on this one after all */<br />
			cifsFileInfo_put(open_file);</p>
<p>			if (open_file->closePend) /* list could have changed */<br />
				goto refind_writable;<br />
			/* else we simply continue to the next entry. Thus<br />
			   we do not loop on reopen errors.  If we<br />
			   can not reopen the file, for example if we<br />
			   reconnected to a server with another client<br />
			   racing to delete or lock the file we would not<br />
			   make progress if we restarted before the beginning<br />
			   of the loop here. */<br />
		}<br />
	}<br />
	/* couldn&#8217;t find useable FH with same pid, try any available */<br />
	if (!any_available) {<br />
		any_available = true;<br />
		goto refind_writable;<br />
	}<br />
	read_unlock(&#038;GlobalSMBSeslock);<br />
	return NULL;<br />
}</p>
<p>static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)<br />
{<br />
	struct address_space *mapping = page->mapping;<br />
	loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;<br />
	char *write_data;<br />
	int rc = -EFAULT;<br />
	int bytes_written = 0;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	struct inode *inode;<br />
	struct cifsFileInfo *open_file;</p>
<p>	if (!mapping || !mapping->host)<br />
		return -EFAULT;</p>
<p>	inode = page->mapping->host;<br />
	cifs_sb = CIFS_SB(inode->i_sb);<br />
	pTcon = cifs_sb->tcon;</p>
<p>	offset += (loff_t)from;<br />
	write_data = kmap(page);<br />
	write_data += from;</p>
<p>	if ((to > PAGE_CACHE_SIZE) || (from > to)) {<br />
		kunmap(page);<br />
		return -EIO;<br />
	}</p>
<p>	/* racing with truncate? */<br />
	if (offset > mapping->host->i_size) {<br />
		kunmap(page);<br />
		return 0; /* don&#8217;t care */<br />
	}</p>
<p>	/* check to make sure that we are not extending the file */<br />
	if (mapping->host->i_size &#8211; offset < (loff_t)to)<br />
		to = (unsigned)(mapping->host->i_size &#8211; offset);</p>
<p>	open_file = find_writable_file(CIFS_I(mapping->host));<br />
	if (open_file) {<br />
		bytes_written = cifs_write(open_file->pfile, write_data,<br />
					   to-from, &#038;offset);<br />
		cifsFileInfo_put(open_file);<br />
		/* Does mm or vfs already set times? */<br />
		inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);<br />
		if ((bytes_written > 0) &#038;&#038; (offset))<br />
			rc = 0;<br />
		else if (bytes_written < 0)<br />
			rc = bytes_written;<br />
	} else {<br />
		cFYI(1, ("No writeable filehandles for inode"));<br />
		rc = -EIO;<br />
	}</p>
<p>	kunmap(page);<br />
	return rc;<br />
}</p>
<p>static int cifs_writepages(struct address_space *mapping,<br />
			   struct writeback_control *wbc)<br />
{<br />
	struct backing_dev_info *bdi = mapping->backing_dev_info;<br />
	unsigned int bytes_to_write;<br />
	unsigned int bytes_written;<br />
	struct cifs_sb_info *cifs_sb;<br />
	int done = 0;<br />
	pgoff_t end;<br />
	pgoff_t index;<br />
	int range_whole = 0;<br />
	struct kvec *iov;<br />
	int len;<br />
	int n_iov = 0;<br />
	pgoff_t next;<br />
	int nr_pages;<br />
	__u64 offset = 0;<br />
	struct cifsFileInfo *open_file;<br />
	struct cifsInodeInfo *cifsi = CIFS_I(mapping->host);<br />
	struct page *page;<br />
	struct pagevec pvec;<br />
	int rc = 0;<br />
	int scanned = 0;<br />
	int xid, long_op;</p>
<p>	cifs_sb = CIFS_SB(mapping->host->i_sb);</p>
<p>	/*<br />
	 * If wsize is smaller that the page cache size, default to writing<br />
	 * one page at a time via cifs_writepage<br />
	 */<br />
	if (cifs_sb->wsize < PAGE_CACHE_SIZE)<br />
		return generic_writepages(mapping, wbc);</p>
<p>	if ((cifs_sb->tcon->ses) &#038;&#038; (cifs_sb->tcon->ses->server))<br />
		if (cifs_sb->tcon->ses->server->secMode &#038;<br />
				(SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))<br />
			if (!experimEnabled)<br />
				return generic_writepages(mapping, wbc);</p>
<p>	iov = kmalloc(32 * sizeof(struct kvec), GFP_KERNEL);<br />
	if (iov == NULL)<br />
		return generic_writepages(mapping, wbc);</p>
<p>	/*<br />
	 * BB: Is this meaningful for a non-block-device file system?<br />
	 * If it is, we should test it again after we do I/O<br />
	 */<br />
	if (wbc->nonblocking &#038;&#038; bdi_write_congested(bdi)) {<br />
		wbc->encountered_congestion = 1;<br />
		kfree(iov);<br />
		return 0;<br />
	}</p>
<p>	xid = GetXid();</p>
<p>	pagevec_init(&#038;pvec, 0);<br />
	if (wbc->range_cyclic) {<br />
		index = mapping->writeback_index; /* Start from prev offset */<br />
		end = -1;<br />
	} else {<br />
		index = wbc->range_start >> PAGE_CACHE_SHIFT;<br />
		end = wbc->range_end >> PAGE_CACHE_SHIFT;<br />
		if (wbc->range_start == 0 &#038;&#038; wbc->range_end == LLONG_MAX)<br />
			range_whole = 1;<br />
		scanned = 1;<br />
	}<br />
retry:<br />
	while (!done &#038;&#038; (index <= end) &#038;&#038;<br />
	       (nr_pages = pagevec_lookup_tag(&#038;pvec, mapping, &#038;index,<br />
			PAGECACHE_TAG_DIRTY,<br />
			min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1))) {<br />
		int first;<br />
		unsigned int i;</p>
<p>		first = -1;<br />
		next = 0;<br />
		n_iov = 0;<br />
		bytes_to_write = 0;</p>
<p>		for (i = 0; i < nr_pages; i++) {<br />
			page = pvec.pages[i];<br />
			/*<br />
			 * At this point we hold neither mapping->tree_lock nor<br />
			 * lock on the page itself: the page may be truncated or<br />
			 * invalidated (changing page->mapping to NULL), or even<br />
			 * swizzled back from swapper_space to tmpfs file<br />
			 * mapping<br />
			 */</p>
<p>			if (first < 0)<br />
				lock_page(page);<br />
			else if (!trylock_page(page))<br />
				break;</p>
<p>			if (unlikely(page->mapping != mapping)) {<br />
				unlock_page(page);<br />
				break;<br />
			}</p>
<p>			if (!wbc->range_cyclic &#038;&#038; page->index > end) {<br />
				done = 1;<br />
				unlock_page(page);<br />
				break;<br />
			}</p>
<p>			if (next &#038;&#038; (page->index != next)) {<br />
				/* Not next consecutive page */<br />
				unlock_page(page);<br />
				break;<br />
			}</p>
<p>			if (wbc->sync_mode != WB_SYNC_NONE)<br />
				wait_on_page_writeback(page);</p>
<p>			if (PageWriteback(page) ||<br />
					!clear_page_dirty_for_io(page)) {<br />
				unlock_page(page);<br />
				break;<br />
			}</p>
<p>			/*<br />
			 * This actually clears the dirty bit in the radix tree.<br />
			 * See cifs_writepage() for more commentary.<br />
			 */<br />
			set_page_writeback(page);</p>
<p>			if (page_offset(page) >= mapping->host->i_size) {<br />
				done = 1;<br />
				unlock_page(page);<br />
				end_page_writeback(page);<br />
				break;<br />
			}</p>
<p>			/*<br />
			 * BB can we get rid of this?  pages are held by pvec<br />
			 */<br />
			page_cache_get(page);</p>
<p>			len = min(mapping->host->i_size &#8211; page_offset(page),<br />
				  (loff_t)PAGE_CACHE_SIZE);</p>
<p>			/* reserve iov[0] for the smb header */<br />
			n_iov++;<br />
			iov[n_iov].iov_base = kmap(page);<br />
			iov[n_iov].iov_len = len;<br />
			bytes_to_write += len;</p>
<p>			if (first < 0) {<br />
				first = i;<br />
				offset = page_offset(page);<br />
			}<br />
			next = page->index + 1;<br />
			if (bytes_to_write + PAGE_CACHE_SIZE > cifs_sb->wsize)<br />
				break;<br />
		}<br />
		if (n_iov) {<br />
			/* Search for a writable handle every time we call<br />
			 * CIFSSMBWrite2.  We can&#8217;t rely on the last handle<br />
			 * we used to still be valid<br />
			 */<br />
			open_file = find_writable_file(CIFS_I(mapping->host));<br />
			if (!open_file) {<br />
				cERROR(1, (&raquo;No writable handles for inode&raquo;));<br />
				rc = -EBADF;<br />
			} else {<br />
				long_op = cifs_write_timeout(cifsi, offset);<br />
				rc = CIFSSMBWrite2(xid, cifs_sb->tcon,<br />
						   open_file->netfid,<br />
						   bytes_to_write, offset,<br />
						   &#038;bytes_written, iov, n_iov,<br />
						   long_op);<br />
				cifsFileInfo_put(open_file);<br />
				cifs_update_eof(cifsi, offset, bytes_written);</p>
<p>				if (rc || bytes_written < bytes_to_write) {<br />
					cERROR(1, ("Write2 ret %d, wrote %d",<br />
						  rc, bytes_written));<br />
					/* BB what if continued retry is<br />
					   requested via mount flags? */<br />
					if (rc == -ENOSPC)<br />
						set_bit(AS_ENOSPC, &#038;mapping->flags);<br />
					else<br />
						set_bit(AS_EIO, &#038;mapping->flags);<br />
				} else {<br />
					cifs_stats_bytes_written(cifs_sb->tcon,<br />
								 bytes_written);<br />
				}<br />
			}<br />
			for (i = 0; i < n_iov; i++) {<br />
				page = pvec.pages[first + i];<br />
				/* Should we also set page error on<br />
				success rc but too little data written? */<br />
				/* BB investigate retry logic on temporary<br />
				server crash cases and how recovery works<br />
				when page marked as error */<br />
				if (rc)<br />
					SetPageError(page);<br />
				kunmap(page);<br />
				unlock_page(page);<br />
				end_page_writeback(page);<br />
				page_cache_release(page);<br />
			}<br />
			if ((wbc->nr_to_write -= n_iov) <= 0)<br />
				done = 1;<br />
			index = next;<br />
		} else<br />
			/* Need to re-find the pages we skipped */<br />
			index = pvec.pages[0]->index + 1;</p>
<p>		pagevec_release(&#038;pvec);<br />
	}<br />
	if (!scanned &#038;&#038; !done) {<br />
		/*<br />
		 * We hit the last page and there is more work to be done: wrap<br />
		 * back to the start of the file<br />
		 */<br />
		scanned = 1;<br />
		index = 0;<br />
		goto retry;<br />
	}<br />
	if (wbc->range_cyclic || (range_whole &#038;&#038; wbc->nr_to_write > 0))<br />
		mapping->writeback_index = index;</p>
<p>	FreeXid(xid);<br />
	kfree(iov);<br />
	return rc;<br />
}</p>
<p>static int cifs_writepage(struct page *page, struct writeback_control *wbc)<br />
{<br />
	int rc = -EFAULT;<br />
	int xid;</p>
<p>	xid = GetXid();<br />
/* BB add check for wbc flags */<br />
	page_cache_get(page);<br />
	if (!PageUptodate(page))<br />
		cFYI(1, (&raquo;ppw &#8211; page not up to date&raquo;));</p>
<p>	/*<br />
	 * Set the &laquo;writeback&raquo; flag, and clear &laquo;dirty&raquo; in the radix tree.<br />
	 *<br />
	 * A writepage() implementation always needs to do either this,<br />
	 * or re-dirty the page with &laquo;redirty_page_for_writepage()&raquo; in<br />
	 * the case of a failure.<br />
	 *<br />
	 * Just unlocking the page will cause the radix tree tag-bits<br />
	 * to fail to update with the state of the page correctly.<br />
	 */<br />
	set_page_writeback(page);<br />
	rc = cifs_partialpagewrite(page, 0, PAGE_CACHE_SIZE);<br />
	SetPageUptodate(page); /* BB add check for error and Clearuptodate? */<br />
	unlock_page(page);<br />
	end_page_writeback(page);<br />
	page_cache_release(page);<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>static int cifs_write_end(struct file *file, struct address_space *mapping,<br />
			loff_t pos, unsigned len, unsigned copied,<br />
			struct page *page, void *fsdata)<br />
{<br />
	int rc;<br />
	struct inode *inode = mapping->host;</p>
<p>	cFYI(1, (&raquo;write_end for page %p from pos %lld with %d bytes&raquo;,<br />
		 page, pos, copied));</p>
<p>	if (PageChecked(page)) {<br />
		if (copied == len)<br />
			SetPageUptodate(page);<br />
		ClearPageChecked(page);<br />
	} else if (!PageUptodate(page) &#038;&#038; copied == PAGE_CACHE_SIZE)<br />
		SetPageUptodate(page);</p>
<p>	if (!PageUptodate(page)) {<br />
		char *page_data;<br />
		unsigned offset = pos &#038; (PAGE_CACHE_SIZE &#8211; 1);<br />
		int xid;</p>
<p>		xid = GetXid();<br />
		/* this is probably better than directly calling<br />
		   partialpage_write since in this function the file handle is<br />
		   known which we might as well	leverage */<br />
		/* BB check if anything else missing out of ppw<br />
		   such as updating last write time */<br />
		page_data = kmap(page);<br />
		rc = cifs_write(file, page_data + offset, copied, &#038;pos);<br />
		/* if (rc < 0) should we set writebehind rc? */<br />
		kunmap(page);</p>
<p>		FreeXid(xid);<br />
	} else {<br />
		rc = copied;<br />
		pos += copied;<br />
		set_page_dirty(page);<br />
	}</p>
<p>	if (rc > 0) {<br />
		spin_lock(&#038;inode->i_lock);<br />
		if (pos > inode->i_size)<br />
			i_size_write(inode, pos);<br />
		spin_unlock(&#038;inode->i_lock);<br />
	}</p>
<p>	unlock_page(page);<br />
	page_cache_release(page);</p>
<p>	return rc;<br />
}</p>
<p>int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)<br />
{<br />
	int xid;<br />
	int rc = 0;<br />
	struct cifsTconInfo *tcon;<br />
	struct cifsFileInfo *smbfile =<br />
		(struct cifsFileInfo *)file->private_data;<br />
	struct inode *inode = file->f_path.dentry->d_inode;</p>
<p>	xid = GetXid();</p>
<p>	cFYI(1, (&raquo;Sync file &#8211; name: %s datasync: 0x%x&raquo;,<br />
		dentry->d_name.name, datasync));</p>
<p>	rc = filemap_write_and_wait(inode->i_mapping);<br />
	if (rc == 0) {<br />
		rc = CIFS_I(inode)->write_behind_rc;<br />
		CIFS_I(inode)->write_behind_rc = 0;<br />
		tcon = CIFS_SB(inode->i_sb)->tcon;<br />
		if (!rc &#038;&#038; tcon &#038;&#038; smbfile &#038;&#038;<br />
		   !(CIFS_SB(inode->i_sb)->mnt_cifs_flags &#038; CIFS_MOUNT_NOSSYNC))<br />
			rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);<br />
	}</p>
<p>	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>/* static void cifs_sync_page(struct page *page)<br />
{<br />
	struct address_space *mapping;<br />
	struct inode *inode;<br />
	unsigned long index = page->index;<br />
	unsigned int rpages = 0;<br />
	int rc = 0;</p>
<p>	cFYI(1, (&raquo;sync page %p&raquo;,page));<br />
	mapping = page->mapping;<br />
	if (!mapping)<br />
		return 0;<br />
	inode = mapping->host;<br />
	if (!inode)<br />
		return; */</p>
<p>/*	fill in rpages then<br />
	result = cifs_pagein_inode(inode, index, rpages); */ /* BB finish */</p>
<p>/*	cFYI(1, (&raquo;rpages is %d for sync page of Index %ld&raquo;, rpages, index));</p>
<p>#if 0<br />
	if (rc < 0)<br />
		return rc;<br />
	return 0;<br />
#endif<br />
} */</p>
<p>/*<br />
 * As file closes, flush all cached write data for this inode checking<br />
 * for write behind errors.<br />
 */<br />
int cifs_flush(struct file *file, fl_owner_t id)<br />
{<br />
	struct inode *inode = file->f_path.dentry->d_inode;<br />
	int rc = 0;</p>
<p>	/* Rather than do the steps manually:<br />
	   lock the inode for writing<br />
	   loop through pages looking for write behind data (dirty pages)<br />
	   coalesce into contiguous 16K (or smaller) chunks to write to server<br />
	   send to server (prefer in parallel)<br />
	   deal with writebehind errors<br />
	   unlock inode for writing<br />
	   filemapfdatawrite appears easier for the time being */</p>
<p>	rc = filemap_fdatawrite(inode->i_mapping);<br />
	/* reset wb rc if we were able to write out dirty pages */<br />
	if (!rc) {<br />
		rc = CIFS_I(inode)->write_behind_rc;<br />
		CIFS_I(inode)->write_behind_rc = 0;<br />
	}</p>
<p>	cFYI(1, (&raquo;Flush inode %p file %p rc %d&raquo;, inode, file, rc));</p>
<p>	return rc;<br />
}</p>
<p>ssize_t cifs_user_read(struct file *file, char __user *read_data,<br />
	size_t read_size, loff_t *poffset)<br />
{<br />
	int rc = -EACCES;<br />
	unsigned int bytes_read = 0;<br />
	unsigned int total_read = 0;<br />
	unsigned int current_read_size;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	int xid;<br />
	struct cifsFileInfo *open_file;<br />
	char *smb_read_data;<br />
	char __user *current_offset;<br />
	struct smb_com_read_rsp *pSMBr;</p>
<p>	xid = GetXid();<br />
	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);<br />
	pTcon = cifs_sb->tcon;</p>
<p>	if (file->private_data == NULL) {<br />
		rc = -EBADF;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}<br />
	open_file = (struct cifsFileInfo *)file->private_data;</p>
<p>	if ((file->f_flags &#038; O_ACCMODE) == O_WRONLY)<br />
		cFYI(1, (&raquo;attempting read on write only file instance&raquo;));</p>
<p>	for (total_read = 0, current_offset = read_data;<br />
	     read_size > total_read;<br />
	     total_read += bytes_read, current_offset += bytes_read) {<br />
		current_read_size = min_t(const int, read_size &#8211; total_read,<br />
					  cifs_sb->rsize);<br />
		rc = -EAGAIN;<br />
		smb_read_data = NULL;<br />
		while (rc == -EAGAIN) {<br />
			int buf_type = CIFS_NO_BUFFER;<br />
			if ((open_file->invalidHandle) &#038;&#038;<br />
			    (!open_file->closePend)) {<br />
				rc = cifs_reopen_file(file, true);<br />
				if (rc != 0)<br />
					break;<br />
			}<br />
			rc = CIFSSMBRead(xid, pTcon,<br />
					 open_file->netfid,<br />
					 current_read_size, *poffset,<br />
					 &#038;bytes_read, &#038;smb_read_data,<br />
					 &#038;buf_type);<br />
			pSMBr = (struct smb_com_read_rsp *)smb_read_data;<br />
			if (smb_read_data) {<br />
				if (copy_to_user(current_offset,<br />
						smb_read_data +<br />
						4 /* RFC1001 length field */ +<br />
						le16_to_cpu(pSMBr->DataOffset),<br />
						bytes_read))<br />
					rc = -EFAULT;</p>
<p>				if (buf_type == CIFS_SMALL_BUFFER)<br />
					cifs_small_buf_release(smb_read_data);<br />
				else if (buf_type == CIFS_LARGE_BUFFER)<br />
					cifs_buf_release(smb_read_data);<br />
				smb_read_data = NULL;<br />
			}<br />
		}<br />
		if (rc || (bytes_read == 0)) {<br />
			if (total_read) {<br />
				break;<br />
			} else {<br />
				FreeXid(xid);<br />
				return rc;<br />
			}<br />
		} else {<br />
			cifs_stats_bytes_read(pTcon, bytes_read);<br />
			*poffset += bytes_read;<br />
		}<br />
	}<br />
	FreeXid(xid);<br />
	return total_read;<br />
}</p>
<p>static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,<br />
	loff_t *poffset)<br />
{<br />
	int rc = -EACCES;<br />
	unsigned int bytes_read = 0;<br />
	unsigned int total_read;<br />
	unsigned int current_read_size;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	int xid;<br />
	char *current_offset;<br />
	struct cifsFileInfo *open_file;<br />
	int buf_type = CIFS_NO_BUFFER;</p>
<p>	xid = GetXid();<br />
	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);<br />
	pTcon = cifs_sb->tcon;</p>
<p>	if (file->private_data == NULL) {<br />
		rc = -EBADF;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}<br />
	open_file = (struct cifsFileInfo *)file->private_data;</p>
<p>	if ((file->f_flags &#038; O_ACCMODE) == O_WRONLY)<br />
		cFYI(1, (&raquo;attempting read on write only file instance&raquo;));</p>
<p>	for (total_read = 0, current_offset = read_data;<br />
	     read_size > total_read;<br />
	     total_read += bytes_read, current_offset += bytes_read) {<br />
		current_read_size = min_t(const int, read_size &#8211; total_read,<br />
					  cifs_sb->rsize);<br />
		/* For windows me and 9x we do not want to request more<br />
		than it negotiated since it will refuse the read then */<br />
		if ((pTcon->ses) &#038;&#038;<br />
			!(pTcon->ses->capabilities &#038; CAP_LARGE_FILES)) {<br />
			current_read_size = min_t(const int, current_read_size,<br />
					pTcon->ses->server->maxBuf &#8211; 128);<br />
		}<br />
		rc = -EAGAIN;<br />
		while (rc == -EAGAIN) {<br />
			if ((open_file->invalidHandle) &#038;&#038;<br />
			    (!open_file->closePend)) {<br />
				rc = cifs_reopen_file(file, true);<br />
				if (rc != 0)<br />
					break;<br />
			}<br />
			rc = CIFSSMBRead(xid, pTcon,<br />
					 open_file->netfid,<br />
					 current_read_size, *poffset,<br />
					 &#038;bytes_read, &#038;current_offset,<br />
					 &#038;buf_type);<br />
		}<br />
		if (rc || (bytes_read == 0)) {<br />
			if (total_read) {<br />
				break;<br />
			} else {<br />
				FreeXid(xid);<br />
				return rc;<br />
			}<br />
		} else {<br />
			cifs_stats_bytes_read(pTcon, total_read);<br />
			*poffset += bytes_read;<br />
		}<br />
	}<br />
	FreeXid(xid);<br />
	return total_read;<br />
}</p>
<p>int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)<br />
{<br />
	struct dentry *dentry = file->f_path.dentry;<br />
	int rc, xid;</p>
<p>	xid = GetXid();<br />
	rc = cifs_revalidate(dentry);<br />
	if (rc) {<br />
		cFYI(1, (&raquo;Validation prior to mmap failed, error=%d&raquo;, rc));<br />
		FreeXid(xid);<br />
		return rc;<br />
	}<br />
	rc = generic_file_mmap(file, vma);<br />
	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>static void cifs_copy_cache_pages(struct address_space *mapping,<br />
	struct list_head *pages, int bytes_read, char *data,<br />
	struct pagevec *plru_pvec)<br />
{<br />
	struct page *page;<br />
	char *target;</p>
<p>	while (bytes_read > 0) {<br />
		if (list_empty(pages))<br />
			break;</p>
<p>		page = list_entry(pages->prev, struct page, lru);<br />
		list_del(&#038;page->lru);</p>
<p>		if (add_to_page_cache(page, mapping, page->index,<br />
				      GFP_KERNEL)) {<br />
			page_cache_release(page);<br />
			cFYI(1, (&raquo;Add page cache failed&raquo;));<br />
			data += PAGE_CACHE_SIZE;<br />
			bytes_read -= PAGE_CACHE_SIZE;<br />
			continue;<br />
		}</p>
<p>		target = kmap_atomic(page, KM_USER0);</p>
<p>		if (PAGE_CACHE_SIZE > bytes_read) {<br />
			memcpy(target, data, bytes_read);<br />
			/* zero the tail end of this partial page */<br />
			memset(target + bytes_read, 0,<br />
			       PAGE_CACHE_SIZE &#8211; bytes_read);<br />
			bytes_read = 0;<br />
		} else {<br />
			memcpy(target, data, PAGE_CACHE_SIZE);<br />
			bytes_read -= PAGE_CACHE_SIZE;<br />
		}<br />
		kunmap_atomic(target, KM_USER0);</p>
<p>		flush_dcache_page(page);<br />
		SetPageUptodate(page);<br />
		unlock_page(page);<br />
		if (!pagevec_add(plru_pvec, page))<br />
			__pagevec_lru_add_file(plru_pvec);<br />
		data += PAGE_CACHE_SIZE;<br />
	}<br />
	return;<br />
}</p>
<p>static int cifs_readpages(struct file *file, struct address_space *mapping,<br />
	struct list_head *page_list, unsigned num_pages)<br />
{<br />
	int rc = -EACCES;<br />
	int xid;<br />
	loff_t offset;<br />
	struct page *page;<br />
	struct cifs_sb_info *cifs_sb;<br />
	struct cifsTconInfo *pTcon;<br />
	unsigned int bytes_read = 0;<br />
	unsigned int read_size, i;<br />
	char *smb_read_data = NULL;<br />
	struct smb_com_read_rsp *pSMBr;<br />
	struct pagevec lru_pvec;<br />
	struct cifsFileInfo *open_file;<br />
	int buf_type = CIFS_NO_BUFFER;</p>
<p>	xid = GetXid();<br />
	if (file->private_data == NULL) {<br />
		rc = -EBADF;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}<br />
	open_file = (struct cifsFileInfo *)file->private_data;<br />
	cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);<br />
	pTcon = cifs_sb->tcon;</p>
<p>	pagevec_init(&#038;lru_pvec, 0);<br />
	cFYI(DBG2, (&raquo;rpages: num pages %d&raquo;, num_pages));<br />
	for (i = 0; i < num_pages; ) {<br />
		unsigned contig_pages;<br />
		struct page *tmp_page;<br />
		unsigned long expected_index;</p>
<p>		if (list_empty(page_list))<br />
			break;</p>
<p>		page = list_entry(page_list->prev, struct page, lru);<br />
		offset = (loff_t)page->index << PAGE_CACHE_SHIFT;</p>
<p>		/* count adjacent pages that we will read into */<br />
		contig_pages = 0;<br />
		expected_index =<br />
			list_entry(page_list->prev, struct page, lru)->index;<br />
		list_for_each_entry_reverse(tmp_page, page_list, lru) {<br />
			if (tmp_page->index == expected_index) {<br />
				contig_pages++;<br />
				expected_index++;<br />
			} else<br />
				break;<br />
		}<br />
		if (contig_pages + i >  num_pages)<br />
			contig_pages = num_pages &#8211; i;</p>
<p>		/* for reads over a certain size could initiate async<br />
		   read ahead */</p>
<p>		read_size = contig_pages * PAGE_CACHE_SIZE;<br />
		/* Read size needs to be in multiples of one page */<br />
		read_size = min_t(const unsigned int, read_size,<br />
				  cifs_sb->rsize &#038; PAGE_CACHE_MASK);<br />
		cFYI(DBG2, (&raquo;rpages: read size 0x%x  contiguous pages %d&raquo;,<br />
				read_size, contig_pages));<br />
		rc = -EAGAIN;<br />
		while (rc == -EAGAIN) {<br />
			if ((open_file->invalidHandle) &#038;&#038;<br />
			    (!open_file->closePend)) {<br />
				rc = cifs_reopen_file(file, true);<br />
				if (rc != 0)<br />
					break;<br />
			}</p>
<p>			rc = CIFSSMBRead(xid, pTcon,<br />
					 open_file->netfid,<br />
					 read_size, offset,<br />
					 &#038;bytes_read, &#038;smb_read_data,<br />
					 &#038;buf_type);<br />
			/* BB more RC checks ? */<br />
			if (rc == -EAGAIN) {<br />
				if (smb_read_data) {<br />
					if (buf_type == CIFS_SMALL_BUFFER)<br />
						cifs_small_buf_release(smb_read_data);<br />
					else if (buf_type == CIFS_LARGE_BUFFER)<br />
						cifs_buf_release(smb_read_data);<br />
					smb_read_data = NULL;<br />
				}<br />
			}<br />
		}<br />
		if ((rc < 0) || (smb_read_data == NULL)) {<br />
			cFYI(1, ("Read error in readpages: %d", rc));<br />
			break;<br />
		} else if (bytes_read > 0) {<br />
			task_io_account_read(bytes_read);<br />
			pSMBr = (struct smb_com_read_rsp *)smb_read_data;<br />
			cifs_copy_cache_pages(mapping, page_list, bytes_read,<br />
				smb_read_data + 4 /* RFC1001 hdr */ +<br />
				le16_to_cpu(pSMBr->DataOffset), &#038;lru_pvec);</p>
<p>			i +=  bytes_read >> PAGE_CACHE_SHIFT;<br />
			cifs_stats_bytes_read(pTcon, bytes_read);<br />
			if ((bytes_read &#038; PAGE_CACHE_MASK) != bytes_read) {<br />
				i++; /* account for partial page */</p>
<p>				/* server copy of file can have smaller size<br />
				   than client */<br />
				/* BB do we need to verify this common case ?<br />
				   this case is ok &#8211; if we are at server EOF<br />
				   we will hit it on next read */</p>
<p>				/* break; */<br />
			}<br />
		} else {<br />
			cFYI(1, (&raquo;No bytes read (%d) at offset %lld . &raquo;<br />
				 &laquo;Cleaning remaining pages from readahead list&raquo;,<br />
				 bytes_read, offset));<br />
			/* BB turn off caching and do new lookup on<br />
			   file size at server? */<br />
			break;<br />
		}<br />
		if (smb_read_data) {<br />
			if (buf_type == CIFS_SMALL_BUFFER)<br />
				cifs_small_buf_release(smb_read_data);<br />
			else if (buf_type == CIFS_LARGE_BUFFER)<br />
				cifs_buf_release(smb_read_data);<br />
			smb_read_data = NULL;<br />
		}<br />
		bytes_read = 0;<br />
	}</p>
<p>	pagevec_lru_add_file(&#038;lru_pvec);</p>
<p>/* need to free smb_read_data buf before exit */<br />
	if (smb_read_data) {<br />
		if (buf_type == CIFS_SMALL_BUFFER)<br />
			cifs_small_buf_release(smb_read_data);<br />
		else if (buf_type == CIFS_LARGE_BUFFER)<br />
			cifs_buf_release(smb_read_data);<br />
		smb_read_data = NULL;<br />
	}</p>
<p>	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>static int cifs_readpage_worker(struct file *file, struct page *page,<br />
	loff_t *poffset)<br />
{<br />
	char *read_data;<br />
	int rc;</p>
<p>	page_cache_get(page);<br />
	read_data = kmap(page);<br />
	/* for reads over a certain size could initiate async read ahead */</p>
<p>	rc = cifs_read(file, read_data, PAGE_CACHE_SIZE, poffset);</p>
<p>	if (rc < 0)<br />
		goto io_error;<br />
	else<br />
		cFYI(1, ("Bytes read %d", rc));</p>
<p>	file->f_path.dentry->d_inode->i_atime =<br />
		current_fs_time(file->f_path.dentry->d_inode->i_sb);</p>
<p>	if (PAGE_CACHE_SIZE > rc)<br />
		memset(read_data + rc, 0, PAGE_CACHE_SIZE &#8211; rc);</p>
<p>	flush_dcache_page(page);<br />
	SetPageUptodate(page);<br />
	rc = 0;</p>
<p>io_error:<br />
	kunmap(page);<br />
	page_cache_release(page);<br />
	return rc;<br />
}</p>
<p>static int cifs_readpage(struct file *file, struct page *page)<br />
{<br />
	loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;<br />
	int rc = -EACCES;<br />
	int xid;</p>
<p>	xid = GetXid();</p>
<p>	if (file->private_data == NULL) {<br />
		rc = -EBADF;<br />
		FreeXid(xid);<br />
		return rc;<br />
	}</p>
<p>	cFYI(1, (&raquo;readpage %p at offset %d 0x%x\n&raquo;,<br />
		 page, (int)offset, (int)offset));</p>
<p>	rc = cifs_readpage_worker(file, page, &#038;offset);</p>
<p>	unlock_page(page);</p>
<p>	FreeXid(xid);<br />
	return rc;<br />
}</p>
<p>static int is_inode_writable(struct cifsInodeInfo *cifs_inode)<br />
{<br />
	struct cifsFileInfo *open_file;</p>
<p>	read_lock(&#038;GlobalSMBSeslock);<br />
	list_for_each_entry(open_file, &#038;cifs_inode->openFileList, flist) {<br />
		if (open_file->closePend)<br />
			continue;<br />
		if (open_file->pfile &#038;&#038;<br />
		    ((open_file->pfile->f_flags &#038; O_RDWR) ||<br />
		     (open_file->pfile->f_flags &#038; O_WRONLY))) {<br />
			read_unlock(&#038;GlobalSMBSeslock);<br />
			return 1;<br />
		}<br />
	}<br />
	read_unlock(&#038;GlobalSMBSeslock);<br />
	return 0;<br />
}</p>
<p>/* We do not want to update the file size from server for inodes<br />
   open for write &#8211; to avoid races with writepage extending<br />
   the file &#8211; in the future we could consider allowing<br />
   refreshing the inode only on increases in the file size<br />
   but this is tricky to do without racing with writebehind<br />
   page caching in the current Linux kernel design */<br />
bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file)<br />
{<br />
	if (!cifsInode)<br />
		return true;</p>
<p>	if (is_inode_writable(cifsInode)) {<br />
		/* This inode is open for write at least once */<br />
		struct cifs_sb_info *cifs_sb;</p>
<p>		cifs_sb = CIFS_SB(cifsInode->vfs_inode.i_sb);<br />
		if (cifs_sb->mnt_cifs_flags &#038; CIFS_MOUNT_DIRECT_IO) {<br />
			/* since no page cache to corrupt on directio<br />
			we can change size safely */<br />
			return true;<br />
		}</p>
<p>		if (i_size_read(&#038;cifsInode->vfs_inode) < end_of_file)<br />
			return true;</p>
<p>		return false;<br />
	} else<br />
		return true;<br />
}</p>
<p>static int cifs_write_begin(struct file *file, struct address_space *mapping,<br />
			loff_t pos, unsigned len, unsigned flags,<br />
			struct page **pagep, void **fsdata)<br />
{<br />
	pgoff_t index = pos >> PAGE_CACHE_SHIFT;<br />
	loff_t offset = pos &#038; (PAGE_CACHE_SIZE &#8211; 1);<br />
	loff_t page_start = pos &#038; PAGE_MASK;<br />
	loff_t i_size;<br />
	struct page *page;<br />
	int rc = 0;</p>
<p>	cFYI(1, (&raquo;write_begin from %lld len %d&raquo;, (long long)pos, len));</p>
<p>	page = grab_cache_page_write_begin(mapping, index, flags);<br />
	if (!page) {<br />
		rc = -ENOMEM;<br />
		goto out;<br />
	}</p>
<p>	if (PageUptodate(page))<br />
		goto out;</p>
<p>	/*<br />
	 * If we write a full page it will be up to date, no need to read from<br />
	 * the server. If the write is short, we&#8217;ll end up doing a sync write<br />
	 * instead.<br />
	 */<br />
	if (len == PAGE_CACHE_SIZE)<br />
		goto out;</p>
<p>	/*<br />
	 * optimize away the read when we have an oplock, and we&#8217;re not<br />
	 * expecting to use any of the data we&#8217;d be reading in. That<br />
	 * is, when the page lies beyond the EOF, or straddles the EOF<br />
	 * and the write will cover all of the existing data.<br />
	 */<br />
	if (CIFS_I(mapping->host)->clientCanCacheRead) {<br />
		i_size = i_size_read(mapping->host);<br />
		if (page_start >= i_size ||<br />
		    (offset == 0 &#038;&#038; (pos + len) >= i_size)) {<br />
			zero_user_segments(page, 0, offset,<br />
					   offset + len,<br />
					   PAGE_CACHE_SIZE);<br />
			/*<br />
			 * PageChecked means that the parts of the page<br />
			 * to which we&#8217;re not writing are considered up<br />
			 * to date. Once the data is copied to the<br />
			 * page, it can be set uptodate.<br />
			 */<br />
			SetPageChecked(page);<br />
			goto out;<br />
		}<br />
	}</p>
<p>	if ((file->f_flags &#038; O_ACCMODE) != O_WRONLY) {<br />
		/*<br />
		 * might as well read a page, it is fast enough. If we get<br />
		 * an error, we don&#8217;t need to return it. cifs_write_end will<br />
		 * do a sync write instead since PG_uptodate isn&#8217;t set.<br />
		 */<br />
		cifs_readpage_worker(file, page, &#038;page_start);<br />
	} else {<br />
		/* we could try using another file handle if there is one -<br />
		   but how would we lock it to prevent close of that handle<br />
		   racing with this read? In any case<br />
		   this will be written out by write_end so is fine */<br />
	}<br />
out:<br />
	*pagep = page;<br />
	return rc;<br />
}</p>
<p>static void<br />
cifs_oplock_break(struct slow_work *work)<br />
{<br />
	struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,<br />
						  oplock_break);<br />
	struct inode *inode = cfile->pInode;<br />
	struct cifsInodeInfo *cinode = CIFS_I(inode);<br />
	struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->mnt->mnt_sb);<br />
	int rc, waitrc = 0;</p>
<p>	if (inode &#038;&#038; S_ISREG(inode->i_mode)) {<br />
#ifdef CONFIG_CIFS_EXPERIMENTAL<br />
		if (cinode->clientCanCacheAll == 0)<br />
			break_lease(inode, FMODE_READ);<br />
		else if (cinode->clientCanCacheRead == 0)<br />
			break_lease(inode, FMODE_WRITE);<br />
#endif<br />
		rc = filemap_fdatawrite(inode->i_mapping);<br />
		if (cinode->clientCanCacheRead == 0) {<br />
			waitrc = filemap_fdatawait(inode->i_mapping);<br />
			invalidate_remote_inode(inode);<br />
		}<br />
		if (!rc)<br />
			rc = waitrc;<br />
		if (rc)<br />
			cinode->write_behind_rc = rc;<br />
		cFYI(1, (&raquo;Oplock flush inode %p rc %d&raquo;, inode, rc));<br />
	}</p>
<p>	/*<br />
	 * releasing stale oplock after recent reconnect of smb session using<br />
	 * a now incorrect file handle is not a data integrity issue but do<br />
	 * not bother sending an oplock release if session to server still is<br />
	 * disconnected since oplock already released by the server<br />
	 */<br />
	if (!cfile->closePend &#038;&#038; !cfile->oplock_break_cancelled) {<br />
		rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0,<br />
				 LOCKING_ANDX_OPLOCK_RELEASE, false);<br />
		cFYI(1, (&raquo;Oplock release rc = %d&raquo;, rc));<br />
	}<br />
}</p>
<p>static int<br />
cifs_oplock_break_get(struct slow_work *work)<br />
{<br />
	struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,<br />
						  oplock_break);<br />
	mntget(cfile->mnt);<br />
	cifsFileInfo_get(cfile);<br />
	return 0;<br />
}</p>
<p>static void<br />
cifs_oplock_break_put(struct slow_work *work)<br />
{<br />
	struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,<br />
						  oplock_break);<br />
	mntput(cfile->mnt);<br />
	cifsFileInfo_put(cfile);<br />
}</p>
<p>const struct slow_work_ops cifs_oplock_break_ops = {<br />
	.get_ref	= cifs_oplock_break_get,<br />
	.put_ref	= cifs_oplock_break_put,<br />
	.execute	= cifs_oplock_break,<br />
};</p>
<p>const struct address_space_operations cifs_addr_ops = {<br />
	.readpage = cifs_readpage,<br />
	.readpages = cifs_readpages,<br />
	.writepage = cifs_writepage,<br />
	.writepages = cifs_writepages,<br />
	.write_begin = cifs_write_begin,<br />
	.write_end = cifs_write_end,<br />
	.set_page_dirty = __set_page_dirty_nobuffers,<br />
	/* .sync_page = cifs_sync_page, */<br />
	/* .direct_IO = */<br />
};</p>
<p>/*<br />
 * cifs_readpages requires the server to support a buffer large enough to<br />
 * contain the header plus one complete page of data.  Otherwise, we need<br />
 * to leave cifs_readpages out of the address space operations.<br />
 */<br />
const struct address_space_operations cifs_addr_ops_smallbuf = {<br />
	.readpage = cifs_readpage,<br />
	.writepage = cifs_writepage,<br />
	.writepages = cifs_writepages,<br />
	.write_begin = cifs_write_begin,<br />
	.write_end = cifs_write_end,<br />
	.set_page_dirty = __set_page_dirty_nobuffers,<br />
	/* .sync_page = cifs_sync_page, */<br />
	/* .direct_IO = */<br />
};</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/file-c-7/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>export.c</title>
		<link>http://lynyrd.ru/export-c-2</link>
		<comments>http://lynyrd.ru/export-c-2#comments</comments>
		<pubDate>Sun, 31 Jan 2010 03:26:03 +0000</pubDate>
		<dc:creator>lynyrd</dc:creator>
				<category><![CDATA[dns_resolve]]></category>

		<guid isPermaLink="false">http://lynyrd.ru/export-c-2</guid>
		<description><![CDATA[/*
 *   fs/cifs/export.c
 *
 *   Copyright (C) International Business Machines  Corp., 2007
 *   Author(s): Steve French (sfrench@us.ibm.com)
 *
 *   Common Internet FileSystem (CIFS) client
 *
 *   Operations related to support for exporting files via NFSD
 *
 *   This library is free software; ]]></description>
			<content:encoded><![CDATA[<p>/*<br />
 *   fs/cifs/export.c<span id="more-938"></span><br />
 *<br />
 *   Copyright (C) International Business Machines  Corp., 2007<br />
 *   Author(s): Steve French (sfrench@us.ibm.com)<br />
 *<br />
 *   Common Internet FileSystem (CIFS) client<br />
 *<br />
 *   Operations related to support for exporting files via NFSD<br />
 *<br />
 *   This library is free software; you can redistribute it and/or modify<br />
 *   it under the terms of the GNU Lesser General Public License as published<br />
 *   by the Free Software Foundation; either version 2.1 of the License, or<br />
 *   (at your option) any later version.<br />
 *<br />
 *   This library is distributed in the hope that it will be useful,<br />
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See<br />
 *   the GNU Lesser General Public License for more details.<br />
 *<br />
 *   You should have received a copy of the GNU Lesser General Public License<br />
 *   along with this library; if not, write to the Free Software<br />
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br />
 */</p>
<p> /*<br />
  * See Documentation/filesystems/Exporting<br />
  * and examples in fs/exportfs<br />
  *<br />
  * Since cifs is a network file system, an &laquo;fsid&raquo; must be included for<br />
  * any nfs exports file entries which refer to cifs paths.  In addition<br />
  * the cifs mount must be mounted with the &laquo;serverino&raquo; option (ie use stable<br />
  * server inode numbers instead of locally generated temporary ones).<br />
  * Although cifs inodes do not use generation numbers (have generation number<br />
  * of zero) &#8211; the inode number alone should be good enough for simple cases<br />
  * in which users want to export cifs shares with NFS. The decode and encode<br />
  * could be improved by using a new routine which expects 64 bit inode numbers<br />
  * instead of the default 32 bit routines in fs/exportfs<br />
  *<br />
  */</p>
<p>#include
<linux/fs.h>
#include
<linux/exportfs.h>
#include &laquo;cifsglob.h&raquo;<br />
#include &laquo;cifs_debug.h&raquo;<br />
#include &laquo;cifsfs.h&raquo;</p>
<p>#ifdef CONFIG_CIFS_EXPERIMENTAL<br />
static struct dentry *cifs_get_parent(struct dentry *dentry)<br />
{<br />
	/* BB need to add code here eventually to enable export via NFSD */<br />
	cFYI(1, (&raquo;get parent for %p&raquo;, dentry));<br />
	return ERR_PTR(-EACCES);<br />
}</p>
<p>const struct export_operations cifs_export_ops = {<br />
	.get_parent = cifs_get_parent,<br />
/*	Following five export operations are unneeded so far and can default:<br />
	.get_dentry =<br />
	.get_name =<br />
	.find_exported_dentry =<br />
	.decode_fh =<br />
	.encode_fs =  */<br />
};</p>
<p>#endif /* EXPERIMENTAL */</p>
]]></content:encoded>
			<wfw:commentRss>http://lynyrd.ru/export-c-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
