Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

API for reading memory

Posted on 1997-06-16
11
Medium Priority
?
495 Views
Last Modified: 2006-11-17
I am writing a program that that uses API calls to store a large file in a Allocated Chunk of memory.  How can I retrieve data from this chunk and store it back in to an array.
0
Comment
Question by:stephaner
  • 5
  • 3
  • 3
11 Comments
 
LVL 7

Expert Comment

by:tward
ID: 1427313
What is the function you are using to put it in memory?
0
 

Author Comment

by:stephaner
ID: 1427314
Here is a copy of the subroutine.  This subroutine is part of a class.


Public Sub Load()
  Dim FileSize As Long      'Used to store the file size
  Dim hFile As Long         'Used as a handle to the File
  Dim retval As Long        'Used as generic return value
  Dim lpBytesread As Long   'Used by Api(ReadFile)
 

   
  'Get the size of the file
    FileSize = FileLen(FileName)

  'Verify that the file is not zero length.
    If FileSize > 0 Then

      'Allocate a block of memory equal to the size of the input file.
        mlng_HandleMemory = GlobalAlloc(GMEM_ZEROINIT, FileSize)
       

        'Verify that the allocation succeded
          If mlng_HandleMemory <> 0 Then

            'Lock newly allocated memory
              mlng_MemoryAddress = GlobalLock(mlng_HandleMemory)
         
             
            'Open the File
              hFile = CreateFile(FileName, GENERIC_READ, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, ByVal 0&)
             
                       
            'Read File into Memory
              retval = lread(hFile, ByVal mlng_MemoryAddress, FileSize)
         
                           
            'Close the File
              retval = CloseHandle(hFile)
....
         
                           
0
 
LVL 7

Expert Comment

by:tward
ID: 1427315
Try the following API call:

Declare Function ReadProcessMemory Lib "kernel32" Alias "ReadProcessMemory" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long

Here is an explanation of the function:

The ReadProcessMemory function reads memory in a specified process. The entire area to be read must be accessible, or the operation fails.
BOOL ReadProcessMemory(
    HANDLE hProcess,      // handle of the process whose memory is read  
    LPCVOID lpBaseAddress,      // address to start reading
    LPVOID lpBuffer,      // address of buffer to place read data
    DWORD nSize,      // number of bytes to read
    LPDWORD lpNumberOfBytesRead       // address of number of bytes read
   );      
 
Parameters
hProcess
Identifies an open handle of a process whose memory is read. The handle must have PROCESS_VM_READ access to the process.
lpBaseAddress
Points to the base address in the specified process to be read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access. If this is the case, the function proceeds; otherwise, the function fails.
lpBuffer
Points to a buffer that receives the contents from the address space of the specified process.
nSize
Specifies the requested number of bytes to read from the specified process.
lpNumberOfBytesRead
Points to the actual number of bytes transferred into the specified buffer. If lpNumberOfBytesRead is NULL, the parameter is ignored.
 
Return Values
If the function succeeds, the return value is TRUE.
If the function fails, the return value is FALSE. To get extended error information, call GetLastError.
The function fails if the requested read operation crosses into an area of the process that is inaccessible.
Remarks
ReadProcessMemory copies the data in the specified address range from the address space of the specified process into the specified buffer of the current process. Any process that has a handle with PROCESS_VM_READ access can call the function. The process whose address space is read is typically, but not necessarily, being debugged.
The entire area to be read must be accessible. If it is not, the function fails as noted previously.

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 7

Expert Comment

by:tward
ID: 1427316
Also note that after you are done with the memory you need to do a GlobalUnlock which I don't see in your above code.
0
 

Author Comment

by:stephaner
ID: 1427317
I am not sure how to put my class together using this function.  Maybe a little background on what I am trying to achieve would help.
My class is used for bitmap manipulation and display.  The idea is that I would have a load function which copies the whole file into memory.  Then I could implement functions to read and dissect the data such as getting the BitmapHeadears, Bitmapdata, ShowBitmap, SaveBitmap.  It seems that since I will be accessing this data often, it would be faster to do it this way than simply reading the data from the file every time I need it.

