Coverage for /root/GitHubProjects/impacket/impacket/dcerpc/v5/par.py : 68%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# Impacket - Collection of Python classes for working with network protocols.
2#
3# SECUREAUTH LABS. Copyright (C) 2021 SecureAuth Corporation. All rights reserved.
4#
5# This software is provided under a slightly modified version
6# of the Apache Software License. See the accompanying LICENSE file
7# for more information.
8#
9# Description:
10# [MS-PAR] Interface implementation
11# https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-par
12#
13# Best way to learn how to use these calls is to grab the protocol standard
14# so you understand what the call does, and then read the test case located
15# at https://github.com/SecureAuthCorp/impacket/tree/master/tests/SMB_RPC
16#
17# Some calls have helper functions, which makes it even easier to use.
18# They are located at the end of this file.
19# Helper functions start with "h"<name of the call>.
20# There are test cases for them too.
21#
22# Author:
23# Adam (@cube0x0)
24#
25from impacket import system_errors
26from impacket.dcerpc.v5.dtypes import ULONGLONG, UINT, USHORT, LPWSTR, DWORD, ULONG, NULL
27from impacket.dcerpc.v5.ndr import NDRCALL, NDRSTRUCT, NDRUNION, NDRPOINTER, NDRUniConformantArray
28from impacket.dcerpc.v5.rpcrt import DCERPCException
29from impacket.uuid import uuidtup_to_bin, string_to_bin
31MSRPC_UUID_PAR = uuidtup_to_bin(('76F03F96-CDFD-44FC-A22C-64950A001209', '1.0'))
32MSRPC_UUID_WINSPOOL = string_to_bin('9940CA8E-512F-4C58-88A9-61098D6896BD')
34class DCERPCSessionError(DCERPCException):
35 def __init__(self, error_string=None, error_code=None, packet=None):
36 DCERPCException.__init__(self, error_string, error_code, packet)
38 def __str__( self ):
39 key = self.error_code
40 if key in system_errors.ERROR_MESSAGES:
41 error_msg_short = system_errors.ERROR_MESSAGES[key][0]
42 error_msg_verbose = system_errors.ERROR_MESSAGES[key][1]
43 return 'RPRN SessionError: code: 0x%x - %s - %s' % (self.error_code, error_msg_short, error_msg_verbose)
44 else:
45 return 'RPRN SessionError: unknown error code: 0x%x' % self.error_code
47################################################################################
48# CONSTANTS
49################################################################################
50# 2.2.1.1.7 STRING_HANDLE
51STRING_HANDLE = LPWSTR
52class PSTRING_HANDLE(NDRPOINTER):
53 referent = (
54 ('Data', STRING_HANDLE),
55 )
57# 2.2.3.1 Access Values
58JOB_ACCESS_ADMINISTER = 0x00000010
59JOB_ACCESS_READ = 0x00000020
60JOB_EXECUTE = 0x00020010
61JOB_READ = 0x00020020
62JOB_WRITE = 0x00020010
63JOB_ALL_ACCESS = 0x000F0030
64PRINTER_ACCESS_ADMINISTER = 0x00000004
65PRINTER_ACCESS_USE = 0x00000008
66PRINTER_ACCESS_MANAGE_LIMITED = 0x00000040
67PRINTER_ALL_ACCESS = 0x000F000C
68PRINTER_EXECUTE = 0x00020008
69PRINTER_READ = 0x00020008
70PRINTER_WRITE = 0x00020008
71SERVER_ACCESS_ADMINISTER = 0x00000001
72SERVER_ACCESS_ENUMERATE = 0x00000002
73SERVER_ALL_ACCESS = 0x000F0003
74SERVER_EXECUTE = 0x00020002
75SERVER_READ = 0x00020002
76SERVER_WRITE = 0x00020003
77SPECIFIC_RIGHTS_ALL = 0x0000FFFF
78STANDARD_RIGHTS_ALL = 0x001F0000
79STANDARD_RIGHTS_EXECUTE = 0x00020000
80STANDARD_RIGHTS_READ = 0x00020000
81STANDARD_RIGHTS_REQUIRED = 0x000F0000
82STANDARD_RIGHTS_WRITE = 0x00020000
83SYNCHRONIZE = 0x00100000
84DELETE = 0x00010000
85READ_CONTROL = 0x00020000
86WRITE_DAC = 0x00040000
87WRITE_OWNER = 0x00080000
88GENERIC_READ = 0x80000000
89GENERIC_WRITE = 0x40000000
90GENERIC_EXECUTE = 0x20000000
91GENERIC_ALL = 0x10000000
93# 2.2.3.6.1 Printer Change Flags for Use with a Printer Handle
94PRINTER_CHANGE_SET_PRINTER = 0x00000002
95PRINTER_CHANGE_DELETE_PRINTER = 0x00000004
96PRINTER_CHANGE_PRINTER = 0x000000FF
97PRINTER_CHANGE_ADD_JOB = 0x00000100
98PRINTER_CHANGE_SET_JOB = 0x00000200
99PRINTER_CHANGE_DELETE_JOB = 0x00000400
100PRINTER_CHANGE_WRITE_JOB = 0x00000800
101PRINTER_CHANGE_JOB = 0x0000FF00
102PRINTER_CHANGE_SET_PRINTER_DRIVER = 0x20000000
103PRINTER_CHANGE_TIMEOUT = 0x80000000
104PRINTER_CHANGE_ALL = 0x7777FFFF
105PRINTER_CHANGE_ALL_2 = 0x7F77FFFF
107# 2.2.3.6.2 Printer Change Flags for Use with a Server Handle
108PRINTER_CHANGE_ADD_PRINTER_DRIVER = 0x10000000
109PRINTER_CHANGE_DELETE_PRINTER_DRIVER = 0x40000000
110PRINTER_CHANGE_PRINTER_DRIVER = 0x70000000
111PRINTER_CHANGE_ADD_FORM = 0x00010000
112PRINTER_CHANGE_DELETE_FORM = 0x00040000
113PRINTER_CHANGE_SET_FORM = 0x00020000
114PRINTER_CHANGE_FORM = 0x00070000
115PRINTER_CHANGE_ADD_PORT = 0x00100000
116PRINTER_CHANGE_CONFIGURE_PORT = 0x00200000
117PRINTER_CHANGE_DELETE_PORT = 0x00400000
118PRINTER_CHANGE_PORT = 0x00700000
119PRINTER_CHANGE_ADD_PRINT_PROCESSOR = 0x01000000
120PRINTER_CHANGE_DELETE_PRINT_PROCESSOR = 0x04000000
121PRINTER_CHANGE_PRINT_PROCESSOR = 0x07000000
122PRINTER_CHANGE_ADD_PRINTER = 0x00000001
123PRINTER_CHANGE_FAILED_CONNECTION_PRINTER = 0x00000008
124PRINTER_CHANGE_SERVER = 0x08000000
126# 2.2.3.7 Printer Enumeration Flags
127PRINTER_ENUM_LOCAL = 0x00000002
128PRINTER_ENUM_CONNECTIONS = 0x00000004
129PRINTER_ENUM_NAME = 0x00000008
130PRINTER_ENUM_REMOTE = 0x00000010
131PRINTER_ENUM_SHARED = 0x00000020
132PRINTER_ENUM_NETWORK = 0x00000040
133PRINTER_ENUM_EXPAND = 0x00004000
134PRINTER_ENUM_CONTAINER = 0x00008000
135PRINTER_ENUM_ICON1 = 0x00010000
136PRINTER_ENUM_ICON2 = 0x00020000
137PRINTER_ENUM_ICON3 = 0x00040000
138PRINTER_ENUM_ICON8 = 0x00800000
139PRINTER_ENUM_HIDE = 0x01000000
142# 2.2.3.8 Printer Notification Values
143PRINTER_NOTIFY_CATEGORY_2D = 0x00000000
144PRINTER_NOTIFY_CATEGORY_ALL = 0x00010000
145PRINTER_NOTIFY_CATEGORY_3D = 0x00020000
148# 3.1.4.4.8 RpcAddPrinterDriverEx Values
149APD_STRICT_UPGRADE = 0x00000001
150APD_STRICT_DOWNGRADE = 0x00000002
151APD_COPY_ALL_FILES = 0x00000004
152APD_COPY_NEW_FILES = 0x00000008
153APD_COPY_FROM_DIRECTORY = 0x00000010
154APD_DONT_COPY_FILES_TO_CLUSTER = 0x00001000
155APD_COPY_TO_ALL_SPOOLERS = 0x00002000
156APD_INSTALL_WARNED_DRIVER = 0x00008000
157APD_RETURN_BLOCKING_STATUS_CODE = 0x00010000
159################################################################################
160# STRUCTURES
161################################################################################
162# 2.2.1.1.4 PRINTER_HANDLE
163class PRINTER_HANDLE(NDRSTRUCT):
164 structure = (
165 ('Data','20s=b""'),
166 )
167 def getAlignment(self):
168 if self._isNDR64 is True:
169 return 8
170 else:
171 return 4
173# 2.2.1.2.1 DEVMODE_CONTAINER
174class BYTE_ARRAY(NDRUniConformantArray):
175 item = 'c'
177class PBYTE_ARRAY(NDRPOINTER):
178 referent = (
179 ('Data', BYTE_ARRAY),
180 )
182class DEVMODE_CONTAINER(NDRSTRUCT):
183 structure = (
184 ('cbBuf',DWORD),
185 ('pDevMode',PBYTE_ARRAY),
186 )
188# 2.2.1.11.1 SPLCLIENT_INFO_1
189class SPLCLIENT_INFO_1(NDRSTRUCT):
190 structure = (
191 ('dwSize',DWORD),
192 ('pMachineName',LPWSTR),
193 ('pUserName',LPWSTR),
194 ('dwBuildNum',DWORD),
195 ('dwMajorVersion',DWORD),
196 ('dwMinorVersion',DWORD),
197 ('wProcessorArchitecture',USHORT),
198 )
200class PSPLCLIENT_INFO_1(NDRPOINTER):
201 referent = (
202 ('Data', SPLCLIENT_INFO_1),
203 )
205# 2.2.1.11.2 SPLCLIENT_INFO_2
206class SPLCLIENT_INFO_2(NDRSTRUCT):
207 structure = (
208 ('notUsed',ULONGLONG),
209 )
211class PSPLCLIENT_INFO_2(NDRPOINTER):
212 referent = (
213 ('Data', SPLCLIENT_INFO_2),
214 )
215# 2.2.1.11.3 SPLCLIENT_INFO_3
216class SPLCLIENT_INFO_3(NDRSTRUCT):
217 structure = (
218 ('cbSize',UINT),
219 ('dwFlags',DWORD),
220 ('dwFlags',DWORD),
221 ('pMachineName',LPWSTR),
222 ('pUserName',LPWSTR),
223 ('dwBuildNum',DWORD),
224 ('dwMajorVersion',DWORD),
225 ('dwMinorVersion',DWORD),
226 ('wProcessorArchitecture',USHORT),
227 ('hSplPrinter',ULONGLONG),
228 )
230class PSPLCLIENT_INFO_3(NDRPOINTER):
231 referent = (
232 ('Data', SPLCLIENT_INFO_3),
233 )
235# 2.2.1.5.1 DRIVER_INFO_1
236class DRIVER_INFO_1(NDRSTRUCT):
237 structure = (
238 ('pName', STRING_HANDLE ),
239 )
240class PDRIVER_INFO_1(NDRPOINTER):
241 referent = (
242 ('Data', DRIVER_INFO_1),
243 )
245# 2.2.1.5.2 DRIVER_INFO_2
246class DRIVER_INFO_2(NDRSTRUCT):
247 structure = (
248 ('cVersion',DWORD),
249 ('pName', LPWSTR),
250 ('pEnvironment', LPWSTR),
251 ('pDriverPath', LPWSTR),
252 ('pDataFile', LPWSTR),
253 ('pConfigFile', LPWSTR),
254 )
255class PDRIVER_INFO_2(NDRPOINTER):
256 referent = (
257 ('Data', DRIVER_INFO_2),
258 )
260# 2.2.1.2.3 DRIVER_CONTAINER
261class DRIVER_INFO_UNION(NDRUNION):
262 commonHdr = (
263 ('tag', ULONG),
264 )
265 union = {
266 1 : ('pNotUsed', PDRIVER_INFO_1),
267 2 : ('Level2', PDRIVER_INFO_2),
268 }
270class DRIVER_CONTAINER(NDRSTRUCT):
271 structure = (
272 ('Level', DWORD),
273 ('DriverInfo', DRIVER_INFO_UNION),
274 )
276# 2.2.1.2.14 SPLCLIENT_CONTAINER
277class CLIENT_INFO_UNION(NDRUNION):
278 commonHdr = (
279 ('tag', ULONG),
280 )
281 union = {
282 1 : ('pClientInfo1', PSPLCLIENT_INFO_1),
283 2 : ('pNotUsed1', PSPLCLIENT_INFO_2),
284 3 : ('pNotUsed2', PSPLCLIENT_INFO_3),
285 }
287class SPLCLIENT_CONTAINER(NDRSTRUCT):
288 structure = (
289 ('Level',DWORD),
290 ('ClientInfo',CLIENT_INFO_UNION),
291 )
293# 2.2.1.13.2 RPC_V2_NOTIFY_OPTIONS_TYPE
294class USHORT_ARRAY(NDRUniConformantArray):
295 item = '<H'
297class PUSHORT_ARRAY(NDRPOINTER):
298 referent = (
299 ('Data', USHORT_ARRAY),
300 )
302class RpcAsync_V2_NOTIFY_OPTIONS_TYPE(NDRSTRUCT):
303 structure = (
304 ('Type',USHORT),
305 ('Reserved0',USHORT),
306 ('Reserved1',DWORD),
307 ('Reserved2',DWORD),
308 ('Count',DWORD),
309 ('pFields',PUSHORT_ARRAY),
310 )
312class PRPC_V2_NOTIFY_OPTIONS_TYPE_ARRAY(NDRPOINTER):
313 referent = (
314 ('Data', RpcAsync_V2_NOTIFY_OPTIONS_TYPE),
315 )
317# 2.2.1.13.1 RPC_V2_NOTIFY_OPTIONS
318class RpcAsync_V2_NOTIFY_OPTIONS(NDRSTRUCT):
319 structure = (
320 ('Version',DWORD),
321 ('Reserved',DWORD),
322 ('Count',DWORD),
323 ('pTypes',PRPC_V2_NOTIFY_OPTIONS_TYPE_ARRAY),
324 )
326class PRPC_V2_NOTIFY_OPTIONS(NDRPOINTER):
327 referent = (
328 ('Data', RpcAsync_V2_NOTIFY_OPTIONS),
329 )
332################################################################################
333# RPC CALLS
334################################################################################
335# 3.1.4.1.21 RpcAsyncEnumPrinters (Opnum 38)
336class RpcAsyncEnumPrinters(NDRCALL):
337 opnum = 38
338 structure = (
339 ('Flags', DWORD),
340 ('Name', STRING_HANDLE),
341 ('Level', DWORD),
342 ('pPrinterEnum', PBYTE_ARRAY),
343 ('cbBuf', DWORD),
344 )
346class RpcAsyncEnumPrintersResponse(NDRCALL):
347 structure = (
348 ('pPrinterEnum', PBYTE_ARRAY),
349 ('pcbNeeded', DWORD),
350 ('pcReturned', DWORD),
351 ('ErrorCode', ULONG),
352 )
354# 3.1.4.1.1 RpcAsyncOpenPrinter (Opnum 0)
355class RpcAsyncOpenPrinter(NDRCALL):
356 opnum = 0
357 structure = (
358 ('pPrinterName', STRING_HANDLE),
359 ('pDatatype', LPWSTR),
360 ('pDevModeContainer', DEVMODE_CONTAINER),
361 ('AccessRequired', DWORD),
362 ('pClientInfo', SPLCLIENT_CONTAINER),
363 )
365class RpcAsyncOpenPrinterResponse(NDRCALL):
366 structure = (
367 ('pHandle', PRINTER_HANDLE),
368 ('ErrorCode', ULONG),
369 )
371# 3.1.4.1.10 RpcAsyncClosePrinter (Opnum 20)
372class RpcAsyncClosePrinter(NDRCALL):
373 opnum = 20
374 structure = (
375 ('phPrinter', PRINTER_HANDLE),
376 )
378class RpcAsyncClosePrinterResponse(NDRCALL):
379 structure = (
380 ('phPrinter', PRINTER_HANDLE),
381 ('ErrorCode', ULONG),
382 )
384# 3.1.4.2.3 RpcAsyncEnumPrinterDrivers (Opnum 40)
385class RpcAsyncEnumPrinterDrivers(NDRCALL):
386 opnum = 40
387 structure = (
388 ('pName', STRING_HANDLE),
389 ('pEnvironment', LPWSTR),
390 ('Level', DWORD),
391 ('pDrivers', PBYTE_ARRAY),
392 ('cbBuf', DWORD),
393 )
395class RpcAsyncEnumPrinterDriversResponse(NDRCALL):
396 structure = (
397 ('pDrivers', PBYTE_ARRAY),
398 ('pcbNeeded', DWORD),
399 ('pcReturned', DWORD),
400 ('ErrorCode', ULONG),
401 )
403# 3.1.4.2.2 RpcAsyncAddPrinterDriver (Opnum 39)
404class RpcAsyncAddPrinterDriver(NDRCALL):
405 opnum = 39
406 structure = (
407 ('pName', STRING_HANDLE),
408 ('pDriverContainer', DRIVER_CONTAINER),
409 ('dwFileCopyFlags', DWORD),
410 )
412class RpcAsyncAddPrinterDriverResponse(NDRCALL):
413 structure = (
414 ('ErrorCode', ULONG),
415 )
417################################################################################
418# OPNUMs and their corresponding structures
419################################################################################
420OPNUMS = {
421 0 : (RpcAsyncOpenPrinter, RpcAsyncOpenPrinterResponse),
422 #1 : (RpcAsyncAddPrinter, RpcAsyncAddPrinterResponse),
423 20 : (RpcAsyncClosePrinter, RpcAsyncClosePrinterResponse),
424 38 : (RpcAsyncEnumPrinters, RpcAsyncEnumPrintersResponse),
425 39 : (RpcAsyncAddPrinterDriver, RpcAsyncAddPrinterDriver),
426 40 : (RpcAsyncEnumPrinterDrivers, RpcAsyncEnumPrinterDriversResponse),
427}
429################################################################################
430# HELPER FUNCTIONS
431################################################################################
432def checkNullString(string):
433 if string == NULL:
434 return string
436 if string[-1:] != '\x00':
437 return string + '\x00'
438 else:
439 return string
441def hRpcAsyncClosePrinter(dce, phPrinter):
442 """
443 RpcClosePrinter closes a handle to a printer object, server object, job object, or port object.
444 Full Documentation: https://msdn.microsoft.com/en-us/library/cc244768.aspx
446 :param DCERPC_v5 dce: a connected DCE instance.
447 :param PRINTER_HANDLE phPrinter: A handle to a printer object, server object, job object, or port object.
449 :return: a RpcClosePrinterResponse instance, raises DCERPCSessionError on error.
450 """
451 request = RpcAsyncClosePrinter()
452 request['phPrinter'] = phPrinter
453 return dce.request(request, MSRPC_UUID_WINSPOOL)
456def hRpcAsyncOpenPrinter(dce, printerName, pDatatype=NULL, pDevModeContainer=NULL, accessRequired=SERVER_READ,
457 pClientInfo=NULL):
458 """
459 RpcOpenPrinterEx retrieves a handle for a printer, port, port monitor, print job, or print server
460 Full Documentation: https://msdn.microsoft.com/en-us/library/cc244809.aspx
462 :param DCERPC_v5 dce: a connected DCE instance.
463 :param string printerName: A string for a printer connection, printer object, server object, job object, port
464 object, or port monitor object. This MUST be a Domain Name System (DNS), NetBIOS, Internet Protocol version 4
465 (IPv4), Internet Protocol version 6 (IPv6), or Universal Naming Convention (UNC) name that remote procedure
466 call (RpcAsync) binds to, and it MUST uniquely identify a print server on the network.
467 :param string pDatatype: A string that specifies the data type to be associated with the printer handle.
468 :param DEVMODE_CONTAINER pDevModeContainer: A DEVMODE_CONTAINER structure. This parameter MUST adhere to the specification in
469 DEVMODE_CONTAINER Parameters (section 3.1.4.1.8.1).
470 :param int accessRequired: The access level that the client requires for interacting with the object to which a
471 handle is being opened.
472 :param SPLCLIENT_CONTAINER pClientInfo: This parameter MUST adhere to the specification in SPLCLIENT_CONTAINER Parameters.
474 :return: a RpcOpenPrinterExResponse instance, raises DCERPCSessionError on error.
475 """
476 request = RpcAsyncOpenPrinter()
477 request['pPrinterName'] = checkNullString(printerName)
478 request['pDatatype'] = pDatatype
479 if pDevModeContainer is NULL:
480 request['pDevModeContainer']['pDevMode'] = NULL
481 else:
482 request['pDevModeContainer'] = pDevModeContainer
484 request['AccessRequired'] = accessRequired
485 if pClientInfo is NULL:
486 raise Exception('pClientInfo cannot be NULL')
488 request['pClientInfo'] = pClientInfo
489 return dce.request(request, MSRPC_UUID_WINSPOOL)
492def hRpcAsyncEnumPrinters(dce, flags, name = NULL, level = 1):
493 """
494 RpcEnumPrinters enumerates available printers, print servers, domains, or print providers.
495 Full Documentation: https://msdn.microsoft.com/en-us/library/cc244794.aspx
497 :param DCERPC_v5 dce: a connected DCE instance.
498 :param int flags: The types of print objects that this method enumerates. The value of this parameter is the
499 result of a bitwise OR of one or more of the Printer Enumeration Flags (section 2.2.3.7).
500 :param string name: NULL or a server name parameter as specified in Printer Server Name Parameters (section 3.1.4.1.4).
501 :param level: The level of printer information structure.
503 :return: a RpcEnumPrintersResponse instance, raises DCERPCSessionError on error.
504 """
505 request = RpcAsyncEnumPrinters()
506 request['Flags'] = flags
507 request['Name'] = name
508 request['pPrinterEnum'] = NULL
509 request['Level'] = level
510 bytesNeeded = 0
511 try:
512 dce.request(request, MSRPC_UUID_WINSPOOL)
513 except DCERPCSessionError as e:
514 if str(e).find('ERROR_INSUFFICIENT_BUFFER') < 0:
515 raise
516 bytesNeeded = e.get_packet()['pcbNeeded']
518 request = RpcAsyncEnumPrinters()
519 request['Flags'] = flags
520 request['Name'] = name
521 request['Level'] = level
523 request['cbBuf'] = bytesNeeded
524 request['pPrinterEnum'] = b'a' * bytesNeeded
525 return dce.request(request, MSRPC_UUID_WINSPOOL)
528def hRpcAsyncAddPrinterDriver(dce, pName, pDriverContainer, dwFileCopyFlags):
529 """
530 RpcAddPrinterDriverEx installs a printer driver on the print server
531 Full Documentation: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/b96cc497-59e5-4510-ab04-5484993b259b
533 :param DCERPC_v5 dce: a connected DCE instance.
534 :param pName
535 :param pDriverContainer
536 :param dwFileCopyFlags
538 :return: raises DCERPCSessionError on error.
539 """
540 request = RpcAsyncAddPrinterDriver()
541 request['pName'] = checkNullString(pName)
542 request['pDriverContainer'] = pDriverContainer
543 request['dwFileCopyFlags'] = dwFileCopyFlags
545 #return request
546 return dce.request(request, MSRPC_UUID_WINSPOOL)
549def hRpcAsyncEnumPrinterDrivers(dce, pName, pEnvironment, Level):
550 """
551 RpcEnumPrinterDrivers enumerates the printer drivers installed on a specified print server.
552 Full Documentation: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rprn/857d00ac-3682-4a0d-86ca-3d3c372e5e4a
554 :param DCERPC_v5 dce: a connected DCE instance.
555 :param pName
556 :param pEnvironment
557 :param Level
558 :param pDrivers
559 :param cbBuf
560 :param pcbNeeded
561 :param pcReturned
563 :return: raises DCERPCSessionError on error.
564 """
565 # get value for cbBuf
566 request = RpcAsyncEnumPrinterDrivers()
567 request['pName'] = checkNullString(pName)
568 request['pEnvironment'] = pEnvironment
569 request['Level'] = Level
570 request['pDrivers'] = NULL
571 request['cbBuf'] = 0
572 try:
573 dce.request(request, MSRPC_UUID_WINSPOOL)
574 except DCERPCSessionError as e:
575 if str(e).find('ERROR_INSUFFICIENT_BUFFER') < 0:
576 raise
577 bytesNeeded = e.get_packet()['pcbNeeded']
579 # now do RpcEnumPrinterDrivers again
580 request = RpcAsyncEnumPrinterDrivers()
581 request['pName'] = checkNullString(pName)
582 request['pEnvironment'] = pEnvironment
583 request['Level'] = Level
584 request['pDrivers'] = b'a' * bytesNeeded
585 request['cbBuf'] = bytesNeeded
587 #return request
588 return dce.request(request, MSRPC_UUID_WINSPOOL)