diff options
Diffstat (limited to 'source3/rpc_server')
-rw-r--r-- | source3/rpc_server/srv_spoolss_util.c | 106 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_util.h | 18 |
2 files changed, 124 insertions, 0 deletions
diff --git a/source3/rpc_server/srv_spoolss_util.c b/source3/rpc_server/srv_spoolss_util.c index 377c71296b..b23514c394 100644 --- a/source3/rpc_server/srv_spoolss_util.c +++ b/source3/rpc_server/srv_spoolss_util.c @@ -1241,6 +1241,112 @@ done: return result; } +/* + * The special behaviour of the spoolss forms is documented at the website: + * + * Managing Win32 Printserver Forms + * http://unixwiz.net/techtips/winspooler-forms.html + */ + +WERROR winreg_printer_addform1(struct pipes_struct *p, + struct spoolss_AddFormInfo1 *form) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct rpc_pipe_client *winreg_pipe = NULL; + struct policy_handle hive_hnd, key_hnd; + struct winreg_String wvalue; + DATA_BLOB blob; + uint32_t num_info = 0; + union spoolss_FormInfo *info = NULL; + uint32_t i; + WERROR result; + NTSTATUS status; + TALLOC_CTX *tmp_ctx; + + tmp_ctx = talloc_new(p->mem_ctx); + if (tmp_ctx == NULL) { + return WERR_NOMEM; + } + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + result = winreg_printer_openkey(tmp_ctx, + p->server_info, + &winreg_pipe, + TOP_LEVEL_CONTROL_FORMS_KEY, + "", + true, + access_mask, + &hive_hnd, + &key_hnd); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + goto done; + } + + result = winreg_printer_enumforms1(p, &num_info, &info); + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n", + TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result))); + goto done; + } + + /* If form name already exists or is builtin return ALREADY_EXISTS */ + for (i = 0; i < num_info; i++) { + if (strequal(info[i].info1.form_name, form->form_name)) { + result = WERR_FILE_EXISTS; + goto done; + } + } + + wvalue.name = form->form_name; + + blob = data_blob_talloc(tmp_ctx, NULL, 32); + SIVAL(blob.data, 0, form->size.width); + SIVAL(blob.data, 4, form->size.height); + SIVAL(blob.data, 8, form->area.left); + SIVAL(blob.data, 12, form->area.top); + SIVAL(blob.data, 16, form->area.right); + SIVAL(blob.data, 20, form->area.bottom); + SIVAL(blob.data, 24, num_info + 1); /* FIXME */ + SIVAL(blob.data, 28, form->flags); + + status = rpccli_winreg_SetValue(winreg_pipe, + tmp_ctx, + &key_hnd, + wvalue, + REG_BINARY, + blob.data, + blob.length, + &result); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n", + wvalue.name, nt_errstr(status))); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + result = ntstatus_to_werror(status); + goto done; + } + + result = WERR_OK; +done: + if (winreg_pipe != NULL) { + if (is_valid_policy_hnd(&key_hnd)) { + rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &key_hnd, NULL); + } + if (is_valid_policy_hnd(&hive_hnd)) { + rpccli_winreg_CloseKey(winreg_pipe, tmp_ctx, &hive_hnd, NULL); + } + } + + TALLOC_FREE(info); + TALLOC_FREE(tmp_ctx); + return result; +} + WERROR winreg_printer_enumforms1(struct pipes_struct *p, uint32_t *pnum_info, union spoolss_FormInfo **pinfo) diff --git a/source3/rpc_server/srv_spoolss_util.h b/source3/rpc_server/srv_spoolss_util.h index 28e7e5b485..99cf68107c 100644 --- a/source3/rpc_server/srv_spoolss_util.h +++ b/source3/rpc_server/srv_spoolss_util.h @@ -171,6 +171,24 @@ WERROR winreg_delete_printer_key(struct pipes_struct *p, const char *key); /** + * @internal + * + * @brief This function adds a form to the list of available forms that can be + * selected for the specified printer. + * + * @param[in] p The pipes structure to be able to open a new pipe. + * + * @param[in] form The form to add. + * + * @return WERR_OK on success. + * WERR_ALREADY_EXISTS if the form already exists or is a + * builtin form. + * A corresponding DOS error is something went wrong. + */ +WERROR winreg_printer_addform1(struct pipes_struct *p, + struct spoolss_AddFormInfo1 *form); + +/* * @brief This function enumerates the forms supported by the specified printer. * * @param[in] p The pipes structure to be able to open a new pipe. |