I was trying to get Accent Color for use in my WPF app, and i found one class in GitHub that always is the same.
static class UxTheme
{
[DllImport("uxtheme.dll", EntryPoint = "#98", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]
public static extern uint GetImmersiveUserColorSetPreference(bool forceCheckRegistry, bool skipCheckOnFail);
[DllImport("uxtheme.dll", EntryPoint = "#94", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]
public static extern uint GetImmersiveColorSetCount();
[DllImport("uxtheme.dll", EntryPoint = "#95", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]
public static extern uint GetImmersiveColorFromColorSetEx(uint immersiveColorSet, uint immersiveColorType,
bool ignoreHighContrast, uint highContrastCacheMode);
[DllImport("uxtheme.dll", EntryPoint = "#96", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]
public static extern uint GetImmersiveColorTypeFromName(IntPtr name);
[DllImport("uxtheme.dll", EntryPoint = "#100", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Auto)]
public static extern IntPtr GetImmersiveColorNamedTypeByIndex(uint index);
}
I was finding uxtheme documentation in SDK and MSDN but this methods aren't.
I dumpbin uxtheme.dll and surprise! they are unnamed functions. (Except #95 & #98).
How can i get signatures of the uxtheme (or others) library? Then, i can try-error guessing the functions i need.
Related
I'm currently developing an app that have to move a file to another application folder. But the other application must have a specific permissions on files that are copied.
When I use the Win32 API to MoveFileFromApp (it's uwp app), it doesn't update the security attributes to inherit the folder.
here is the code of MoveFile (C#)
[DllImport("api-ms-win-core-file-fromapp-l1-1-0.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall, SetLastError = true)]
internal static extern bool MoveFileFromApp(
string lpExistingFileName, string lpNewFileName);
Does anyone know how to set these security permissions for the folder automatically during the moving process ?
Thank you very much !
I tried to use SetNamedSecurityInfo method by P/Invoke in UWP app with the following code. The error ERROR_ACCESS_DENIED(error code is 5) always exists in UWP app. But in Win32, the usage of SetNamedSecurityInfo method with the value UNPROTECTED_DACL_SECURITY_INFORMATION to inherit the security attributes is successful.
In UWP, there are some limitations on file system access permission. Though the SetNamedSecurityInfo method can be called successfully, it does not work as expected.
The code to use SetNamedSecurityInfo method in UWP:
public uint DACL_SECURITY_INFORMATION = 0x00000004;
public uint UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000;
public uint ACL_REVISION = 0x2;
[StructLayout(LayoutKind.Sequential)]
public struct ACL
{
public byte AclRevision;
public byte Sbz1;
public ushort AclSize;
public ushort AceCount;
public ushort Sbz2;
}
public enum SE_OBJECT_TYPE
{
SE_UNKNOWN_OBJECT_TYPE = 0,
SE_FILE_OBJECT,
SE_SERVICE,
SE_PRINTER,
SE_REGISTRY_KEY,
SE_LMSHARE,
SE_KERNEL_OBJECT,
SE_WINDOW_OBJECT,
SE_DS_OBJECT,
SE_DS_OBJECT_ALL,
SE_PROVIDER_DEFINED_OBJECT,
SE_WMIGUID_OBJECT,
SE_REGISTRY_WOW64_32KEY,
SE_REGISTRY_WOW64_64KEY,
}
[DllImport("api-ms-win-core-file-fromapp-l1-1-0.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool MoveFileFromAppW(
string lpExistingFileName,
string lpNewFileName);
[DllImport("advapi32.DLL", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern uint SetNamedSecurityInfo(
string lpFileName,
SE_OBJECT_TYPE ObjectType,
uint SecurityInfo,
IntPtr psidOwner,
IntPtr psidGroup,
ref ACL pDacl,
IntPtr pSacl);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool InitializeAcl(ref ACL pAcl, int nAclLength, uint dwAclRevision);
[DllImport("api-ms-win-core-file-fromapp-l1-1-0.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
internal static extern bool MoveFileFromApp(
string lpExistingFileName,
string lpNewFileName
);
public void SetFilePermission(string FileName)
{//Use the method to let the file inherit the security attributes from parent object
bool ret = false;
ACL pDacl = new ACL();
ret = InitializeAcl(ref pDacl, Marshal.SizeOf<ACL>(), ACL_REVISION);
uint SecurityInfo = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
uint err = SetNamedSecurityInfo(FileName, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfo, IntPtr.Zero, IntPtr.Zero, ref pDacl, IntPtr.Zero);
}
I am working with wtsapi32.dll. (Window Terminal Service api)
I am trying to get user info from method WTSQueryUserConfig.
[DllImport("wtsapi32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WTSQueryUserConfig(
[MarshalAs(UnmanagedType.LPStr)] string pServerName,
[MarshalAs(UnmanagedType.LPStr)] string pUserName,
WTS_CONFIG_CLASS wtsConfigClass,
out StringBuilder pBuffer,
out int dataLength);
I have problem with user with SAM-Account-Name in japanese (unicode).
I have modified my class with (unicode version):
[DllImport("wtsapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WTSQueryUserConfigW(
[MarshalAs(UnmanagedType.LPStr)] string pServerName,
[MarshalAs(UnmanagedType.LPStr)] string pUserName,
WTS_CONFIG_CLASS wtsConfigClass,
out StringBuilder pBuffer,
out int dataLength);
But I call this method with japanese SAM-Account-Name it does not work.
Users without unicode characters works fine with non-unicode version method.
Finally I only used the charset configuration for the input parameters
[DllImport("wtsapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WTSQueryUserConfigW(
string pServerName,
string pUserName,
WindowsTerminalServiceConfig wtsConfigClass,
out StringBuilder pBuffer,
out int dataLength);
I'm trying to open a raw printer connection and the StartDocPrinter call is failing. Win32Error is 122 (ERROR_INSUFFICIENT_BUFFER).
This executable works fine on the same computer when run as a normal user or as administrator, but fails when run as the "local system" user. (Though I've had it work on several other computers running as the "local system" user.) I really don't want to consider running it as a different user, since it's running through a service and would probably involve several other large changes to the system.
using System;
using System.Runtime.InteropServices;
namespace EPLTest
{
class Program
{
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public class DOCINFOA
{
[MarshalAs(UnmanagedType.LPStr)]
public string pDocName;
[MarshalAs(UnmanagedType.LPStr)]
public string pOutputFile;
[MarshalAs(UnmanagedType.LPStr)]
public string pDataType;
}
[DllImport("winspool.Drv", EntryPoint = "OpenPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool OpenPrinter([MarshalAs(UnmanagedType.LPStr)] string szPrinter, out IntPtr hPrinter, IntPtr pd);
[DllImport("winspool.Drv", EntryPoint = "ClosePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool ClosePrinter(IntPtr hPrinter);
[DllImport("winspool.Drv", EntryPoint = "StartDocPrinterA", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool StartDocPrinter(IntPtr hPrinter, Int32 level, [In, MarshalAs(UnmanagedType.LPStruct)] DOCINFOA di);
[DllImport("winspool.Drv", EntryPoint = "EndDocPrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool EndDocPrinter(IntPtr hPrinter);
static void Main(string[] args)
{
IntPtr hPrinter;
if (!OpenPrinter("ZDesigner LP2824 Raw".Normalize(), out hPrinter, IntPtr.Zero))
{
Console.WriteLine("OpenPrinter Error:" + Marshal.GetLastWin32Error());
return;
}
Console.WriteLine("hPrinter: " + hPrinter.ToString("x8"));
DOCINFOA di = new DOCINFOA { pDocName = "Barcode Test", pDataType = "RAW" };
if (StartDocPrinter(hPrinter, 1, di))
{
Console.WriteLine("StartDocPrinter Success");
// Printing code omitted for brevity
EndDocPrinter(hPrinter);
}
else
{
Console.WriteLine("StartDocPrinter Error:" + Marshal.GetLastWin32Error());
}
ClosePrinter(hPrinter);
}
}
}
Sample output:
hPrinter: 010b7e3c
StartDocPrinter Error:122
Any ideas?
I try use a dll created in c in c#, but I get the error "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
I see very topics here, but i'm not solve the problem. It's possible help me?
My C# code is:
[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr LoadLibrary(string dllToLoad);
[DllImport("kernel32", CharSet = CharSet.Ansi, ExactSpelling = true, SetLastError = true)]
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
[DllImport("kernel32")]
public static extern bool FreeLibrary(IntPtr hModule);
[DllImport("lib.dll", EntryPoint = "LoadRes", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern SRes LoadRes([MarshalAs(UnmanagedType.LPStr)]string str, bool type);
SRes sres = new SRes();
string path="C:\\123456.fil";
System.IntPtr load = LoadLibrary("lib.dll");
System.IntPtr adress = GetProcAddress(load, "LoadRes");
sres = LoadRes(path, true);
My code to export in c is
__declspec(dllexport) SRes LoadRes( const char *filename, bool header_only );
Thank's for help!!
I'm using the [DLLImport] attribute to access a bunch of C++ functions in my .NET code.
For now, I have all the functions in the following way:
const string DLL_Path = "path\\to\\my\\dll.dll";
[DllImport(DLL_Path,
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
public static extern int MyFunction1();
[DllImport(DLL_Path,
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
public static extern ErrorCode MyFunction2(int id);
[DllImport(DLL_Path,
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
public static extern ErrorCode MyFunction3(string server, byte timeout,
ref int connection_id, ref DeviceInfo pInfos);
[DllImport(DLL_Path,
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
public static extern ErrorCode MyFunction4([MarshalAs(UnmanagedType.LPArray)] byte[] pVersion,
ref int psize);
[DllImport(DLL_Path,
CallingConvention = CallingConvention.StdCall,
CharSet = CharSet.Ansi)]
public static extern ErrorCode MyFunction5(int errorcode,
[MarshalAs(UnmanagedType.LPTStr)] string pmsg, ref int psize);
Which is rather not pleasing to the eye: the repetition of attributes seems unefficient and destroys readability for the prototypes of the functions. Especially since I have something like 20 or 30 functions to import.
I wonder if I could have the [DllImport(DLL_Path, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] part only once somewhere and have the function definitions more clearly identified, like this pseudo code:
const string DLL_Path = "path\\to\\my\\dll.dll";
// some code defining a section which tells that the next functions are DLLImport
[DllImport(DLL_Path, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)]
{
public static extern int MyFunction1();
public static extern ErrorCode MyFunction2(int id);
public static extern ErrorCode MyFunction3(string server, byte timeout, ref int connection_id, ref DeviceInfo pInfos);
public static extern ErrorCode MyFunction4([MarshalAs(UnmanagedType.LPArray)] byte[] pVersion, ref int psize);
public static extern ErrorCode MyFunction5(int errorcode, [MarshalAs(UnmanagedType.LPTStr)] string pmsg, ref int psize);
}
Is this possible?
I found this question in SO: Shorten amount of DllImport in C#? but it suggests dynamically loading the functions through LoadLibrary and GetProcAddress, which I find less readable.
No, there's no way to reduce the Attributes to a single declaration. You'll need to apply the Attribute to all methods.
But you can at least shorten your Attribute declarations to [DllImport(DLL_Path)], because the values you are specifying for CallingConvention and CharSet are the same as the default values.