dotnet / pinvoke

A library containing all P/Invoke code so you don't have to import it every time. Maintained and updated to support the latest Windows OS.
MIT License
2.11k stars 220 forks source link

Request: Better exception handling or documentation for CreateFile #598

Closed BinToss closed 2 years ago

BinToss commented 2 years ago

The following code block results in an exception thrown by mscorlib (.NET Framework 4.6.2) with little explanation of its cause.

var directoryInfo = new DirectoryInfo("D:/SymbolCache");
Kernel32.SECURITY_ATTRIBUTES? sa = null;
Kernel32.SafeObjectHandle hDirectory = Kernel32.CreateFile(
    filename: directoryInfo.FullName,
    access: Kernel32.ACCESS_MASK.GenericRight.GENERIC_READ | Kernel32.ACCESS_MASK.GenericRight.GENERIC_WRITE,
    share: Kernel32.FileShare.None,
    securityAttributes: sa,
    creationDisposition: Kernel32.CreationDisposition.OPEN_EXISTING,
    flagsAndAttributes: Kernel32.CreateFileFlags.FILE_FLAG_BACKUP_SEMANTICS,
    templateFile: null
);
Parameter name: SafeHandle cannot be null.
   at System.StubHelpers.StubHelpers.SafeHandleAddRef(SafeHandle pHandle, Boolean& success)
   at PInvoke.Kernel32.CreateFile(Char* filename, ACCESS_MASK access, FileShare share, SECURITY_ATTRIBUTES* securityAttributes, CreationDisposition creationDisposition, CreateFileFlags flagsAndAttributes, SafeObjectHandle templateFile)
   at PInvoke.Kernel32.CreateFile(String filename, ACCESS_MASK access, FileShare share, Nullable`1 securityAttributes, CreationDisposition creationDisposition, CreateFileFlags flagsAndAttributes, SafeObjectHandle templateFile)

Which parameter caused the NullArgumentException? templateFile? filename? securityAttributes? Is it an issue that did not originate from my code or even PInvoke.Kernel32 for that matter?

BinToss commented 2 years ago

In hindsight, this may be a request for the Windows API itself, rather than a wrapper. Still, If anyone knows how this SafeHandle became null, I'd appreciate an explanation and some suggestions.

Edit: I may need to double-check if SeBackupPrivilege was set properly.

AArnott commented 2 years ago

You passed in a null SafeHandle yourself: templateFile: null.

.NET interop cannot handle a null SafeHandle. You must create a SafeHandle with an invalid/null native handle and pass that in explicitly.

BinToss commented 2 years ago

Ah, thank you! The documentation said the parameter could be null, but I suppose that isn't the case.