/* * Copyright (c) 2000-2001 Boris Popov * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by Boris Popov. * 4. Neither the name of the author nor the names of any co-contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: smb_subr.c,v 1.27.108.1 2005/06/02 00:55:39 lindak Exp $ */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Portions Copyright (C) 2001 - 2013 Apple Inc. All rights reserved. * Copyright 2018 Nexenta Systems, Inc. All rights reserved. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void smb_credinit(struct smb_cred *scred, cred_t *cr) { /* cr arg is optional */ if (cr == NULL) cr = ddi_get_cred(); #ifdef _KERNEL if (is_system_labeled()) { cr = crdup(cr); (void) setpflags(NET_MAC_AWARE, 1, cr); } else #endif { crhold(cr); } scred->scr_cred = cr; } void smb_credrele(struct smb_cred *scred) { if (scred->scr_cred != NULL) { crfree(scred->scr_cred); scred->scr_cred = NULL; } } #ifndef _KERNEL /* ARGSUSED */ void smb_debugmsg(const char *func, char *msg) { } #endif /* _KERNEL */ /* * Helper for the SMBERROR macro, etc. * This is also a good place for a breakpoint * or a dtrace probe, i.e. fbt:nsmb:smb_errmsg */ void smb_errmsg(int cel, const char *func_name, const char *fmt, ...) { va_list adx; char buf[100]; va_start(adx, fmt); if (cel == CE_CONT) { /* * This is one of our xxxDEBUG macros. * Don't bother to log these, but just * fire a dtrace probe with the message. */ (void) vsnprintf(buf, sizeof (buf), fmt, adx); DTRACE_PROBE2(debugmsg2, (char *), func_name, (char *), buf); #ifndef _KERNEL smb_debugmsg(func_name, buf); #endif } else { /* * This is one of our xxxERROR macros. * Add a prefix to the fmt string, * then let vcmn_err do the args. */ (void) snprintf(buf, sizeof (buf), "?%s: %s", func_name, fmt); DTRACE_PROBE3(debugmsg3, (char *), func_name, (char *), buf, va_list, adx); vcmn_err(cel, buf, adx); } va_end(adx); } #if 1 /* def SMB_SOCKETDATA_DEBUG */ void m_dumpm(mblk_t *m) { int len, seg; len = msgdsize(m); DTRACE_PROBE2(dsize, int, len, (mblk_t *), m); for (seg = 0; m; seg++) { DTRACE_PROBE2(mblk, int, seg, (mblk_t *), m); m = m->b_cont; } } #endif #ifndef EPROTO #define EPROTO ECONNABORTED #endif #ifndef ELIBACC #define ELIBACC ENOENT #endif #ifndef ENODATA #define ENODATA EINVAL #endif #ifndef ENOTUNIQ #define ENOTUNIQ EADDRINUSE #endif #ifndef ECOMM #define ECOMM EIO #endif #ifndef ENOMEDIUM #define ENOMEDIUM ENXIO #endif #ifndef ETIME #define ETIME ETIMEDOUT #endif #ifndef EMOREDATA #define EMOREDATA (0x7fff) #endif /* * Log any un-handled NT or DOS errors we encounter. * Make these log NOTICE in a debug build to ensure * they get noticed during tests. In the field these * are unimportant, so just fire a Dtrace probe. */ static int unknown_err_logpri = #ifdef DEBUG CE_NOTE; #else CE_CONT; #endif typedef struct nt2errno { unsigned int nterr; int errno; } nt2errno_t; static const nt2errno_t nt2errno[] = { /* Alphabetical order. */ {NT_STATUS_ACCESS_DENIED, EACCES}, {NT_STATUS_ACCESS_VIOLATION, EACCES}, {NT_STATUS_ACCOUNT_DISABLED, EACCES}, {NT_STATUS_ACCOUNT_EXPIRED, EACCES}, {NT_STATUS_ACCOUNT_LOCKED_OUT, EACCES}, {NT_STATUS_ACCOUNT_RESTRICTION, EACCES}, {NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE}, {NT_STATUS_BAD_NETWORK_NAME, ENOENT}, {NT_STATUS_BAD_NETWORK_PATH, ENOENT}, {NT_STATUS_BUFFER_TOO_SMALL, E2BIG}, {NT_STATUS_CANCELLED, ECANCELED}, {NT_STATUS_CANNOT_DELETE, EACCES}, {NT_STATUS_CONFLICTING_ADDRESSES, EADDRINUSE}, {NT_STATUS_CONNECTION_ABORTED, ECONNABORTED}, {NT_STATUS_CONNECTION_DISCONNECTED, ECONNABORTED}, {NT_STATUS_CONNECTION_REFUSED, ECONNREFUSED}, {NT_STATUS_CONNECTION_RESET, ENETRESET}, {NT_STATUS_DELETE_PENDING, EACCES}, {NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV}, {NT_STATUS_DEVICE_PROTOCOL_ERROR, EPROTO}, {NT_STATUS_DIRECTORY_NOT_EMPTY, ENOTEMPTY}, {NT_STATUS_DISK_FULL, ENOSPC}, {NT_STATUS_DLL_NOT_FOUND, ELIBACC}, {NT_STATUS_DUPLICATE_NAME, EINVAL}, {NT_STATUS_EAS_NOT_SUPPORTED, ENOTSUP}, {NT_STATUS_EA_TOO_LARGE, E2BIG}, {NT_STATUS_END_OF_FILE, ENODATA}, {NT_STATUS_FILE_CLOSED, EBADF}, {NT_STATUS_FILE_DELETED, ENOENT}, {NT_STATUS_FILE_INVALID, EIO}, {NT_STATUS_FILE_IS_A_DIRECTORY, EISDIR}, {NT_STATUS_FILE_LOCK_CONFLICT, EAGAIN}, {NT_STATUS_FILE_RENAMED, ENOENT}, {NT_STATUS_FLOAT_INEXACT_RESULT, ERANGE}, {NT_STATUS_FLOAT_OVERFLOW, ERANGE}, {NT_STATUS_FLOAT_UNDERFLOW, ERANGE}, {NT_STATUS_HOST_UNREACHABLE, EHOSTUNREACH}, {NT_STATUS_ILL_FORMED_PASSWORD, EAUTH}, {NT_STATUS_INFO_LENGTH_MISMATCH, EINVAL}, {NT_STATUS_INSUFFICIENT_RESOURCES, EAGAIN}, {NT_STATUS_INSUFF_SERVER_RESOURCES, EAGAIN}, {NT_STATUS_INTEGER_OVERFLOW, ERANGE}, {NT_STATUS_INVALID_ACCOUNT_NAME, EAUTH}, {NT_STATUS_INVALID_BUFFER_SIZE, EIO}, {NT_STATUS_INVALID_DEVICE_REQUEST, EINVAL}, {NT_STATUS_INVALID_HANDLE, EBADF}, {NT_STATUS_INVALID_INFO_CLASS, EINVAL}, {NT_STATUS_INVALID_LEVEL, ENOTSUP}, {NT_STATUS_INVALID_LOCK_SEQUENCE, EINVAL}, {NT_STATUS_INVALID_LOGON_HOURS, EAUTH}, {NT_STATUS_INVALID_OWNER, EINVAL}, {NT_STATUS_INVALID_PARAMETER, EINVAL}, {NT_STATUS_INVALID_PIPE_STATE, EPIPE}, {NT_STATUS_INVALID_PRIMARY_GROUP, EINVAL}, {NT_STATUS_INVALID_WORKSTATION, EACCES}, {NT_STATUS_IN_PAGE_ERROR, EFAULT}, {NT_STATUS_IO_DEVICE_ERROR, EIO}, {NT_STATUS_IO_TIMEOUT, ETIMEDOUT}, {NT_STATUS_IP_ADDRESS_CONFLICT1, EADDRINUSE}, {NT_STATUS_IP_ADDRESS_CONFLICT2, EADDRINUSE}, {NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT}, {NT_STATUS_LOCK_NOT_GRANTED, EAGAIN}, {NT_STATUS_LOGIN_TIME_RESTRICTION, EAUTH}, {NT_STATUS_LOGON_FAILURE, EAUTH}, {NT_STATUS_LOGON_TYPE_NOT_GRANTED, EAUTH}, {NT_STATUS_MEDIA_WRITE_PROTECTED, EROFS}, {NT_STATUS_MEMORY_NOT_ALLOCATED, EFAULT}, {NT_STATUS_MORE_PROCESSING_REQUIRED, EINPROGRESS}, {NT_STATUS_NAME_TOO_LONG, ENAMETOOLONG}, {NT_STATUS_NETWORK_ACCESS_DENIED, EACCES}, {NT_STATUS_NETWORK_BUSY, EBUSY}, {NT_STATUS_NETWORK_NAME_DELETED, ENOENT}, {NT_STATUS_NETWORK_UNREACHABLE, ENETUNREACH}, {NT_STATUS_NET_WRITE_FAULT, ECOMM}, {NT_STATUS_NONEXISTENT_EA_ENTRY, ENOENT}, {NT_STATUS_NONEXISTENT_SECTOR, ESPIPE}, {NT_STATUS_NONE_MAPPED, EINVAL}, {NT_STATUS_NOT_A_DIRECTORY, ENOTDIR}, {NT_STATUS_NOT_FOUND, ENOENT}, {NT_STATUS_NOT_IMPLEMENTED, ENOTSUP}, {NT_STATUS_NOT_LOCKED, ENOLCK}, {NT_STATUS_NOT_MAPPED_VIEW, EINVAL}, {NT_STATUS_NOT_SUPPORTED, ENOTSUP}, {NT_STATUS_NO_EAS_ON_FILE, ENOENT}, {NT_STATUS_NO_LOGON_SERVERS, EAUTH}, {NT_STATUS_NO_MEDIA, ENOMEDIUM}, {NT_STATUS_NO_MEDIA_IN_DEVICE, ENOMEDIUM}, {NT_STATUS_NO_MEMORY, ENOMEM}, {NT_STATUS_NO_SUCH_DEVICE, ENODEV}, {NT_STATUS_NO_SUCH_FILE, ENOENT}, {NT_STATUS_NO_SUCH_LOGON_SESSION, EAUTH}, {NT_STATUS_NO_SUCH_USER, EAUTH}, {NT_STATUS_NO_TRUST_LSA_SECRET, EAUTH}, {NT_STATUS_NO_TRUST_SAM_ACCOUNT, EAUTH}, {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST}, {NT_STATUS_OBJECT_NAME_INVALID, EINVAL}, {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT}, {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR}, {NT_STATUS_OBJECT_PATH_NOT_FOUND, ENOENT}, {NT_STATUS_OBJECT_PATH_SYNTAX_BAD, EINVAL}, {NT_STATUS_OBJECT_TYPE_MISMATCH, EBADF}, {NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, {NT_STATUS_PASSWORD_EXPIRED, EAUTH}, {NT_STATUS_PASSWORD_MUST_CHANGE, EAUTH}, {NT_STATUS_PASSWORD_RESTRICTION, EAUTH}, {NT_STATUS_PATH_NOT_COVERED, ENOENT}, {NT_STATUS_PIPE_BROKEN, EPIPE}, {NT_STATUS_PIPE_BUSY, EPIPE}, {NT_STATUS_PIPE_CONNECTED, EISCONN}, {NT_STATUS_PIPE_DISCONNECTED, EPIPE}, {NT_STATUS_PIPE_NOT_AVAILABLE, EBUSY}, {NT_STATUS_PORT_CONNECTION_REFUSED, ECONNREFUSED}, {NT_STATUS_PORT_DISCONNECTED, EBADF}, {NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE}, {NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH}, {NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT}, {NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, {NT_STATUS_RANGE_NOT_LOCKED, EAGAIN}, /* like F_SETLK */ {NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT}, {NT_STATUS_REMOTE_DISCONNECT, ESHUTDOWN}, {NT_STATUS_REMOTE_NOT_LISTENING, ECONNREFUSED}, {NT_STATUS_REQUEST_NOT_ACCEPTED, EACCES}, {NT_STATUS_RETRY, EAGAIN}, {NT_STATUS_SHARING_VIOLATION, EBUSY}, {NT_STATUS_TIMER_NOT_CANCELED, ETIME}, {NT_STATUS_TOO_MANY_LINKS, EMLINK}, {NT_STATUS_TOO_MANY_OPENED_FILES, EMFILE}, {NT_STATUS_TRUSTED_DOMAIN_FAILURE, EAUTH}, {NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE, EAUTH}, {NT_STATUS_UNABLE_TO_FREE_VM, EADDRINUSE}, {NT_STATUS_UNSUCCESSFUL, EINVAL}, {NT_STATUS_WRONG_PASSWORD, EAUTH}, {0, 0} }; /* * Table for converting NT STATUS values to DOS class/code. * Rows ordered by integer value of last column (NT STATUS) */ typedef struct nt2doserr { unsigned short dclass; unsigned short derr; unsigned int nterr; } nt2doserr_t; static const nt2doserr_t nt2doserr[] = { {ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_INFO_CLASS}, {ERRDOS, ERROR_BAD_LENGTH, NT_STATUS_INFO_LENGTH_MISMATCH}, {ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, {ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA}, {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_INITIAL_STACK}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_BAD_INITIAL_PC}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_CID}, {ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER}, {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, {ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, {ERRDOS, ERROR_HANDLE_EOF, NT_STATUS_END_OF_FILE}, {ERRDOS, ERROR_WRONG_DISK, NT_STATUS_WRONG_VOLUME}, {ERRDOS, ERROR_NOT_READY, NT_STATUS_NO_MEDIA_IN_DEVICE}, {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, {ERRDOS, ERROR_SECTOR_NOT_FOUND, NT_STATUS_NONEXISTENT_SECTOR}, {ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, {ERRDOS, ERROR_INVALID_ADDRESS, NT_STATUS_CONFLICTING_ADDRESSES}, {ERRDOS, ERROR_INVALID_ADDRESS, NT_STATUS_NOT_MAPPED_VIEW}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_UNABLE_TO_FREE_VM}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_UNABLE_TO_DELETE_SECTION}, {ERRDOS, NERR_InvalidAPI, NT_STATUS_INVALID_SYSTEM_SERVICE}, {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_INSTRUCTION}, {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_VIEW_SIZE}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_INVALID_FILE_FOR_SECTION}, {ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED}, {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, {ERRDOS, ERROR_BUFFER_OVERFLOW, NT_STATUS_BUFFER_TOO_SMALL}, {ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, {ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION}, {ERRHRD, ERRgeneral, NT_STATUS_UNWIND}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_STACK}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_UNWIND_TARGET}, {ERRDOS, ERROR_NOT_LOCKED, NT_STATUS_NOT_LOCKED}, {ERRHRD, ERRgeneral, NT_STATUS_PARITY_ERROR}, {ERRDOS, ERROR_INVALID_ADDRESS, NT_STATUS_UNABLE_TO_DECOMMIT_VM}, {ERRDOS, ERROR_INVALID_ADDRESS, NT_STATUS_NOT_COMMITTED}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PORT_ATTRIBUTES}, {ERRHRD, ERRgeneral, NT_STATUS_PORT_MESSAGE_TOO_LONG}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_MIX}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, {ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, {ERRDOS, ERROR_INVALID_NAME, NT_STATUS_OBJECT_NAME_INVALID}, {ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, {ERRDOS, ERROR_ALREADY_EXISTS, NT_STATUS_OBJECT_NAME_COLLISION}, {ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, {ERRDOS, ERROR_BAD_PATHNAME, NT_STATUS_OBJECT_PATH_INVALID}, {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, {ERRDOS, ERROR_BAD_PATHNAME, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, {ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN}, {ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR}, {ERRDOS, ERROR_CRC, NT_STATUS_DATA_ERROR}, {ERRDOS, ERROR_CRC, NT_STATUS_CRC_ERROR}, {ERRDOS, ERRnomem, NT_STATUS_SECTION_TOO_BIG}, {ERRDOS, ERRnoaccess, NT_STATUS_PORT_CONNECTION_REFUSED}, {ERRDOS, ERRbadfid, NT_STATUS_INVALID_PORT_HANDLE}, {ERRDOS, ERROR_SHARING_VIOLATION, NT_STATUS_SHARING_VIOLATION}, {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_EXCEEDED}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PAGE_PROTECTION}, {ERRDOS, ERROR_NOT_OWNER, NT_STATUS_MUTANT_NOT_OWNED}, {ERRDOS, ERROR_TOO_MANY_POSTS, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_PORT_ALREADY_SET}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_SECTION_NOT_IMAGE}, {ERRDOS, ERROR_SIGNAL_REFUSED, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, {ERRDOS, ERRnoaccess, NT_STATUS_THREAD_IS_TERMINATING}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_BAD_WORKING_SET_LIMIT}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INCOMPATIBLE_FILE_MAP}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_SECTION_PROTECTION}, {ERRDOS, ERROR_EAS_NOT_SUPPORTED, NT_STATUS_EAS_NOT_SUPPORTED}, {ERRDOS, ERROR_EA_LIST_INCONSISTENT, NT_STATUS_EA_TOO_LARGE}, {ERRHRD, ERRgeneral, NT_STATUS_NONEXISTENT_EA_ENTRY}, {ERRHRD, ERRgeneral, NT_STATUS_NO_EAS_ON_FILE}, {ERRHRD, ERRgeneral, NT_STATUS_EA_CORRUPT_ERROR}, {ERRDOS, ERROR_LOCK_VIOLATION, NT_STATUS_FILE_LOCK_CONFLICT}, {ERRDOS, ERROR_LOCK_VIOLATION, NT_STATUS_LOCK_NOT_GRANTED}, {ERRDOS, ERRnoaccess, NT_STATUS_DELETE_PENDING}, {ERRDOS, ERROR_NOT_SUPPORTED, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, {ERRHRD, ERRgeneral, NT_STATUS_UNKNOWN_REVISION}, {ERRHRD, ERRgeneral, NT_STATUS_REVISION_MISMATCH}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_OWNER}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PRIMARY_GROUP}, {ERRHRD, ERRgeneral, NT_STATUS_NO_IMPERSONATION_TOKEN}, {ERRHRD, ERRgeneral, NT_STATUS_CANT_DISABLE_MANDATORY}, {ERRDOS, NERR_LogonServerNotFound, NT_STATUS_NO_LOGON_SERVERS}, {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_LOGON_SESSION}, {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PRIVILEGE}, {ERRDOS, ERRnoaccess, NT_STATUS_PRIVILEGE_NOT_HELD}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, {ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS}, {ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, {ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, {ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN}, {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_PASSWORD}, {ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, {ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {ERRSRV, NERR_InvalidLogonHours, NT_STATUS_INVALID_LOGON_HOURS}, {ERRSRV, NERR_InvalidWorkstation, NT_STATUS_INVALID_WORKSTATION}, {ERRSRV, NERR_PasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, {ERRSRV, NERR_AccountExpired, NT_STATUS_ACCOUNT_DISABLED}, {ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SUB_AUTHORITY}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACL}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SID}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SECURITY_DESCR}, {ERRDOS, ERROR_PROC_NOT_FOUND, NT_STATUS_PROCEDURE_NOT_FOUND}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_INVALID_IMAGE_FORMAT}, {ERRHRD, ERRgeneral, NT_STATUS_NO_TOKEN}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_INHERITANCE_ACL}, {ERRDOS, ERROR_NOT_LOCKED, NT_STATUS_RANGE_NOT_LOCKED}, {ERRDOS, ERROR_DISK_FULL, NT_STATUS_DISK_FULL}, {ERRHRD, ERRgeneral, NT_STATUS_SERVER_DISABLED}, {ERRHRD, ERRgeneral, NT_STATUS_SERVER_NOT_DISABLED}, {ERRDOS, ERROR_TOO_MANY_NAMES, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, {ERRDOS, ERROR_NO_MORE_ITEMS, NT_STATUS_GUIDS_EXHAUSTED}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ID_AUTHORITY}, {ERRDOS, ERROR_NO_MORE_ITEMS, NT_STATUS_AGENTS_EXHAUSTED}, {ERRDOS, ERROR_LABEL_TOO_LONG, NT_STATUS_INVALID_VOLUME_LABEL}, {ERRDOS, ERROR_OUTOFMEMORY, NT_STATUS_SECTION_NOT_EXTENDED}, {ERRDOS, ERROR_INVALID_ADDRESS, NT_STATUS_NOT_MAPPED_DATA}, {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_DATA_NOT_FOUND}, {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_NAME_NOT_FOUND}, {ERRHRD, ERRgeneral, NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DENORMAL_OPERAND}, {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INEXACT_RESULT}, {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INVALID_OPERATION}, {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_OVERFLOW}, {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_STACK_CHECK}, {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_UNDERFLOW}, {ERRHRD, ERRgeneral, NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, {ERRDOS, ERROR_ARITHMETIC_OVERFLOW, NT_STATUS_INTEGER_OVERFLOW}, {ERRHRD, ERRgeneral, NT_STATUS_PRIVILEGED_INSTRUCTION}, {ERRDOS, ERRnomem, NT_STATUS_TOO_MANY_PAGING_FILES}, {ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, {ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, {ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, {ERRDOS, ERROR_CRC, NT_STATUS_DEVICE_DATA_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, {ERRDOS, ERROR_NOT_READY, NT_STATUS_DEVICE_POWER_FAILURE}, {ERRDOS, ERROR_INVALID_ADDRESS, NT_STATUS_FREE_VM_NOT_AT_BASE}, {ERRDOS, ERROR_INVALID_ADDRESS, NT_STATUS_MEMORY_NOT_ALLOCATED}, {ERRHRD, ERRgeneral, NT_STATUS_WORKING_SET_QUOTA}, {ERRDOS, ERROR_WRITE_PROTECT, NT_STATUS_MEDIA_WRITE_PROTECTED}, {ERRDOS, ERROR_NOT_READY, NT_STATUS_DEVICE_NOT_READY}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_GROUP_ATTRIBUTES}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_IMPERSONATION_LEVEL}, {ERRHRD, ERRgeneral, NT_STATUS_CANT_OPEN_ANONYMOUS}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_VALIDATION_CLASS}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_TOKEN_TYPE}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_BAD_MASTER_BOOT_RECORD}, {ERRHRD, ERRgeneral, NT_STATUS_INSTRUCTION_MISALIGNMENT}, {ERRDOS, ERROR_PIPE_BUSY, NT_STATUS_INSTANCE_NOT_AVAILABLE}, {ERRDOS, ERROR_PIPE_BUSY, NT_STATUS_PIPE_NOT_AVAILABLE}, {ERRDOS, ERROR_BAD_PIPE, NT_STATUS_INVALID_PIPE_STATE}, {ERRDOS, ERROR_PIPE_BUSY, NT_STATUS_PIPE_BUSY}, {ERRDOS, ERRbadfunc, NT_STATUS_ILLEGAL_FUNCTION}, {ERRDOS, ERROR_PIPE_NOT_CONNECTED, NT_STATUS_PIPE_DISCONNECTED}, {ERRDOS, ERROR_NO_DATA, NT_STATUS_PIPE_CLOSING}, {ERRHRD, ERRgeneral, NT_STATUS_PIPE_CONNECTED}, {ERRHRD, ERRgeneral, NT_STATUS_PIPE_LISTENING}, {ERRDOS, ERROR_BAD_PIPE, NT_STATUS_INVALID_READ_MODE}, {ERRDOS, ERROR_SEM_TIMEOUT, NT_STATUS_IO_TIMEOUT}, {ERRDOS, ERROR_HANDLE_EOF, NT_STATUS_FILE_FORCED_CLOSED}, {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STARTED}, {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STOPPED}, {ERRHRD, ERRgeneral, NT_STATUS_COULD_NOT_INTERPRET}, {ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, {ERRDOS, ERROR_NOT_SUPPORTED, NT_STATUS_NOT_SUPPORTED}, {ERRDOS, ERROR_REM_NOT_LIST, NT_STATUS_REMOTE_NOT_LISTENING}, {ERRDOS, ERROR_DUP_NAME, NT_STATUS_DUPLICATE_NAME}, {ERRDOS, ERROR_BAD_NETPATH, NT_STATUS_BAD_NETWORK_PATH}, {ERRDOS, ERROR_NETWORK_BUSY, NT_STATUS_NETWORK_BUSY}, {ERRDOS, ERROR_DEV_NOT_EXIST, NT_STATUS_DEVICE_DOES_NOT_EXIST}, {ERRDOS, ERROR_TOO_MANY_CMDS, NT_STATUS_TOO_MANY_COMMANDS}, {ERRDOS, ERROR_ADAP_HDW_ERR, NT_STATUS_ADAPTER_HARDWARE_ERROR}, {ERRDOS, ERROR_BAD_NET_RESP, NT_STATUS_INVALID_NETWORK_RESPONSE}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, {ERRDOS, ERROR_BAD_REM_ADAP, NT_STATUS_BAD_REMOTE_ADAPTER}, {ERRDOS, ERROR_PRINTQ_FULL, NT_STATUS_PRINT_QUEUE_FULL}, {ERRDOS, ERROR_NO_SPOOL_SPACE, NT_STATUS_NO_SPOOL_SPACE}, {ERRDOS, ERROR_PRINT_CANCELLED, NT_STATUS_PRINT_CANCELLED}, {ERRDOS, ERROR_NETNAME_DELETED, NT_STATUS_NETWORK_NAME_DELETED}, {ERRDOS, ERROR_NETWORK_ACCESS_DENIED, NT_STATUS_NETWORK_ACCESS_DENIED}, {ERRDOS, ERROR_BAD_DEV_TYPE, NT_STATUS_BAD_DEVICE_TYPE}, {ERRDOS, ERROR_BAD_NET_NAME, NT_STATUS_BAD_NETWORK_NAME}, {ERRDOS, ERROR_TOO_MANY_NAMES, NT_STATUS_TOO_MANY_NAMES}, {ERRDOS, ERROR_TOO_MANY_SESS, NT_STATUS_TOO_MANY_SESSIONS}, {ERRDOS, ERROR_SHARING_PAUSED, NT_STATUS_SHARING_PAUSED}, {ERRDOS, ERROR_REQ_NOT_ACCEP, NT_STATUS_REQUEST_NOT_ACCEPTED}, {ERRDOS, ERROR_REDIR_PAUSED, NT_STATUS_REDIRECTOR_PAUSED}, {ERRDOS, ERROR_NET_WRITE_FAULT, NT_STATUS_NET_WRITE_FAULT}, {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_AT_LIMIT}, {ERRDOS, ERROR_NOT_SAME_DEVICE, NT_STATUS_NOT_SAME_DEVICE}, {ERRDOS, ERRnoaccess, NT_STATUS_FILE_RENAMED}, {ERRDOS, ERROR_VC_DISCONNECTED, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_SECURITY_ON_OBJECT}, {ERRHRD, ERRgeneral, NT_STATUS_CANT_WAIT}, {ERRDOS, ERROR_NO_DATA, NT_STATUS_PIPE_EMPTY}, {ERRHRD, ERRgeneral, NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, {ERRHRD, ERRgeneral, NT_STATUS_CANT_TERMINATE_SELF}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SERVER_STATE}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_STATE}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_ROLE}, {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_DOMAIN}, {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_EXISTS}, {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, {ERRDOS, ERROR_OPLOCK_NOT_GRANTED, NT_STATUS_OPLOCK_NOT_GRANTED}, {ERRDOS, ERROR_INVALID_OPLOCK_PROTOCOL, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_CORRUPTION}, {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_GENERIC_NOT_MAPPED}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_DESCRIPTOR_FORMAT}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_USER_BUFFER}, {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_IO_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_CREATE_ERR}, {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_MAP_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_EXTEND_ERR}, {ERRHRD, ERRgeneral, NT_STATUS_NOT_LOGON_PROCESS}, {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_EXISTS}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_1}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_2}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_3}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_4}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_5}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_6}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_7}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_8}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_9}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_10}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_11}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_INVALID_PARAMETER_12}, {ERRDOS, ERRbadpath, NT_STATUS_REDIRECTOR_NOT_STARTED}, {ERRHRD, ERRgeneral, NT_STATUS_REDIRECTOR_STARTED}, {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW}, {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PACKAGE}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_FUNCTION_TABLE}, {ERRDOS, ERROR_ENVVAR_NOT_FOUND, NT_STATUS_VARIABLE_NOT_FOUND}, {ERRDOS, ERROR_DIR_NOT_EMPTY, NT_STATUS_DIRECTORY_NOT_EMPTY}, {ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR}, {ERRDOS, ERROR_DIRECTORY, NT_STATUS_NOT_A_DIRECTORY}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE}, {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION}, {ERRDOS, ERROR_FILENAME_EXCED_RANGE, NT_STATUS_NAME_TOO_LONG}, {ERRDOS, NERR_OpenFiles, NT_STATUS_FILES_OPEN}, {ERRDOS, NERR_DevInUse, NT_STATUS_CONNECTION_IN_USE}, {ERRHRD, ERRgeneral, NT_STATUS_MESSAGE_NOT_FOUND}, {ERRDOS, ERRnoaccess, NT_STATUS_PROCESS_IS_TERMINATING}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LOGON_TYPE}, {ERRHRD, ERRgeneral, NT_STATUS_NO_GUID_TRANSLATION}, {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_IMPERSONATE}, {ERRHRD, ERRgeneral, NT_STATUS_IMAGE_ALREADY_LOADED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_LDT}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_SIZE}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_OFFSET}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_DESCRIPTOR}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_INVALID_IMAGE_NE_FORMAT}, {ERRHRD, ERRgeneral, NT_STATUS_RXACT_INVALID_STATE}, {ERRHRD, ERRgeneral, NT_STATUS_RXACT_COMMIT_FAILURE}, {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_FILE_SIZE_ZERO}, {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, {ERRHRD, ERRgeneral, NT_STATUS_CANCELLED}, {ERRDOS, ERRnoaccess, NT_STATUS_CANNOT_DELETE}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_COMPUTER_NAME}, {ERRDOS, ERRnoaccess, NT_STATUS_FILE_DELETED}, {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_ACCOUNT}, {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_GROUP}, {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_USER}, {ERRHRD, ERRgeneral, NT_STATUS_MEMBERS_PRIMARY_GROUP}, {ERRDOS, ERRbadfid, NT_STATUS_FILE_CLOSED}, {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_THREADS}, {ERRHRD, ERRgeneral, NT_STATUS_THREAD_NOT_IN_PROCESS}, {ERRHRD, ERRgeneral, NT_STATUS_TOKEN_ALREADY_IN_USE}, {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA_EXCEEDED}, {ERRHRD, ERRgeneral, NT_STATUS_COMMITMENT_LIMIT}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_INVALID_IMAGE_LE_FORMAT}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_INVALID_IMAGE_NOT_MZ}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_INVALID_IMAGE_PROTECT}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_INVALID_IMAGE_WIN_16}, {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SERVER_CONFLICT}, {ERRHRD, ERRgeneral, NT_STATUS_TIME_DIFFERENCE_AT_DC}, {ERRHRD, ERRgeneral, NT_STATUS_SYNCHRONIZATION_REQUIRED}, {ERRDOS, ERROR_MOD_NOT_FOUND, NT_STATUS_DLL_NOT_FOUND}, {ERRHRD, ERRgeneral, NT_STATUS_OPEN_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_IO_PRIVILEGE_FAILED}, {ERRDOS, ERROR_INVALID_ORDINAL, NT_STATUS_ORDINAL_NOT_FOUND}, {ERRDOS, ERROR_PROC_NOT_FOUND, NT_STATUS_ENTRYPOINT_NOT_FOUND}, {ERRHRD, ERRgeneral, NT_STATUS_CONTROL_C_EXIT}, {ERRDOS, ERROR_NETNAME_DELETED, NT_STATUS_LOCAL_DISCONNECT}, {ERRDOS, ERROR_NETNAME_DELETED, NT_STATUS_REMOTE_DISCONNECT}, {ERRDOS, ERROR_REM_NOT_LIST, NT_STATUS_REMOTE_RESOURCES}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_LINK_FAILED}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_LINK_TIMEOUT}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_INVALID_CONNECTION}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_INVALID_ADDRESS}, {ERRHRD, ERRgeneral, NT_STATUS_DLL_INIT_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_MISSING_SYSTEMFILE}, {ERRHRD, ERRgeneral, NT_STATUS_UNHANDLED_EXCEPTION}, {ERRHRD, ERRgeneral, NT_STATUS_APP_INIT_FAILURE}, {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_CREATE_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_PAGEFILE}, {ERRDOS, ERROR_INVALID_LEVEL, NT_STATUS_INVALID_LEVEL}, {ERRDOS, ERROR_INVALID_PASSWORD, NT_STATUS_WRONG_PASSWORD_CORE}, {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_FLOAT_CONTEXT}, {ERRDOS, ERROR_BROKEN_PIPE, NT_STATUS_PIPE_BROKEN}, {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_CORRUPT}, {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_IO_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_EVENT_PAIR}, {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_VOLUME}, {ERRHRD, ERRgeneral, NT_STATUS_SERIAL_NO_DEVICE_INITED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_ALIAS}, {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_ALIAS}, {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_ALIAS}, {ERRHRD, ERRgeneral, NT_STATUS_ALIAS_EXISTS}, {ERRHRD, ERRgeneral, NT_STATUS_LOGON_NOT_GRANTED}, {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SECRETS}, {ERRHRD, ERRgeneral, NT_STATUS_SECRET_TOO_LONG}, {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_FULLSCREEN_MODE}, {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_CONTEXT_IDS}, {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_TYPE_NOT_GRANTED}, {ERRHRD, ERRgeneral, NT_STATUS_NOT_REGISTRY_FILE}, {ERRHRD, ERRgeneral, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_FT_MISSING_MEMBER}, {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_SERVICE_ENTRY}, {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_CHARACTER}, {ERRHRD, ERRgeneral, NT_STATUS_UNMAPPABLE_CHARACTER}, {ERRHRD, ERRgeneral, NT_STATUS_UNDEFINED_CHARACTER}, {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_VOLUME}, {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_WRONG_CYLINDER}, {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_UNKNOWN_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_BAD_REGISTERS}, {ERRHRD, ERRgeneral, NT_STATUS_DISK_RECALIBRATE_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_DISK_OPERATION_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_DISK_RESET_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_SHARED_IRQ_BUSY}, {ERRHRD, ERRgeneral, NT_STATUS_FT_ORPHANING}, {ERRHRD, ERRgeneral, NT_STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT}, {ERRHRD, ERRgeneral, NT_STATUS_PARTITION_FAILURE}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BLOCK_LENGTH}, {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_PARTITIONED}, {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_LOCK_MEDIA}, {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, {ERRHRD, ERRgeneral, NT_STATUS_EOM_OVERFLOW}, {ERRHRD, ERRgeneral, NT_STATUS_NO_MEDIA}, {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_MEMBER}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_MEMBER}, {ERRHRD, ERRgeneral, NT_STATUS_KEY_DELETED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_LOG_SPACE}, {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SIDS}, {ERRHRD, ERRgeneral, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, {ERRHRD, ERRgeneral, NT_STATUS_KEY_HAS_CHILDREN}, {ERRHRD, ERRgeneral, NT_STATUS_CHILD_MUST_BE_VOLATILE}, {ERRDOS, ERROR_INVALID_PARAMETER, NT_STATUS_DEVICE_CONFIGURATION_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_INTERNAL_ERROR}, {ERRDOS, ERROR_BAD_COMMAND, NT_STATUS_INVALID_DEVICE_STATE}, {ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_PROTOCOL_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_BACKUP_CONTROLLER}, {ERRHRD, ERRgeneral, NT_STATUS_LOG_FILE_FULL}, {ERRDOS, ERROR_WRITE_PROTECT, NT_STATUS_TOO_LATE}, {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET}, {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CORRUPT}, {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_CANT_START}, {ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, {ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, {ERRDOS, NERR_NetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, {ERRSRV, NERR_AccountExpired, NT_STATUS_ACCOUNT_EXPIRED}, {ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, {ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CHANGED}, {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, {ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, {ERRHRD, ERRgeneral, NT_STATUS_FS_DRIVER_REQUIRED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_USER_SESSION_DELETED}, {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, {ERRDOS, ERRnomem, NT_STATUS_INSUFF_SERVER_RESOURCES}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, {ERRDOS, ERROR_TOO_MANY_NAMES, NT_STATUS_TOO_MANY_ADDRESSES}, {ERRDOS, ERROR_DUP_NAME, NT_STATUS_ADDRESS_ALREADY_EXISTS}, {ERRDOS, ERROR_NETNAME_DELETED, NT_STATUS_ADDRESS_CLOSED}, {ERRDOS, ERROR_NETNAME_DELETED, NT_STATUS_CONNECTION_DISCONNECTED}, {ERRDOS, ERROR_NETNAME_DELETED, NT_STATUS_CONNECTION_RESET}, {ERRDOS, ERROR_TOO_MANY_NAMES, NT_STATUS_TOO_MANY_NODES}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_TRANSACTION_ABORTED}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_TRANSACTION_TIMED_OUT}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_TRANSACTION_NO_RELEASE}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_TRANSACTION_NO_MATCH}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_TRANSACTION_RESPONDED}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_TRANSACTION_INVALID_ID}, {ERRDOS, ERROR_UNEXP_NET_ERR, NT_STATUS_TRANSACTION_INVALID_TYPE}, {ERRDOS, ERROR_NOT_SUPPORTED, NT_STATUS_NOT_SERVER_SESSION}, {ERRDOS, ERROR_NOT_SUPPORTED, NT_STATUS_NOT_CLIENT_SESSION}, {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_LOAD_REGISTRY_FILE}, {ERRHRD, ERRgeneral, NT_STATUS_DEBUG_ATTACH_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_SYSTEM_PROCESS_TERMINATED}, {ERRHRD, ERRgeneral, NT_STATUS_DATA_NOT_ACCEPTED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, {ERRHRD, ERRgeneral, NT_STATUS_VDM_HARD_ERROR}, {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_CANCEL_TIMEOUT}, {ERRHRD, ERRgeneral, NT_STATUS_REPLY_MESSAGE_MISMATCH}, {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_ALIGNMENT}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, {ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, {ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, {ERRSRV, NERR_PasswordExpired, NT_STATUS_PASSWORD_MUST_CHANGE}, {ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, {ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, {ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW_READ}, {ERRHRD, ERRgeneral, NT_STATUS_FAIL_CHECK}, {ERRHRD, ERRgeneral, NT_STATUS_DUPLICATE_OBJECTID}, {ERRHRD, ERRgeneral, NT_STATUS_OBJECTID_EXISTS}, {ERRHRD, ERRgeneral, NT_STATUS_CONVERT_TO_LARGE}, {ERRHRD, ERRgeneral, NT_STATUS_RETRY}, {ERRHRD, ERRgeneral, NT_STATUS_FOUND_OUT_OF_SCOPE}, {ERRHRD, ERRgeneral, NT_STATUS_ALLOCATE_BUCKET}, {ERRHRD, ERRgeneral, NT_STATUS_PROPSET_NOT_FOUND}, {ERRHRD, ERRgeneral, NT_STATUS_MARSHALL_OVERFLOW}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_VARIANT}, {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, {ERRDOS, ERRnoaccess, NT_STATUS_ACCOUNT_LOCKED_OUT}, {ERRDOS, ERRbadfid, NT_STATUS_HANDLE_NOT_CLOSABLE}, {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED}, {ERRHRD, ERRgeneral, NT_STATUS_GRACEFUL_DISCONNECT}, {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_NOT_ASSOCIATED}, {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_INVALID}, {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ACTIVE}, {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE}, {ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE}, {ERRHRD, ERRgeneral, NT_STATUS_PROTOCOL_UNREACHABLE}, {ERRHRD, ERRgeneral, NT_STATUS_PORT_UNREACHABLE}, {ERRHRD, ERRgeneral, NT_STATUS_REQUEST_ABORTED}, {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_COMPRESSION_BUFFER}, {ERRHRD, ERRgeneral, NT_STATUS_USER_MAPPED_FILE}, {ERRHRD, ERRgeneral, NT_STATUS_AUDIT_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_TIMER_RESOLUTION_NOT_SET}, {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_COUNT_LIMIT}, {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_TIME_RESTRICTION}, {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_WKSTA_RESTRICTION}, {ERRDOS, ERROR_BAD_EXE_FORMAT, NT_STATUS_IMAGE_MP_UP_MISMATCH}, {ERRHRD, ERRgeneral, NT_STATUS_INSUFFICIENT_LOGON_INFO}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_DLL_ENTRYPOINT}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_SERVICE_ENTRYPOINT}, {ERRHRD, ERRgeneral, NT_STATUS_LPC_REPLY_LOST}, {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT1}, {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT2}, {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_QUOTA_LIMIT}, {ERRSRV, ERRbadtype, NT_STATUS_PATH_NOT_COVERED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_CALLBACK_ACTIVE}, {ERRHRD, ERRgeneral, NT_STATUS_LICENSE_QUOTA_EXCEEDED}, {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_SHORT}, {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_RECENT}, {ERRHRD, ERRgeneral, NT_STATUS_PWD_HISTORY_CONFLICT}, {ERRHRD, ERRgeneral, NT_STATUS_PLUGPLAY_NO_DEVICE}, {ERRHRD, ERRgeneral, NT_STATUS_UNSUPPORTED_COMPRESSION}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_HW_PROFILE}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH}, {ERRDOS, ERROR_INVALID_ORDINAL, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, {ERRDOS, ERROR_PROC_NOT_FOUND, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, {ERRDOS, ERROR_NOT_OWNER, NT_STATUS_RESOURCE_NOT_OWNED}, {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LINKS}, {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_LIST_INCONSISTENT}, {ERRHRD, ERRgeneral, NT_STATUS_FILE_IS_OFFLINE}, {ERRDOS, ERROR_NOT_READY, NT_STATUS_VOLUME_DISMOUNTED}, {ERRDOS, ERROR_BAD_PATHNAME, NT_STATUS_DIRECTORY_IS_A_REPARSE_POINT}, {ERRDOS, ERRnoaccess, NT_STATUS_ENCRYPTION_FAILED}, {ERRDOS, ERRnoaccess, NT_STATUS_DECRYPTION_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_RANGE_NOT_FOUND}, {ERRDOS, ERRnoaccess, NT_STATUS_NO_RECOVERY_POLICY}, {ERRDOS, ERRnoaccess, NT_STATUS_NO_EFS}, {ERRDOS, ERRnoaccess, NT_STATUS_WRONG_EFS}, {ERRDOS, ERRnoaccess, NT_STATUS_NO_USER_KEYS}, {ERRDOS, ERRbadfunc, NT_STATUS_VOLUME_NOT_UPGRADED}, {0, 0, 0} }; int smb_maperr32(uint32_t nterr) { const nt2errno_t *nt2e; const nt2doserr_t *nt2d; switch (NT_SC_SEVERITY(nterr)) { case NT_STATUS_SEVERITY_SUCCESS: case NT_STATUS_SEVERITY_INFORMATIONAL: return (0); } /* first try direct map to unix */ for (nt2e = nt2errno; nt2e->errno; nt2e++) if (nt2e->nterr == nterr) return (nt2e->errno); smb_errmsg(unknown_err_logpri, "smb_maperr32", "No direct map for 32 bit server error (0x%x)\n", nterr); /* ok, then try mapping to dos to unix */ for (nt2d = nt2doserr; nt2d->nterr; nt2d++) if (nt2d->nterr == nterr) return (smb_maperror(nt2d->dclass, nt2d->derr)); return (EIO); } uint_t smb_doserr2status(int dclass, int derr) { const nt2doserr_t *nt2d; if (dclass == 0 && derr == 0) return (0); for (nt2d = nt2doserr; nt2d->nterr; nt2d++) if (nt2d->dclass == dclass && nt2d->derr == derr) return (nt2d->nterr); return (NT_STATUS_UNSUCCESSFUL); } int smb_maperror(int eclass, int eno) { if (eclass == 0 && eno == 0) return (0); switch (eclass) { case ERRDOS: switch (eno) { case ERROR_INVALID_LEVEL: return (ENOTSUP); case ERRbadfunc: case ERRbadenv: case ERRbadformat: case ERRremcd: case ERRrmuns: return (EINVAL); case ERRbadfile: case ERRbadpath: case ERROR_BAD_DEV_TYPE: case ERROR_BAD_NET_NAME: return (ENOENT); case ERRnofids: return (EMFILE); case ERRnoaccess: /* * XXX CSM Reported on samba-technical 12/7/2002 * * There is a case for which server(s) return * ERRnoaccess but should return ERRdiskfull: When * the offset for a write is exactly the server * file size limit then Samba (at least) thinks * the reason for zero bytes having been written * must have been "access denied" from the local * filesystem. This cannot be easily worked * around since the server behaviour is * indistinguishable from actual access denied. * An incomplete workaround: attempt a 2 byte write * from "offset-1". (That may require reading at * offset-1 first.) The flaw is that reading or * writing at offset-1 could cause an * unrelated error (due to a byte range lock * for instance) and we can't presume the * order servers check errors in. */ case ERRbadaccess: return (EACCES); case ERRbadshare: return (EBUSY); case ERRbadfid: return (EBADF); case ERRbadmcb: return (EIO); case ERRnomem: return (ENOMEM); /* actually remote no mem... */ case ERRbadmem: return (EFAULT); case ERRbaddata: return (E2BIG); case ERRbaddrive: case ERRnotready: /* nt */ return (ENXIO); case ERRdiffdevice: return (EXDEV); case ERRnofiles: return (0); /* eeof ? */ case ERRlock: return (EAGAIN); case ERRfilexists: return (EEXIST); case ERROR_INVALID_NAME: return (ENOENT); case ERROR_DIR_NOT_EMPTY: return (ENOTEMPTY); case ERROR_NOT_LOCKED: return (0); /* we unlock on any close */ case ERROR_ALREADY_EXISTS: return (EEXIST); case ERRmoredata: return (EMOREDATA); } break; case ERRSRV: switch (eno) { case ERRerror: return (EINVAL); case ERRbadpw: return (EAUTH); case ERRaccess: case ERRbaduid: return (EACCES); case ERRinvnid: return (ENETRESET); case ERRinvnetname: return (ENXIO); case ERRbadtype: /* reserved and returned */ return (EIO); case NERR_AccountExpired: /* account exists but disabled */ return (EPERM); } break; case ERRHRD: switch (eno) { case ERRnowrite: return (EROFS); case ERRbadunit: return (ENODEV); case ERRbadreq: return (EBADRPC); case ERRbadshare: return (ETXTBSY); case ERRlock: return (EAGAIN); case ERRdiskfull: return (EFBIG); case ERRnotready: case ERRbadcmd: case ERRdata: case ERRgeneral: return (EIO); } } smb_errmsg(unknown_err_logpri, "smb_maperror", "Unknown DOS error %d/%d\n", eclass, eno); return (EIO); } #define SMALL_CONV 256 /* * Decode an SMB OTW string (Unicode or OEM chars) * converting to UTF-8 in the output buffer. * outlen is in/out (max size on input) * insize is the wire size (2 * chars if unicode) * The output string is null terminated. * Output length does not include the null. */ int smb_get_dstring(struct mdchain *mdc, struct smb_vc *vcp, char *outbuf, size_t *outlen, int insize) { uint16_t convbuf[SMALL_CONV]; uint16_t *cbuf; size_t cbufalloc, inlen, outsize; int error; if (insize <= 0) return (0); /* Note: inlen is UTF-16 symbols. */ inlen = insize / 2; if (*outlen < 2) return (EINVAL); outsize = *outlen - 1; /* room for null */ /* * Get a buffer for the conversion and fill it. * Use stack buffer if the string is * small enough, else allocate. */ if (insize < sizeof (convbuf)) { cbufalloc = 0; cbuf = convbuf; } else { cbufalloc = insize + 2; cbuf = kmem_alloc(cbufalloc, KM_SLEEP); } error = md_get_mem(mdc, cbuf, insize, MB_MSYSTEM); if (error != 0) goto out; cbuf[inlen] = 0; /* * Handle the easy case (non-unicode). * XXX: Technically, we should convert * the string to OEM codeset first... * Modern servers all use Unicode, so * this is good enough. */ if (SMB_UNICODE_STRINGS(vcp) == 0) { *outlen = strlcpy(outbuf, (char *)cbuf, outsize); if (*outlen > outsize) { *outlen = outsize; error = E2BIG; } } else { /* * Convert from UTF-16 to UTF-8 */ error = uconv_u16tou8(cbuf, &inlen, (uchar_t *)outbuf, outlen, UCONV_IN_LITTLE_ENDIAN); if (error == 0) { outbuf[*outlen] = '\0'; } } ASSERT(*outlen == strlen(outbuf)); out: if (cbufalloc != 0) kmem_free(cbuf, cbufalloc); return (error); } /* * It's surprising that this function does utf8-ucs2 conversion. * One would expect only smb_put_dstring to do that. * Fixing that will require changing a bunch of callers. XXX */ /*ARGSUSED*/ int smb_put_dmem(struct mbchain *mbp, struct smb_vc *vcp, const char *src, int size, int caseopt, int *lenp) { uint16_t convbuf[SMALL_CONV]; uint16_t *cbuf; size_t cbufalloc, inlen, outlen; int error; if (size <= 0) return (0); /* * Handle the easy case (non-unicode). * XXX: Technically, we should convert * the string to OEM codeset first... * Modern servers all use Unicode, so * this is good enough. */ if (SMB_UNICODE_STRINGS(vcp) == 0) { error = mb_put_mem(mbp, src, size, MB_MSYSTEM); if (!error && lenp) *lenp += size; return (error); } /* * Convert to UCS-2 (really UTF-16). * Use stack buffer if the string is * small enough, else allocate. */ if (size <= SMALL_CONV) { cbufalloc = 0; outlen = SMALL_CONV; cbuf = convbuf; } else { outlen = size; /* in utf-16 characters */ cbufalloc = outlen * 2; cbuf = kmem_alloc(cbufalloc, KM_SLEEP); } inlen = size; error = uconv_u8tou16((uchar_t *)src, &inlen, cbuf, &outlen, UCONV_OUT_LITTLE_ENDIAN | UCONV_IGNORE_NULL); outlen *= 2; /* convert to bytes */ if (!error) { (void) mb_put_padbyte(mbp); /* align */ error = mb_put_mem(mbp, (char *)cbuf, outlen, MB_MSYSTEM); } if (!error && lenp) *lenp += outlen; if (cbufalloc) kmem_free(cbuf, cbufalloc); return (error); } int smb_put_dstring(struct mbchain *mbp, struct smb_vc *vcp, const char *src, int caseopt) { int error, len; /* * Let smb_put_dmem put both the string * and the terminating null. */ len = strlen(src) + 1; error = smb_put_dmem(mbp, vcp, src, len, caseopt, NULL); if (error) return (error); return (error); } int smb_smb_ntcreate(struct smb_share *ssp, struct mbchain *name_mb, uint32_t crflag, uint32_t req_acc, uint32_t efa, uint32_t sh_acc, uint32_t disp, uint32_t createopt, uint32_t impersonate, struct smb_cred *scrp, smb_fh_t *fhp, uint32_t *cr_act_p, struct smbfattr *fap) { int err; if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) { err = smb2_smb_ntcreate(ssp, name_mb, NULL, NULL, crflag, req_acc, efa, sh_acc, disp, createopt, impersonate, scrp, &fhp->fh_fid2, cr_act_p, fap); } else { err = smb1_smb_ntcreate(ssp, name_mb, crflag, req_acc, efa, sh_acc, disp, createopt, impersonate, scrp, &fhp->fh_fid1, cr_act_p, fap); } return (err); } int smb_smb_close(struct smb_share *ssp, smb_fh_t *fhp, struct smb_cred *scrp) { int err; if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) { err = smb2_smb_close(ssp, &fhp->fh_fid2, scrp); } else { err = smb1_smb_close(ssp, fhp->fh_fid1, NULL, scrp); } return (err); } /* * Largest size to use with LARGE_READ/LARGE_WRITE. * Specs say up to 64k data bytes, but Windows traffic * uses 60k... no doubt for some good reason. * (Probably to keep 4k block alignment.) */ uint32_t smb1_large_io_max = (60*1024); /* * Common function for read/write with UIO. * Called by netsmb smb_usr_rw, * smbfs_readvnode, smbfs_writevnode */ int smb_rwuio(smb_fh_t *fhp, uio_rw_t rw, uio_t *uiop, smb_cred_t *scred, int timo) { struct smb_share *ssp = FHTOSS(fhp); struct smb_vc *vcp = SSTOVC(ssp); ssize_t save_resid; uint32_t len, rlen, maxlen; int error = 0; int (*iofun)(smb_fh_t *, uint32_t *, uio_t *, smb_cred_t *, int); /* After reconnect, the fid is invalid. */ if (fhp->fh_vcgenid != ssp->ss_vcgenid) return (ESTALE); if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) { if (rw == UIO_READ) { iofun = smb2_smb_read; maxlen = vcp->vc_sopt.sv2_maxread; } else { /* UIO_WRITE */ iofun = smb2_smb_write; maxlen = vcp->vc_sopt.sv2_maxwrite; } } else { /* * Using NT LM 0.12, so readx, writex. * Make sure we can represent the offset. */ if ((vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_FILES) == 0 && (uiop->uio_loffset + uiop->uio_resid) > UINT32_MAX) return (EFBIG); if (rw == UIO_READ) { iofun = smb_smb_readx; if (vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_READX) maxlen = smb1_large_io_max; else maxlen = vcp->vc_rxmax; } else { /* UIO_WRITE */ iofun = smb_smb_writex; if (vcp->vc_sopt.sv_caps & SMB_CAP_LARGE_WRITEX) maxlen = smb1_large_io_max; else maxlen = vcp->vc_wxmax; } } save_resid = uiop->uio_resid; while (uiop->uio_resid > 0) { /* Lint: uio_resid may be 64-bits */ rlen = len = (uint32_t)min(maxlen, uiop->uio_resid); error = (*iofun)(fhp, &rlen, uiop, scred, timo); /* * Note: the iofun called uio_update, so * not doing that here as one might expect. * * Quit the loop either on error, or if we * transferred less then requested. */ if (error || (rlen < len)) break; timo = 0; /* only first I/O should wait */ } if (error && (save_resid != uiop->uio_resid)) { /* * Stopped on an error after having * successfully transferred data. * Suppress this error. */ SMBSDEBUG("error %d suppressed\n", error); error = 0; } return (error); }