`FindFirstFileExFromApp` generate `void*` at `lpFindFileData`
gumbarros opened this issue · comments
Actual behavior
FindFirstFileExFromApp
generate void*
at lpFindFileData
Expected behavior
FindFirstFileExFromApp
should generate out WIN32_FIND_DATAW
at lpFindFileData
Repro steps
NativeMethods.txt
content:
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.
FindFirstFileExFromApp
FindNextFile
FindClose
FileTimeToSystemTime
WIN32_FIND_DATAW
NativeMethods.json
content (if present):
// Copyright (c) 2024 Files Community
// Licensed under the MIT License. See the LICENSE.
{
"$schema": "https://aka.ms/CsWin32.schema.json",
// Emit COM interfaces instead of structs, and allow generation of non-blittable structs for the sake of an easier to use API.
"allowMarshaling": true,
// A value indicating whether to generate APIs judged to be unnecessary or redundant given the target framework.
// This is useful for multi-targeting projects that need a consistent set of APIs across target frameworks
// to avoid too many conditional compilation regions.
"multiTargetingFriendlyAPIs": false,
// A value indicating whether friendly overloads should use safe handles.
"useSafeHandles": true,
// Omit ANSI functions and remove `W` suffix from UTF-16 functions.
"wideCharOnly": true,
// A value indicating whether to emit a single source file as opposed to types spread across many files.
"emitSingleFile": false,
// The name of a single class under which all p/invoke methods and constants are generated, regardless of imported module.
"className": "PInvoke",
// A value indicating whether to expose the generated APIs publicly (as opposed to internally).
"public": true
}
- Any of your own code that should be shared?
We migrated from:
[DllImport("api-ms-win-core-file-fromapp-l1-1-0.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr FindFirstFileExFromApp(
string lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
out WIN32_FIND_DATA lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
IntPtr lpSearchFilter,
int dwAdditionalFlags);
To:
public static SafeFileHandle FindFirstFileExFromApp(
string lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
out WIN32_FIND_DATAW lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
IntPtr lpSearchFilter,
int dwAdditionalFlags)
{
return PInvoke.FindFirstFileExFromApp(lpFileName, fInfoLevelId, out lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
}
The new code don't compile because lpFindFileData is void*
Context
- CsWin32 version: latest
- Target Framework:
net8.0
The actual behavior is by design. If you take a look at the header file or the docs, you'll see that the parameter is defined as LPVOID lpFindFileData
, which in C# translates to void*
.
In fact the docs suggest that the type of data that is initialized here depends on other arguments, so assuming it is WIN32_FIND_DATAW
sounds like it would lead to malfunctions in at least some cases.
But this shouldn't block you. If you expect a WIN32_FIND_DATAW
struct to be initialized based on your other arguments, go ahead and create such a struct and then pass a pointer to it as the argument.