From f6b8bc4355d220b4773a0b864b036633eb7bfa6f Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 29 Dec 2015 09:47:35 -0800 Subject: [PATCH 1/2] Kernel32 uses native pointers, with IntPtr overloads generated during the build Work toward #76 --- .../Kernel32+PROC_THREAD_ATTRIBUTE_LIST.cs | 19 +++++++++++++ src/Kernel32.Desktop/Kernel32+PipeMode.cs | 2 +- .../Kernel32+STARTUPINFOEX.cs | 4 +-- src/Kernel32.Desktop/Kernel32.Desktop.csproj | 14 +++++++++- src/Kernel32.Desktop/Kernel32.cs | 28 +++++++++---------- .../Kernel32+FindFirstFileExFlags.cs | 2 +- .../Kernel32+FormatMessageFlags.cs | 2 +- src/Kernel32.Shared/Kernel32.Shared.projitems | 4 ++- src/Kernel32.Shared/Kernel32.cs | 5 ++-- src/Kernel32/Kernel32.csproj | 9 ++++++ 10 files changed, 66 insertions(+), 23 deletions(-) create mode 100644 src/Kernel32.Desktop/Kernel32+PROC_THREAD_ATTRIBUTE_LIST.cs diff --git a/src/Kernel32.Desktop/Kernel32+PROC_THREAD_ATTRIBUTE_LIST.cs b/src/Kernel32.Desktop/Kernel32+PROC_THREAD_ATTRIBUTE_LIST.cs new file mode 100644 index 00000000..2f901109 --- /dev/null +++ b/src/Kernel32.Desktop/Kernel32+PROC_THREAD_ATTRIBUTE_LIST.cs @@ -0,0 +1,19 @@ +// Copyright (c) to owners found in https://github.com/AArnott/pinvoke/blob/master/COPYRIGHT.md. All rights reserved. +// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. + +namespace PInvoke +{ + /// + /// Contains the nested type. + /// + public partial class Kernel32 + { + /// + /// An empty struct. + /// + public struct PROC_THREAD_ATTRIBUTE_LIST + { + // This struct intentionally left blank. It has no fields, per the processthreadsapi.h file. + } + } +} diff --git a/src/Kernel32.Desktop/Kernel32+PipeMode.cs b/src/Kernel32.Desktop/Kernel32+PipeMode.cs index 7f58f039..c876b297 100644 --- a/src/Kernel32.Desktop/Kernel32+PipeMode.cs +++ b/src/Kernel32.Desktop/Kernel32+PipeMode.cs @@ -45,7 +45,7 @@ public enum PipeMode : uint /// /// Blocking mode is enabled. When the pipe handle is specified in the /// , - /// , or function, the + /// , or function, the /// operations are not completed until there is data to read, all data is written, or a client is connected. Use of /// this mode can mean waiting indefinitely in some situations for a client process to perform an action. /// diff --git a/src/Kernel32.Desktop/Kernel32+STARTUPINFOEX.cs b/src/Kernel32.Desktop/Kernel32+STARTUPINFOEX.cs index f9f2db83..ae095eb9 100644 --- a/src/Kernel32.Desktop/Kernel32+STARTUPINFOEX.cs +++ b/src/Kernel32.Desktop/Kernel32+STARTUPINFOEX.cs @@ -12,7 +12,7 @@ namespace PInvoke public partial class Kernel32 { /// - /// Specifies the window station, desktop, standard handles, and attributes for a new process. It is used with the and functions. + /// Specifies the window station, desktop, standard handles, and attributes for a new process. It is used with the and functions. /// [StructLayout(LayoutKind.Sequential)] public struct STARTUPINFOEX @@ -23,7 +23,7 @@ public struct STARTUPINFOEX public STARTUPINFO StartupInfo; /// - /// An attribute list. This list is created by the function. + /// An attribute list. This list is created by the function. /// public IntPtr lpAttributeList; diff --git a/src/Kernel32.Desktop/Kernel32.Desktop.csproj b/src/Kernel32.Desktop/Kernel32.Desktop.csproj index 7a3b2670..e0ccdd2b 100644 --- a/src/Kernel32.Desktop/Kernel32.Desktop.csproj +++ b/src/Kernel32.Desktop/Kernel32.Desktop.csproj @@ -41,6 +41,7 @@ + @@ -49,12 +50,23 @@ - + + MSBuild:GenerateCodeFromAttributes + + + {6a77281b-c503-44ea-90c1-0e9868d06cd0} + CodeGenerationAttributes.Net40 + + + {C1815471-02AF-4BB9-8D83-652ADBAFF5B6} + CodeGeneration + false + {b08c3c79-4cdd-4d37-933c-07d3452fd5f1} Windows.Core diff --git a/src/Kernel32.Desktop/Kernel32.cs b/src/Kernel32.Desktop/Kernel32.cs index 93483811..86c53ea4 100644 --- a/src/Kernel32.Desktop/Kernel32.cs +++ b/src/Kernel32.Desktop/Kernel32.cs @@ -38,7 +38,7 @@ public static partial class Kernel32 /// /// Creates a new process and its primary thread. The new process runs in the security context of the calling process. - /// If the calling process is impersonating another user, the new process uses the token for the calling process, not the impersonation token. To run the new process in the security context of the user represented by the impersonation token, use the or CreateProcessWithLogonW function. + /// If the calling process is impersonating another user, the new process uses the token for the calling process, not the impersonation token. To run the new process in the security context of the user represented by the impersonation token, use the or CreateProcessWithLogonW function. /// /// /// The name of the module to be executed. This module can be a Windows-based application. It can be some other type of module (for example, MS-DOS or OS/2) if the appropriate subsystem is available on the local computer. @@ -99,14 +99,14 @@ public static partial class Kernel32 /// [DllImport(api_ms_win_core_processthreads_l1_1_1, SetLastError = true, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool CreateProcess( + public static unsafe extern bool CreateProcess( string lpApplicationName, string lpCommandLine, SECURITY_ATTRIBUTES lpProcessAttributes, SECURITY_ATTRIBUTES lpThreadAttributes, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandles, CreateProcessFlags dwCreationFlags, - IntPtr lpEnvironment, // IntPtr because it may point to unicode or ANSI characters, based on a flag. + void* lpEnvironment, // pointer because it may point to unicode or ANSI characters, based on a flag. string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); @@ -180,7 +180,7 @@ public static extern bool CreateProcess( /// [DllImport(api_ms_win_core_processthreads_l1_1_1, SetLastError = true, CharSet = CharSet.Unicode)] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool CreateProcessAsUser( + public static unsafe extern bool CreateProcessAsUser( IntPtr hToken, string lpApplicationName, string lpCommandLine, @@ -188,7 +188,7 @@ public static extern bool CreateProcessAsUser( SECURITY_ATTRIBUTES lpThreadAttributes, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandles, CreateProcessFlags dwCreationFlags, - IntPtr lpEnvironment, // IntPtr because it may point to unicode or ANSI characters, based on a flag. + void* lpEnvironment, // pointer because it may point to unicode or ANSI characters, based on a flag. string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, out PROCESS_INFORMATION lpProcessInformation); @@ -227,13 +227,13 @@ public static extern void GetStartupInfo( /// /// /// First, call this function with the parameter set to the maximum number of attributes you will be using and the lpAttributeList to NULL. The function returns the required buffer size in bytes in the lpSize parameter. Allocate enough space for the data in the lpAttributeList buffer and call the function again to initialize the buffer. - /// To add attributes to the list, call the function. To specify these attributes when creating a process, specify in the dwCreationFlag parameter and a structure in the lpStartupInfo parameter. Note that you can specify the same structure to multiple child processes. + /// To add attributes to the list, call the function. To specify these attributes when creating a process, specify in the dwCreationFlag parameter and a structure in the lpStartupInfo parameter. Note that you can specify the same structure to multiple child processes. /// When you have finished using the list, call the function. /// [DllImport(api_ms_win_core_processthreads_l1_1_1, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool InitializeProcThreadAttributeList( - IntPtr lpAttributeList, + public static unsafe extern bool InitializeProcThreadAttributeList( + PROC_THREAD_ATTRIBUTE_LIST* lpAttributeList, int dwAttributeCount, uint dwFlags, ref IntPtr lpSize); // SIZE_T (the size varies with the bitness) @@ -242,7 +242,7 @@ public static extern bool InitializeProcThreadAttributeList( /// Updates the specified attribute in a list of attributes for process and thread creation. /// /// - /// A pointer to an attribute list created by the function. + /// A pointer to an attribute list created by the function. /// /// /// This parameter is reserved and must be zero. @@ -266,8 +266,8 @@ public static extern bool InitializeProcThreadAttributeList( /// [DllImport(api_ms_win_core_processthreads_l1_1_1, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] - public static extern bool UpdateProcThreadAttribute( - IntPtr lpAttributeList, + public static unsafe extern bool UpdateProcThreadAttribute( + PROC_THREAD_ATTRIBUTE_LIST* lpAttributeList, uint dwFlags, ref uint Attribute, IntPtr lpValue, @@ -279,7 +279,7 @@ public static extern bool UpdateProcThreadAttribute( /// Deletes the specified list of attributes for process and thread creation. /// /// - /// The attribute list. This list is created by the function. + /// The attribute list. This list is created by the function. /// [DllImport(api_ms_win_core_processthreads_l1_1_1)] public static extern void DeleteProcThreadAttributeList( @@ -657,7 +657,7 @@ public static extern unsafe bool GetOverlappedResult( /// /// If the function succeeds, the return value is nonzero. The cancel operation for all pending I/O operations issued by /// the calling thread for the specified file handle was successfully requested. The thread can use the - /// function to determine when the I/O operations themselves have been completed. + /// function to determine when the I/O operations themselves have been completed. /// /// If the function fails, the return value is zero (0). To get extended error information, call the /// function. @@ -872,7 +872,7 @@ public static extern SafeObjectHandle CreateNamedPipe( /// /// Waits until either a time-out interval elapses or an instance of the specified named pipe is available for - /// connection (that is, the pipe's server process has a pending operation on the + /// connection (that is, the pipe's server process has a pending operation on the /// pipe). /// /// diff --git a/src/Kernel32.Shared/Kernel32+FindFirstFileExFlags.cs b/src/Kernel32.Shared/Kernel32+FindFirstFileExFlags.cs index 55387aa2..babb4c4a 100644 --- a/src/Kernel32.Shared/Kernel32+FindFirstFileExFlags.cs +++ b/src/Kernel32.Shared/Kernel32+FindFirstFileExFlags.cs @@ -11,7 +11,7 @@ namespace PInvoke public partial class Kernel32 { /// - /// Optional flags to pass to the method. + /// Optional flags to pass to the method. /// [Flags] public enum FindFirstFileExFlags diff --git a/src/Kernel32.Shared/Kernel32+FormatMessageFlags.cs b/src/Kernel32.Shared/Kernel32+FormatMessageFlags.cs index 7107c836..ab672736 100644 --- a/src/Kernel32.Shared/Kernel32+FormatMessageFlags.cs +++ b/src/Kernel32.Shared/Kernel32+FormatMessageFlags.cs @@ -11,7 +11,7 @@ namespace PInvoke public partial class Kernel32 { /// - /// Flags passed to the method. + /// Flags passed to the method. /// [Flags] public enum FormatMessageFlags diff --git a/src/Kernel32.Shared/Kernel32.Shared.projitems b/src/Kernel32.Shared/Kernel32.Shared.projitems index 73566dbc..b24a3fa2 100644 --- a/src/Kernel32.Shared/Kernel32.Shared.projitems +++ b/src/Kernel32.Shared/Kernel32.Shared.projitems @@ -19,7 +19,9 @@ - + + MSBuild:GenerateCodeFromAttributes + diff --git a/src/Kernel32.Shared/Kernel32.cs b/src/Kernel32.Shared/Kernel32.cs index 00b51ebe..e852b077 100644 --- a/src/Kernel32.Shared/Kernel32.cs +++ b/src/Kernel32.Shared/Kernel32.cs @@ -11,6 +11,7 @@ namespace PInvoke /// /// Exported functions from the Kernel32.dll Windows library. /// + [OfferIntPtrOverloads] public static partial class Kernel32 { /// @@ -84,7 +85,7 @@ public static partial class Kernel32 /// If the function fails or fails to locate files from the search string in the lpFileName parameter, the return value is INVALID_HANDLE_VALUE and the contents of lpFindFileData are indeterminate.To get extended error information, call the function. /// [DllImport(api_ms_win_core_file_l1_2_0)] - public static extern SafeFindFilesHandle FindFirstFileEx(string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, out WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, IntPtr lpSearchFilter, FindFirstFileExFlags dwAdditionalFlags); + public static unsafe extern SafeFindFilesHandle FindFirstFileEx(string lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, out WIN32_FIND_DATA lpFindFileData, FINDEX_SEARCH_OPS fSearchOp, void* lpSearchFilter, FindFirstFileExFlags dwAdditionalFlags); /// /// Formats a message string. The function requires a message definition as input. The message definition can come from a buffer passed into the function. It can come from a message table resource in an already-loaded module. Or the caller can ask the function to search the system's message table resource(s) for the message definition. The function finds the message definition in a message table resource based on a message identifier and a language identifier. The function copies the formatted message text to an output buffer, processing any embedded insert sequences if requested. @@ -131,7 +132,7 @@ public static partial class Kernel32 /// If the function fails, the return value is zero.To get extended error information, call . /// [DllImport(api_ms_win_core_localization_l1_2_0, CharSet = CharSet.Unicode, SetLastError = true)] - public static extern int FormatMessage(FormatMessageFlags dwFlags, IntPtr lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, int nSize, IntPtr[] Arguments); + public static unsafe extern int FormatMessage(FormatMessageFlags dwFlags, void* lpSource, uint dwMessageId, uint dwLanguageId, StringBuilder lpBuffer, int nSize, IntPtr[] Arguments); /// /// Retrieves the thread identifier of the calling thread. diff --git a/src/Kernel32/Kernel32.csproj b/src/Kernel32/Kernel32.csproj index 9d0ffa06..04198757 100644 --- a/src/Kernel32/Kernel32.csproj +++ b/src/Kernel32/Kernel32.csproj @@ -29,6 +29,15 @@ + + {1387e009-7086-4572-ac8d-ce4242adec77} + CodeGenerationAttributes + + + {C1815471-02AF-4BB9-8D83-652ADBAFF5B6} + CodeGeneration + false + {b08c3c79-4cdd-4d37-933c-07d3452fd5f1} Windows.Core From 765c587245d3bc453ea7cc9ead4ed71f3395588b Mon Sep 17 00:00:00 2001 From: Andrew Arnott Date: Tue, 29 Dec 2015 10:37:26 -0800 Subject: [PATCH 2/2] Finish removal of IntPtr method overloads in Kernel32 --- src/Kernel32.Desktop/Kernel32.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Kernel32.Desktop/Kernel32.cs b/src/Kernel32.Desktop/Kernel32.cs index 86c53ea4..b76db0dd 100644 --- a/src/Kernel32.Desktop/Kernel32.cs +++ b/src/Kernel32.Desktop/Kernel32.cs @@ -227,8 +227,8 @@ public static extern void GetStartupInfo( /// /// /// First, call this function with the parameter set to the maximum number of attributes you will be using and the lpAttributeList to NULL. The function returns the required buffer size in bytes in the lpSize parameter. Allocate enough space for the data in the lpAttributeList buffer and call the function again to initialize the buffer. - /// To add attributes to the list, call the function. To specify these attributes when creating a process, specify in the dwCreationFlag parameter and a structure in the lpStartupInfo parameter. Note that you can specify the same structure to multiple child processes. - /// When you have finished using the list, call the function. + /// To add attributes to the list, call the function. To specify these attributes when creating a process, specify in the dwCreationFlag parameter and a structure in the lpStartupInfo parameter. Note that you can specify the same structure to multiple child processes. + /// When you have finished using the list, call the function. /// [DllImport(api_ms_win_core_processthreads_l1_1_1, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] @@ -251,7 +251,7 @@ public static unsafe extern bool InitializeProcThreadAttributeList( /// The attribute key to update in the attribute list. /// /// - /// A pointer to the attribute value. This value should persist until the attribute is destroyed using the function. + /// A pointer to the attribute value. This value should persist until the attribute is destroyed using the function. /// /// /// The size of the attribute value specified by the parameter. @@ -270,7 +270,7 @@ public static unsafe extern bool UpdateProcThreadAttribute( PROC_THREAD_ATTRIBUTE_LIST* lpAttributeList, uint dwFlags, ref uint Attribute, - IntPtr lpValue, + void* lpValue, IntPtr cbSize, // SIZE_T varies by bitness ref IntPtr lpPreviousValue, ref IntPtr lpReturnSize); @@ -282,8 +282,8 @@ public static unsafe extern bool UpdateProcThreadAttribute( /// The attribute list. This list is created by the function. /// [DllImport(api_ms_win_core_processthreads_l1_1_1)] - public static extern void DeleteProcThreadAttributeList( - IntPtr lpAttributeList); + public static unsafe extern void DeleteProcThreadAttributeList( + PROC_THREAD_ATTRIBUTE_LIST* lpAttributeList); /// /// Allocates a new console for the calling process.