summaryrefslogtreecommitdiffstats
path: root/source3/registry/reg_backend_printing.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/registry/reg_backend_printing.c')
-rw-r--r--source3/registry/reg_backend_printing.c281
1 files changed, 281 insertions, 0 deletions
diff --git a/source3/registry/reg_backend_printing.c b/source3/registry/reg_backend_printing.c
new file mode 100644
index 0000000..3b5e7bf
--- /dev/null
+++ b/source3/registry/reg_backend_printing.c
@@ -0,0 +1,281 @@
+/*
+ * Unix SMB/CIFS implementation.
+ * Virtual Windows Registry Layer
+ * Copyright (C) Gerald Carter 2002-2005
+ * Copyright (c) Andreas Schneider <asn@samba.org> 2010
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Implementation of registry virtual views for printing information */
+
+#include "includes.h"
+#include "registry.h"
+#include "reg_util_internal.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_REGISTRY
+
+extern struct registry_ops regdb_ops;
+
+/* registry paths used in the print_registry[] */
+#define KEY_CONTROL_PRINTERS "HKLM\\SYSTEM\\CURRENTCONTROLSET\\CONTROL\\PRINT\\PRINTERS"
+#define KEY_WINNT_PRINTERS "HKLM\\SOFTWARE\\MICROSOFT\\WINDOWS NT\\CURRENTVERSION\\PRINT\\PRINTERS"
+
+/* callback table for various registry paths below the ones we service in this module */
+
+struct reg_dyn_tree {
+ /* full key path in normalized form */
+ const char *path;
+
+ /* callbscks for fetch/store operations */
+ int ( *fetch_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
+ bool (*store_subkeys) ( const char *path, struct regsubkey_ctr *subkeys );
+ int (*fetch_values) ( const char *path, struct regval_ctr *values );
+ bool (*store_values) ( const char *path, struct regval_ctr *values );
+};
+
+/*********************************************************************
+ *********************************************************************
+ ** "HKLM/SYSTEM/CURRENTCONTROLSET/CONTROL/PRINT/PRINTERS"
+ ** "HKLM/SOFTWARE/MICROSOFT/WINDOWS NT/CURRENTVERSION/PRINT/PRINTERS"
+ *********************************************************************
+ *********************************************************************/
+
+static char *create_printer_registry_path(TALLOC_CTX *mem_ctx, const char *key) {
+ char *path;
+ char *subkey = NULL;
+
+ path = talloc_strdup(mem_ctx, key);
+ if (path == NULL) {
+ return NULL;
+ }
+
+ path = normalize_reg_path(mem_ctx, path);
+ if (path == NULL) {
+ return NULL;
+ }
+
+ if (strncmp(path, KEY_CONTROL_PRINTERS, strlen(KEY_CONTROL_PRINTERS)) == 0) {
+ subkey = reg_remaining_path(mem_ctx, key + strlen(KEY_CONTROL_PRINTERS));
+ if (subkey == NULL) {
+ return NULL;
+ }
+ return talloc_asprintf(mem_ctx, "%s\\%s", KEY_WINNT_PRINTERS, subkey);
+ }
+
+ return NULL;
+}
+
+/*********************************************************************
+ *********************************************************************/
+
+static int key_printers_fetch_keys( const char *key, struct regsubkey_ctr *subkeys )
+{
+ TALLOC_CTX *ctx = talloc_tos();
+ char *printers_key;
+
+ printers_key = create_printer_registry_path(ctx, key);
+ if (printers_key == NULL) {
+ /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
+ return regdb_ops.fetch_subkeys(KEY_WINNT_PRINTERS, subkeys);
+ }
+
+ return regdb_ops.fetch_subkeys(printers_key, subkeys);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subkeys )
+{
+ TALLOC_CTX *ctx = talloc_tos();
+ char *printers_key;
+
+ printers_key = create_printer_registry_path(ctx, key);
+ if (printers_key == NULL) {
+ /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
+ return regdb_ops.store_subkeys(KEY_WINNT_PRINTERS, subkeys);
+ }
+
+ return regdb_ops.store_subkeys(printers_key, subkeys);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static int key_printers_fetch_values(const char *key, struct regval_ctr *values)
+{
+ TALLOC_CTX *ctx = talloc_tos();
+ char *printers_key;
+
+ printers_key = create_printer_registry_path(ctx, key);
+ if (printers_key == NULL) {
+ /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
+ return regdb_ops.fetch_values(KEY_WINNT_PRINTERS, values);
+ }
+
+ return regdb_ops.fetch_values(printers_key, values);
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static bool key_printers_store_values(const char *key, struct regval_ctr *values)
+{
+ TALLOC_CTX *ctx = talloc_tos();
+ char *printers_key;
+
+ printers_key = create_printer_registry_path(ctx, key);
+ if (printers_key == NULL) {
+ /* normalize on the 'HKLM\SOFTWARE\....\Print\Printers' key */
+ return regdb_ops.store_values(KEY_WINNT_PRINTERS, values);
+ }
+
+ return regdb_ops.store_values(printers_key, values);
+}
+
+/**********************************************************************
+ *********************************************************************
+ ** Structure to hold dispatch table of ops for various printer keys.
+ ** Make sure to always store deeper keys along the same path first so
+ ** we ge a more specific match.
+ *********************************************************************
+ *********************************************************************/
+
+static struct reg_dyn_tree print_registry[] = {
+{ KEY_CONTROL_PRINTERS,
+ &key_printers_fetch_keys,
+ &key_printers_store_keys,
+ &key_printers_fetch_values,
+ &key_printers_store_values },
+
+{ NULL, NULL, NULL, NULL, NULL }
+};
+
+
+/**********************************************************************
+ *********************************************************************
+ ** Main reg_printing interface functions
+ *********************************************************************
+ *********************************************************************/
+
+/***********************************************************************
+ Lookup a key in the print_registry table, returning its index.
+ -1 on failure
+ **********************************************************************/
+
+static int match_registry_path(const char *key)
+{
+ int i;
+ char *path = NULL;
+ TALLOC_CTX *ctx = talloc_tos();
+
+ if ( !key )
+ return -1;
+
+ path = talloc_strdup(ctx, key);
+ if (!path) {
+ return -1;
+ }
+ path = normalize_reg_path(ctx, path);
+ if (!path) {
+ return -1;
+ }
+
+ for ( i=0; print_registry[i].path; i++ ) {
+ if (strncmp( path, print_registry[i].path, strlen(print_registry[i].path) ) == 0 )
+ return i;
+ }
+
+ return -1;
+}
+
+/***********************************************************************
+ **********************************************************************/
+
+static int regprint_fetch_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
+{
+ int i = match_registry_path( key );
+
+ if ( i == -1 )
+ return -1;
+
+ if ( !print_registry[i].fetch_subkeys )
+ return -1;
+
+ return print_registry[i].fetch_subkeys( key, subkeys );
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static bool regprint_store_reg_keys( const char *key, struct regsubkey_ctr *subkeys )
+{
+ int i = match_registry_path( key );
+
+ if ( i == -1 )
+ return False;
+
+ if ( !print_registry[i].store_subkeys )
+ return False;
+
+ return print_registry[i].store_subkeys( key, subkeys );
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static int regprint_fetch_reg_values(const char *key, struct regval_ctr *values)
+{
+ int i = match_registry_path( key );
+
+ if ( i == -1 )
+ return -1;
+
+ /* return 0 values by default since we know the key had
+ to exist because the client opened a handle */
+
+ if ( !print_registry[i].fetch_values )
+ return 0;
+
+ return print_registry[i].fetch_values( key, values );
+}
+
+/**********************************************************************
+ *********************************************************************/
+
+static bool regprint_store_reg_values(const char *key, struct regval_ctr *values)
+{
+ int i = match_registry_path( key );
+
+ if ( i == -1 )
+ return False;
+
+ if ( !print_registry[i].store_values )
+ return False;
+
+ return print_registry[i].store_values( key, values );
+}
+
+/*
+ * Table of function pointers for accessing printing data
+ */
+
+struct registry_ops printing_ops = {
+ .fetch_subkeys = regprint_fetch_reg_keys,
+ .fetch_values = regprint_fetch_reg_values,
+ .store_subkeys = regprint_store_reg_keys,
+ .store_values = regprint_store_reg_values,
+};