diff options
Diffstat (limited to 'usr/src/uts/common/fs/smbsrv/smb_print.c')
-rw-r--r-- | usr/src/uts/common/fs/smbsrv/smb_print.c | 305 |
1 files changed, 129 insertions, 176 deletions
diff --git a/usr/src/uts/common/fs/smbsrv/smb_print.c b/usr/src/uts/common/fs/smbsrv/smb_print.c index 4e21dfdd2b..43074b6882 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_print.c +++ b/usr/src/uts/common/fs/smbsrv/smb_print.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -29,64 +29,54 @@ #include <smbsrv/smb_kproto.h> - /* - * smb_com_open_print_file - * - * This message is sent to create a new printer file which will be deleted - * once it has been closed and printed. - * - * Client Request Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 2 - * USHORT SetupLength; Length of printer setup data - * USHORT Mode; 0 = Text mode (DOS expands TABs) - * 1 = Graphics mode - * USHORT ByteCount; Count of data bytes; min = 2 - * UCHAR BufferFormat; 0x04 - * STRING IdentifierString[]; Identifier string - * - * Tid in the SMB header must refer to a printer resource type. + * Create a new printer file, which should be deleted automatically once + * it has been closed and printed. * * SetupLength is the number of bytes in the first part of the resulting * print spool file which contains printer-specific control strings. * * Mode can have the following values: - * * 0 Text mode. The server may optionally * expand tabs to a series of spaces. * 1 Graphics mode. No conversion of data * should be done by the server. * - * IdentifierString can be used by the server to provide some sort of per- - * client identifying component to the print file. + * IdentifierString can be used by the server to provide some sort of + * per-client identifying component to the print file. * - * Server Response Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 1 - * USHORT Fid; File handle - * USHORT ByteCount; Count of data bytes = 0 - * - * Fid is the returned handle which may be used by subsequent write and - * close operations. When the file is finally closed, it will be sent to - * the spooler and printed. - * - * 4.5.1.1 Errors - * - * ERRDOS/ERRnoaccess - * ERRDOS/ERRnofids - * ERRSRV/ERRinvdevice - * ERRSRV/ERRbaduid - * ERRSRV/ERRqfull - * ERRSRV/ERRqtoobig + * When the file is closed, it will be sent to the spooler and printed. */ smb_sdrc_t smb_pre_open_print_file(smb_request_t *sr) { - DTRACE_SMB_1(op__OpenPrintFile__start, smb_request_t *, sr); - return (SDRC_SUCCESS); + static uint32_t tmp_id = 10000; + struct open_param *op = &sr->arg.open; + char *path; + char *identifier; + uint16_t setup; + uint16_t mode; + int rc; + + bzero(op, sizeof (sr->arg.open)); + + rc = smbsr_decode_vwv(sr, "ww", &setup, &mode); + if (rc == 0) + rc = smbsr_decode_data(sr, "%S", sr, &identifier); + + atomic_inc_32(&tmp_id); + + path = smb_srm_alloc(sr, MAXPATHLEN); + (void) snprintf(path, MAXPATHLEN, "%s%05u", identifier, tmp_id); + op->fqi.fq_path.pn_path = path; + + op->create_disposition = FILE_OVERWRITE_IF; + op->create_options = FILE_NON_DIRECTORY_FILE; + + DTRACE_SMB_2(op__OpenPrintFile__start, smb_request_t *, sr, + struct open_param *, op); + + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } void @@ -95,46 +85,42 @@ smb_post_open_print_file(smb_request_t *sr) DTRACE_SMB_1(op__OpenPrintFile__done, smb_request_t *, sr); } -smb_sdrc_t /*ARGSUSED*/ +smb_sdrc_t smb_com_open_print_file(smb_request_t *sr) { - return (SDRC_NOT_IMPLEMENTED); -} + int rc; + if (!STYPE_ISPRN(sr->tid_tree->t_res_type)) { + smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE, + ERRDOS, ERROR_BAD_DEV_TYPE); + return (SDRC_ERROR); + } + + if (smb_common_create(sr) != NT_STATUS_SUCCESS) + return (SDRC_ERROR); + + rc = smbsr_encode_result(sr, 1, 0, "bww", 1, sr->smb_fid, 0); + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); +} /* - * smb_com_close_print_file - * - * - * This message invalidates the specified file handle and queues the file - * for printing. - * - * Client Request Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 1 - * USHORT Fid; File handle - * USHORT ByteCount; Count of data bytes = 0 - * - * Fid refers to a file previously created with SMB_COM_OPEN_PRINT_FILE. + * Close the specified file handle and queue the file for printing. + * The fid refers to a file previously created as a print spool file. * On successful completion of this request, the file is queued for * printing by the server. * - * Server Response Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 0 - * USHORT ByteCount; Count of data bytes = 0 - * - * Servers which negotiate dialects of LANMAN1.0 and newer allow all the - * other types of Fid closing requests to invalidate the Fid and begin - * spooling. + * Servers that negotiate LANMAN1.0 or later allow all the the fid + * to be closed and printed via any close request. */ smb_sdrc_t smb_pre_close_print_file(smb_request_t *sr) { + int rc; + + rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid); + DTRACE_SMB_1(op__ClosePrintFile__start, smb_request_t *, sr); - return (SDRC_SUCCESS); + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } void @@ -143,81 +129,21 @@ smb_post_close_print_file(smb_request_t *sr) DTRACE_SMB_1(op__ClosePrintFile__done, smb_request_t *, sr); } -smb_sdrc_t /*ARGSUSED*/ +smb_sdrc_t smb_com_close_print_file(smb_request_t *sr) { - return (SDRC_NOT_IMPLEMENTED); -} + if (!STYPE_ISPRN(sr->tid_tree->t_res_type)) { + smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE, + ERRDOS, ERROR_BAD_DEV_TYPE); + return (SDRC_ERROR); + } + return (smb_com_close(sr)); +} /* - * smb_com_get_print_queue - * - * This message obtains a list of the elements currently in the print queue - * on the server. - * - * Client Request Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 2 - * USHORT MaxCount; Max number of entries to return - * USHORT StartIndex; First queue entry to return - * USHORT ByteCount; Count of data bytes = 0 - * - * StartIndex specifies the first entry in the queue to return. - * - * MaxCount specifies the maximum number of entries to return, this may be - * a positive or negative number. A positive number requests a forward - * search, a negative number indicates a backward search. - * - * Server Response Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 2 - * USHORT Count; Number of entries returned - * USHORT RestartIndex; Index of entry after last - * returned - * USHORT ByteCount; Count of data bytes; min = 3 - * UCHAR BufferFormat; 0x01 -- Data block - * USHORT DataLength; Length of data - * UCHAR Data[]; Queue elements - * - * Count indicates how many entries were actually returned. RestartIndex - * is the index of the entry following the last entry returned; it may be - * used as the StartIndex in a subsequent request to resume the queue - * listing. - * - * The format of each returned queue element is: - * - * Queue Element Member Description - * ================================ =================================== - * - * SMB_DATE FileDate; Date file was queued - * SMB_TIME FileTime; Time file was queued - * UCHAR Status; Entry status. One of: - * 01 = held or stopped - * 02 = printing - * 03 = awaiting print - * 04 = in intercept - * 05 = file had error - * 06 = printer error - * 07-FF = reserved - * USHORT SpoolFileNumber; Assigned by the spooler - * ULONG SpoolFileSize; Number of bytes in spool file - * UCHAR Reserved; - * UCHAR SpoolFileName[16]; Client which created the spool file - * - * SMB_COM_GET_PRINT_QUEUE will return less than the requested number of - * elements only when the top or end of the queue is encountered. - * - * Support for this SMB is server optional. In particular, no current - * Microsoft client software issues this request. - * - * 4.5.2.1 Errors - * - * ERRHRD/ERRnotready - * ERRHRD/ERRerror - * ERRSRV/ERRbaduid + * Get a list of print queue entries on the server. Support for + * this request is optional (not required for Windows clients). */ smb_sdrc_t smb_pre_get_print_queue(smb_request_t *sr) @@ -246,58 +172,85 @@ smb_com_get_print_queue(smb_request_t *sr) return (SDRC_SUCCESS); } - /* - * smb_com_write_print_file - * - * This message is sent to write bytes into a print spool file. - * - * Client Request Description - * ================================== ================================= - * - * UCHAR WordCount; Count of parameter words = 1 - * USHORT Fid; File handle - * USHORT ByteCount; Count of data bytes; min = 4 - * UCHAR BufferFormat; 0x01 -- Data block - * USHORT DataLength; Length of data - * UCHAR Data[]; Data - * - * Fid indicates the print spool file to be written, it must refer to a - * print spool file. - * - * ByteCount specifies the number of bytes to be written, and must be less - * than MaxBufferSize for the Tid specified. - * - * Data contains the bytes to append to the print spool file. The first - * SetupLength bytes in the resulting print spool file contain printer - * setup data. SetupLength is specified in the SMB_COM_OPEN_PRINT_FILE SMB - * request. - * - * Server Response Description - * ================================== ================================= + * Write (append) data to a print spool file. The fid must refer to + * a print spool file. * - * UCHAR WordCount; Count of parameter words = 0 - * USHORT ByteCount; Count of data bytes = 0 - * - * Servers which negotiate a protocol dialect of LANMAN1.0 or later also - * support the application of normal write requests to print spool files. + * The first SetupLength bytes (see SMB_COM_OPEN_PRINT_FILE) in the + * print spool file contain printer setup data. * + * Servers that negotiate LANMAN1.0 or later also support the use of + * normal write requests with print spool files. */ smb_sdrc_t smb_pre_write_print_file(smb_request_t *sr) { + smb_rw_param_t *param; + int rc; + + param = kmem_zalloc(sizeof (smb_rw_param_t), KM_SLEEP); + sr->arg.rw = param; + param->rw_magic = SMB_RW_MAGIC; + + rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid); + DTRACE_SMB_1(op__WritePrintFile__start, smb_request_t *, sr); - return (SDRC_SUCCESS); + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } void smb_post_write_print_file(smb_request_t *sr) { DTRACE_SMB_1(op__WritePrintFile__done, smb_request_t *, sr); + + kmem_free(sr->arg.rw, sizeof (smb_rw_param_t)); } -smb_sdrc_t /*ARGSUSED*/ +smb_sdrc_t smb_com_write_print_file(smb_request_t *sr) { - return (SDRC_NOT_IMPLEMENTED); + smb_rw_param_t *param = sr->arg.rw; + smb_node_t *node; + smb_attr_t attr; + int rc; + + if (!STYPE_ISPRN(sr->tid_tree->t_res_type)) { + smbsr_error(sr, NT_STATUS_BAD_DEVICE_TYPE, + ERRDOS, ERROR_BAD_DEV_TYPE); + return (SDRC_ERROR); + } + + smbsr_lookup_file(sr); + if (sr->fid_ofile == NULL) { + smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid); + return (SDRC_ERROR); + } + + node = sr->fid_ofile->f_node; + sr->user_cr = smb_ofile_getcred(sr->fid_ofile); + + if (smb_node_getattr(sr, node, &attr) != 0) { + smbsr_error(sr, NT_STATUS_INTERNAL_ERROR, + ERRDOS, ERROR_INTERNAL_ERROR); + return (SDRC_ERROR); + } + + if ((smbsr_decode_data(sr, "D", ¶m->rw_vdb)) != 0) { + smbsr_error(sr, NT_STATUS_INVALID_PARAMETER, + ERRDOS, ERROR_INVALID_PARAMETER); + return (SDRC_ERROR); + } + + param->rw_count = param->rw_vdb.vdb_len; + param->rw_offset = attr.sa_vattr.va_size; + param->rw_vdb.vdb_uio.uio_loffset = (offset_t)param->rw_offset; + + if ((rc = smb_common_write(sr, param)) != 0) { + if (sr->smb_error.status != NT_STATUS_FILE_LOCK_CONFLICT) + smbsr_errno(sr, rc); + return (SDRC_ERROR); + } + + rc = smbsr_encode_empty_result(sr); + return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR); } |