s3-spoolss: Added a winreg_addform1 function.
authorAndreas Schneider <asn@samba.org>
Wed, 31 Mar 2010 11:04:04 +0000 (13:04 +0200)
committerGünther Deschner <gd@samba.org>
Wed, 7 Apr 2010 13:16:53 +0000 (15:16 +0200)
Signed-off-by: Günther Deschner <gd@samba.org>
source3/rpc_server/srv_spoolss_util.c
source3/rpc_server/srv_spoolss_util.h

index 377c71296b8091018b255821e816fa6f88139d6f..b23514c394a894b5c597d458ec425e82704e4132 100644 (file)
@@ -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)
index 28e7e5b485b6ce8539e99777ae87593b57ceadec..99cf68107c729350c5af565cbb44d94249c29b9c 100644 (file)
@@ -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.