From: Günther Deschner Date: Mon, 31 Oct 2016 16:43:28 +0000 (+0100) Subject: s3-rpc_cli: add winreg_get_core_driver() X-Git-Tag: ldb-1.1.30~268 X-Git-Url: http://git.samba.org/?a=commitdiff_plain;h=071faf59dc528a78f724a48b20754318da252968;p=samba.git s3-rpc_cli: add winreg_get_core_driver() Guenther Signed-off-by: Guenther Deschner Reviewed-by: Andreas Schneider --- diff --git a/source3/rpc_client/cli_winreg_spoolss.c b/source3/rpc_client/cli_winreg_spoolss.c index 5ec97e6a94c..1823168685d 100644 --- a/source3/rpc_client/cli_winreg_spoolss.c +++ b/source3/rpc_client/cli_winreg_spoolss.c @@ -34,6 +34,7 @@ #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print" #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers" +#define TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY TOP_LEVEL_PRINT_KEY "\\PackageInstallation" #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print" #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms" @@ -3968,3 +3969,165 @@ done: TALLOC_FREE(tmp_ctx); return result; } + +WERROR winreg_get_core_driver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *architecture, + const struct GUID *core_driver_guid, + struct spoolss_CorePrinterDriver **_core_printer_driver) +{ + uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + struct policy_handle hive_hnd, key_hnd; + struct spoolss_CorePrinterDriver *c; + struct spoolss_PrinterEnumValues *enum_values = NULL; + struct spoolss_PrinterEnumValues *v; + uint32_t num_values = 0; + TALLOC_CTX *tmp_ctx; + WERROR result; + NTSTATUS status; + const char *path; + const char *guid_str; + uint32_t i; + const char **enum_names = NULL; + enum winreg_Type *enum_types = NULL; + DATA_BLOB *enum_data_blobs = NULL; + + ZERO_STRUCT(hive_hnd); + ZERO_STRUCT(key_hnd); + + tmp_ctx = talloc_stackframe(); + if (tmp_ctx == NULL) { + return WERR_NOT_ENOUGH_MEMORY; + } + + path = talloc_asprintf(tmp_ctx, "%s\\%s\\CorePrinterDrivers", + TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY, + architecture); + if (path == NULL) { + result = WERR_NOT_ENOUGH_MEMORY; + goto done; + } + + guid_str = GUID_string2(tmp_ctx, core_driver_guid); + if (guid_str == NULL) { + result = WERR_NOT_ENOUGH_MEMORY; + goto done; + } + + result = winreg_printer_openkey(tmp_ctx, + winreg_handle, + path, + guid_str, /* key */ + false, + access_mask, + &hive_hnd, + &key_hnd); + + if (!W_ERROR_IS_OK(result)) { + DEBUG(5, ("winreg_get_core_driver: " + "Could not open core driver key (%s,%s): %s\n", + guid_str, architecture, win_errstr(result))); + goto done; + } + + status = dcerpc_winreg_enumvals(tmp_ctx, + winreg_handle, + &key_hnd, + &num_values, + &enum_names, + &enum_types, + &enum_data_blobs, + &result); + if (!NT_STATUS_IS_OK(status)){ + result = ntstatus_to_werror(status); + } + + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_get_core_driver: " + "Could not enumerate values for (%s,%s): %s\n", + guid_str, architecture, win_errstr(result))); + goto done; + } + + enum_values = talloc_zero_array(tmp_ctx, + struct spoolss_PrinterEnumValues, + num_values); + if (enum_values == NULL){ + result = WERR_NOT_ENOUGH_MEMORY; + goto done; + } + + for (i = 0; i < num_values; i++){ + enum_values[i].value_name = enum_names[i]; + enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2; + enum_values[i].type = enum_types[i]; + enum_values[i].data_length = enum_data_blobs[i].length; + enum_values[i].data = NULL; + if (enum_values[i].data_length != 0){ + enum_values[i].data = &enum_data_blobs[i]; + } + } + + c = talloc_zero(tmp_ctx, struct spoolss_CorePrinterDriver); + if (c == NULL) { + result = WERR_NOT_ENOUGH_MEMORY; + goto done; + } + + c->core_driver_guid = *core_driver_guid; + + result = WERR_OK; + + for (i = 0; i < num_values; i++) { + const char *tmp_str; + + v = &enum_values[i]; + + result = winreg_enumval_to_sz(c, v, + "InfPath", + &c->szPackageID); + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(c, v, + "DriverDate", + &tmp_str); + if (W_ERROR_IS_OK(result)) { + result = winreg_printer_date_to_NTTIME(tmp_str, + &c->driver_date); + } + CHECK_ERROR(result); + + result = winreg_enumval_to_sz(c, v, + "DriverVersion", + &tmp_str); + if (W_ERROR_IS_OK(result)) { + result = winreg_printer_ver_to_qword(tmp_str, + &c->driver_version); + } + CHECK_ERROR(result); + } + + if (!W_ERROR_IS_OK(result)) { + DEBUG(0, ("winreg_enumval_to_TYPE() failed " + "for %s: %s\n", v->value_name, + win_errstr(result))); + goto done; + } + + *_core_printer_driver = talloc_steal(mem_ctx, c); + result = WERR_OK; +done: + if (winreg_handle != NULL) { + WERROR ignore; + + if (is_valid_policy_hnd(&key_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore); + } + if (is_valid_policy_hnd(&hive_hnd)) { + dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore); + } + } + + TALLOC_FREE(tmp_ctx); + return result; +} diff --git a/source3/rpc_client/cli_winreg_spoolss.h b/source3/rpc_client/cli_winreg_spoolss.h index 6542fc94f1c..90ff7315e82 100644 --- a/source3/rpc_client/cli_winreg_spoolss.h +++ b/source3/rpc_client/cli_winreg_spoolss.h @@ -599,5 +599,27 @@ WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx, uint32_t version, uint32_t *num_drivers, const char ***drivers); +/** + * @brief This function gets a core printer driver + * + * @param[in] mem_ctx A talloc memory context. + * + * @param[in] b The dcerpc binding handle + * + * @param[in] architecture The architecture type. + * + * @param[in] core_driver_guid The core driver guid. + * + * @param[out] core_printer_driver The returned core printer driver definiton + * + * @return On success WERR_OK, a corresponding DOS error is + * something went wrong. + */ + +WERROR winreg_get_core_driver(TALLOC_CTX *mem_ctx, + struct dcerpc_binding_handle *winreg_handle, + const char *architecture, + const struct GUID *core_driver_guid, + struct spoolss_CorePrinterDriver **_core_printer_driver); #endif /* _RPC_CLIENT_CLI_WINREG_SPOOLSS_H_ */