Search
Module:
Directory

   Desktop Functions:

   Smart Device Functions:


Show Recent Changes
Subscribe (RSS)
Misc. Pages
Comments
FAQ
Helpful Tools
Playground
Suggested Reading
Website TODO List
Download Visual Studio Add-In

CreateFile (kernel32)
 
.
Summary

C# Signature:

  /// <summary>
  /// The CreateFile function creates or opens a file, file stream, directory, physical disk, volume, console buffer, tape drive,
  /// communications resource, mailslot, or named pipe. The function returns a handle that can be used to access an object.
  /// </summary>
  /// <param name="lpFileName"></param>
  /// <param name="dwDesiredAccess"> access to the object, which can be read, write, or both</param>
  /// <param name="dwShareMode">The sharing mode of an object, which can be read, write, both, or none</param>
  /// <param name="SecurityAttributes">A pointer to a SECURITY_ATTRIBUTES structure that determines whether or not the returned handle can
  /// be inherited by child processes. Can be null</param>
  /// <param name="dwCreationDisposition">An action to take on files that exist and do not exist</param>
  /// <param name="dwFlagsAndAttributes">The file attributes and flags. </param>
  /// <param name="hTemplateFile">A handle to a template file with the GENERIC_READ access right. The template file supplies file attributes
  /// and extended attributes for the file that is being created. This parameter can be null</param>
  /// <returns>If the function succeeds, the return value is an open handle to a specified file. If a specified file exists before the function
  /// all and dwCreationDisposition is CREATE_ALWAYS or OPEN_ALWAYS, a call to GetLastError returns ERROR_ALREADY_EXISTS, even when the function
  /// succeeds. If a file does not exist before the call, GetLastError returns 0 (zero).
  /// If the function fails, the return value is INVALID_HANDLE_VALUE. To get extended error information, call GetLastError.
  /// </returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall, SetLastError = true)]
  public static extern SafeFileHandle CreateFile(
        string lpFileName,
        uint dwDesiredAccess,
        uint dwShareMode,
        IntPtr SecurityAttributes,
        uint dwCreationDisposition,
        uint dwFlagsAndAttributes,
        IntPtr hTemplateFile
        );

C# Signature:

[DllImport("kernel32.dll", SetLastError=true, CharSet=CharSet.Auto)]
public static extern IntPtr CreateFile(
   string lpFileName,
   EFileAccess dwDesiredAccess,
   EFileShare dwShareMode,
   IntPtr lpSecurityAttributes,
   ECreationDisposition dwCreationDisposition,
   EFileAttributes dwFlagsAndAttributes,
   IntPtr hTemplateFile);

C# Signature:

