LCOV - code coverage report
Current view: top level - lib/printer_driver - printer_driver.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 0 635 0.0 %
Date: 2024-04-21 15:09:00 Functions: 0 22 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             : 
       4             :    Copyright (C) Guenther Deschner 2016
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : #include "librpc/gen_ndr/ndr_spoolss.h"
      22             : #include "rpc_client/init_spoolss.h"
      23             : #include "libgpo/gpo_ini.h"
      24             : #include "printer_driver.h"
      25             : 
      26             : #define ADD_TO_ARRAY(mem_ctx, type, elem, array, num) \
      27             : do { \
      28             :         *(array) = talloc_realloc(mem_ctx, (*(array)), type, (*(num))+1); \
      29             :         SMB_ASSERT((*(array)) != NULL); \
      30             :         (*(array))[*(num)] = (elem); \
      31             :         (*(num)) += 1; \
      32             : } while (0)
      33             : 
      34             : 
      35             : /* GetPrinterDriverDirectory  -> drivers and dependent files */
      36             : #define PRINTER_INF_DIRID_66000
      37             : 
      38             : /* GetPrintProcessorDirectory -> print processors */
      39             : #define PRINTER_INF_DIRID_66001
      40             : 
      41             : /* GetColorDirectory -> color profiles */
      42             : #define PRINTER_INF_DIRID_66003
      43             : 
      44           0 : static const char *get_string_unquote(const char *s)
      45             : {
      46           0 :         bool ok;
      47           0 :         size_t len;
      48             : 
      49           0 :         if (s == NULL) {
      50           0 :                 return NULL;
      51             :         }
      52             : 
      53           0 :         len = strlen(s);
      54           0 :         if (len < 2) {
      55           0 :                 return s;
      56             :         }
      57             : 
      58           0 :         if (s[0] == '"' && s[len-1] == '"') {
      59           0 :                 ok = trim_string(discard_const(s), "\"", "\"");
      60           0 :                 if (!ok) {
      61           0 :                         return NULL;
      62             :                 }
      63             :         }
      64             : 
      65           0 :         return s;
      66             : }
      67             : 
      68             : /*
      69             :  * '%STRING%' indicates STRING is localized in the [Strings] section
      70             :  */
      71             : 
      72           0 : static const char *get_string_token(struct gp_inifile_context *ctx,
      73             :                                     const char *s)
      74             : {
      75           0 :         NTSTATUS status;
      76           0 :         bool ok;
      77           0 :         char *key;
      78           0 :         const char *s2;
      79             : 
      80           0 :         if (s != NULL &&  s[0] != '%' && s[strlen(s)-1] != '%') {
      81           0 :                 return s;
      82             :         }
      83             : 
      84           0 :         ok = trim_string(discard_const(s), "%", "%");
      85           0 :         if (!ok) {
      86           0 :                 return NULL;
      87             :         }
      88             : 
      89           0 :         key = talloc_asprintf(ctx, "Strings:%s", s);
      90           0 :         if (key == NULL) {
      91           0 :                 return NULL;
      92             :         }
      93             : 
      94           0 :         status = gp_inifile_getstring(ctx, key, &s2);
      95           0 :         talloc_free(key);
      96           0 :         if (!NT_STATUS_IS_OK(status)) {
      97             :                 /* what can you do... */
      98           0 :                 return s;
      99             :         }
     100             : 
     101           0 :         return s2;
     102             : }
     103             : 
     104           0 : static NTSTATUS gp_inifile_getstring_ext(struct gp_inifile_context *ctx,
     105             :                                          const char *key,
     106             :                                          const char **ret)
     107             : {
     108           0 :         NTSTATUS status;
     109           0 :         const char *s;
     110             : 
     111           0 :         status = gp_inifile_getstring(ctx, key, &s);
     112           0 :         if (!NT_STATUS_IS_OK(status)) {
     113           0 :                 return status;
     114             :         }
     115             : 
     116           0 :         s = get_string_unquote(s);
     117           0 :         if (s == NULL) {
     118           0 :                 return NT_STATUS_INTERNAL_ERROR;
     119             :         }
     120             : 
     121           0 :         if (s[0] == '%' && s[strlen(s)-1] == '%') {
     122           0 :                 s = get_string_token(ctx, s);
     123             :         }
     124             : 
     125           0 :         s = get_string_unquote(s);
     126           0 :         if (s == NULL) {
     127           0 :                 return NT_STATUS_INTERNAL_ERROR;
     128             :         }
     129             : 
     130           0 :         *ret = s;
     131             : 
     132           0 :         return NT_STATUS_OK;
     133             : }
     134             : 
     135           0 : static NTSTATUS find_manufacturer_name(struct gp_inifile_context *ctx,
     136             :                                        TALLOC_CTX *mem_ctx,
     137             :                                        const char *section_name,
     138             :                                        const char **manufacturer_name)
     139             : {
     140           0 :         NTSTATUS status;
     141           0 :         size_t num_keys = 0;
     142           0 :         const char **keys = NULL;
     143           0 :         const char **values = NULL;
     144           0 :         const char *s;
     145           0 :         char *p;
     146             : 
     147           0 :         status = gp_inifile_enum_section(ctx, section_name, &num_keys, &keys, &values);
     148           0 :         if (!NT_STATUS_IS_OK(status)) {
     149           0 :                 return status;
     150             :         }
     151             : 
     152           0 :         if (num_keys < 1) {
     153           0 :                 return NT_STATUS_INVALID_PARAMETER;
     154             :         }
     155             : 
     156           0 :         s = talloc_strdup(mem_ctx, keys[0]);
     157           0 :         if (s == NULL) {
     158           0 :                 return NT_STATUS_NO_MEMORY;
     159             :         }
     160             : 
     161           0 :         p = strchr(s, ':');
     162           0 :         if (p == NULL) {
     163           0 :                 return NT_STATUS_NO_MEMORY;
     164             :         }
     165           0 :         *p = '\0';
     166           0 :         p++;
     167             : 
     168           0 :         s = get_string_unquote(p);
     169           0 :         if (s == NULL) {
     170           0 :                 return NT_STATUS_INTERNAL_ERROR;
     171             :         }
     172             : 
     173           0 :         s = get_string_token(ctx, s);
     174             : 
     175           0 :         s = get_string_unquote(s);
     176           0 :         if (s == NULL) {
     177           0 :                 return NT_STATUS_INTERNAL_ERROR;
     178             :         }
     179             : 
     180           0 :         if (s != NULL) {
     181           0 :                 *manufacturer_name = talloc_strdup(mem_ctx, s);
     182           0 :                 if (*manufacturer_name == NULL) {
     183           0 :                         return NT_STATUS_NO_MEMORY;
     184             :                 }
     185             :         }
     186             : 
     187           0 :         talloc_free(keys);
     188           0 :         talloc_free(values);
     189             : 
     190           0 :         return NT_STATUS_OK;
     191             : }
     192             : 
     193           0 : static NTSTATUS find_manufacturer_url(struct gp_inifile_context *ctx,
     194             :                                       TALLOC_CTX *mem_ctx,
     195             :                                       const char *section_name,
     196             :                                       const char *manufacturer_name,
     197             :                                       const char **manufacturer_url)
     198             : {
     199           0 :         NTSTATUS status;
     200           0 :         size_t num_keys = 0;
     201           0 :         const char **keys = NULL;
     202           0 :         const char **values = NULL;
     203           0 :         const char *s;
     204           0 :         char *p;
     205             : 
     206           0 :         status = gp_inifile_enum_section(ctx, section_name, &num_keys, &keys, &values);
     207             : 
     208           0 :         if (!NT_STATUS_IS_OK(status)) {
     209           0 :                 return status;
     210             :         }
     211             : 
     212           0 :         if (num_keys < 1) {
     213           0 :                 return NT_STATUS_INVALID_PARAMETER;
     214             :         }
     215             : 
     216           0 :         p = strchr(keys[0], ':');
     217           0 :         if (p == NULL) {
     218           0 :                 return NT_STATUS_NO_MEMORY;
     219             :         }
     220           0 :         *p = '\0';
     221           0 :         p++;
     222             : 
     223           0 :         s = get_string_unquote(p);
     224           0 :         if (s == NULL) {
     225           0 :                 return NT_STATUS_INTERNAL_ERROR;
     226             :         }
     227             : 
     228           0 :         s = get_string_token(ctx, s);
     229             : 
     230           0 :         s = get_string_unquote(s);
     231           0 :         if (s == NULL) {
     232           0 :                 return NT_STATUS_INTERNAL_ERROR;
     233             :         }
     234             : 
     235           0 :         if (strequal(s, manufacturer_name)) {
     236           0 :                 s = get_string_unquote(values[0]);
     237           0 :                 if (s == NULL) {
     238           0 :                         return NT_STATUS_INTERNAL_ERROR;
     239             :                 }
     240             :         }
     241             : 
     242           0 :         if (s != NULL) {
     243           0 :                 *manufacturer_url = talloc_strdup(mem_ctx, s);
     244           0 :                 if (*manufacturer_url == NULL) {
     245           0 :                         return NT_STATUS_NO_MEMORY;
     246             :                 }
     247             :         }
     248             : 
     249           0 :         talloc_free(keys);
     250           0 :         talloc_free(values);
     251             : 
     252           0 :         return NT_STATUS_OK;
     253             : }
     254             : 
     255           0 : static NTSTATUS add_string_to_spoolss_array(TALLOC_CTX *mem_ctx,
     256             :                                             const char *s,
     257             :                                             struct spoolss_StringArray **r)
     258             : {
     259           0 :         size_t count = 2;
     260           0 :         struct spoolss_StringArray *a = *r;
     261           0 :         bool ok;
     262           0 :         int i;
     263             : 
     264           0 :         if (a == NULL) {
     265           0 :                 a = talloc_zero(mem_ctx, struct spoolss_StringArray);
     266           0 :                 if (a == NULL) {
     267           0 :                         return NT_STATUS_NO_MEMORY;
     268             :                 }
     269             :         }
     270             : 
     271           0 :         if (a->string == NULL) {
     272           0 :                 a->string = talloc_zero_array(a, const char *, count);
     273           0 :                 if (a->string == NULL) {
     274           0 :                         return NT_STATUS_NO_MEMORY;
     275             :                 }
     276             :         }
     277             : 
     278           0 :         for (i = 0; a->string[i] != NULL; i++) { ;; }
     279           0 :         count = i;
     280             : 
     281           0 :         ok = add_string_to_array(mem_ctx, s, &a->string, &count);
     282           0 :         if (!ok) {
     283           0 :                 return NT_STATUS_NO_MEMORY;
     284             :         }
     285             : 
     286           0 :         a->string = talloc_realloc(mem_ctx, a->string, const char *, count + 1);
     287           0 :         if (a->string == NULL) {
     288           0 :                 return NT_STATUS_NO_MEMORY;
     289             :         }
     290           0 :         a->string[count] = NULL;
     291             : 
     292           0 :         *r = a;
     293             : 
     294           0 :         return NT_STATUS_OK;
     295             : }
     296             : 
     297           0 : static NTSTATUS add_dependent_driver_file(TALLOC_CTX *mem_ctx,
     298             :                                           const char *file,
     299             :                                           struct spoolss_StringArray **r)
     300             : {
     301           0 :         char *p;
     302             : 
     303           0 :         if (file == NULL) {
     304           0 :                 return NT_STATUS_INVALID_PARAMETER;
     305             :         }
     306             : 
     307           0 :         if (file[0] == '@') {
     308           0 :                 file++;
     309             :         }
     310             : 
     311           0 :         p = strchr(file, ',');
     312           0 :         if (p != NULL) {
     313           0 :                 *p = '\0';
     314             :         }
     315             : 
     316           0 :         return add_string_to_spoolss_array(mem_ctx, file, r);
     317             : }
     318             : 
     319             : /*
     320             :  * https://msdn.microsoft.com/de-de/windows/hardware/drivers/install/inf-manufacturer-section
     321             :  *
     322             :  * [Manufacturer]
     323             :  * "Kyocera"=Kyocera,NTx86.5.1,NTx86.6.0,NTamd64.5.1,NTamd64.6.0
     324             :  */
     325             : 
     326           0 : static NTSTATUS enum_devices_in_toc(struct gp_inifile_context *ctx,
     327             :                                     TALLOC_CTX *mem_ctx,
     328             :                                     size_t *pnum_devices,
     329             :                                     const char ***pdevices,
     330             :                                     const char ***pdevice_values)
     331             : {
     332           0 :         NTSTATUS status;
     333           0 :         size_t i, num_manufacturers = 0;
     334           0 :         const char **manufacturers = NULL;
     335           0 :         const char **values = NULL;
     336           0 :         char *p;
     337           0 :         bool ok;
     338             : 
     339           0 :         status = gp_inifile_enum_section(ctx, "Manufacturer", &num_manufacturers, &manufacturers, &values);
     340           0 :         if (!NT_STATUS_IS_OK(status)) {
     341           0 :                 return status;
     342             :         }
     343             : 
     344           0 :         for (i = 0; i < num_manufacturers; i++) {
     345             : 
     346           0 :                 const char *models_section_name;
     347           0 :                 const char *s;
     348           0 :                 char **decorations;
     349           0 :                 int j;
     350             : 
     351           0 :                 DEBUG(11,("processing manufacturer: %s\n", manufacturers[i]));
     352             : 
     353           0 :                 status = gp_inifile_getstring(ctx, manufacturers[i], &s);
     354           0 :                 if (!NT_STATUS_IS_OK(status)) {
     355           0 :                         return status;
     356             :                 }
     357             : 
     358           0 :                 decorations = str_list_make_v3(mem_ctx, s, ",");
     359           0 :                 if (decorations == NULL) {
     360           0 :                         return NT_STATUS_NO_MEMORY;
     361             :                 }
     362             : 
     363           0 :                 models_section_name = decorations[0];
     364             : 
     365           0 :                 for (j = 1; decorations[j] != NULL; j++) {
     366             : 
     367             :                         /*
     368             :                          * https://msdn.microsoft.com/de-de/windows/hardware/drivers/install/inf-models-section
     369             :                          */
     370             : 
     371           0 :                         const char *decorated_models_section_name;
     372           0 :                         size_t d, num_devices = 0;
     373           0 :                         const char **devices = NULL;
     374           0 :                         const char **device_values = NULL;
     375           0 :                         size_t c = 0;
     376             : 
     377           0 :                         decorated_models_section_name = talloc_asprintf(mem_ctx, "%s.%s",
     378             :                                                                         models_section_name,
     379           0 :                                                                         decorations[j]);
     380           0 :                         if (decorated_models_section_name == NULL) {
     381           0 :                                 return NT_STATUS_NO_MEMORY;
     382             :                         }
     383             : 
     384           0 :                         DEBUG(11,("processing decorated models_section_name: %s\n",
     385             :                                 decorated_models_section_name));
     386             : 
     387           0 :                         status = gp_inifile_enum_section(ctx, decorated_models_section_name,
     388             :                                                          &num_devices, &devices,
     389             :                                                          &device_values);
     390           0 :                         if (!NT_STATUS_IS_OK(status)) {
     391           0 :                                 return status;
     392             :                         }
     393           0 :                         for (d = 0; d < num_devices; d++) {
     394             : 
     395           0 :                                 DEBUG(11,("processing device: %s\n",
     396             :                                         devices[d]));
     397             : 
     398           0 :                                 s = talloc_strdup(mem_ctx, devices[d]);
     399           0 :                                 if (s == NULL) {
     400           0 :                                         return NT_STATUS_NO_MEMORY;
     401             :                                 }
     402             : 
     403           0 :                                 p = strchr(s, ':');
     404           0 :                                 if (p == NULL) {
     405           0 :                                         return NT_STATUS_DRIVER_INTERNAL_ERROR;
     406             :                                 }
     407             : 
     408           0 :                                 *p = '\0';
     409           0 :                                 p++;
     410             : 
     411           0 :                                 s = get_string_unquote(p);
     412             : 
     413           0 :                                 ok = add_string_to_array(mem_ctx, s, pdevices, pnum_devices);
     414           0 :                                 if (!ok) {
     415           0 :                                         return NT_STATUS_NO_MEMORY;
     416             :                                 }
     417           0 :                                 ok = add_string_to_array(mem_ctx, device_values[d], pdevice_values, &c);
     418           0 :                                 if (!ok) {
     419           0 :                                         return NT_STATUS_NO_MEMORY;
     420             :                                 }
     421             :                         }
     422             :                 }
     423             :         }
     424             : 
     425           0 :         return NT_STATUS_OK;
     426             : }
     427             : 
     428           0 : static NTSTATUS find_device_in_toc(struct gp_inifile_context *ctx,
     429             :                                    TALLOC_CTX *mem_ctx,
     430             :                                    const char *device_description,
     431             :                                    const char **value)
     432             : {
     433           0 :         NTSTATUS status;
     434           0 :         size_t d, num_devices = 0;
     435           0 :         const char **devices = NULL;
     436           0 :         const char **device_values = NULL;
     437             : 
     438           0 :         if (device_description == NULL) {
     439           0 :                 return NT_STATUS_INVALID_PARAMETER;
     440             :         }
     441             : 
     442           0 :         status = enum_devices_in_toc(ctx, mem_ctx,
     443             :                                      &num_devices,
     444             :                                      &devices,
     445             :                                      &device_values);
     446           0 :         if (!NT_STATUS_IS_OK(status)) {
     447           0 :                 return status;
     448             :         }
     449             : 
     450           0 :         for (d = 0; d < num_devices; d++) {
     451             : 
     452           0 :                 if (strequal(device_description, devices[d])) {
     453             : 
     454           0 :                         DEBUG(10,("found device_description: %s\n",
     455             :                                 device_description));
     456             : 
     457           0 :                         *value = talloc_strdup(mem_ctx, device_values[d]);
     458           0 :                         if (*value == NULL) {
     459           0 :                                 return NT_STATUS_NO_MEMORY;
     460             :                         }
     461           0 :                         DEBUGADD(10,("and returned: %s\n", *value));
     462             : 
     463           0 :                         return NT_STATUS_OK;
     464             :                 }
     465             :         }
     466             : 
     467           0 :         return NT_STATUS_DRIVER_INTERNAL_ERROR;
     468             : }
     469             : 
     470             : /*
     471             :  * https://msdn.microsoft.com/de-de/windows/hardware/drivers/install/inf-copyfiles-directive
     472             :  */
     473             : 
     474           0 : static NTSTATUS process_driver_section_copyfiles(struct gp_inifile_context *ctx,
     475             :                                                  TALLOC_CTX *mem_ctx,
     476             :                                                  const char *driver_section,
     477             :                                                  struct spoolss_AddDriverInfo8 *r)
     478             : {
     479           0 :         NTSTATUS status;
     480           0 :         size_t i, num_keys = 0;
     481           0 :         char *p, *key;
     482           0 :         const char **keys = NULL;
     483           0 :         const char **values = NULL;
     484           0 :         char *str;
     485           0 :         const char *s;
     486             : 
     487           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", driver_section, "CopyFiles");
     488           0 :         if (key == NULL) {
     489           0 :                 return NT_STATUS_NO_MEMORY;
     490             :         }
     491             : 
     492           0 :         DEBUG(10,("Checking for CopyFiles entry in %s\n", driver_section));
     493             : 
     494           0 :         status = gp_inifile_getstring(ctx, key, &s);
     495           0 :         if (!NT_STATUS_IS_OK(status)) {
     496           0 :                 return NT_STATUS_OK;
     497             :         }
     498             : 
     499           0 :         DEBUG(10,("these are the files to copy: %s\n", s));
     500             : 
     501           0 :         while (next_token_talloc(mem_ctx, &s, &str, ",")) {
     502             : 
     503           0 :                 DEBUG(10,("trying section: %s\n", str));
     504             : 
     505           0 :                 if (str[0] == '@') {
     506           0 :                         DEBUG(10,("adding dependent driver file: %s\n", str));
     507           0 :                         status = add_dependent_driver_file(mem_ctx, str, &r->dependent_files);
     508           0 :                         if (!NT_STATUS_IS_OK(status)) {
     509           0 :                                 return status;
     510             :                         }
     511           0 :                         continue;
     512             :                 }
     513             : 
     514           0 :                 status = gp_inifile_enum_section(ctx, str, &num_keys, &keys, &values);
     515           0 :                 if (NT_STATUS_IS_OK(status)) {
     516           0 :                         for (i = 0; i < num_keys; i++) {
     517           0 :                                 p = strchr(keys[i], ':');
     518           0 :                                 if (p == NULL) {
     519           0 :                                         return NT_STATUS_INVALID_PARAMETER;
     520             :                                 }
     521           0 :                                 *p = '\0';
     522           0 :                                 p++;
     523             : 
     524           0 :                                 DEBUG(10,("adding dependent driver file: %s\n", p));
     525             : 
     526           0 :                                 status = add_dependent_driver_file(mem_ctx, p, &r->dependent_files);
     527           0 :                                 if (!NT_STATUS_IS_OK(status)) {
     528           0 :                                         return status;
     529             :                                 }
     530             :                         }
     531           0 :                         TALLOC_FREE(keys);
     532           0 :                         TALLOC_FREE(values);
     533             :                 }
     534             :         }
     535             : 
     536           0 :         return NT_STATUS_OK;
     537             : }
     538             : 
     539             : #define process_driver_section_val(_ctx, _mem_ctx, _section, _r, _key, _element) \
     540             : do { \
     541             :         NTSTATUS _status; \
     542             :         const char *__key, *_s; \
     543             :         __key = talloc_asprintf(_mem_ctx, "%s:%s", _section, _key); \
     544             :         NT_STATUS_HAVE_NO_MEMORY(__key); \
     545             :         _status = gp_inifile_getstring(_ctx, __key, &_s); \
     546             :         if (NT_STATUS_IS_OK(_status)) { \
     547             :                 (_r)->_element = talloc_strdup(mem_ctx, _s); \
     548             :                 NT_STATUS_HAVE_NO_MEMORY((_r)->_element); \
     549             :         } \
     550             : } while(0);
     551             : 
     552           0 : static NTSTATUS process_driver_section_colorprofiles(struct gp_inifile_context *ctx,
     553             :                                                      TALLOC_CTX *mem_ctx,
     554             :                                                      const char *section,
     555             :                                                      struct spoolss_AddDriverInfo8 *r)
     556             : {
     557           0 :         NTSTATUS status;
     558           0 :         const char *key, *s;
     559             : 
     560           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", section, "ColorProfiles");
     561           0 :         if (key == NULL) {
     562           0 :                 return NT_STATUS_NO_MEMORY;
     563             :         }
     564             : 
     565           0 :         status = gp_inifile_getstring_ext(ctx, key, &s);
     566           0 :         if (NT_STATUS_IS_OK(status)) {
     567             : 
     568           0 :                 status = add_string_to_spoolss_array(mem_ctx, s, &r->color_profiles);
     569           0 :                 if (!NT_STATUS_IS_OK(status)) {
     570           0 :                         return status;
     571             :                 }
     572             :         }
     573             : 
     574           0 :         return NT_STATUS_OK;
     575             : }
     576             : 
     577           0 : static NTSTATUS process_driver_section_printprocessor(struct gp_inifile_context *ctx,
     578             :                                                       TALLOC_CTX *mem_ctx,
     579             :                                                       const char *section,
     580             :                                                       struct spoolss_AddDriverInfo8 *r)
     581             : {
     582           0 :         NTSTATUS status;
     583           0 :         char *key, *p;
     584           0 :         const char *s;
     585             : 
     586           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", section, "PrintProcessor");
     587           0 :         if (key == NULL) {
     588           0 :                 return NT_STATUS_NO_MEMORY;
     589             :         }
     590             : 
     591           0 :         status = gp_inifile_getstring_ext(ctx, key, &s);
     592           0 :         if (NT_STATUS_IS_OK(status)) {
     593           0 :                 s = get_string_unquote(s);
     594             : 
     595           0 :                 p = strchr(s, ',');
     596           0 :                 if (p == NULL) {
     597           0 :                         return NT_STATUS_INVALID_PARAMETER;
     598             :                 }
     599           0 :                 *p = '\0';
     600           0 :                 r->print_processor = talloc_strdup(mem_ctx, s);
     601           0 :                 if (r->print_processor == NULL) {
     602           0 :                         return NT_STATUS_NO_MEMORY;
     603             :                 }
     604             :         }
     605             : 
     606           0 :         return NT_STATUS_OK;
     607             : }
     608             : 
     609           0 : static NTSTATUS process_driver_section_data_section(struct gp_inifile_context *ctx,
     610             :                                                     TALLOC_CTX *mem_ctx,
     611             :                                                     const char *section,
     612             :                                                     struct spoolss_AddDriverInfo8 *r)
     613             : {
     614           0 :         NTSTATUS status;
     615           0 :         char *key;
     616           0 :         const char *s;
     617             : 
     618           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", section, "DataSection");
     619           0 :         if (key == NULL) {
     620           0 :                 return NT_STATUS_NO_MEMORY;
     621             :         }
     622             : 
     623           0 :         status = gp_inifile_getstring(ctx, key, &s);
     624           0 :         if (NT_STATUS_IS_OK(status)) {
     625           0 :                 process_driver_section_val(ctx, mem_ctx, s, r,
     626           0 :                                            "DriverFile", driver_path);
     627           0 :                 process_driver_section_val(ctx, mem_ctx, s, r,
     628           0 :                                            "HelpFile", help_file);
     629           0 :                 process_driver_section_val(ctx, mem_ctx, s, r,
     630           0 :                                            "DataFile", data_file);
     631           0 :                 process_driver_section_val(ctx, mem_ctx, s, r,
     632           0 :                                            "ConfigFile", config_file);
     633             :         }
     634             : 
     635           0 :         return NT_STATUS_OK;
     636             : }
     637             : 
     638             : 
     639           0 : static NTSTATUS process_one_core_driver_section(struct gp_inifile_context *core_ctx,
     640             :                                                 TALLOC_CTX *mem_ctx,
     641             :                                                 const char *driver_section,
     642             :                                                 struct spoolss_AddDriverInfo8 *r)
     643             : {
     644           0 :         NTSTATUS status;
     645           0 :         size_t i, num_keys = 0;
     646           0 :         const char **keys = NULL;
     647           0 :         const char **values = NULL;
     648             : 
     649           0 :         DEBUG(10,("CoreDriverSection is: %s\n", driver_section));
     650             : 
     651           0 :         status = gp_inifile_enum_section(core_ctx, driver_section, &num_keys, &keys, &values);
     652           0 :         if (!NT_STATUS_IS_OK(status)) {
     653           0 :                 return status;
     654             :         }
     655             : 
     656           0 :         for (i = 0; i < num_keys; i++) {
     657             : 
     658           0 :                 status = process_driver_section_copyfiles(core_ctx, mem_ctx, driver_section, r);
     659           0 :                 if (!NT_STATUS_IS_OK(status)) {
     660           0 :                         return status;
     661             :                 }
     662             : 
     663           0 :                 process_driver_section_val(core_ctx, mem_ctx, driver_section, r,
     664           0 :                                            "DriverFile", driver_path);
     665           0 :                 process_driver_section_val(core_ctx, mem_ctx, driver_section, r,
     666           0 :                                            "HelpFile", help_file);
     667           0 :                 process_driver_section_val(core_ctx, mem_ctx, driver_section, r,
     668           0 :                                            "ConfigFile", config_file);
     669             : 
     670           0 :                 status = process_driver_section_colorprofiles(core_ctx, mem_ctx, driver_section, r);
     671           0 :                 if (!NT_STATUS_IS_OK(status)) {
     672           0 :                         return status;
     673             :                 }
     674             :         }
     675             : 
     676           0 :         talloc_free(keys);
     677           0 :         talloc_free(values);
     678             : 
     679           0 :         return NT_STATUS_OK;
     680             : }
     681             : 
     682             : /*
     683             :  * CoreDriverSections="{D20EA372-DD35-4950-9ED8-A6335AFE79F0},UNIDRV_BIDI.OEM,UNIDRV_BIDI_DATA","{D20EA372-DD35-4950-9ED8-A6335AFE79F2},PCLXL.OEM","{D20EA372-DD35-4950-9ED8-A6335AFE79F3},sRGBPROFILE.OEM"
     684             :  */
     685           0 : static NTSTATUS process_core_driver_sections(struct gp_inifile_context *core_ctx,
     686             :                                              TALLOC_CTX *mem_ctx,
     687             :                                              const char *value,
     688             :                                              struct spoolss_AddDriverInfo8 *r)
     689             : {
     690           0 :         NTSTATUS status;
     691           0 :         char *p;
     692           0 :         char **list;
     693           0 :         int i;
     694             : 
     695           0 :         list = str_list_make_v3(mem_ctx, value, ",");
     696           0 :         if (list == NULL) {
     697           0 :                 return NT_STATUS_NO_MEMORY;
     698             :         }
     699             : 
     700           0 :         for (i = 0; list[i] != NULL; i++) {
     701           0 :                 char **array;
     702           0 :                 int a;
     703             : 
     704             :                 /* FIXME: do we have to validate the core driver guid ? */
     705             : 
     706           0 :                 p = strchr(list[i], ',');
     707           0 :                 if (p != NULL) {
     708           0 :                         *p = '\0';
     709           0 :                         p++;
     710             :                 }
     711             : 
     712           0 :                 DEBUG(10,("CoreDriverSections we have to process: %s\n", p));
     713             : 
     714           0 :                 array = str_list_make_v3(mem_ctx, p, ",");
     715           0 :                 if (array == NULL) {
     716           0 :                         return NT_STATUS_NO_MEMORY;
     717             :                 }
     718             : 
     719           0 :                 for (a = 0; array[a] != NULL; a++) {
     720             : 
     721           0 :                         if (core_ctx == NULL) {
     722           0 :                                 DEBUG(0,("Need to process CoreDriverSections but "
     723             :                                         "have no Core Driver Context!\n"));
     724           0 :                                 return NT_STATUS_DRIVER_INTERNAL_ERROR;
     725             :                         }
     726             : 
     727           0 :                         status = process_one_core_driver_section(core_ctx, mem_ctx, array[a], r);
     728           0 :                         if (!NT_STATUS_IS_OK(status)) {
     729           0 :                                 continue;
     730             :                         }
     731             :                 }
     732             :         }
     733             : 
     734           0 :         return NT_STATUS_OK;
     735             : }
     736             : 
     737             : /*
     738             :  * https://msdn.microsoft.com/de-de/windows/hardware/drivers/install/inf-ddinstall-section
     739             :  */
     740           0 : static NTSTATUS find_driver_files(struct gp_inifile_context *ctx,
     741             :                                   struct gp_inifile_context *core_ctx,
     742             :                                   TALLOC_CTX *mem_ctx,
     743             :                                   const char *driver_name,
     744             :                                   struct spoolss_AddDriverInfo8 *r)
     745             : {
     746           0 :         NTSTATUS status;
     747           0 :         char *key;
     748           0 :         const char *s;
     749           0 :         const char *value;
     750           0 :         char *install_section_name;
     751           0 :         bool ok;
     752           0 :         char *hw_id;
     753             : 
     754           0 :         status = find_device_in_toc(ctx, mem_ctx, driver_name, &value);
     755           0 :         if (!NT_STATUS_IS_OK(status)) {
     756           0 :                 return status;
     757             :         }
     758             : 
     759           0 :         r->driver_name = talloc_strdup(mem_ctx, driver_name);
     760           0 :         if (r->driver_name == NULL) {
     761           0 :                 return NT_STATUS_NO_MEMORY;
     762             :         }
     763             : 
     764           0 :         ok = next_token_talloc(mem_ctx, &value, &install_section_name, ",");
     765           0 :         if (!ok) {
     766           0 :                 return NT_STATUS_INVALID_PARAMETER;
     767             :         }
     768             : 
     769           0 :         DEBUG(10,("driver_name: %s, value: %s, install_section_name: %s\n",
     770             :                 driver_name, value, install_section_name));
     771             : 
     772             :         /* Hardware Id is optional */
     773           0 :         ok = next_token_talloc(mem_ctx, &value, &hw_id, ",");
     774           0 :         if (ok) {
     775           0 :                 r->hardware_id = hw_id;
     776             :         }
     777             : 
     778           0 :         status = process_driver_section_copyfiles(ctx, mem_ctx, install_section_name, r);
     779           0 :         if (!NT_STATUS_IS_OK(status)) {
     780           0 :                 return status;
     781             :         }
     782             : 
     783           0 :         process_driver_section_val(ctx, mem_ctx, install_section_name, r,
     784           0 :                                    "DriverFile", driver_path);
     785           0 :         process_driver_section_val(ctx, mem_ctx, install_section_name, r,
     786           0 :                                    "HelpFile", help_file);
     787           0 :         process_driver_section_val(ctx, mem_ctx, install_section_name, r,
     788           0 :                                    "DataFile", data_file);
     789           0 :         process_driver_section_val(ctx, mem_ctx, install_section_name, r,
     790           0 :                                    "ConfigFile", config_file);
     791             : 
     792           0 :         status = process_driver_section_printprocessor(ctx, mem_ctx, install_section_name, r);
     793           0 :         if (!NT_STATUS_IS_OK(status)) {
     794           0 :                 return status;
     795             :         }
     796             : 
     797           0 :         status = process_driver_section_data_section(ctx, mem_ctx, install_section_name, r);
     798           0 :         if (!NT_STATUS_IS_OK(status)) {
     799           0 :                 return status;
     800             :         }
     801             : 
     802           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", install_section_name, "CoreDriverSections");
     803           0 :         if (key == NULL) {
     804           0 :                 return NT_STATUS_NO_MEMORY;
     805             :         }
     806             : 
     807           0 :         status = gp_inifile_getstring(ctx, key, &s);
     808           0 :         if (NT_STATUS_IS_OK(status)) {
     809             : 
     810           0 :                 DEBUG(10,("found CoreDriverSections: %s\n", s));
     811             : 
     812           0 :                 status = process_core_driver_sections(core_ctx, mem_ctx, s, r);
     813           0 :                 if (!NT_STATUS_IS_OK(status)) {
     814           0 :                         return status;
     815             :                 }
     816             :         }
     817             : 
     818           0 :         return NT_STATUS_OK;
     819             : }
     820             : 
     821             : struct inf_context {
     822             :         struct gp_inifile_context *ctx;
     823             :         struct gp_inifile_context *core_ctx;
     824             : };
     825             : 
     826           0 : static NTSTATUS init_inf_context(TALLOC_CTX *mem_ctx,
     827             :                                  const char *inf_filename,
     828             :                                  const char *core_filename,
     829             :                                  struct inf_context **_inf_ctx)
     830             : {
     831           0 :         NTSTATUS status;
     832           0 :         struct gp_inifile_context *ctx;
     833           0 :         struct gp_inifile_context *core_ctx = NULL;
     834           0 :         struct inf_context *inf_ctx;
     835             : 
     836           0 :         inf_ctx = talloc_zero(mem_ctx, struct inf_context);
     837           0 :         if (inf_ctx == NULL) {
     838           0 :                 return NT_STATUS_NO_MEMORY;
     839             :         }
     840             : 
     841           0 :         status = gp_inifile_init_context_direct(mem_ctx,
     842             :                                                 inf_filename,
     843             :                                                 &ctx);
     844           0 :         if (!NT_STATUS_IS_OK(status)) {
     845           0 :                 DEBUG(10,("init_inf_context: failed to load %s\n", inf_filename));
     846           0 :                 return status;
     847             :         }
     848             : 
     849           0 :         if (ctx->generated_filename != NULL) {
     850           0 :                 unlink(ctx->generated_filename);
     851             :         }
     852             : 
     853           0 :         if (core_filename != NULL) {
     854           0 :                 status = gp_inifile_init_context_direct(mem_ctx,
     855             :                                                         core_filename,
     856             :                                                         &core_ctx);
     857           0 :                 if (!NT_STATUS_IS_OK(status)) {
     858           0 :                         DEBUG(10,("init_inf_context: failed to load %s\n", core_filename));
     859           0 :                         return status;
     860             :                 }
     861             : 
     862           0 :                 if (core_ctx->generated_filename != NULL) {
     863           0 :                         unlink(core_ctx->generated_filename);
     864             :                 }
     865             :         }
     866             : 
     867           0 :         inf_ctx->ctx = ctx;
     868           0 :         inf_ctx->core_ctx = core_ctx;
     869             : 
     870           0 :         *_inf_ctx = inf_ctx;
     871             : 
     872           0 :         return NT_STATUS_OK;
     873             : }
     874             : 
     875           0 : static NTSTATUS process_driver_driverver(struct gp_inifile_context *ctx,
     876             :                                          struct spoolss_AddDriverInfo8 *r)
     877             : {
     878           0 :         NTSTATUS status;
     879           0 :         const char *s;
     880           0 :         char *p;
     881           0 :         bool ok;
     882           0 :         const char *str;
     883             : 
     884           0 :         status = gp_inifile_getstring(ctx, "Version:DriverVer", &s);
     885           0 :         if (!NT_STATUS_IS_OK(status)) {
     886           0 :                 return status;
     887             :         }
     888             : 
     889           0 :         str = talloc_strdup(ctx, s);
     890           0 :         if (str == NULL) {
     891           0 :                 return NT_STATUS_NO_MEMORY;
     892             :         }
     893             : 
     894           0 :         p = strchr(str, ',');
     895           0 :         if (p) {
     896           0 :                 *p = '\0';
     897           0 :                 p++;
     898             :         }
     899             : 
     900           0 :         ok = spoolss_timestr_to_NTTIME(str, &r->driver_date);
     901           0 :         if (!ok) {
     902           0 :                 return NT_STATUS_INVALID_PARAMETER;
     903             :         }
     904             : 
     905           0 :         ok = spoolss_driver_version_to_qword(p, &r->driver_version);
     906           0 :         if (!ok) {
     907           0 :                 return NT_STATUS_INVALID_PARAMETER;
     908             :         }
     909             : 
     910           0 :         return NT_STATUS_OK;
     911             : }
     912             : 
     913             : /*
     914             :  * Parse a SourceDisksNames section,
     915             :  * https://msdn.microsoft.com/de-de/windows/hardware/drivers/install/inf-sourcedisksnames-section?f=255&MSPPError=-2147217396
     916             :  */
     917           0 : static NTSTATUS process_source_disk_name(struct gp_inifile_context *ctx,
     918             :                                          TALLOC_CTX *mem_ctx,
     919             :                                          const char *short_environment,
     920             :                                          const char **source_disk_name)
     921             : {
     922           0 :         NTSTATUS status;
     923           0 :         bool ok;
     924           0 :         const char *key;
     925           0 :         size_t i, num_keys = 0;
     926           0 :         const char **keys = NULL;
     927           0 :         const char **values = NULL;
     928             : 
     929           0 :         key = talloc_asprintf(mem_ctx, "SourceDisksNames.%s", short_environment);
     930           0 :         if (key == NULL) {
     931           0 :                 return NT_STATUS_NO_MEMORY;
     932             :         }
     933             : 
     934           0 :         status = gp_inifile_enum_section(ctx, key, &num_keys, &keys, &values);
     935           0 :         if (!NT_STATUS_IS_OK(status)) {
     936           0 :                 return status;
     937             :         }
     938             : 
     939           0 :         if (keys == NULL && values == NULL) {
     940           0 :                 key = "SourceDisksNames";
     941             : 
     942           0 :                 status = gp_inifile_enum_section(ctx, key, &num_keys, &keys, &values);
     943           0 :                 if (!NT_STATUS_IS_OK(status)) {
     944           0 :                         return status;
     945             :                 }
     946             :         }
     947             : 
     948           0 :         for (i = 0; i < num_keys; i++) {
     949             : 
     950             :                 /*
     951             :                  * 1   = %Disk1%,,,"Amd64"
     952             :                  * diskid = disk-description[,[tag-or-cab-file],[unused],[path],[flags][,tag-file]]
     953             :                  */
     954           0 :                 char *disk_description, *tag_or_cab_file, *unused, *path;
     955             : 
     956           0 :                 ok = next_token_no_ltrim_talloc(mem_ctx, &values[i], &disk_description, ",");
     957           0 :                 if (!ok) {
     958           0 :                         continue;
     959             :                 }
     960             : 
     961           0 :                 ok = next_token_no_ltrim_talloc(mem_ctx, &values[i], &tag_or_cab_file, ",");
     962           0 :                 if (!ok) {
     963           0 :                         continue;
     964             :                 }
     965             : 
     966           0 :                 ok = next_token_no_ltrim_talloc(mem_ctx, &values[i], &unused, ",");
     967           0 :                 if (!ok) {
     968           0 :                         continue;
     969             :                 }
     970             : 
     971           0 :                 ok = next_token_no_ltrim_talloc(mem_ctx, &values[i], &path, ",");
     972           0 :                 if (!ok) {
     973           0 :                         continue;
     974             :                 }
     975             : 
     976           0 :                 *source_disk_name = path;
     977             : 
     978           0 :                 return NT_STATUS_OK;
     979             :         }
     980             : 
     981           0 :         return NT_STATUS_NOT_FOUND;
     982             : }
     983             : 
     984           0 : static NTSTATUS setup_driver_by_name(TALLOC_CTX *mem_ctx,
     985             :                                      struct inf_context *inf_ctx,
     986             :                                      const char *filename,
     987             :                                      const char *environment,
     988             :                                      const char *driver_name,
     989             :                                      struct spoolss_AddDriverInfo8 *r,
     990             :                                      const char **source_disk_name)
     991             : {
     992           0 :         NTSTATUS status;
     993           0 :         struct gp_inifile_context *ctx = inf_ctx->ctx;
     994           0 :         struct gp_inifile_context *core_ctx = inf_ctx->core_ctx;
     995           0 :         char *key;
     996           0 :         bool ok;
     997           0 :         const char *short_environment;
     998           0 :         const char *s;
     999             : 
    1000           0 :         short_environment = spoolss_get_short_filesys_environment(environment);
    1001           0 :         if (short_environment == NULL) {
    1002           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1003             :         }
    1004             : 
    1005           0 :         status = find_driver_files(ctx, core_ctx, mem_ctx, driver_name, r);
    1006           0 :         if (!NT_STATUS_IS_OK(status)) {
    1007           0 :                 return status;
    1008             :         }
    1009             : 
    1010           0 :         status = process_source_disk_name(ctx, mem_ctx,
    1011             :                                           short_environment,
    1012             :                                           source_disk_name);
    1013           0 :         if (!NT_STATUS_IS_OK(status)) {
    1014           0 :                 return status;
    1015             :         }
    1016             : 
    1017           0 :         r->inf_path = talloc_strdup(mem_ctx, filename);
    1018           0 :         if (r->inf_path == NULL) {
    1019           0 :                 return NT_STATUS_NO_MEMORY;
    1020             :         }
    1021             : 
    1022           0 :         r->architecture = talloc_strdup(mem_ctx, environment);
    1023           0 :         if (r->architecture == NULL) {
    1024           0 :                 return NT_STATUS_NO_MEMORY;
    1025             :         }
    1026             : 
    1027           0 :         if (r->print_processor == NULL) {
    1028           0 :                 r->print_processor = talloc_strdup(mem_ctx, "winprint");
    1029           0 :                 if (r->print_processor == NULL) {
    1030           0 :                         return NT_STATUS_NO_MEMORY;
    1031             :                 }
    1032             :         }
    1033             : 
    1034           0 :         status = gp_inifile_getstring_ext(ctx, "Version:Class", &s);
    1035           0 :         if (NT_STATUS_IS_OK(status)) {
    1036           0 :                 if (strequal(s, "Printer")) {
    1037           0 :                         r->printer_driver_attributes |= PRINTER_DRIVER_CLASS;
    1038             :                 }
    1039             :         }
    1040             : 
    1041           0 :         status = gp_inifile_getstring(ctx, "Version:Signature", &s);
    1042           0 :         if (!NT_STATUS_IS_OK(status)) {
    1043           0 :                 return status;
    1044             :         }
    1045           0 :         if (!strequal(s, "\"$Windows NT$\"")) {
    1046           0 :                 return NT_STATUS_INVALID_SIGNATURE;
    1047             :         }
    1048             : 
    1049           0 :         r->version = SPOOLSS_DRIVER_VERSION_200X;
    1050           0 :         status = gp_inifile_getstring(ctx, "Version:ClassVer", &s);
    1051           0 :         if (NT_STATUS_IS_OK(status)) {
    1052           0 :                 int cmp = strncasecmp_m(s, "4.0", 3);
    1053           0 :                 if (cmp == 0) {
    1054           0 :                         r->version = SPOOLSS_DRIVER_VERSION_2012;
    1055             :                 }
    1056           0 :                 if (strequal(s, "3.0")) {
    1057           0 :                         r->version = SPOOLSS_DRIVER_VERSION_200X;
    1058             :                 }
    1059             :         }
    1060             : 
    1061           0 :         status = gp_inifile_getstring_ext(ctx, "Version:Provider", &s);
    1062           0 :         if (NT_STATUS_IS_OK(status)) {
    1063           0 :                 if (s != NULL) {
    1064           0 :                         r->provider = talloc_strdup(mem_ctx, s);
    1065           0 :                         if (r->provider == NULL) {
    1066           0 :                                 return NT_STATUS_NO_MEMORY;
    1067             :                         }
    1068             :                 }
    1069             :         }
    1070             : 
    1071           0 :         status = process_driver_driverver(ctx, r);
    1072           0 :         if (!NT_STATUS_IS_OK(status)) {
    1073           0 :                 return status;
    1074             :         }
    1075             : 
    1076           0 :         r->printer_driver_attributes &= ~PRINTER_DRIVER_SANDBOX_ENABLED;
    1077             : 
    1078           0 :         status = gp_inifile_getstring(ctx, "Version:DriverIsolation", &s);
    1079           0 :         if (NT_STATUS_IS_OK(status)) {
    1080           0 :                 int cmp = strncasecmp_m(s, "2", 1);
    1081           0 :                 if (cmp == 0) {
    1082           0 :                         r->printer_driver_attributes |= PRINTER_DRIVER_SANDBOX_ENABLED;
    1083             :                 }
    1084           0 :                 cmp = strncasecmp_m(s, "0", 1);
    1085           0 :                 if (cmp == 0) {
    1086           0 :                         r->printer_driver_attributes &= ~PRINTER_DRIVER_SANDBOX_ENABLED;
    1087             :                 }
    1088             :         }
    1089             : 
    1090           0 :         status = find_manufacturer_name(ctx, mem_ctx, "Manufacturer", &r->manufacturer_name);
    1091           0 :         if (!NT_STATUS_IS_OK(status)) {
    1092           0 :                 return status;
    1093             :         }
    1094             : 
    1095           0 :         status = find_manufacturer_url(ctx, mem_ctx, "OEM URLS", r->manufacturer_name, &r->manufacturer_url);
    1096           0 :         if (!NT_STATUS_IS_OK(status)) {
    1097             :                 /* not critical */
    1098           0 :         }
    1099             : 
    1100           0 :         status = gp_inifile_getbool(ctx, "PrinterPackageInstallation:PackageAware", &ok);
    1101           0 :         if (NT_STATUS_IS_OK(status)) {
    1102           0 :                 if (ok) {
    1103           0 :                         r->printer_driver_attributes |= PRINTER_DRIVER_PACKAGE_AWARE;
    1104             :                 }
    1105             :         }
    1106             : 
    1107           0 :         key = talloc_asprintf(mem_ctx, "%s.%s:%s",
    1108             :                 "PrinterPackageInstallation", short_environment, "PackageAware");
    1109           0 :         if (key == NULL) {
    1110           0 :                 return NT_STATUS_NO_MEMORY;
    1111             :         }
    1112             : 
    1113           0 :         status = gp_inifile_getbool(ctx, key, &ok);
    1114           0 :         if (NT_STATUS_IS_OK(status)) {
    1115           0 :                 if (ok) {
    1116           0 :                         r->printer_driver_attributes |= PRINTER_DRIVER_PACKAGE_AWARE;
    1117             :                 }
    1118             :         }
    1119             : 
    1120           0 :         key = talloc_asprintf(mem_ctx, "%s.%s:%s",
    1121             :                 "PrinterPackageInstallation", short_environment, "CoreDriverDependencies");
    1122           0 :         if (key == NULL) {
    1123           0 :                 return NT_STATUS_NO_MEMORY;
    1124             :         }
    1125             : 
    1126           0 :         status = gp_inifile_getstring(ctx, key, &s);
    1127           0 :         if (NT_STATUS_IS_OK(status)) {
    1128           0 :                 char **list;
    1129           0 :                 r->core_driver_dependencies = talloc_zero(mem_ctx, struct spoolss_StringArray);
    1130           0 :                 if (r->core_driver_dependencies == NULL) {
    1131           0 :                         return NT_STATUS_NO_MEMORY;
    1132             :                 }
    1133             : 
    1134           0 :                 list = str_list_make_v3(r->core_driver_dependencies, s, ",");
    1135           0 :                 if (list == NULL) {
    1136           0 :                         return NT_STATUS_NO_MEMORY;
    1137             :                 }
    1138           0 :                 r->core_driver_dependencies->string = const_str_list(list);
    1139             :         }
    1140             : 
    1141           0 :         key = talloc_asprintf(mem_ctx, "%s.%s:%s",
    1142             :                 "PrinterPackageInstallation", short_environment, "InboxVersionRequired");
    1143           0 :         if (key == NULL) {
    1144           0 :                 return NT_STATUS_NO_MEMORY;
    1145             :         }
    1146             : 
    1147           0 :         status = gp_inifile_getstring(ctx, key, &s);
    1148           0 :         if (NT_STATUS_IS_OK(status)) {
    1149           0 :                 if (strequal(s, "UseDriverVer")) {
    1150           0 :                         r->min_inbox_driver_ver_date = r->driver_date;
    1151           0 :                         r->min_inbox_driver_ver_version = r->driver_version;
    1152             :                 }
    1153             :         }
    1154             : 
    1155           0 :         return NT_STATUS_OK;
    1156             : }
    1157             : 
    1158             : /****************************************************************
    1159             :  parse a printer inf file
    1160             : ****************************************************************/
    1161             : 
    1162           0 : NTSTATUS driver_inf_parse(TALLOC_CTX *mem_ctx,
    1163             :                           const char *core_driver_inf,
    1164             :                           const char *filename,
    1165             :                           const char *environment,
    1166             :                           const char *driver_name,
    1167             :                           struct spoolss_AddDriverInfo8 *r,
    1168             :                           const char **source_disk_name)
    1169             : {
    1170           0 :         NTSTATUS status;
    1171           0 :         struct inf_context *inf_ctx;
    1172             : 
    1173           0 :         if (!filename || !environment) {
    1174           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1175             :         }
    1176             : 
    1177           0 :         status = init_inf_context(mem_ctx,
    1178             :                                   filename,
    1179             :                                   core_driver_inf,
    1180             :                                   &inf_ctx);
    1181           0 :         if (!NT_STATUS_IS_OK(status)) {
    1182           0 :                 return status;
    1183             :         }
    1184             : 
    1185           0 :         status = setup_driver_by_name(mem_ctx, inf_ctx,
    1186             :                                       filename,
    1187             :                                       environment,
    1188             :                                       driver_name,
    1189             :                                       r,
    1190             :                                       source_disk_name);
    1191           0 :         if (!NT_STATUS_IS_OK(status)) {
    1192           0 :                 return status;
    1193             :         }
    1194             : 
    1195           0 :         return NT_STATUS_OK;
    1196             : }
    1197             : 
    1198           0 : NTSTATUS driver_inf_list(TALLOC_CTX *mem_ctx,
    1199             :                          const char *core_driver_inf,
    1200             :                          const char *filename,
    1201             :                          const char *environment,
    1202             :                          uint32_t *count,
    1203             :                          struct spoolss_AddDriverInfo8 **_r)
    1204             : {
    1205           0 :         NTSTATUS status;
    1206           0 :         const char *short_environment;
    1207           0 :         size_t d, num_devices = 0;
    1208           0 :         const char **devices = NULL;
    1209           0 :         const char **device_values = NULL;
    1210           0 :         struct inf_context *inf_ctx;
    1211             : 
    1212           0 :         if (!filename || !environment) {
    1213           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1214             :         }
    1215             : 
    1216           0 :         short_environment = spoolss_get_short_filesys_environment(environment);
    1217           0 :         if (short_environment == NULL) {
    1218           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1219             :         }
    1220             : 
    1221           0 :         status = init_inf_context(mem_ctx,
    1222             :                                   filename,
    1223             :                                   core_driver_inf,
    1224             :                                   &inf_ctx);
    1225           0 :         if (!NT_STATUS_IS_OK(status)) {
    1226           0 :                 return status;
    1227             :         }
    1228             : 
    1229           0 :         status = enum_devices_in_toc(inf_ctx->ctx, mem_ctx,
    1230             :                                      &num_devices,
    1231             :                                      &devices,
    1232             :                                      &device_values);
    1233           0 :         if (!NT_STATUS_IS_OK(status)) {
    1234           0 :                 return status;
    1235             :         }
    1236             : 
    1237           0 :         for (d = 0; d < num_devices; d++) {
    1238             : 
    1239           0 :                 struct spoolss_AddDriverInfo8 r;
    1240           0 :                 const char *source_disk_name;
    1241             : 
    1242           0 :                 ZERO_STRUCT(r);
    1243             : 
    1244           0 :                 status = setup_driver_by_name(mem_ctx, inf_ctx, filename,
    1245           0 :                                               environment, devices[d], &r,
    1246             :                                               &source_disk_name);
    1247           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1248           0 :                         return status;
    1249             :                 }
    1250             : 
    1251           0 :                 ADD_TO_ARRAY(mem_ctx, struct spoolss_AddDriverInfo8, r, _r, count);
    1252             :         }
    1253             : 
    1254           0 :         return NT_STATUS_OK;
    1255             : }

Generated by: LCOV version 1.14