Solved

Calls for Backup Application

Posted on 1997-05-09
2
208 Views
Last Modified: 2012-08-13
I am using VB4(32) under WIndows NT and am trying to create a backup program which will be able to access files which are constantly in use and back them up. (ie a MS Access database)

I have gathered that BackupRead and BackupWrite should be called from the "kernel32" library, and that files should be opened with backup program access.  What I am having trouble with is DLL calling conventions:

How do I pass NULL to a DLL call?  I need to pass NULL where a LONG variable should be  to achieve specific results, but I cannot simply say VARIABLE& = NULL then pass it, or I get an "Invalid use of Null" error on compile.

Also,   what structure should I pass to ReadFile?  I tried passing an array of type Byte, but I received  errors when trying to compile.

Buffer(bSize) As Byte  didn't seem to work.  Can someone post a sample of how to use ReadFile then WriteFile from VB, using a structure to store the Read data?
(I should be able to figure out how to use BackupRead and BackupWrite from there)

Thanks a lot,

ah077@chebucto.ns.ca
0
Comment
Question by:asmcmrr
2 Comments
 
LVL 7

Accepted Solution

by:
tward earned 180 total points
Comment Utility
*******************************************************************
You can pass a NULL by simply passing 0&
*******************************************************************

*******************************************************************
Here are all the definitions you should need:

Type OVERLAPPED
        Internal As Long
        InternalHigh As Long
        offset As Long
        OffsetHigh As Long
        hEvent As Long
End Type

Declare Function ReadFile Lib "kernel32" Alias "ReadFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToRead As Long, lpNumberOfBytesRead As Long, lpOverlapped As OVERLAPPED) As Long

Declare Function WriteFile Lib "kernel32" Alias "WriteFile" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As OVERLAPPED) As Long
*******************************************************************

*******************************************************************
Here is a complete explanation of ReadFile (from C/C++):
*******************************************************************
The ReadFile function reads data from a file, starting at the position indicated by the file pointer. After the read operation has been completed, the file pointer is adjusted by the number of bytes actually read, unless the file handle is created with the overlapped attribute. If the file handle is created for overlapped input and output (I/O), the application must adjust the position of the file pointer after the read operation.
BOOL ReadFile(
    HANDLE hFile,      // handle of file to read
    LPVOID lpBuffer,      // address of buffer that receives data  
    DWORD nNumberOfBytesToRead,      // number of bytes to read
    LPDWORD lpNumberOfBytesRead,      // address of number of bytes read
    LPOVERLAPPED lpOverlapped       // address of structure for data
   );      
 
Parameters
hFile
Identifies the file to be read. The file handle must have been created with GENERIC_READ access to the file.
Windows NT
For asynchronous read operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function, or a socket handle returned by the socket or accept functions.
Windows 95
For asynchronous read operations, hFile can be a communications resource, mailslot, or named pipe handle opened with the FILE_FLAG_OVERLAPPED flag by CreateFile, or a socket handle returned by the socket or accept functions. Windows 95 does not support asynchronous read operations on disk files.
lpBuffer
Points to the buffer that receives the data read from the file.
nNumberOfBytesToRead
Specifies the number of bytes to be read from the file.
lpNumberOfBytesRead
Points to the number of bytes read. ReadFile sets this value to zero before doing any work or error checking. If this parameter is zero when ReadFile returns TRUE on a named pipe, the other end of the message-mode pipe called the WriteFile function with nNumberOfBytesToWrite set to zero.
If lpOverlapped is NULL, lpNumberOfBytesRead cannot be NULL.
If lpOverlapped is not NULL, lpNumberOfBytesRead can be NULL. If this is an overlapped read operation, you can get the number of bytes read by calling GetOverlappedResult. If hFile is associated with an I/O completion port, you can get the number of bytes read by calling GetQueuedCompletionStatus.
lpOverlapped
Points to an OVERLAPPED structure. This structure is required if hFile was created with FILE_FLAG_OVERLAPPED.
If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was created with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the read operation is complete.
If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure and ReadFile may return before the read operation has been completed. In this case, ReadFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING. This allows the calling process to continue while the read operation finishes. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the read operation.
If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the read operation starts at the current file position and ReadFile does not return until the operation has been completed.
If hFile is not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the read operation starts at the offset specified in the OVERLAPPED structure. ReadFile does not return until the read operation has been completed.
 
