def iter_memory_snapshot(self, minAddr = None, maxAddr = None):
        """
        Returns an iterator that allows you to go through the memory contents
        of a process.

        It's basically the same as the L{take_memory_snapshot} method, but it
        takes the snapshot of each memory region as it goes, as opposed to
        taking the whole snapshot at once. This allows you to work with very
        large snapshots without a significant performance penalty.

        Example::
            # Print the memory contents of a process.
            process.suspend()
            try:
                snapshot = process.generate_memory_snapshot()
                for mbi in snapshot:
                    print HexDump.hexblock(mbi.content, mbi.BaseAddress)
            finally:
                process.resume()

        The downside of this is the process must remain suspended while
        iterating the snapshot, otherwise strange things may happen.

        The snapshot can only iterated once. To be able to iterate indefinitely
        call the L{generate_memory_snapshot} method instead.

        You can also iterate the memory of a dead process, just as long as the
        last open handle to it hasn't been closed.

        @see: L{take_memory_snapshot}

        @type  minAddr: int
        @param minAddr: (Optional) Starting address in address range to query.

        @type  maxAddr: int
        @param maxAddr: (Optional) Ending address in address range to query.

        @rtype:  iterator of L{win32.MemoryBasicInformation}
        @return: Iterator of memory region information objects.
            Two extra properties are added to these objects:
             - C{filename}: Mapped filename, or C{None}.
             - C{content}: Memory contents, or C{None}.
        """

        # One may feel tempted to include calls to self.suspend() and
        # self.resume() here, but that wouldn't work on a dead process.
        # It also wouldn't be needed when debugging since the process is
        # already suspended when the debug event arrives. So it's up to
        # the user to suspend the process if needed.

        # Get the memory map.
        memory = self.get_memory_map(minAddr, maxAddr)

        # Abort if the map couldn't be retrieved.
        if not memory:
            return

        # Get the mapped filenames.
        # Don't fail on access denied errors.
        try:
            filenames = self.get_mapped_filenames(memory)
        except WindowsError:
            e = sys.exc_info()[1]
            if e.winerror != win32.ERROR_ACCESS_DENIED:
                raise
            filenames = dict()

        # Trim the first memory information block if needed.
        if minAddr is not None:
            minAddr = MemoryAddresses.align_address_to_page_start(minAddr)
            mbi = memory[0]
            if mbi.BaseAddress < minAddr:
                mbi.RegionSize  = mbi.BaseAddress + mbi.RegionSize - minAddr
                mbi.BaseAddress = minAddr

        # Trim the last memory information block if needed.
        if maxAddr is not None:
            if maxAddr != MemoryAddresses.align_address_to_page_start(maxAddr):
                maxAddr = MemoryAddresses.align_address_to_page_end(maxAddr)
            mbi = memory[-1]
            if mbi.BaseAddress + mbi.RegionSize > maxAddr:
                mbi.RegionSize = maxAddr - mbi.BaseAddress

        # Read the contents of each block and yield it.
        while memory:
            mbi = memory.pop(0) # so the garbage collector can take it
            mbi.filename = filenames.get(mbi.BaseAddress, None)
            if mbi.has_content():
                mbi.content = self.read(mbi.BaseAddress, mbi.RegionSize)
            else:
                mbi.content = None
            yield mbi
Returns an iterator that allows you to go through the memory contents
        of a process.

        It's basically the same as the L{take_memory_snapshot} method, but it
        takes the snapshot of each memory region as it goes, as opposed to
        taking the whole snapshot at once. This allows you to work with very
        large snapshots without a significant performance penalty.

        Example::
            # Print the memory contents of a process.
            process.suspend()
            try:
                snapshot = process.generate_memory_snapshot()
                for mbi in snapshot:
                    print HexDump.hexblock(mbi.content, mbi.BaseAddress)
            finally:
                process.resume()

        The downside of this is the process must remain suspended while
        iterating the snapshot, otherwise strange things may happen.

        The snapshot can only iterated once. To be able to iterate indefinitely
        call the L{generate_memory_snapshot} method instead.

        You can also iterate the memory of a dead process, just as long as the
        last open handle to it hasn't been closed.

        @see: L{take_memory_snapshot}

        @type  minAddr: int
        @param minAddr: (Optional) Starting address in address range to query.

        @type  maxAddr: int
        @param maxAddr: (Optional) Ending address in address range to query.

        @rtype:  iterator of L{win32.MemoryBasicInformation}
        @return: Iterator of memory region information objects.
            Two extra properties are added to these objects:
             - C{filename}: Mapped filename, or C{None}.
             - C{content}: Memory contents, or C{None}.