c# - Access CurrentUser Registry Key for Impersonated User - Compatibility with .NET 3.5 -
i've written application impersonate user account, handle current_user registry key (using pinvoke "loaduserprofile" retrieve profileinfo.hprofile object) , create registry key using registrykey.fromhandle.
reference code:
using (windowsimpersonationcontext impersonateduser = windowsidentity.impersonate(htoken)) { using (saferegistryhandle safehandle = new saferegistryhandle(hprofile, true)) { using (registrykey impersonateduserhkcu = registrykey.fromhandle(safehandle, registryview.default)) { // registry } } }
this piece of code works (run in windows 7), made use of objects/methods supported .net 4.0 , greater (saferegistryhandle, registrykey.fromhandle(), registryview enum).
now, need make application compatible .net 3.5, use in machine windows xp , no possibilities install .net framework 4.0.
are there equivalent objects can use .net 3.5 accomplish same result? (that is, make modification registry key impersonated user). or exist kind of source codes of only-.net 4 objects?
after days of research, and msdn community same question, i've found way follow accomplish needs.
the initial suggestion use win api function regopenkeyex
(see p/invoke website infos , samples); according this msdn article, i've found that
if service or application impersonates different users, not use function hkey_current_user. instead, call regopencurrentuser function.
finally, way go regopencurrentuser
function. (unfortunately there's still no trace of function on p/invoke website, can find infos on msdn)
this how define it:
[dllimport("advapi32.dll", charset = charset.auto)] public static extern int regopencurrentuser(int samdesired, out intptr phkresult); public enum registrysecurity { key_all_access = 0xf003f, key_create_link = 0x0020, key_create_sub_key = 0x0004, key_enumerate_sub_keys = 0x0008, key_execute = 0x20019, key_notify = 0x0010, key_query_value = 0x0001, key_read = 0x20019, key_set_value = 0x0002, key_wow64_32key = 0x0200, key_wow64_64key = 0x0100, key_write = 0x20006, } public intptr getimpersonateuserregistryhandle(registrysecurity _access) { intptr safehandle = new intptr(); int result = regopencurrentuser((int)_access, out safehandle); return safehandle; } /// <summary> /// registry key pointer. /// </summary> /// <param name="hkey">pointer registry key</param> /// <param name="writable">whether or not key writable.</param> /// <param name="ownshandle">whether or not own handle.</param> /// <returns>registry key pointed given pointer.</returns> public registrykey _pointertoregistrykey(intptr hkey, bool writable, bool ownshandle) { //get bindingflags private contructors system.reflection.bindingflags privateconstructors = system.reflection.bindingflags.instance | system.reflection.bindingflags.nonpublic; //get type saferegistryhandle type saferegistryhandletype = typeof(microsoft.win32.safehandles.safehandlezeroorminusoneisinvalid).assembly.gettype("microsoft.win32.safehandles.saferegistryhandle"); //get array of types matching args of ctor want type[] saferegistryhandlectortypes = new type[] { typeof(intptr), typeof(bool) }; //get constructorinfo our object system.reflection.constructorinfo saferegistryhandlectorinfo = saferegistryhandletype.getconstructor( privateconstructors, null, saferegistryhandlectortypes, null); //invoke constructor, getting saferegistryhandle object safehandle = saferegistryhandlectorinfo.invoke(new object[] { hkey, ownshandle }); //get type of registrykey type registrykeytype = typeof(registrykey); //get array of types matching args of ctor want type[] registrykeyconstructortypes = new type[] { saferegistryhandletype, typeof(bool) }; //get constructorinfo our object system.reflection.constructorinfo registrykeyctorinfo = registrykeytype.getconstructor( privateconstructors, null, registrykeyconstructortypes, null); //invoke constructor, getting registrykey registrykey resultkey = (registrykey)registrykeyctorinfo.invoke(new object[] { safehandle, writable }); //return resulting key return resultkey; }
and how use registry:
intptr localregistryhandle = getimpersonateuserregistryhandle(testregistryaccess.registrysecurity.key_all_access); using(registrykey localregistry = _pointertoregistrykey(localregistryhandle, true, true)) { // local registry }
Comments
Post a Comment