Return Values
If the function succeeds, the return value is TRUE. If the return value is TRUE and the number of bytes read is zero, the file pointer was beyond the current end of the file at the time of the read operation. However, if the file was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the return value is FALSE and GetLastError returns ERROR_HANDLE_EOF when the file pointer goes beyond the current end of file.
If the function fails, the return value is FALSE. To get extended error information, call GetLastError.
Remarks
ReadFile returns when one of the following is true: a write operation completes on the write end of the pipe, the number of bytes requested has been read, or an error occurs.
If part of the file is locked by another process and the read operation overlaps the locked portion, this function fails.
Applications must not read from nor write to the input buffer that a read operation is using until the read operation completes. A premature access to the input buffer may lead to corruption of the data read into that buffer.
Characters can be read from the console input buffer by using ReadFile with a handle to console input. The console mode determines the exact behavior of the ReadFile function.
If a named pipe is being read in message mode and the next message is longer than the nNumberOfBytesToRead parameter specifies, ReadFile returns FALSE and GetLastError returns ERROR_MORE_DATA. The remainder of the message may be read by a subsequent call to the ReadFile or PeekNamedPipe function.
When reading from a communications device, the behavior of ReadFile is governed by the current communication timeouts as set and retrieved using the SetCommTimeouts and GetCommTimeouts functions. Unpredictable results can occur if you fail to set the timeout values. For more information about communication timeouts, see COMMTIMEOUTS.
If ReadFile attempts to read from a mailslot whose buffer is too small, the function returns FALSE and GetLastError returns ERROR_INSUFFICIENT_BUFFER.
If the anonymous write pipe handle has been closed and ReadFile attempts to read using the corresponding anonymous read pipe handle, the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE.
The ReadFile function may fail and return ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests.
The ReadFile code to check for the end-of-file condition (eof) differs for synchronous and asynchronous read operations.
When a synchronous read operation reaches the end of a file, ReadFile returns TRUE and sets *lpNumberOfBytesRead to zero. The following sample code tests for end-of-file for a synchronous read operation:
// attempt a synchronous read operation  
bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead, NULL) ;
// check for eof
if (bResult &&  nBytesRead == 0, ) {
      // we're at the end of the file
      }
 
An asynchronous read operation can encounter the end of a file during the initiating call to ReadFile, or during subsequent asynchronous operation.
If EOF is detected at ReadFile time for an asynchronous read operation, ReadFile returns FALSE and GetLastError returns ERROR_HANDLE_EOF.
If EOF is detected during subsequent asynchronous operation, the call to GetOverlappedResult to obtain the results of that operation returns FALSE and GetLastError returns ERROR_HANDLE_EOF.
The following sample code illustrates testing for end-of-file for an asynchronous read operation:
// set up overlapped structure fields  
// to simplify this sample, we'll eschew an event handle
gOverLapped.Offset     = 0;
gOverLapped.OffsetHigh = 0;
gOverLapped.hEvent     = NULL;
 
// attempt an asynchronous read operation
bResult = ReadFile(hFile, &inBuffer, nBytesToRead, &nBytesRead,
             &gOverlapped) ;
 
// if there was a problem, or the async. operation's still pending ...
if (!bResult) {
 
      // deal with the error code
      switch (dwError = GetLastError()) {
 
            case ERROR_HANDLE_EOF: {
                  // we're reached the end of the file
                  // during the call to ReadFile
                  
                  // code to handle that
                  }
 
            case ERROR_IO_PENDING: {
                  // asynchronous i/o is still in progress
                  
                  // do something else for a while
                  GoDoSomethingElse() ;
                  
                  // check on the results of the asynchronous read
                  bResult = GetOverlappedResult(hFile, &gOverlapped,
                                                      &nBytesRead, FALSE) ;
                  
                  // if there was a problem ...
                  if (!bResult) {
                  
                        // deal with the error code
                        switch (dwError = GetLastError()) {
                  
                              case ERROR_HANDLE_EOF: {
                                    // we're reached the end of the file
                                    //during asynchronous operation
                                    }
 
                              // deal with other error cases
 
                              } // end switch
                        } // end if
                  } // end case
 
            // deal with other error cases
 
            } // end switch
      } // end if
 

See Also
CreateFile, GetCommTimeouts, GetOverlappedResult, GetQueuedCompletionStatus, OVERLAPPED, PeekNamedPipe, ReadFileEx, SetCommTimeouts, WriteFile
 
*******************************************************************
Here is a complete explanation of WriteFile (from C/C++):
*******************************************************************

The WriteFile function writes data to a file and is designed for both synchronous and asynchronous operation. The function starts writing data to the file at the position indicated by the file pointer. After the write operation has been completed, the file pointer is adjusted by the number of bytes actually written, except when the file is opened with FILE_FLAG_OVERLAPPED. If the file handle was created for overlapped input and output (I/O), the application must adjust the position of the file pointer after the write operation is finished.
BOOL WriteFile(
    HANDLE hFile,      // handle to file to write to
    LPCVOID lpBuffer,      // pointer to data to write to file
    DWORD nNumberOfBytesToWrite,      // number of bytes to write
    LPDWORD lpNumberOfBytesWritten,      // pointer to number of bytes written
    LPOVERLAPPED lpOverlapped       // pointer to structure needed for overlapped I/O
   );      
 