It is for this reason that there is no call to unlock the memory as this would be done in the Save routine.

Also I have implemented this save routine, although it does copy data back into a file (using lwrite),  the data does not correspond with the original copy of it.

Is it that my approach to the problem is inadequate, or unrealizable?

0
 

Author Comment

by:stephaner
ID: 1427318



0
 
LVL 5

Accepted Solution

by:
y96andha earned 400 total points
ID: 1427319
Use the RtlMoveMemory function.

Example to copy 400 bytes of data starting with position 20 in the memory chunk, and to put these bytes back at position 1024 in the memory chunk:

Declare Sub MoveMemory1 Lib "kernel32"  Alias "RtlMoveMemory" (Byval dest as String, Byval src as Long, Byval bytes as Long)

Declare Sub MoveMemory2 Lib "kernel32"  Alias "RtlMoveMemory" (Byval dest as Long, Byval src as String, Byval bytes as Long)

Dim data as String
data=String(400,0)
CopyMemory1 data, mlng_MemoryAddress+20, 400

CopyMemory2 mlng_MemoryAddress+1024, data, 400



Please comment if you have any questions.

0
 

Author Comment

by:stephaner
ID: 1427320
I could not find the above declrations in the API file.  Do you no why?  Also right now I am using "agCopyData" to perform this task. However, this does not allow me to read in anything other than a string.  I would like to be able to read in directly other data types such as Intgers and Longs.  Would your functions allow for this?
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427321
Yes, they would. All you have to do is to make sure that the declaration passes pointers as the first two arguments and a length as the last. To read a Long, you would make a declaration like this:

Declare Sub MoveMemory3 Lib "kernel32" Alias "RtlMoveMemory" (dest as Long, Byval src as Long, Byval bytes as Long)

Dim data as Long
MoveMemory3 data, mlng_MemoryAddress+47, Len(data)


Notice that there is no ByVal on the first argument, which makes  VB take its address and pass it to the DLL function.

I do not know why the declaration is not in the API file. Maybe because VB isn't made for using pointers. Do you know if there is any instruction in VB to get the address of a certain variable? Anyway, I got the declaration from my C++ compiler, so it should work.

I cannot find a declaration for agCopyData either.

0
 

Author Comment

by:stephaner
ID: 1427322
Ok, I was able to make it work for the following types: Byte, String, Integer, Long.  However I still need to know what the declare would be for an array of bytes? a UDT?  Also I had to modify each declare depending on the type.  Is there a way to have only one declare that fits all?

"agCopydata" is part of a lib called "ApiGid32.dll"
This lib contans the functions you mentioned such as:
agGetAddressForObject, gGetAddressForInteger, agGetAddressForLPSTR
and other usefull functions.  For more inforrmation on this lib:
"www.desare.com"
0
 
LVL 5

Expert Comment

by:y96andha
ID: 1427323
I do not know for an array of bytes. I have a student version of VB, which means I do not have a manual, just a CD. I think that you should pass the first byte. UDT= User Defined Type? In that case, it will work just like Byte, Integer, Long and so on.

To make a declare fit all, you should use

Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (dest as Any, src as Any, Byval bytes as Long)

This should enable you to specify whatever type you'd like. It could be that you still need need to specify the pointer address, that is, the mlng_MemoryAddress part as "ByVal xxx as Long".

On the other hand, if you can get the address for any data type, then you can use

Declare Sub MoveMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest as Long, ByVal src as Long, Byval bytes as Long)

and just pass in the addresses.


0

Featured Post

Vote for the Most Valuable Expert

It’s time to recognize experts that go above and beyond with helpful solutions and engagement on site. Choose from the top experts in the Hall of Fame or on the right rail of your favorite topic page. Look for the blue “Nominate” button on their profile to vote.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Suggested Courses

972 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question