How to use CreateFile and WriteFile functions from "kernel32" in VB.NET ?

Posted on 2004-04-21
Medium Priority
Last Modified: 2012-05-04
Greetings !

I'm converting classic vb project to VB.NET. The application does Cheque scanning and store images in memory, so the developer has to save those images manually to the hard disk (HD).

I'm having a difficulty while saving to the HD using VB.NET

Please have a look at the function I wrote in Classic VB.

'// Saves an image from memory
Public Function SaveImage(ByVal strFileName$, ByVal lngMem&, ByVal lngBytes&) As Long
    Dim lngFile&
    Dim lngTemp&
    lngFile = CreateFile(strFileName, GENERIC_WRITE, FILE_SHARE_READ, 0, _
                         CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, 0)
    If lngFile = INVALID_HANDLE_VALUE Then
        SaveImage = -801 '// FSM Error opening TIFF/file
        Exit Function
    End If
    '// Write the image to the file
    If (WriteFile(lngFile, ByVal lngMem, lngBytes, lngTemp, ByVal 0&) = 0) Then
        SaveImage = -803 '// FSM Error writing to TIFF/file
    End If
    CloseHandle (lngFile)
End Function

In VB.NET, I'm writing this routine:

Public Function SaveImage(ByVal strFileName As String, ByVal lngMem As Int32, _
            ByVal lngBytes As Int32) As Int32

        If File.Exists(strFileName) Then File.Delete(strFileName)
        Dim fs As New FileStream(strFileName, FileMode.CreateNew, FileAccess.Write)
        Dim w As New BinaryWriter(fs)
End Function

Image is getting created in the given path, but when i try to open in Imaging Preview, Error is prompting "The doument's format is invalid or not supported."

Can anyone of you please help me to convert that function in VB.NET. Your help will be highly appreciated. I'm stuck.

Question by:yamiho
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 5
LVL 12

Expert Comment

ID: 10885233
All you've written to the file is an integer.  Finish writing all the data and should be all set.

Your write code looks fine, you're just not writing enough.  here's a link to the MS site for reference.


Author Comment

ID: 10885357

Thanks for your response. But I'm not really getting what exactly I'm missing in the code. Can you please elaborate it ? I'm trying to write a tiff image (imgFront.tif).

Alternatively, can I use CreateFile and WriteFile?

'Declaration for CreateFile (VB.Net Syntax)
Public Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Integer, ByVal dwShareMode As Integer,<MarshalAs(UnmanagedType.Struct)> ByRef   lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Integer, ByVal dwFlagsAndAttributes As Integer, ByVal hTemplateFile As Integer) As Integer

'Declaration for WriteFile (VB.Net Syntax)
Public Declare Function WriteFile Lib "kernel32" Alias "WriteFile" (ByVal hFile As Integer, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Integer, lpNumberOfBytesWritten As Integer,<MarshalAs(UnmanagedType.Struct)> ByRef   lpOverlapped As OVERLAPPED) As Integer

But I've no idea how to write error code free and implement it. Can you help me to solve this issue.

Thanks a lot.
LVL 12

Expert Comment

ID: 10885438
You do not need to go to the WinAPI to create a file in .NET.  There are already classes in the .NET framework (System.IO namespace) to do this. See the link above.

All you need to do is get the byte respresentation of the TIFF file and write it out.  Something like this.

Public Sub SaveFile(sFilePath as String, bt as Byte())

        ' Create the new, empty data file.
        If File.Exists(sFilePath) Then
        End If
        Dim fs As New FileStream(sFilePath, FileMode.CreateNew)
        ' Create the writer for data.
        Dim w As New BinaryWriter(fs)
        ' Write data to the file
End Sub
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.


Author Comment

ID: 10885526
Thanks a lot. Yes I'm beginning to understand from you. And extremely sorry for asking silly question. Once i scan the image is stored in the memory and i need to retrieve from the memory and save it in the hard disk. How do i retrieve from the memory. Any reference/example ?

Author Comment