Parameters
hFile
Identifies the file to be written to. The file handle must have been created with GENERIC_WRITE access to the file.
Windows NT
For asynchronous write operations, hFile can be any handle opened with the FILE_FLAG_OVERLAPPED flag by the CreateFile function, or a socket handle returned by the socket or accept functions.
Windows 95
For asynchronous write operations, hFile can be a communications resource, mailslot, or named pipe handle opened with the FILE_FLAG_OVERLAPPED flag by CreateFile, or a socket handle returned by the socket or accept functions. Windows 95 does not support asynchronous write operations on disk files.
lpBuffer
Points to the buffer containing the data to be written to the file.
nNumberOfBytesToWrite
Specifies the number of bytes to write to the file.
Unlike the MS-DOS operating system, Windows NT interprets a value of zero as specifying a null write operation. A null write operation does not write any bytes but does cause the time stamp to change.
Named pipe write operations across a network are limited to 65535 bytes.
lpNumberOfBytesWritten
Points to the number of bytes written by this function call. WriteFile sets this value to zero before doing any work or error checking.
If lpOverlapped is NULL, lpNumberOfBytesWritten cannot be NULL.
If lpOverlapped is not NULL, lpNumberOfBytesWritten can be NULL. If this is an overlapped write operation, you can get the number of bytes written by calling GetOverlappedResult. If hFile is associated with an I/O completion port, you can get the number of bytes written by calling GetQueuedCompletionStatus.
lpOverlapped
Points to an OVERLAPPED structure. This structure is required if hFile was opened with FILE_FLAG_OVERLAPPED.
If hFile was opened with FILE_FLAG_OVERLAPPED, the lpOverlapped parameter must not be NULL. It must point to a valid OVERLAPPED structure. If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the function can incorrectly report that the write operation is complete.
If hFile was opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile may return before the write operation has been completed. In this case, WriteFile returns FALSE and the GetLastError function returns ERROR_IO_PENDING. This allows the calling process to continue processing while the write operation is being completed. The event specified in the OVERLAPPED structure is set to the signaled state upon completion of the write operation.
If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is NULL, the write operation starts at the current file position and WriteFile does not return until the operation has been completed.
If hFile was not opened with FILE_FLAG_OVERLAPPED and lpOverlapped is not NULL, the write operation starts at the offset specified in the OVERLAPPED structure and WriteFile does not return until the write operation has been completed.
 
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.
Remarks
If part of the file is locked by another process and the write operation overlaps the locked portion, this function fails.
Applications must not read from nor write to the output buffer that a write operation is using until the write operation completes. Premature access of the output buffer may lead to corruption of the data written from that buffer.
Characters can be written to the screen buffer using WriteFile with a handle to console output. The exact behavior of the function is determined by the console mode. The data is written to the current cursor position. The cursor position is updated after the write operation.
Unlike the MS-DOS operating system, Windows NT interprets zero bytes to write as specifying a null write operation and WriteFile does not truncate or extend the file. To truncate or extend a file, use the SetEndOfFile function.
When writing to a nonblocking, byte-mode pipe handle with insufficient buffer space, WriteFile returns TRUE with *lpNumberOfBytesWritten < nNumberOfBytesToWrite.
When an application uses the WriteFile function to write to a pipe, the write operation may not finish if the pipe buffer is full. The write operation is completed when a read operation (using the ReadFile function) makes more buffer space available.
If the anonymous read pipe handle has been closed and WriteFile attempts to write using the corresponding anonymous write pipe handle, the function returns FALSE and GetLastError returns ERROR_BROKEN_PIPE.
The WriteFile function may fail with ERROR_INVALID_USER_BUFFER or ERROR_NOT_ENOUGH_MEMORY whenever there are too many outstanding asynchronous I/O requests.
If hFile is a handle to a named pipe, the Offset and OffsetHigh members of the OVERLAPPED structure pointed to by lpOverlapped must be zero, or the function will fail.
See Also
CreateFile, GetLastError, GetOverlappedResult, GetQueuedCompletionStatus, OVERLAPPED, ReadFile, SetEndOfFile, WriteFileEx

If you need anything else just leave a comment...
0
 
LVL 1

Author Comment

by:asmcmrr
Comment Utility
This is your Structure definition in VB format:

Type OVERLAPPED
        Internal As Long
        InternalHigh As Long
        offset As Long
        OffsetHigh As Long
        hEvent As Long
End Type

This is how you pass the structure in VB:

Dim rv as Long
Dim hFile as Long
Dim nNumberOfBytesToRead as Long
Dim lpNumberOfBytesRead as Long
Dim lpBuffer as Any

rv= ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, _ lpNumberOfBytesRead, lpOverlapped )

That should work for you...  Just remember anything that is going to be set by the calling DLL Function needs to be passed in ByRef otherwise you will have problems.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

If you have ever used Microsoft Word then you know that it has a good spell checker and it may have occurred to you that the ability to check spelling might be a nice piece of functionality to add to certain applications of yours. Well the code that…
Enums (shorthand for ‘enumerations’) are not often used by programmers but they can be quite valuable when they are.  What are they? An Enum is just a type of variable like a string or an Integer, but in this case one that you create that contains…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

763 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

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now