I would like to be able to access *.lnk files from any folder on my desktop.
I know that Windows.Storage cannot access *.lnk files but I can read and access them from from Win32 or System.IO in WPF apps.
Is there a way for me to incorporate FindFirstFileEx() into my app without getting access permission errors?
I have seen articles on FullTrustProcessLauncher Class and CustomCapabilities settings but no examples using Kernal32 methods, or advice on even if this would work.
but no examples using Kernal32 methods
For this scenario, you could use desktop-bridge desktop extension to approach, for detail steps please refer stfan's blog UWP with Desktop Extension.
For using Kernal32 methods, please refer pinvoke document.
public enum FINDEX_INFO_LEVELS
{
FindExInfoStandard = 0,
FindExInfoBasic = 1
}
public enum FINDEX_SEARCH_OPS
{
FindExSearchNameMatch = 0,
FindExSearchLimitToDirectories = 1,
FindExSearchLimitToDevices = 2
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct WIN32_FIND_DATA
{
public uint dwFileAttributes;
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
public uint nFileSizeHigh;
public uint nFileSizeLow;
public uint dwReserved0;
public uint dwReserved1;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string cFileName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string cAlternateFileName;
}
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern IntPtr FindFirstFileEx(
string lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
out WIN32_FIND_DATA lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
IntPtr lpSearchFilter,
int dwAdditionalFlags);
Related
I am trying to hook outgoing connections with c#. I found this question:
Windows Filtering Platform - How can I block incoming connections based on local port?
But at sample some error with code and some missing classes to use.
I am trying to generate structs with p/invoke signature toolkit, but I have some very big class-generated code, where 90% calling dependence.
So I think I must realise external prototypes and then call them.
Here is my code:
public static class WpfProvider
{
private static void Test()
{
var RemotePort = 8080; //port to block
// connect to engine
var session = new FWPM_SESSION0_();
session.flags = 0xFFF;
IntPtr engineHandle;
FwpmEngineOpen0(null, RPC.RPC_C_AUTHN_WINNT, IntPtr.Zero, session, ref engineHandle);
// create a subLayer to attach filters to
var subLayerGuid = Guid.NewGuid();
var subLayer = new FWPM_SUBLAYER0_();
subLayer.subLayerKey = subLayerGuid;
subLayer.displayData.name = DisplayName;
subLayer.displayData.description = DisplayName;
subLayer.flags = 0;
subLayer.weight = 0x100;
FwpmSubLayerAdd0(engineHandle, subLayer, IntPtr.Zero);
var condition = new FWPM_FILTER_CONDITION0
{
fieldKey = Fwpm.FWPM_CONDITION_IP_REMOTE_PORT,
matchType = Fwpm.FWP_MATCH_TYPE.FWP_MATCH_EQUAL,
conditionValue =
{
type = Fwpm.FWP_DATA_TYPE.FWP_UINT16,
uint16 = RemotePort
}
};
// create the filter itself
var fwpFilter = new FWPM_FILTER0();
fwpFilter.layerKey = FWPM_LAYER_ALE_AUTH_CONNECT_V4;
fwpFilter.action.type = FWP_ACTION_BLOCK;
fwpFilter.subLayerKey = subLayerGuid;
fwpFilter.weight.type = Fwpm.FWP_DATA_TYPE.FWP_EMPTY; // auto-weight.
fwpFilter.numFilterConditions = (uint)1;
var condsArray = new[] { condition };
var condsPtr = SafeNativeMethods.MarshalArray(condsArray); // helper to create a native array from a C# one
fwpFilter.filterCondition = condsPtr;
fwpFilter.displayData.name = DisplayName;
fwpFilter.displayData.description = DisplayName;
Microsoft.Win32.UnsaveNativeMethods
// add the filter
UInt64 filterId = 0L;
FwpmFilterAdd0(engineHandle, ref fwpFilter, IntPtr.Zero, out filterId));
}
/// Return Type: DWORD->unsigned int
///serverName: wchar_t*
///authnService: UINT32->unsigned int
///authIdentity: SEC_WINNT_AUTH_IDENTITY_W*
///session: FWPM_SESSION0*
///engineHandle: HANDLE*
[System.Runtime.InteropServices.DllImportAttribute("FWPUClnt.dll", EntryPoint = "FwpmEngineOpen0")]
public static extern uint FwpmEngineOpen0([System.Runtime.InteropServices.In()] [System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)] string serverName, uint authnService, [System.Runtime.InteropServices.In()] IntPtr authIdentity, [System.Runtime.InteropServices.In()] IntPtr session, ref IntPtr engineHandle);
/// Return Type: DWORD->unsigned int
///engineHandle: HANDLE->void*
///subLayer: FWPM_SUBLAYER0*
///sd: PSECURITY_DESCRIPTOR->PVOID->void*
[System.Runtime.InteropServices.DllImportAttribute("FWPUClnt.dll", EntryPoint = "FwpmSubLayerAdd0")]
public static extern uint FwpmSubLayerAdd0([System.Runtime.InteropServices.In()] IntPtr engineHandle, [System.Runtime.InteropServices.In()] ref FWPM_SUBLAYER0 subLayer, [System.Runtime.InteropServices.In()] IntPtr sd);
/// Return Type: DWORD->unsigned int
///engineHandle: HANDLE->void*
///filter: FWPM_FILTER0*
///sd: PSECURITY_DESCRIPTOR->PVOID->void*
///id: UINT64*->UInt64
[System.Runtime.InteropServices.DllImportAttribute("FWPUClnt.dll", EntryPoint = "FwpmFilterAdd0")]
public static extern uint FwpmFilterAdd0([System.Runtime.InteropServices.In()] IntPtr engineHandle, [System.Runtime.InteropServices.In()] ref FWPM_FILTER0 filter, [System.Runtime.InteropServices.In()] IntPtr sd, UInt64 id);
}
static class RPC
{
public static uint RPC_C_AUTHN_NONE = 0;//No authentication.
public static uint RPC_C_AUTHN_DCE_PRIVATE = 1;//DCE private key authentication.
public static uint RPC_C_AUTHN_DCE_PUBLIC = 2;//DCE public key authentication.
public static uint RPC_C_AUTHN_DEC_PUBLIC = 4;//DEC public key authentication.Reserved for future use.
public static uint RPC_C_AUTHN_GSS_NEGOTIATE = 9;//Snego security support provider.
public static uint RPC_C_AUTHN_WINNT = 10;//NTLMSSP
public static uint RPC_C_AUTHN_GSS_SCHANNEL = 14;//Schannel security support provider. This authentication service supports SSL 2.0, SSL 3.0, TLS, and PCT.
public static uint RPC_C_AUTHN_GSS_KERBEROS = 16;//Kerberos security support provider.
public static uint RPC_C_AUTHN_DPA = 17;//DPA security support provider.
public static uint RPC_C_AUTHN_MSN = 18;//MSN security support provider.
public static uint RPC_C_AUTHN_KERNEL = 20;//Kernel security support provider.
public static uint RPC_C_AUTHN_DIGEST = 21;//Digest security support provider.
public static uint RPC_C_AUTHN_NEGO_EXTENDER = 30;//NEGO extender security support provider.
public static uint RPC_C_AUTHN_PKU2U = 31;//PKU2U security support provider.
public static uint RPC_C_AUTHN_MQ = 100;//MQ security support provider.
public static uint RPC_C_AUTHN_DEFAULT = 0xFFFFFFFF; //The system default authentication service. When this value is specified, COM uses its normal security blanket negotiation algorithm to pick an authentication service.For more information, see Security Blanket Negotiation.
}
#region WPF imports
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential, CharSet = System.Runtime.InteropServices.CharSet.Ansi)]
public struct GUID
{
public uint Data1;/// unsigned int
public ushort Data2;/// unsigned short
public ushort Data3;/// unsigned short
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValTStr, SizeConst = 8)]
public string Data4;// unsigned char[8]
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct SID_IDENTIFIER_AUTHORITY
{
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I1)]
public byte[] Value;// BYTE[6]
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct SID
{
public byte Revision;/// BYTE->unsigned char
public byte SubAuthorityCount;/// BYTE->unsigned char
public SID_IDENTIFIER_AUTHORITY IdentifierAuthority;/// SID_IDENTIFIER_AUTHORITY->_SID_IDENTIFIER_AUTHORITY
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 1, ArraySubType = System.Runtime.InteropServices.UnmanagedType.U4)]
public uint[] SubAuthority;// DWORD[1]
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct SEC_WINNT_AUTH_IDENTITY_W
{
public IntPtr User;/// unsigned short*
public uint UserLength;/// unsigned int
public IntPtr Domain;/// unsigned short*
public uint DomainLength;/// unsigned int
public IntPtr Password;/// unsigned short*
public uint PasswordLength;/// unsigned int
public uint Flags;// unsigned int
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct FWP_BYTE_BLOB
{
public uint size; /// UINT32->unsigned int
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPStr)]
public string data;// UINT8*
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct FWPM_DISPLAY_DATA0
{
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string name;// wchar_t*
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string description;// wchar_t*
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct FWPM_SESSION0
{
public GUID sessionKey;/// GUID->_GUID
public FWPM_DISPLAY_DATA0 displayData;/// FWPM_DISPLAY_DATA0->FWPM_DISPLAY_DATA0_
public uint flags;/// UINT32->unsigned int
public uint txnWaitTimeoutInMSec;/// UINT32->unsigned int
public uint processId;/// DWORD->unsigned int
public IntPtr sid;/// SID*
[System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.LPWStr)]
public string username;/// wchar_t*
public int kernelMode;// BOOL->int
}
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct FWPM_SUBLAYER0
{
public GUID subLayerKey;/// GUID->_GUID
public FWPM_DISPLAY_DATA0 displayData;/// FWPM_DISPLAY_DATA0->FWPM_DISPLAY_DATA0_
public ushort flags;/// UINT16->unsigned short
public IntPtr providerKey;/// GUID*
public FWP_BYTE_BLOB providerData;/// FWP_BYTE_BLOB->FWP_BYTE_BLOB_
public ushort weight;// UINT16->unsigned short
}
Thanks
This is the first time I try to hook windows API. My goal is to monitor all files that a process is going to create/open/read/write.
In order to be the most verbose possible, I decided to hook the ntdll.dll API such as NtCreateFile() and NtOpenFile(). So, in order to acheive this goal, I went on EasyHook, which seems easy and robust.
I've essetially followed the FileMon example, changing what I really wanted: the Hooked function.
When I try to read information about the file that is going to be opened, I try to read information from the OBJECT_ATTRIBUTES structure, such as
the ObjectName. Those are integer pointers, so I expected to use the function Marshal.PtrToStringAuto(attributes.objectName) in order to get the string value. However, the result is I can only have bad strings, without any meaning. Also, the File access seems to be not working. I guess there's something wrong with this
code, maybe in the DllImport signatures. Be adviced I had to replace SafeHandle with IntPtr, because of EasyHook was complaining about marshaling them.
Can someone help me?
Here's my specific code of the injected DLL:
Here's the Run method code
public void Run(RemoteHooking.IContext InContext, String inChannelName)
{
// First of all, install all the hooks
try
{
// NtCreateFile
fileCreationHook = LocalHook.Create(
LocalHook.GetProcAddress("ntdll.dll", "NtCreateFile"),
new CreateFileDelegate(CreateFile_Hooked),
this
);
fileCreationHook = LocalHook.Create(
LocalHook.GetProcAddress("ntdll.dll", "NtOpenFile"),
new OpenFileDelegate(OpenFile_Hooked),
this
);
fileCreationHook.ThreadACL.SetExclusiveACL(new Int32[] { 0 });
remoteIf.Log("File creation Hook correctly installed on pid "+RemoteHooking.GetCurrentProcessId());
}
catch (Exception e)
{
remoteIf.Log(e.Message);
remoteIf.Log(e.StackTrace);
return;
}
// Wake up the process
remoteIf.Log("Waiking up process...");
RemoteHooking.WakeUpProcess();
while (true)
{
Thread.Sleep(500);
if (queue.Count > 0)
{
String[] package = null;
lock (queue)
{
package = queue.ToArray();
queue.Clear();
}
remoteIf.OnCreateFile(RemoteHooking.GetCurrentProcessId(), package);
}
else
remoteIf.Ping();
}
}
Here's the contructor code:
public InjectedDLL(RemoteHooking.IContext InContext, String inChannelName)
{
// Create the structure which will contain all the messages
queue = new Stack<string>();
// Initiate the connection to the Injector process, getting back its interface
remoteIf = RemoteHooking.IpcConnectClient<IPCInterface>(inChannelName);
// Try invocating a method to test the connection.
remoteIf.Ping();
}
Here there are the Hook delegate and the hook function
public delegate int CreateFileDelegate(out IntPtr handle,
System.IO.FileAccess access,
ref OBJECT_ATTRIBUTES objectAttributes,
out IO_STATUS_BLOCK ioStatus,
ref long allocSize,
uint fileAttributes,
System.IO.FileShare share,
uint createDisposition,
uint createOptions,
IntPtr eaBuffer,
uint eaLength);
public int CreateFile_Hooked(
out IntPtr handle,
System.IO.FileAccess access,
ref OBJECT_ATTRIBUTES objectAttributes,
out IO_STATUS_BLOCK ioStatus,
ref long allocSize,
uint fileAttributes,
System.IO.FileShare share,
uint createDisposition,
uint createOptions,
IntPtr eaBuffer,
uint eaLength)
{
//string s = Marshal.PtrToStringAuto(objectAttributes.ObjectName);
int res = NtCreateFile(out handle, access,ref objectAttributes,out ioStatus, ref allocSize,fileAttributes, share,createDisposition,createOptions,eaBuffer,eaLength);
return res;
}
Here there are the NtDll.Dll native functions:
[DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true)]
public static extern int NtCreateFile(
out IntPtr handle,
System.IO.FileAccess access,
ref OBJECT_ATTRIBUTES objectAttributes,
out IO_STATUS_BLOCK ioStatus,
ref long allocSize,
uint fileAttributes,
System.IO.FileShare share,
uint createDisposition,
uint createOptions,
IntPtr eaBuffer,
uint eaLength);
[DllImport("ntdll.dll", ExactSpelling = true, SetLastError = true)]
public static extern int NtOpenFile(
out IntPtr handle,
System.IO.FileAccess access,
ref OBJECT_ATTRIBUTES objectAttributes,
out IO_STATUS_BLOCK ioStatus,
System.IO.FileShare share,
uint openOptions
);
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct OBJECT_ATTRIBUTES
{
public Int32 Length;
public IntPtr RootDirectory;
public IntPtr ObjectName;
public uint Attributes;
public IntPtr SecurityDescriptor;
public IntPtr SecurityQualityOfService;
}
[StructLayout(LayoutKind.Sequential, Pack = 0)]
public struct IO_STATUS_BLOCK
{
public uint status;
public IntPtr information;
}
ObjectName is a pointer to a UNICODE_STRING struct. A managed equivalent looks like this:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct UNICODE_STRING
{
public ushort Length;
public ushort MaximumLength;
[MarshalAs(UnmanagedType.LPWStr)]
public String Buffer;
}
You need to use marshalling to get a managed copy of the struct.
var us = Marshal.PtrToStructure<UNICODE_STRING>(objectAttributes.ObjectName);
Once you have the managed struct you can access the Buffer field to get the name of the object.
I'm trying to write an application which will creates a new desktop using the Win32 API.
The below code works in Windows 7 but but in Windows 8 the desktop is created with out the desktop icons and with an empty taskbar.
public class Desktop
{
private const int NORMAL_PRIORITY_CLASS = 0x00000020;
private const long DF_ALLOWOTHERACCOUNTHOOK = 0x0001L;
private const uint DELETE = 0x00010000;
private const uint READ_CONTROL = 0x00020000;
private const uint WRITE_DAC = 0x00040000;
private const uint WRITE_OWNER = 0x00080000;
private const uint STANDARD_RIGHTS_REQUIRED = DELETE | READ_CONTROL | WRITE_DAC | WRITE_OWNER;
private const long DESKTOP_CREATEWINDOW = 0x0002L;
private const long DESKTOP_ENUMERATE = 0x0040L;
private const long DESKTOP_WRITEOBJECTS = 0x0080L;
private const long DESKTOP_SWITCHDESKTOP = 0x0100L;
private const long DESKTOP_CREATEMENU = 0x0004L;
private const long DESKTOP_HOOKCONTROL = 0x0008L;
private const long DESKTOP_READOBJECTS = 0x0001L;
private const long DESKTOP_JOURNALRECORD = 0x0010L;
private const long DESKTOP_JOURNALPLAYBACK = 0x0020L;
private const uint AccessRights = (uint)DESKTOP_JOURNALRECORD |
(uint)DESKTOP_JOURNALPLAYBACK |
(uint)DESKTOP_CREATEWINDOW |
(uint)DESKTOP_ENUMERATE |
(uint)DESKTOP_WRITEOBJECTS |
(uint)DESKTOP_SWITCHDESKTOP |
(uint)DESKTOP_CREATEMENU |
(uint)DESKTOP_HOOKCONTROL |
(uint)DESKTOP_READOBJECTS |
STANDARD_RIGHTS_REQUIRED;
private delegate bool EnumDesktopProc(string lpszDesktop, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr GetProcessWindowStation();
[DllImport("user32.dll")]
private static extern bool EnumDesktops(IntPtr hwinsta, EnumDesktopProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
public static extern IntPtr CreateDesktop(string desktopName, string device, string deviceMode, int flags, uint accessMask, [In] ref SECURITY_ATTRIBUTES attributes);
[DllImport("user32.dll")]
private static extern IntPtr OpenDesktop(string lpszDesktop, uint dwFlags, bool fInherit, uint dwDesiredAccess);
[DllImport("user32.dll")]
private static extern bool SwitchDesktop(IntPtr hDesktop);
[DllImport("kernel32.dll")]
private static extern bool CreateProcess(string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, int dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref STARTUPINFO lpStartupInfo, ref PROCESS_INFORMATION lpProcessInformation);
[StructLayout(LayoutKind.Sequential)]
public struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
[StructLayout(LayoutKind.Sequential)]
private struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public int dwX;
public int dwY;
public int dwXSize;
public int dwYSize;
public int dwXCountChars;
public int dwYCountChars;
public int dwFillAttribute;
public int dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
[StructLayout(LayoutKind.Sequential)]
private struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
private static List<string> _desktops = new List<string>();
public static IntPtr Create(string name)
{
var securityAttributes = new SECURITY_ATTRIBUTES();
securityAttributes.nLength = Marshal.SizeOf(securityAttributes);
return CreateDesktop(name, null, null, (int) DF_ALLOWOTHERACCOUNTHOOK, AccessRights, ref securityAttributes);
}
public static IntPtr Open(string name)
{
return OpenDesktop(name, 0, false, AccessRights);
}
public static bool Show(IntPtr desktopPrt)
{
if (desktopPrt == IntPtr.Zero) return false;
return SwitchDesktop(desktopPrt);
}
public static void Prepare(string desktopName)
{
CreateProcess("C:\\Windows\\explorer.exe", desktopName);
}
public static bool Exists(string name)
{
return GetDesktops().Any(s => s == name);
}
private static void CreateProcess(string path, string desktopName)
{
STARTUPINFO si = new STARTUPINFO();
si.cb = Marshal.SizeOf(si);
si.lpDesktop = desktopName;
PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
var lpCurrentDirectory = Path.GetDirectoryName(path);
CreateProcess(path, null, IntPtr.Zero, IntPtr.Zero, true, NORMAL_PRIORITY_CLASS, IntPtr.Zero, lpCurrentDirectory, ref si, ref pi);
}
private static string[] GetDesktops()
{
IntPtr windowStation = GetProcessWindowStation();
if (windowStation == IntPtr.Zero) return new string[0];
_desktops.Clear();
bool result = EnumDesktops(windowStation, DesktopEnumProc, IntPtr.Zero);
if (!result) return new string[0];
return _desktops.ToArray();
}
private static bool DesktopEnumProc(string lpszDesktop, IntPtr lParam)
{
_desktops.Add(lpszDesktop);
return true;
}
}
Usage:
var desktopName = "TestDesktop";
var desktopPrt = Desktop.Create(desktopName);
Desktop.Show(desktopPrt);
Desktop.Prepare(desktopName);
The Sysinternals Desktops app (http://technet.microsoft.com/en-us/sysinternals/cc817881.aspx) uses the same API and it works in Windows 8 so there must be something that I am missing.
Does anyone have any pointers for me? Or does anyone know of any where I can find examples of how to use this API? MSDN for the API calls gives a lot of information but no many examples.
Thanks ;D
EDIT: Sry, I realised that you run it in your code snippet, please ignore my comment.
How about explicitly running explorer.exe for each desktop you create? That one handles icons, taskbar, etc ...
When you run SysInternals Desktops app you can see that it actually does that.
Can I do this with some API I am overlooking or do I have to figure out porting the C# .NET API calls mentioned here into PowerShell to make this happen in a script?
You can use Add-Type cmdlet to easily port it I believe:
$sig = #"
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct NativeCredential
{
public UInt32 Flags;
public CRED_TYPE Type;
public IntPtr TargetName;
public IntPtr Comment;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
public UInt32 CredentialBlobSize;
public IntPtr CredentialBlob;
public UInt32 Persist;
public UInt32 AttributeCount;
public IntPtr Attributes;
public IntPtr TargetAlias;
public IntPtr UserName;
internal static NativeCredential GetNativeCredential(Credential cred)
{
NativeCredential ncred = new NativeCredential();
ncred.AttributeCount = 0;
ncred.Attributes = IntPtr.Zero;
ncred.Comment = IntPtr.Zero;
ncred.TargetAlias = IntPtr.Zero;
ncred.Type = CRED_TYPE.GENERIC;
ncred.Persist = (UInt32)1;
ncred.CredentialBlobSize = (UInt32)cred.CredentialBlobSize;
ncred.TargetName = Marshal.StringToCoTaskMemUni(cred.TargetName);
ncred.CredentialBlob = Marshal.StringToCoTaskMemUni(cred.CredentialBlob);
ncred.UserName = Marshal.StringToCoTaskMemUni(System.Environment.UserName);
return ncred;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct Credential
{
public UInt32 Flags;
public CRED_TYPE Type;
public string TargetName;
public string Comment;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
public UInt32 CredentialBlobSize;
public string CredentialBlob;
public UInt32 Persist;
public UInt32 AttributeCount;
public IntPtr Attributes;
public string TargetAlias;
public string UserName;
}
public enum CRED_TYPE : uint
{
GENERIC = 1,
DOMAIN_PASSWORD = 2,
DOMAIN_CERTIFICATE = 3,
DOMAIN_VISIBLE_PASSWORD = 4,
GENERIC_CERTIFICATE = 5,
DOMAIN_EXTENDED = 6,
MAXIMUM = 7, // Maximum supported cred type
MAXIMUM_EX = (MAXIMUM + 1000), // Allow new applications to run on old OSes
}
public class CriticalCredentialHandle : Microsoft.Win32.SafeHandles.CriticalHandleZeroOrMinusOneIsInvalid
{
public CriticalCredentialHandle(IntPtr preexistingHandle)
{
SetHandle(preexistingHandle);
}
public Credential GetCredential()
{
if (!IsInvalid)
{
NativeCredential ncred = (NativeCredential)Marshal.PtrToStructure(handle,
typeof(NativeCredential));
Credential cred = new Credential();
cred.CredentialBlobSize = ncred.CredentialBlobSize;
cred.CredentialBlob = Marshal.PtrToStringUni(ncred.CredentialBlob,
(int)ncred.CredentialBlobSize / 2);
cred.UserName = Marshal.PtrToStringUni(ncred.UserName);
cred.TargetName = Marshal.PtrToStringUni(ncred.TargetName);
cred.TargetAlias = Marshal.PtrToStringUni(ncred.TargetAlias);
cred.Type = ncred.Type;
cred.Flags = ncred.Flags;
cred.Persist = ncred.Persist;
return cred;
}
else
{
throw new InvalidOperationException("Invalid CriticalHandle!");
}
}
override protected bool ReleaseHandle()
{
if (!IsInvalid)
{
CredFree(handle);
SetHandleAsInvalid();
return true;
}
return false;
}
}
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag, out IntPtr CredentialPtr);
[DllImport("Advapi32.dll", EntryPoint = "CredFree", SetLastError = true)]
public static extern bool CredFree([In] IntPtr cred);
"#
Add-Type -MemberDefinition $sig -Namespace "ADVAPI32" -Name 'Util'
$targetName = "computer"
$nCredPtr= New-Object IntPtr
$success = [ADVAPI32.Util]::CredRead($targetName,1,0,[ref] $nCredPtr)
if($success){
$critCred = New-Object ADVAPI32.Util+CriticalCredentialHandle $nCredPtr
$cred = $critCred.GetCredential()
$password = $cred.CredentialBlob;
write-host -fore blue $password
}
Adapted from here: http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/e91769eb-dbce-4e77-8b61-d3e55690b511/
Based on: http://blogs.msdn.com/b/peerchan/archive/2005/11/01/487834.aspx
This has already been done:
http://gallery.technet.microsoft.com/scriptcenter/PowerShell-Credentials-d44c3cde/view/Discussions
It provides a couple cred-man related methods, and it is already documented.
I'm trying to find out the 'correct' windows API for finding out the localized name of 'special' folders, specifically the Recycle Bin. I want to be able to prompt the user with a suitably localized dialog box asking them if they want to send files to the recycle bin or delete them directly.
I've found lots on the internet (and on Stackoverflow) about how to do the actual deletion, and it seems simple enough, I just really want to be able to have the text localized.
Read this article for code samples and usage:
http://www.codeproject.com/KB/winsdk/SpecialFolders.aspx
Also there is an article on MSDN that helps you Identify the Location of Special Folders with API Calls
I actually didn't find the CodeProject article terribly helpful, so I thought I'd answer this question with the actual code that I used to retrieve the localized name of the recycle bin.
This sample also tries to behave correctly with regard to freeing resources. Any comments are welcome, especially if you spot an error with my resource management!
public static string GetLocalizedRecycleBinName()
{
IntPtr relative_pidl, parent_ptr, absolute_pidl;
PInvoke.SHGetFolderLocation(IntPtr.Zero, PInvoke.CSIDL.BitBucket,
IntPtr.Zero, 0, out absolute_pidl);
try
{
PInvoke.SHBindToParent(absolute_pidl,
ref PInvoke.Guids.IID_IShellFolder,
out parent_ptr, out relative_pidl);
PInvoke.IShellFolder shell_folder =
Marshal.GetObjectForIUnknown(parent_ptr)
as PInvoke.IShellFolder;
// Release() for this object is called at finalization
if (shell_folder == null)
return Strings.RecycleBin;
PInvoke.STRRET strret = new PInvoke.STRRET();
StringBuilder sb = new StringBuilder(260);
shell_folder.GetDisplayNameOf(relative_pidl, PInvoke.SHGNO.Normal,
out strret);
PInvoke.StrRetToBuf(ref strret, relative_pidl, sb, 260);
string name = sb.ToString();
return String.IsNullOrEmpty(name) ? Strings.RecycleBin : name;
}
finally { PInvoke.ILFree(absolute_pidl); }
}
static class PInvoke
{
[DllImport("shell32.dll")]
public static extern int SHGetFolderLocation(IntPtr hwndOwner,
CSIDL nFolder, IntPtr hToken, uint dwReserved, out IntPtr ppidl);
[DllImport("shell32.dll")]
public static extern int SHBindToParent(IntPtr lpifq, [In] ref Guid riid,
out IntPtr ppv, out IntPtr pidlLast);
[DllImport("shlwapi.dll")]
public static extern Int32 StrRetToBuf(ref STRRET pstr, IntPtr pidl,
StringBuilder pszBuf, uint cchBuf);
[DllImport("shell32.dll")]
public static extern void ILFree([In] IntPtr pidl);
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214E6-0000-0000-C000-000000000046")]
public interface IShellFolder
{
[PreserveSig]
Int32 CompareIDs(Int32 lParam, IntPtr pidl1, IntPtr pidl2);
void ParseDisplayName(IntPtr hwnd, IntPtr pbc, String pszDisplayName,
UInt32 pchEaten, out IntPtr ppidl, UInt32 pdwAttributes);
void EnumObjects(IntPtr hwnd, int grfFlags,
out IntPtr ppenumIDList);
void BindToObject(IntPtr pidl, IntPtr pbc, [In] ref Guid riid,
out IntPtr ppv);
void BindToStorage(IntPtr pidl, IntPtr pbc, [In] ref Guid riid,
out IntPtr ppv);
void CreateViewObject(IntPtr hwndOwner, [In] ref Guid riid,
out IntPtr ppv);
void GetAttributesOf(UInt32 cidl,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)]
IntPtr[] apidl, ref uint rgfInOut);
void GetUIObjectOf(IntPtr hwndOwner, UInt32 cidl,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]
IntPtr[] apidl, [In] ref Guid riid, UInt32 rgfReserved,
out IntPtr ppv);
void GetDisplayNameOf(IntPtr pidl, SHGNO uFlags, out STRRET pName);
void SetNameOf(IntPtr hwnd, IntPtr pidl, string pszName,
int uFlags, out IntPtr ppidlOut);
}
public enum CSIDL
{
BitBucket = 0x000a,
}
public enum SHGNO
{
Normal = 0x0000, ForParsing = 0x8000,
}
[StructLayout(LayoutKind.Explicit, Size = 520)]
public struct STRRETinternal
{
[FieldOffset(0)] public IntPtr pOleStr;
[FieldOffset(0)] public IntPtr pStr;
[FieldOffset(0)] public uint uOffset;
}
[StructLayout(LayoutKind.Sequential)]
public struct STRRET
{
public uint uType;
public STRRETinternal data;
}
public class Guids
{
public static Guid IID_IShellFolder =
new Guid("{000214E6-0000-0000-C000-000000000046}");
}
}