ID: 10885557
This is a API function documentation prepared by vendor for your better understand what i'm talking about. I'm unable to understand, coz he is talking in low level language. I'm a beginner. :(

he is talking about scanning image and capturing front and rear image.


function name: fsmSortGetFrontMemory, fsmSortGetBackMemory

NOTE:  fsmSortGetFrontMemory should only be called by the above mentioned call back functions.
NOTE:  fsmSortGetBackMemory should only be called by the above mentioned call back functions.

Get the memory locations for the front from struct SortCallBack pointed to by lParam.  fsnSortGetBackMemory gets the memory location for the back image.
NOTE:  It is the user’s responsibility to allocate enough memory for the images.  We suggest 128,000 for TIFF (bitonal, black/white images) and 8 * 128,000 for gray scale (JPEG, 25% quality).  Obviously, these are extremely generous sizes for the files.  Smaller will work but we do not guarantee the results.  

NOTE:  On the 5180 when fsmScanImageFirst is called, the image call back function will return the image in memory.

#include <fsmfuji.h>

char * PASCAL fsmSortGetFrontMemory(long lParam, long *plFrontSize)
char * PASCAL fsmSortGetBackMemory(long lParam, long *plBackSize)


Gets the memory pointers for the document from struct SortCallBack pointed to by lParam.


lParam            lParam passed to the call back function.  Pass lParam in the call back function directly to this function without modification.

plFrontFileSize             Size in bytes of front image in memory.
plBackFileSize             Size in bytes of back image in memory.


Return functions points to pcFront or memory location for the front image or pcBack or memory location for the back image.  If return is NULL, then no image is available in memory or if  *plFrontSize or *plBackSize = 0, then an image is not available.

NULL             Image memory not found or not valid.

Functions Called


I'm implementing like this :

Dim lngMemFront, lngMemBack As Int32
lngMemBack = fsmSortGetBackMemory(LParam, lngSizeBack)

plz help..
LVL 12

Expert Comment

ID: 10885561
That's a good question.  How do you access it in classic VB? Do you have a handle or a pointer to the image?  I'm not sure what you are using to do the scanning or the API to the scanning program.  That's where you fill find the answer.

You can use the System.Drawing.Image class


to work with the image once you know how to get a hold of its memory representation
LVL 12

Expert Comment

ID: 10885576
Who makes the scanner?  

Author Comment

ID: 10886250
This scanner was developed by Fuji Machine Systems and DLL written by different vendor. I'm getting to understand now.

Can you give an example of System.Drawing.Image which reads image from the memory and write to a hard disk in TIFF Format ?
LVL 12

Expert Comment

ID: 10888579
Reading from memory requires accessing the vendor's dll, which looks like to returns a pointer to two parts of the image (front and back).  The function also returns the size of the image.

How are you calling the methods to the dll in VB6?
LVL 12

Accepted Solution

dfiala13 earned 2000 total points
ID: 10888879
I think this is about how you would do it.  Since I don't have the scanner or API I can't test it, but something like this should work to get the front or back image.  I have no idea how you combine them, but this is how you would get the data out of memory and into a Byte array

Dim bufPtr as IntPtr
Dim lParam as Int32
Dim lFrontSize as Int32

bufPtr = fsmSortGetFrontMemory(lParam, lFrontSize)
Dim bt(lFrontSize) as Byte

'this will copy the memory into the bt Byte array
Marshal.Copy(bufPtr, bt, 0, lFrontSize)

Here's the doc for the Marshal.Copy function...

You'll need to import the System.Runtime.InteropServices namespace into your class to use it.


Author Comment

ID: 10895443
thanks a lot for your help...

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

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

If you're writing a .NET application to connect to an Access .mdb database and use pre-existing queries that require parameters, you've come to the right place! Let's say the pre-existing query(qryCust) in Access takes a Date as a parameter and l…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
In this brief tutorial Pawel from AdRem Software explains how you can quickly find out which services are running on your network, or what are the IP addresses of servers responsible for each service. Software used is freeware NetCrunch Tools (https…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses

719 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