diff options
Diffstat (limited to 'source3/registry/reg_backend_printing.c')
-rw-r--r-- | source3/registry/reg_backend_printing.c | 281 |
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, +}; |