async def hREnumServicesStatusW( dce, hSCManager, dwServiceType=SERVICE_WIN32_OWN_PROCESS | SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_WIN32_SHARE_PROCESS | SERVICE_INTERACTIVE_PROCESS, dwServiceState=SERVICE_STATE_ALL): class ENUM_SERVICE_STATUSW2(NDRSTRUCT): # This is a little trick, since the original structure is slightly different # but instead of parsing the LPBYTE buffer at hand, we just do it with the aid # of the NDR library, although the pointers are swapped from the original specification. # Why is this? Well.. since we're getting an LPBYTE back, it's just a copy of the remote's memory # where the pointers are actually POINTING to the data. # Sadly, the pointers are not aligned based on the services records, so we gotta do this # It should be easier in C of course. class STR(NDRPOINTER): referent = (('Data', WIDESTR), ) structure = ( ('lpServiceName', STR), ('lpDisplayName', STR), ('ServiceStatus', SERVICE_STATUS), ) enumServicesStatus = REnumServicesStatusW() enumServicesStatus['hSCManager'] = hSCManager enumServicesStatus['dwServiceType'] = dwServiceType enumServicesStatus['dwServiceState'] = dwServiceState enumServicesStatus['cbBufSize'] = 0 enumServicesStatus['lpResumeIndex'] = NULL resp, e = await dce.request(enumServicesStatus) if e is not None: #print('e! %s' % e) if isinstance(e, SMBException): #this case the exception is coming from the SMB connection itself, it's is dead Jim return None, e if e.get_error_code() == system_errors.ERROR_MORE_DATA: resp = e.get_packet() enumServicesStatus['cbBufSize'] = resp['pcbBytesNeeded'] resp, e = await dce.request(enumServicesStatus) else: return None, e # Now we're supposed to have all services returned. Now we gotta parse them enumArray = NDRUniConformantArray() enumArray.item = ENUM_SERVICE_STATUSW2 enumArray.setArraySize(resp['lpServicesReturned']) data = b''.join(resp['lpBuffer']) enumArray.fromString(data) data = data[4:] # Since the pointers here are pointing to the actual data, we have to reparse # the referents for record in enumArray['Data']: offset = record.fields['lpDisplayName'].fields['ReferentID'] - 4 name = WIDESTR(data[offset:]) record['lpDisplayName'] = name['Data'] offset = record.fields['lpServiceName'].fields['ReferentID'] - 4 name = WIDESTR(data[offset:]) record['lpServiceName'] = name['Data'] return enumArray['Data'], None
def __setitem__(self, key, value): self.fields['MaximumCount'] = None self.data = None # force recompute return NDRUniConformantArray.__setitem__(self, key, [ord(c) for c in value])