LCOV - code coverage report
Current view: top level - lib/printer_driver - printer_driver.c (source / functions) Hit Total Coverage
Test: coverage report for master 6248eab5 Lines: 0 544 0.0 %
Date: 2021-08-25 13:27:56 Functions: 0 23 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             :         bool ok;
      47             :         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             :         NTSTATUS status;
      76             :         bool ok;
      77             :         char *key;
      78             :         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             :         NTSTATUS status;
     109             :         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             :         NTSTATUS status;
     141           0 :         size_t num_keys = 0;
     142           0 :         const char **keys = NULL;
     143           0 :         const char **values = NULL;
     144             :         const char *s;
     145             :         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             :         NTSTATUS status;
     200           0 :         size_t num_keys = 0;
     201           0 :         const char **keys = NULL;
     202           0 :         const char **values = NULL;
     203             :         const char *s;
     204             :         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             :         bool ok;
     262             :         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             :         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             :         NTSTATUS status;
     333           0 :         size_t i, num_manufacturers = 0;
     334           0 :         const char **manufacturers = NULL;
     335           0 :         const char **values = NULL;
     336             :         char *p;
     337             :         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             :                 const char *models_section_name;
     347             :                 const char *s;
     348             :                 char **decorations;
     349             :                 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             :                         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 :                         for (d = 0; d < num_devices; d++) {
     391             : 
     392           0 :                                 DEBUG(11,("processing device: %s\n",
     393             :                                         devices[d]));
     394             : 
     395           0 :                                 s = talloc_strdup(mem_ctx, devices[d]);
     396           0 :                                 if (s == NULL) {
     397           0 :                                         return NT_STATUS_NO_MEMORY;
     398             :                                 }
     399             : 
     400           0 :                                 p = strchr(s, ':');
     401           0 :                                 if (p == NULL) {
     402           0 :                                         return NT_STATUS_DRIVER_INTERNAL_ERROR;
     403             :                                 }
     404             : 
     405           0 :                                 *p = '\0';
     406           0 :                                 p++;
     407             : 
     408           0 :                                 s = get_string_unquote(p);
     409             : 
     410           0 :                                 ok = add_string_to_array(mem_ctx, s, pdevices, pnum_devices);
     411           0 :                                 if (!ok) {
     412           0 :                                         return NT_STATUS_NO_MEMORY;
     413             :                                 }
     414           0 :                                 ok = add_string_to_array(mem_ctx, device_values[d], pdevice_values, &c);
     415           0 :                                 if (!ok) {
     416           0 :                                         return NT_STATUS_NO_MEMORY;
     417             :                                 }
     418             :                         }
     419             :                 }
     420             :         }
     421             : 
     422           0 :         return NT_STATUS_OK;
     423             : }
     424             : 
     425           0 : static NTSTATUS find_device_in_toc(struct gp_inifile_context *ctx,
     426             :                                    TALLOC_CTX *mem_ctx,
     427             :                                    const char *device_description,
     428             :                                    const char **value)
     429             : {
     430             :         NTSTATUS status;
     431           0 :         size_t d, num_devices = 0;
     432           0 :         const char **devices = NULL;
     433           0 :         const char **device_values = NULL;
     434             : 
     435           0 :         if (device_description == NULL) {
     436           0 :                 return NT_STATUS_INVALID_PARAMETER;
     437             :         }
     438             : 
     439           0 :         status = enum_devices_in_toc(ctx, mem_ctx,
     440             :                                      &num_devices,
     441             :                                      &devices,
     442             :                                      &device_values);
     443           0 :         if (!NT_STATUS_IS_OK(status)) {
     444           0 :                 return status;
     445             :         }
     446             : 
     447           0 :         for (d = 0; d < num_devices; d++) {
     448             : 
     449           0 :                 if (strequal(device_description, devices[d])) {
     450             : 
     451           0 :                         DEBUG(10,("found device_description: %s\n",
     452             :                                 device_description));
     453             : 
     454           0 :                         *value = talloc_strdup(mem_ctx, device_values[d]);
     455           0 :                         if (*value == NULL) {
     456           0 :                                 return NT_STATUS_NO_MEMORY;
     457             :                         }
     458           0 :                         DEBUGADD(10,("and returned: %s\n", *value));
     459             : 
     460           0 :                         return NT_STATUS_OK;
     461             :                 }
     462             :         }
     463             : 
     464           0 :         return NT_STATUS_DRIVER_INTERNAL_ERROR;
     465             : }
     466             : 
     467             : /*
     468             :  * https://msdn.microsoft.com/de-de/windows/hardware/drivers/install/inf-copyfiles-directive
     469             :  */
     470             : 
     471           0 : static NTSTATUS process_driver_section_copyfiles(struct gp_inifile_context *ctx,
     472             :                                                  TALLOC_CTX *mem_ctx,
     473             :                                                  const char *driver_section,
     474             :                                                  struct spoolss_AddDriverInfo8 *r)
     475             : {
     476             :         NTSTATUS status;
     477           0 :         size_t i, num_keys = 0;
     478             :         char *p, *key;
     479           0 :         const char **keys = NULL;
     480           0 :         const char **values = NULL;
     481             :         char *str;
     482             :         const char *s;
     483             : 
     484           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", driver_section, "CopyFiles");
     485           0 :         if (key == NULL) {
     486           0 :                 return NT_STATUS_NO_MEMORY;
     487             :         }
     488             : 
     489           0 :         DEBUG(10,("Checking for CopyFiles entry in %s\n", driver_section));
     490             : 
     491           0 :         status = gp_inifile_getstring(ctx, key, &s);
     492           0 :         if (!NT_STATUS_IS_OK(status)) {
     493           0 :                 return NT_STATUS_OK;
     494             :         }
     495             : 
     496           0 :         DEBUG(10,("these are the files to copy: %s\n", s));
     497             : 
     498           0 :         while (next_token_talloc(mem_ctx, &s, &str, ",")) {
     499             : 
     500           0 :                 DEBUG(10,("trying section: %s\n", str));
     501             : 
     502           0 :                 if (str[0] == '@') {
     503           0 :                         DEBUG(10,("adding dependent driver file: %s\n", str));
     504           0 :                         status = add_dependent_driver_file(mem_ctx, str, &r->dependent_files);
     505           0 :                         if (!NT_STATUS_IS_OK(status)) {
     506           0 :                                 return status;
     507             :                         }
     508           0 :                         continue;
     509             :                 }
     510             : 
     511           0 :                 status = gp_inifile_enum_section(ctx, str, &num_keys, &keys, &values);
     512           0 :                 if (NT_STATUS_IS_OK(status)) {
     513           0 :                         for (i = 0; i < num_keys; i++) {
     514           0 :                                 p = strchr(keys[i], ':');
     515           0 :                                 if (p == NULL) {
     516           0 :                                         return NT_STATUS_INVALID_PARAMETER;
     517             :                                 }
     518           0 :                                 *p = '\0';
     519           0 :                                 p++;
     520             : 
     521           0 :                                 DEBUG(10,("adding dependent driver file: %s\n", p));
     522             : 
     523           0 :                                 status = add_dependent_driver_file(mem_ctx, p, &r->dependent_files);
     524           0 :                                 if (!NT_STATUS_IS_OK(status)) {
     525           0 :                                         return status;
     526             :                                 }
     527             :                         }
     528           0 :                         TALLOC_FREE(keys);
     529           0 :                         TALLOC_FREE(values);
     530             :                 }
     531             :         }
     532             : 
     533           0 :         return NT_STATUS_OK;
     534             : }
     535             : 
     536             : #define process_driver_section_val(_ctx, _mem_ctx, _section, _r, _key, _element) \
     537             : do { \
     538             :         NTSTATUS _status; \
     539             :         const char *__key, *_s; \
     540             :         __key = talloc_asprintf(_mem_ctx, "%s:%s", _section, _key); \
     541             :         NT_STATUS_HAVE_NO_MEMORY(__key); \
     542             :         _status = gp_inifile_getstring(_ctx, __key, &_s); \
     543             :         if (NT_STATUS_IS_OK(_status)) { \
     544             :                 (_r)->_element = talloc_strdup(mem_ctx, _s); \
     545             :                 NT_STATUS_HAVE_NO_MEMORY((_r)->_element); \
     546             :         } \
     547             : } while(0);
     548             : 
     549           0 : static NTSTATUS process_driver_section_colorprofiles(struct gp_inifile_context *ctx,
     550             :                                                      TALLOC_CTX *mem_ctx,
     551             :                                                      const char *section,
     552             :                                                      struct spoolss_AddDriverInfo8 *r)
     553             : {
     554             :         NTSTATUS status;
     555             :         const char *key, *s;
     556             : 
     557           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", section, "ColorProfiles");
     558           0 :         if (key == NULL) {
     559           0 :                 return NT_STATUS_NO_MEMORY;
     560             :         }
     561             : 
     562           0 :         status = gp_inifile_getstring_ext(ctx, key, &s);
     563           0 :         if (NT_STATUS_IS_OK(status)) {
     564             : 
     565           0 :                 status = add_string_to_spoolss_array(mem_ctx, s, &r->color_profiles);
     566           0 :                 if (!NT_STATUS_IS_OK(status)) {
     567           0 :                         return status;
     568             :                 }
     569             :         }
     570             : 
     571           0 :         return NT_STATUS_OK;
     572             : }
     573             : 
     574           0 : static NTSTATUS process_driver_section_printprocessor(struct gp_inifile_context *ctx,
     575             :                                                       TALLOC_CTX *mem_ctx,
     576             :                                                       const char *section,
     577             :                                                       struct spoolss_AddDriverInfo8 *r)
     578             : {
     579             :         NTSTATUS status;
     580             :         char *key, *p;
     581             :         const char *s;
     582             : 
     583           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", section, "PrintProcessor");
     584           0 :         if (key == NULL) {
     585           0 :                 return NT_STATUS_NO_MEMORY;
     586             :         }
     587             : 
     588           0 :         status = gp_inifile_getstring_ext(ctx, key, &s);
     589           0 :         if (NT_STATUS_IS_OK(status)) {
     590           0 :                 s = get_string_unquote(s);
     591             : 
     592           0 :                 p = strchr(s, ',');
     593           0 :                 if (p == NULL) {
     594           0 :                         return NT_STATUS_INVALID_PARAMETER;
     595             :                 }
     596           0 :                 *p = '\0';
     597           0 :                 r->print_processor = talloc_strdup(mem_ctx, s);
     598           0 :                 if (r->print_processor == NULL) {
     599           0 :                         return NT_STATUS_NO_MEMORY;
     600             :                 }
     601             :         }
     602             : 
     603           0 :         return NT_STATUS_OK;
     604             : }
     605             : 
     606           0 : static NTSTATUS process_driver_section_data_section(struct gp_inifile_context *ctx,
     607             :                                                     TALLOC_CTX *mem_ctx,
     608             :                                                     const char *section,
     609             :                                                     struct spoolss_AddDriverInfo8 *r)
     610             : {
     611             :         NTSTATUS status;
     612             :         char *key;
     613             :         const char *s;
     614             : 
     615           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", section, "DataSection");
     616           0 :         if (key == NULL) {
     617           0 :                 return NT_STATUS_NO_MEMORY;
     618             :         }
     619             : 
     620           0 :         status = gp_inifile_getstring(ctx, key, &s);
     621           0 :         if (NT_STATUS_IS_OK(status)) {
     622           0 :                 process_driver_section_val(ctx, mem_ctx, s, r,
     623             :                                            "DriverFile", driver_path);
     624           0 :                 process_driver_section_val(ctx, mem_ctx, s, r,
     625             :                                            "HelpFile", help_file);
     626           0 :                 process_driver_section_val(ctx, mem_ctx, s, r,
     627             :                                            "DataFile", data_file);
     628           0 :                 process_driver_section_val(ctx, mem_ctx, s, r,
     629             :                                            "ConfigFile", config_file);
     630             :         }
     631             : 
     632           0 :         return NT_STATUS_OK;
     633             : }
     634             : 
     635             : 
     636           0 : static NTSTATUS process_one_core_driver_section(struct gp_inifile_context *core_ctx,
     637             :                                                 TALLOC_CTX *mem_ctx,
     638             :                                                 const char *driver_section,
     639             :                                                 struct spoolss_AddDriverInfo8 *r)
     640             : {
     641             :         NTSTATUS status;
     642           0 :         size_t i, num_keys = 0;
     643           0 :         const char **keys = NULL;
     644           0 :         const char **values = NULL;
     645             : 
     646           0 :         DEBUG(10,("CoreDriverSection is: %s\n", driver_section));
     647             : 
     648           0 :         status = gp_inifile_enum_section(core_ctx, driver_section, &num_keys, &keys, &values);
     649           0 :         if (!NT_STATUS_IS_OK(status)) {
     650           0 :                 return status;
     651             :         }
     652             : 
     653           0 :         for (i = 0; i < num_keys; i++) {
     654             : 
     655           0 :                 status = process_driver_section_copyfiles(core_ctx, mem_ctx, driver_section, r);
     656           0 :                 if (!NT_STATUS_IS_OK(status)) {
     657           0 :                         return status;
     658             :                 }
     659             : 
     660           0 :                 process_driver_section_val(core_ctx, mem_ctx, driver_section, r,
     661             :                                            "DriverFile", driver_path);
     662           0 :                 process_driver_section_val(core_ctx, mem_ctx, driver_section, r,
     663             :                                            "HelpFile", help_file);
     664           0 :                 process_driver_section_val(core_ctx, mem_ctx, driver_section, r,
     665             :                                            "ConfigFile", config_file);
     666             : 
     667           0 :                 status = process_driver_section_colorprofiles(core_ctx, mem_ctx, driver_section, r);
     668           0 :                 if (!NT_STATUS_IS_OK(status)) {
     669           0 :                         return status;
     670             :                 }
     671             :         }
     672             : 
     673           0 :         talloc_free(keys);
     674           0 :         talloc_free(values);
     675             : 
     676           0 :         return NT_STATUS_OK;
     677             : }
     678             : 
     679             : /*
     680             :  * 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"
     681             :  */
     682           0 : static NTSTATUS process_core_driver_sections(struct gp_inifile_context *core_ctx,
     683             :                                              TALLOC_CTX *mem_ctx,
     684             :                                              const char *value,
     685             :                                              struct spoolss_AddDriverInfo8 *r)
     686             : {
     687             :         NTSTATUS status;
     688             :         char *p;
     689             :         char **list;
     690             :         int i;
     691             : 
     692           0 :         list = str_list_make_v3(mem_ctx, value, ",");
     693           0 :         if (list == NULL) {
     694           0 :                 return NT_STATUS_NO_MEMORY;
     695             :         }
     696             : 
     697           0 :         for (i = 0; list[i] != NULL; i++) {
     698             :                 char **array;
     699             :                 int a;
     700             : 
     701             :                 /* FIXME: do we have to validate the core driver guid ? */
     702             : 
     703           0 :                 p = strchr(list[i], ',');
     704           0 :                 if (p != NULL) {
     705           0 :                         *p = '\0';
     706           0 :                         p++;
     707             :                 }
     708             : 
     709           0 :                 DEBUG(10,("CoreDriverSections we have to process: %s\n", p));
     710             : 
     711           0 :                 array = str_list_make_v3(mem_ctx, p, ",");
     712           0 :                 if (array == NULL) {
     713           0 :                         return NT_STATUS_NO_MEMORY;
     714             :                 }
     715             : 
     716           0 :                 for (a = 0; array[a] != NULL; a++) {
     717             : 
     718           0 :                         if (core_ctx == NULL) {
     719           0 :                                 DEBUG(0,("Need to process CoreDriverSections but "
     720             :                                         "have no Core Driver Context!\n"));
     721           0 :                                 return NT_STATUS_DRIVER_INTERNAL_ERROR;
     722             :                         }
     723             : 
     724           0 :                         status = process_one_core_driver_section(core_ctx, mem_ctx, array[a], r);
     725           0 :                         if (!NT_STATUS_IS_OK(status)) {
     726           0 :                                 continue;
     727             :                         }
     728             :                 }
     729             :         }
     730             : 
     731           0 :         return NT_STATUS_OK;
     732             : }
     733             : 
     734             : /*
     735             :  * https://msdn.microsoft.com/de-de/windows/hardware/drivers/install/inf-ddinstall-section
     736             :  */
     737           0 : static NTSTATUS find_driver_files(struct gp_inifile_context *ctx,
     738             :                                   struct gp_inifile_context *core_ctx,
     739             :                                   TALLOC_CTX *mem_ctx,
     740             :                                   const char *driver_name,
     741             :                                   struct spoolss_AddDriverInfo8 *r)
     742             : {
     743             :         NTSTATUS status;
     744             :         char *key;
     745             :         const char *s;
     746             :         const char *value;
     747             :         char *install_section_name;
     748             :         bool ok;
     749             :         char *hw_id;
     750             : 
     751           0 :         status = find_device_in_toc(ctx, mem_ctx, driver_name, &value);
     752           0 :         if (!NT_STATUS_IS_OK(status)) {
     753           0 :                 return status;
     754             :         }
     755             : 
     756           0 :         r->driver_name = talloc_strdup(mem_ctx, driver_name);
     757           0 :         if (r->driver_name == NULL) {
     758           0 :                 return NT_STATUS_NO_MEMORY;
     759             :         }
     760             : 
     761           0 :         ok = next_token_talloc(mem_ctx, &value, &install_section_name, ",");
     762           0 :         if (!ok) {
     763           0 :                 return NT_STATUS_INVALID_PARAMETER;
     764             :         }
     765             : 
     766           0 :         DEBUG(10,("driver_name: %s, value: %s, install_section_name: %s\n",
     767             :                 driver_name, value, install_section_name));
     768             : 
     769             :         /* Hardware Id is optional */
     770           0 :         ok = next_token_talloc(mem_ctx, &value, &hw_id, ",");
     771           0 :         if (ok) {
     772           0 :                 r->hardware_id = hw_id;
     773             :         }
     774             : 
     775           0 :         status = process_driver_section_copyfiles(ctx, mem_ctx, install_section_name, r);
     776           0 :         if (!NT_STATUS_IS_OK(status)) {
     777           0 :                 return status;
     778             :         }
     779             : 
     780           0 :         process_driver_section_val(ctx, mem_ctx, install_section_name, r,
     781             :                                    "DriverFile", driver_path);
     782           0 :         process_driver_section_val(ctx, mem_ctx, install_section_name, r,
     783             :                                    "HelpFile", help_file);
     784           0 :         process_driver_section_val(ctx, mem_ctx, install_section_name, r,
     785             :                                    "DataFile", data_file);
     786           0 :         process_driver_section_val(ctx, mem_ctx, install_section_name, r,
     787             :                                    "ConfigFile", config_file);
     788             : 
     789           0 :         status = process_driver_section_printprocessor(ctx, mem_ctx, install_section_name, r);
     790           0 :         if (!NT_STATUS_IS_OK(status)) {
     791           0 :                 return status;
     792             :         }
     793             : 
     794           0 :         status = process_driver_section_data_section(ctx, mem_ctx, install_section_name, r);
     795           0 :         if (!NT_STATUS_IS_OK(status)) {
     796           0 :                 return status;
     797             :         }
     798             : 
     799           0 :         key = talloc_asprintf(mem_ctx, "%s:%s", install_section_name, "CoreDriverSections");
     800           0 :         if (key == NULL) {
     801           0 :                 return NT_STATUS_NO_MEMORY;
     802             :         }
     803             : 
     804           0 :         status = gp_inifile_getstring(ctx, key, &s);
     805           0 :         if (NT_STATUS_IS_OK(status)) {
     806             : 
     807           0 :                 DEBUG(10,("found CoreDriverSections: %s\n", s));
     808             : 
     809           0 :                 status = process_core_driver_sections(core_ctx, mem_ctx, s, r);
     810           0 :                 if (!NT_STATUS_IS_OK(status)) {
     811           0 :                         return status;
     812             :                 }
     813             :         }
     814             : 
     815           0 :         return NT_STATUS_OK;
     816             : }
     817             : 
     818             : struct inf_context {
     819             :         struct gp_inifile_context *ctx;
     820             :         struct gp_inifile_context *core_ctx;
     821             : };
     822             : 
     823           0 : static NTSTATUS init_inf_context(TALLOC_CTX *mem_ctx,
     824             :                                  const char *inf_filename,
     825             :                                  const char *core_filename,
     826             :                                  struct inf_context **_inf_ctx)
     827             : {
     828             :         NTSTATUS status;
     829             :         struct gp_inifile_context *ctx;
     830           0 :         struct gp_inifile_context *core_ctx = NULL;
     831             :         struct inf_context *inf_ctx;
     832             : 
     833           0 :         inf_ctx = talloc_zero(mem_ctx, struct inf_context);
     834           0 :         if (inf_ctx == NULL) {
     835           0 :                 return NT_STATUS_NO_MEMORY;
     836             :         }
     837             : 
     838           0 :         status = gp_inifile_init_context_direct(mem_ctx,
     839             :                                                 inf_filename,
     840             :                                                 &ctx);
     841           0 :         if (!NT_STATUS_IS_OK(status)) {
     842           0 :                 DEBUG(10,("init_inf_context: failed to load %s\n", inf_filename));
     843           0 :                 return status;
     844             :         }
     845             : 
     846           0 :         if (ctx->generated_filename != NULL) {
     847           0 :                 unlink(ctx->generated_filename);
     848             :         }
     849             : 
     850           0 :         if (core_filename != NULL) {
     851           0 :                 status = gp_inifile_init_context_direct(mem_ctx,
     852             :                                                         core_filename,
     853             :                                                         &core_ctx);
     854           0 :                 if (!NT_STATUS_IS_OK(status)) {
     855           0 :                         DEBUG(10,("init_inf_context: failed to load %s\n", core_filename));
     856           0 :                         return status;
     857             :                 }
     858             : 
     859           0 :                 if (core_ctx->generated_filename != NULL) {
     860           0 :                         unlink(core_ctx->generated_filename);
     861             :                 }
     862             :         }
     863             : 
     864           0 :         inf_ctx->ctx = ctx;
     865           0 :         inf_ctx->core_ctx = core_ctx;
     866             : 
     867           0 :         *_inf_ctx = inf_ctx;
     868             : 
     869           0 :         return NT_STATUS_OK;
     870             : }
     871             : 
     872           0 : static NTSTATUS process_driver_driverver(struct gp_inifile_context *ctx,
     873             :                                          struct spoolss_AddDriverInfo8 *r)
     874             : {
     875             :         NTSTATUS status;
     876             :         const char *s;
     877             :         char *p;
     878             :         bool ok;
     879             :         const char *str;
     880             : 
     881           0 :         status = gp_inifile_getstring(ctx, "Version:DriverVer", &s);
     882           0 :         if (!NT_STATUS_IS_OK(status)) {
     883           0 :                 return status;
     884             :         }
     885             : 
     886           0 :         str = talloc_strdup(ctx, s);
     887           0 :         if (str == NULL) {
     888           0 :                 return NT_STATUS_NO_MEMORY;
     889             :         }
     890             : 
     891           0 :         p = strchr(str, ',');
     892           0 :         if (p) {
     893           0 :                 *p = '\0';
     894           0 :                 p++;
     895             :         }
     896             : 
     897           0 :         ok = spoolss_timestr_to_NTTIME(str, &r->driver_date);
     898           0 :         if (!ok) {
     899           0 :                 return NT_STATUS_INVALID_PARAMETER;
     900             :         }
     901             : 
     902           0 :         ok = spoolss_driver_version_to_qword(p, &r->driver_version);
     903           0 :         if (!ok) {
     904           0 :                 return NT_STATUS_INVALID_PARAMETER;
     905             :         }
     906             : 
     907           0 :         return NT_STATUS_OK;
     908             : }
     909             : 
     910             : /*
     911             :  * Parse a SourceDisksNames section,
     912             :  * https://msdn.microsoft.com/de-de/windows/hardware/drivers/install/inf-sourcedisksnames-section?f=255&MSPPError=-2147217396
     913             :  */
     914           0 : static NTSTATUS process_source_disk_name(struct gp_inifile_context *ctx,
     915             :                                          TALLOC_CTX *mem_ctx,
     916             :                                          const char *short_environment,
     917             :                                          const char **source_disk_name)
     918             : {
     919             :         NTSTATUS status;
     920             :         bool ok;
     921             :         const char *key;
     922           0 :         size_t i, num_keys = 0;
     923           0 :         const char **keys = NULL;
     924           0 :         const char **values = NULL;
     925             : 
     926           0 :         key = talloc_asprintf(mem_ctx, "SourceDisksNames.%s", short_environment);
     927           0 :         if (key == NULL) {
     928           0 :                 return NT_STATUS_NO_MEMORY;
     929             :         }
     930             : 
     931           0 :         status = gp_inifile_enum_section(ctx, key, &num_keys, &keys, &values);
     932           0 :         if (!NT_STATUS_IS_OK(status)) {
     933           0 :                 return status;
     934             :         }
     935             : 
     936           0 :         if (keys == NULL && values == NULL) {
     937           0 :                 key = "SourceDisksNames";
     938             : 
     939           0 :                 status = gp_inifile_enum_section(ctx, key, &num_keys, &keys, &values);
     940           0 :                 if (!NT_STATUS_IS_OK(status)) {
     941           0 :                         return status;
     942             :                 }
     943             :         }
     944             : 
     945           0 :         for (i = 0; i < num_keys; i++) {
     946             : 
     947             :                 /*
     948             :                  * 1   = %Disk1%,,,"Amd64"
     949             :                  * diskid = disk-description[,[tag-or-cab-file],[unused],[path],[flags][,tag-file]]
     950             :                  */
     951             :                 char *disk_description, *tag_or_cab_file, *unused, *path;
     952             : 
     953           0 :                 ok = next_token_no_ltrim_talloc(mem_ctx, &values[i], &disk_description, ",");
     954           0 :                 if (!ok) {
     955           0 :                         continue;
     956             :                 }
     957             : 
     958           0 :                 ok = next_token_no_ltrim_talloc(mem_ctx, &values[i], &tag_or_cab_file, ",");
     959           0 :                 if (!ok) {
     960           0 :                         continue;
     961             :                 }
     962             : 
     963           0 :                 ok = next_token_no_ltrim_talloc(mem_ctx, &values[i], &unused, ",");
     964           0 :                 if (!ok) {
     965           0 :                         continue;
     966             :                 }
     967             : 
     968           0 :                 ok = next_token_no_ltrim_talloc(mem_ctx, &values[i], &path, ",");
     969           0 :                 if (!ok) {
     970           0 :                         continue;
     971             :                 }
     972             : 
     973           0 :                 *source_disk_name = path;
     974             : 
     975           0 :                 return NT_STATUS_OK;
     976             :         }
     977             : 
     978           0 :         return NT_STATUS_NOT_FOUND;
     979             : }
     980             : 
     981           0 : static NTSTATUS setup_driver_by_name(TALLOC_CTX *mem_ctx,
     982             :                                      struct inf_context *inf_ctx,
     983             :                                      const char *filename,
     984             :                                      const char *environment,
     985             :                                      const char *driver_name,
     986             :                                      struct spoolss_AddDriverInfo8 *r,
     987             :                                      const char **source_disk_name)
     988             : {
     989             :         NTSTATUS status;
     990           0 :         struct gp_inifile_context *ctx = inf_ctx->ctx;
     991           0 :         struct gp_inifile_context *core_ctx = inf_ctx->core_ctx;
     992             :         char *key;
     993             :         bool ok;
     994             :         const char *short_environment;
     995             :         const char *s;
     996             : 
     997           0 :         short_environment = spoolss_get_short_filesys_environment(environment);
     998           0 :         if (short_environment == NULL) {
     999           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1000             :         }
    1001             : 
    1002           0 :         status = find_driver_files(ctx, core_ctx, mem_ctx, driver_name, r);
    1003           0 :         if (!NT_STATUS_IS_OK(status)) {
    1004           0 :                 return status;
    1005             :         }
    1006             : 
    1007           0 :         status = process_source_disk_name(ctx, mem_ctx,
    1008             :                                           short_environment,
    1009             :                                           source_disk_name);
    1010           0 :         if (!NT_STATUS_IS_OK(status)) {
    1011           0 :                 return status;
    1012             :         }
    1013             : 
    1014           0 :         r->inf_path = talloc_strdup(mem_ctx, filename);
    1015           0 :         if (r->inf_path == NULL) {
    1016           0 :                 return NT_STATUS_NO_MEMORY;
    1017             :         }
    1018             : 
    1019           0 :         r->architecture = talloc_strdup(mem_ctx, environment);
    1020           0 :         if (r->architecture == NULL) {
    1021           0 :                 return NT_STATUS_NO_MEMORY;
    1022             :         }
    1023             : 
    1024           0 :         if (r->print_processor == NULL) {
    1025           0 :                 r->print_processor = talloc_strdup(mem_ctx, "winprint");
    1026           0 :                 if (r->print_processor == NULL) {
    1027           0 :                         return NT_STATUS_NO_MEMORY;
    1028             :                 }
    1029             :         }
    1030             : 
    1031           0 :         status = gp_inifile_getstring_ext(ctx, "Version:Class", &s);
    1032           0 :         if (NT_STATUS_IS_OK(status)) {
    1033           0 :                 if (strequal(s, "Printer")) {
    1034           0 :                         r->printer_driver_attributes |= PRINTER_DRIVER_CLASS;
    1035             :                 }
    1036             :         }
    1037             : 
    1038           0 :         status = gp_inifile_getstring(ctx, "Version:Signature", &s);
    1039           0 :         if (!NT_STATUS_IS_OK(status)) {
    1040           0 :                 return status;
    1041             :         }
    1042           0 :         if (!strequal(s, "\"$Windows NT$\"")) {
    1043           0 :                 return NT_STATUS_INVALID_SIGNATURE;
    1044             :         }
    1045             : 
    1046           0 :         r->version = SPOOLSS_DRIVER_VERSION_200X;
    1047           0 :         status = gp_inifile_getstring(ctx, "Version:ClassVer", &s);
    1048           0 :         if (NT_STATUS_IS_OK(status)) {
    1049           0 :                 int cmp = strncasecmp_m(s, "4.0", 3);
    1050           0 :                 if (cmp == 0) {
    1051           0 :                         r->version = SPOOLSS_DRIVER_VERSION_2012;
    1052             :                 }
    1053           0 :                 if (strequal(s, "3.0")) {
    1054           0 :                         r->version = SPOOLSS_DRIVER_VERSION_200X;
    1055             :                 }
    1056             :         }
    1057             : 
    1058           0 :         status = gp_inifile_getstring_ext(ctx, "Version:Provider", &s);
    1059           0 :         if (NT_STATUS_IS_OK(status)) {
    1060           0 :                 if (s != NULL) {
    1061           0 :                         r->provider = talloc_strdup(mem_ctx, s);
    1062           0 :                         if (r->provider == NULL) {
    1063           0 :                                 return NT_STATUS_NO_MEMORY;
    1064             :                         }
    1065             :                 }
    1066             :         }
    1067             : 
    1068           0 :         status = process_driver_driverver(ctx, r);
    1069           0 :         if (!NT_STATUS_IS_OK(status)) {
    1070           0 :                 return status;
    1071             :         }
    1072             : 
    1073           0 :         r->printer_driver_attributes &= ~PRINTER_DRIVER_SANDBOX_ENABLED;
    1074             : 
    1075           0 :         status = gp_inifile_getstring(ctx, "Version:DriverIsolation", &s);
    1076           0 :         if (NT_STATUS_IS_OK(status)) {
    1077           0 :                 int cmp = strncasecmp_m(s, "2", 1);
    1078           0 :                 if (cmp == 0) {
    1079           0 :                         r->printer_driver_attributes |= PRINTER_DRIVER_SANDBOX_ENABLED;
    1080             :                 }
    1081           0 :                 cmp = strncasecmp_m(s, "0", 1);
    1082           0 :                 if (cmp == 0) {
    1083           0 :                         r->printer_driver_attributes &= ~PRINTER_DRIVER_SANDBOX_ENABLED;
    1084             :                 }
    1085             :         }
    1086             : 
    1087           0 :         status = find_manufacturer_name(ctx, mem_ctx, "Manufacturer", &r->manufacturer_name);
    1088           0 :         if (!NT_STATUS_IS_OK(status)) {
    1089           0 :                 return status;
    1090             :         }
    1091             : 
    1092           0 :         status = find_manufacturer_url(ctx, mem_ctx, "OEM URLS", r->manufacturer_name, &r->manufacturer_url);
    1093           0 :         if (!NT_STATUS_IS_OK(status)) {
    1094             :                 /* not critical */
    1095             :         }
    1096             : 
    1097           0 :         status = gp_inifile_getbool(ctx, "PrinterPackageInstallation:PackageAware", &ok);
    1098           0 :         if (NT_STATUS_IS_OK(status)) {
    1099           0 :                 if (ok) {
    1100           0 :                         r->printer_driver_attributes |= PRINTER_DRIVER_PACKAGE_AWARE;
    1101             :                 }
    1102             :         }
    1103             : 
    1104           0 :         key = talloc_asprintf(mem_ctx, "%s.%s:%s",
    1105             :                 "PrinterPackageInstallation", short_environment, "PackageAware");
    1106           0 :         if (key == NULL) {
    1107           0 :                 return NT_STATUS_NO_MEMORY;
    1108             :         }
    1109             : 
    1110           0 :         status = gp_inifile_getbool(ctx, key, &ok);
    1111           0 :         if (NT_STATUS_IS_OK(status)) {
    1112           0 :                 if (ok) {
    1113           0 :                         r->printer_driver_attributes |= PRINTER_DRIVER_PACKAGE_AWARE;
    1114             :                 }
    1115             :         }
    1116             : 
    1117           0 :         key = talloc_asprintf(mem_ctx, "%s.%s:%s",
    1118             :                 "PrinterPackageInstallation", short_environment, "CoreDriverDependencies");
    1119           0 :         if (key == NULL) {
    1120           0 :                 return NT_STATUS_NO_MEMORY;
    1121             :         }
    1122             : 
    1123           0 :         status = gp_inifile_getstring(ctx, key, &s);
    1124           0 :         if (NT_STATUS_IS_OK(status)) {
    1125             :                 char **list;
    1126           0 :                 r->core_driver_dependencies = talloc_zero(mem_ctx, struct spoolss_StringArray);
    1127           0 :                 if (r->core_driver_dependencies == NULL) {
    1128           0 :                         return NT_STATUS_NO_MEMORY;
    1129             :                 }
    1130             : 
    1131           0 :                 list = str_list_make_v3(r->core_driver_dependencies, s, ",");
    1132           0 :                 if (list == NULL) {
    1133           0 :                         return NT_STATUS_NO_MEMORY;
    1134             :                 }
    1135           0 :                 r->core_driver_dependencies->string = const_str_list(list);
    1136             :         }
    1137             : 
    1138           0 :         key = talloc_asprintf(mem_ctx, "%s.%s:%s",
    1139             :                 "PrinterPackageInstallation", short_environment, "InboxVersionRequired");
    1140           0 :         if (key == NULL) {
    1141           0 :                 return NT_STATUS_NO_MEMORY;
    1142             :         }
    1143             : 
    1144           0 :         status = gp_inifile_getstring(ctx, key, &s);
    1145           0 :         if (NT_STATUS_IS_OK(status)) {
    1146           0 :                 if (strequal(s, "UseDriverVer")) {
    1147           0 :                         r->min_inbox_driver_ver_date = r->driver_date;
    1148           0 :                         r->min_inbox_driver_ver_version = r->driver_version;
    1149             :                 }
    1150             :         }
    1151             : 
    1152           0 :         return NT_STATUS_OK;
    1153             : }
    1154             : 
    1155             : /****************************************************************
    1156             :  parse the a printer inf file
    1157             : ****************************************************************/
    1158             : 
    1159           0 : NTSTATUS driver_inf_parse(TALLOC_CTX *mem_ctx,
    1160             :                           const char *core_driver_inf,
    1161             :                           const char *filename,
    1162             :                           const char *environment,
    1163             :                           const char *driver_name,
    1164             :                           struct spoolss_AddDriverInfo8 *r,
    1165             :                           const char **source_disk_name)
    1166             : {
    1167             :         NTSTATUS status;
    1168             :         struct inf_context *inf_ctx;
    1169             : 
    1170           0 :         if (!filename || !environment) {
    1171           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1172             :         }
    1173             : 
    1174           0 :         status = init_inf_context(mem_ctx,
    1175             :                                   filename,
    1176             :                                   core_driver_inf,
    1177             :                                   &inf_ctx);
    1178           0 :         if (!NT_STATUS_IS_OK(status)) {
    1179           0 :                 return status;
    1180             :         }
    1181             : 
    1182           0 :         status = setup_driver_by_name(mem_ctx, inf_ctx,
    1183             :                                       filename,
    1184             :                                       environment,
    1185             :                                       driver_name,
    1186             :                                       r,
    1187             :                                       source_disk_name);
    1188           0 :         if (!NT_STATUS_IS_OK(status)) {
    1189           0 :                 return status;
    1190             :         }
    1191             : 
    1192           0 :         return NT_STATUS_OK;
    1193             : }
    1194             : 
    1195           0 : NTSTATUS driver_inf_list(TALLOC_CTX *mem_ctx,
    1196             :                          const char *core_driver_inf,
    1197             :                          const char *filename,
    1198             :                          const char *environment,
    1199             :                          uint32_t *count,
    1200             :                          struct spoolss_AddDriverInfo8 **_r)
    1201             : {
    1202             :         NTSTATUS status;
    1203             :         const char *short_environment;
    1204           0 :         size_t d, num_devices = 0;
    1205           0 :         const char **devices = NULL;
    1206           0 :         const char **device_values = NULL;
    1207             :         struct inf_context *inf_ctx;
    1208             : 
    1209           0 :         if (!filename || !environment) {
    1210           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1211             :         }
    1212             : 
    1213           0 :         short_environment = spoolss_get_short_filesys_environment(environment);
    1214           0 :         if (short_environment == NULL) {
    1215           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1216             :         }
    1217             : 
    1218           0 :         status = init_inf_context(mem_ctx,
    1219             :                                   filename,
    1220             :                                   core_driver_inf,
    1221             :                                   &inf_ctx);
    1222           0 :         if (!NT_STATUS_IS_OK(status)) {
    1223           0 :                 return status;
    1224             :         }
    1225             : 
    1226           0 :         status = enum_devices_in_toc(inf_ctx->ctx, mem_ctx,
    1227             :                                      &num_devices,
    1228             :                                      &devices,
    1229             :                                      &device_values);
    1230           0 :         if (!NT_STATUS_IS_OK(status)) {
    1231           0 :                 return status;
    1232             :         }
    1233             : 
    1234           0 :         for (d = 0; d < num_devices; d++) {
    1235             : 
    1236             :                 struct spoolss_AddDriverInfo8 r;
    1237             :                 const char *source_disk_name;
    1238             : 
    1239           0 :                 ZERO_STRUCT(r);
    1240             : 
    1241           0 :                 status = setup_driver_by_name(mem_ctx, inf_ctx, filename,
    1242           0 :                                               environment, devices[d], &r,
    1243             :                                               &source_disk_name);
    1244           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1245           0 :                         return status;
    1246             :                 }
    1247             : 
    1248           0 :                 ADD_TO_ARRAY(mem_ctx, struct spoolss_AddDriverInfo8, r, _r, count);
    1249             :         }
    1250             : 
    1251           0 :         return NT_STATUS_OK;
    1252             : }

Generated by: LCOV version 1.13