[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr CreateFile(
   string fileName,
   [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,
   [MarshalAs(UnmanagedType.U4)] FileShare fileShare,
   IntPtr securityAttributes,
   [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
   int flags,
   IntPtr template);

VB.Net Signature:

<DllImport("kernel32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function CreateFile(ByVal lpFileName As String, ByVal dwDesiredAccess As EFileAccess, ByVal dwShareMode As EFileShare, ByVal lpSecurityAttributes As IntPtr, ByVal dwCreationDisposition As ECreationDisposition, ByVal dwFlagsAndAttributes As EFileAttributes, ByVal hTemplateFile As IntPtr) As IntPtr
End Function

User-Defined Types:

[Flags]
public enum EFileAccess : uint
{
   /// <summary>
   ///
   /// </summary>
   GenericRead = 0x80000000,
   /// <summary>
   ///
   /// </summary>
   GenericWrite = 0x40000000,
   /// <summary>
   ///
   /// </summary>
   GenericExecute = 0x20000000,
   /// <summary>
   ///
   /// </summary>
   GenericAll = 0x10000000
}

[Flags]
public enum EFileShare : uint
{
   /// <summary>
   ///
   /// </summary>
   None = 0x00000000,
   /// <summary>
   /// Enables subsequent open operations on an object to request read access.
   /// Otherwise, other processes cannot open the object if they request read access.
   /// If this flag is not specified, but the object has been opened for read access, the function fails.
   /// </summary>
   Read = 0x00000001,
   /// <summary>
   /// Enables subsequent open operations on an object to request write access.
   /// Otherwise, other processes cannot open the object if they request write access.
   /// If this flag is not specified, but the object has been opened for write access, the function fails.
   /// </summary>
   Write = 0x00000002,
   /// <summary>
   /// Enables subsequent open operations on an object to request delete access.
   /// Otherwise, other processes cannot open the object if they request delete access.
   /// If this flag is not specified, but the object has been opened for delete access, the function fails.
   /// </summary>
   Delete = 0x00000004
}

public enum ECreationDisposition : uint
{
   /// <summary>
   /// Creates a new file. The function fails if a specified file exists.
   /// </summary>
   New = 1,
   /// <summary>
   /// Creates a new file, always.
   /// If a file exists, the function overwrites the file, clears the existing attributes, combines the specified file attributes,
   /// and flags with FILE_ATTRIBUTE_ARCHIVE, but does not set the security descriptor that the SECURITY_ATTRIBUTES structure specifies.
   /// </summary>
   CreateAlways = 2,
   /// <summary>
   /// Opens a file. The function fails if the file does not exist.
   /// </summary>
   OpenExisting = 3,
   /// <summary>
   /// Opens a file, always.
   /// If a file does not exist, the function creates a file as if dwCreationDisposition is CREATE_NEW.
   /// </summary>
   OpenAlways = 4,
   /// <summary>
   /// Opens a file and truncates it so that its size is 0 (zero) bytes. The function fails if the file does not exist.
   /// The calling process must open the file with the GENERIC_WRITE access right.
   /// </summary>
   TruncateExisting = 5
}

[Flags]
public enum EFileAttributes : uint
{
   Readonly         = 0x00000001,
   Hidden           = 0x00000002,
   System           = 0x00000004,
   Directory        = 0x00000010,
   Archive          = 0x00000020,
   Device           = 0x00000040,
   Normal           = 0x00000080,
   Temporary        = 0x00000100,
   SparseFile       = 0x00000200,
   ReparsePoint     = 0x00000400,
   Compressed       = 0x00000800,
   Offline          = 0x00001000,
   NotContentIndexed= 0x00002000,
   Encrypted        = 0x00004000,
   Write_Through    = 0x80000000,
   Overlapped       = 0x40000000,
   NoBuffering      = 0x20000000,
   RandomAccess     = 0x10000000,
   SequentialScan   = 0x08000000,
   DeleteOnClose    = 0x04000000,
   BackupSemantics  = 0x02000000,
   PosixSemantics   = 0x01000000,
   OpenReparsePoint = 0x00200000,
   OpenNoRecall     = 0x00100000,
   FirstPipeInstance= 0x00080000
}

Instead of the enum "EFileAttributes" supplied on this page, you can also use "System.IO.FileAttributes". The enum values are identical up to "Encrypted".

This is NOT true for "EFileAccess" and "System.IO.FileAccess"!

Notes:

None.

Tips & Tricks:

You can use the IntPtr from Createfile with FileStream. This is usefull for opening devices such as Com1:, Lpt1: and Prn.

Unlike the FileStream ctor, CreateFile also allows you to open or create Windows 2000 sub-streams (e.g. "C:\Temp.dat:SubStream1").

For example:

IntPtr ptr = CreateFile(filename,access, share,0, mode,0, IntPtr.Zero);
/* Is bad handle? INVALID_HANDLE_VALUE */
if (ptr.ToInt32() == -1)
{
    /* ask the framework to marshall the win32 error code to an exception */
    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
}
else
{
    return new FileStream(ptr,access);
}

Microsoft .NET Framework 2.0 Changes

If you are using version 2.0 of the .NET framework, you will need to make a few changes because of obsolete methods in the release for OpenFile. You can no longer try the good old

    return new FileStream(hDrv, FileAccess.Read);

unless the hDrv is of the new SafeFileHandle type.

Simply replace the IntPtr's with SafeFileHandle - the updated signature is:

    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern SafeFileHandle CreateFile(
        string fileName,
        [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,
        [MarshalAs(UnmanagedType.U4)] FileShare fileShare,
        IntPtr securityAttributes,
        [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
        [MarshalAs(UnmanagedType.U4)] FileAttributes flags,
        IntPtr template);

And call it like:

    SafeFileHandle handle = CreateFile(Path,GENERIC_WRITE,0,
        IntPtr.Zero,OPEN_EXISTING,0,IntPtr.Zero);
    if (handle.IsInvalid)
        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());

And also make sure that you import Microsoft.Win32.SafeHandles. The other code as below in the Alternative Managed API will work the same.

Alternative Managed API:

Do you know one? Please contribute it!

Documentation
CreateFile on MSDN
Documentation
FileStream on MSDN
Documentation
Marshal on MSDN

You're doing this the hard way. Just define it like this:

    [DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern IntPtr CreateFile(
        string fileName,
        [MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,
        [MarshalAs(UnmanagedType.U4)] FileShare fileShare,
        int securityAttributes,
        [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
        int flags,
        IntPtr template);

Now you can use the normal .NET enums that people are familiar with

Thought I post a sample code to help out anyone else who may need help : )

/// Sample code provided as is.
/// Sample Composed by Wijaya "Wi" T
/// References:
/// http://www.dotnettalk.net/Needed_help_on_printing_from_C_and_printer-6941579-1297-a.html
/// http://www.dotnet247.com/247reference/msgs/16/84730.aspx
/// http://www.groupsrv.com/dotnet/viewtopic.php?t=72572
/// http://www.pinvoke.net/default.aspx/kernel32.CreateFile
///    Usage:  
///        Initialize this class in your main code (see below),
///        and walla you are now printing!
///        
///        e.g.:
///        PrintFactory objPrintFactory = new PrintFactory();
///    Thank you:
///        Thank you all who have been contributing to printing to LPT port.
///        God Bless you! : )
///    Addt'l info:
///        Don't forget to reference:
///            using System.Runtime.InteropServices;
///            using System.IO;
///            
public class PrintFactory
{
   public const short FILE_ATTRIBUTE_NORMAL = 0x80;
   public const short INVALID_HANDLE_VALUE = -1;
   public const uint GENERIC_READ = 0x80000000;
   public const uint GENERIC_WRITE = 0x40000000;
   public const uint CREATE_NEW = 1;
   public const uint CREATE_ALWAYS = 2;
   public const uint OPEN_EXISTING = 3;        

   [DllImport("kernel32.dll", SetLastError=true)]
   static extern IntPtr CreateFile(string lpFileName, uint dwDesiredAccess,
       uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
       uint dwFlagsAndAttributes, IntPtr hTemplateFile);

   public PrintFactory()
   {
      IntPtr ptr = CreateFile("LPT1", GENERIC_WRITE, 0,
               IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);

      /* Is bad handle? INVALID_HANDLE_VALUE */
      if (ptr.ToInt32() == -1)
      {
     /* ask the framework to marshall the win32 error code to an exception */
     Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
      }
      else
      {                                    
     String Temp = "This is a test print";
     //This is the cut command on Star TSP 600 Printer
     char[] prnCmdCut = {(char)27, (char)100, (char)51};                
     FileStream lpt = new FileStream(ptr,FileAccess.ReadWrite);
     Byte[] Buff = new Byte[1024];
     //Check to see if your printer support ASCII encoding or Unicode.
     //If unicode is supported, use the following:
     //Buff = System.Text.Encoding.Unicode.GetBytes(Temp);
     Buff = System.Text.Encoding.ASCII.GetBytes(Temp);
     lpt.Write(Buff,0,Buff.Length);                     
     Buff = System.Text.Encoding.ASCII.GetBytes(prnCmdCut);
     lpt.Write(Buff,0,Buff.Length);
     lpt.Close();
       }
    }
}

***********

Where is the secutityAttributes?! It's not to uncommon to want a file handle to be inheritable (e.g. you want to pass a handle to a server component like something running as a "servicedComponent" or a service...) and by using the securityAttributes this can be done...

***********

Note that on win98, mapping the parameters to FileAccess and FileShare will cause CreateFileA to fail. I found this out the hard way, banging my head against a very slow win98 machine across an even slow connection. Instead use the EFileAccess, and EFileShare enumeration constants that match the windows constants ( as mentioned earlier in the article ).

***********

Please edit this page!

Do you have...

  • helpful tips or sample code to share for using this API in managed code?
  • corrections to the existing content?
  • variations of the signature you want to share?
  • additional languages you want to include?

Select "Edit This Page" on the right hand toolbar and edit it! Or add new pages containing supporting types needed for this API (structures, delegates, and more).

 
Access PInvoke.net directly from VS:
Terms of Use
Find References
Show Printable Version
Revisions