def _getTextRange(self, start, end): bufLen = (end - start) + 1 textRange = TextRangeStruct() textRange.chrg.cpMin = start textRange.chrg.cpMax = end processHandle = self.obj.processHandle internalBuf = winKernel.virtualAllocEx(processHandle, None, bufLen, winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE) try: textRange.lpstrText = internalBuf internalTextRange = winKernel.virtualAllocEx( processHandle, None, ctypes.sizeof(textRange), winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE) try: winKernel.writeProcessMemory(processHandle, internalTextRange, ctypes.byref(textRange), ctypes.sizeof(textRange), None) numBytes = watchdog.cancellableSendMessage( self.obj.windowHandle, SCI_GETTEXTRANGE, 0, internalTextRange) finally: winKernel.virtualFreeEx(processHandle, internalTextRange, 0, winKernel.MEM_RELEASE) buf = ctypes.create_string_buffer(bufLen) winKernel.readProcessMemory(processHandle, internalBuf, buf, bufLen, None) finally: winKernel.virtualFreeEx(processHandle, internalBuf, 0, winKernel.MEM_RELEASE) return textUtils.getTextFromRawBytes(buf.raw, numChars=numBytes, encoding=self.encoding, errorsFallback="surrogateescape")
def _getTextRange(self, start, end): if self.obj.editAPIVersion >= 2: # Calculate a buffer size that is twice the size of the text range and a NULL terminating character. # As unicode characters are two bytes in size, # this ensures that our buffer can hold both ANSI and unicode character strings. bufLen = ((end - start) + 1) * 2 # Even though this can return unicode text, we use the ANSI version of the structure. # Using the unicode structure isn't strictly necessary and saves us some confusion textRange = TextRangeStruct() textRange.chrg.cpMin = start textRange.chrg.cpMax = end processHandle = self.obj.processHandle internalBuf = winKernel.virtualAllocEx(processHandle, None, bufLen, winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE) try: textRange.lpstrText = internalBuf internalTextRange = winKernel.virtualAllocEx( processHandle, None, ctypes.sizeof(textRange), winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE) try: winKernel.writeProcessMemory(processHandle, internalTextRange, ctypes.byref(textRange), ctypes.sizeof(textRange), None) # EM_GETTEXTRANGE returns the number of characters copied, # not including the terminating null character. # See https://docs.microsoft.com/en-us/windows/desktop/controls/em-gettextrange numChars = watchdog.cancellableSendMessage( self.obj.windowHandle, EM_GETTEXTRANGE, 0, internalTextRange) finally: winKernel.virtualFreeEx(processHandle, internalTextRange, 0, winKernel.MEM_RELEASE) buf = ctypes.create_string_buffer(bufLen) # Copy the text in the text range to our own buffer. winKernel.readProcessMemory(processHandle, internalBuf, buf, bufLen, None) finally: winKernel.virtualFreeEx(processHandle, internalBuf, 0, winKernel.MEM_RELEASE) # Find out which encoding to use to decode the bytes in the buffer. if ( # The window is unicode, the text range contains multi byte characters. self.obj.isWindowUnicode): encoding = textUtils.WCHAR_ENCODING else: # De encoding will be determined by L{textUtils.getTextFromRawBytes} encoding = None text = textUtils.getTextFromRawBytes(buf.raw, numChars, encoding) # #4095: Some protected richEdit controls do not hide their password characters. # We do this specifically. # Note that protected standard edit controls get characters hidden in _getStoryText. if text and controlTypes.State.PROTECTED in self.obj.states: text = u'*' * len(text) else: text = super(EditTextInfo, self)._getTextRange(start, end) return text
def getAccessibleTextRange(self,start,end): length=((end+1)-start) if length<=0: return u"" # Use a string buffer, as from an unicode buffer, we can't get the raw data. buf = create_string_buffer((length +1) * 2) bridgeDll.getAccessibleTextRange(self.vmID, self.accContext, start, end, buf, length) return textUtils.getTextFromRawBytes(buf.raw, numChars=length, encoding=textUtils.WCHAR_ENCODING)
def ReadConsoleOutputCharacter(handle, length, x, y): # Use a string buffer, as from an unicode buffer, we can't get the raw data. buf = create_string_buffer(length * 2) numCharsRead = c_int() if windll.kernel32.ReadConsoleOutputCharacterW(handle, buf, length, COORD(x, y), byref(numCharsRead)) == 0: raise WinError() return textUtils.getTextFromRawBytes(buf.raw, numChars=numCharsRead.value, encoding=textUtils.WCHAR_ENCODING)