Hopefully, I am not off, but actually, El Choni's example works well for me (thanks for that!).
Here a stripped down version and a description of the test (needs NTFS):
1. Logged on as user "A"
2. Created a directory "C:\ElChoni"
3. Changed security, so only the user "B" has write access, others only read
4. Started the program below, that attempts to create a file in that restricted dir
a) User "A" (before impersonation) tries: no success
b) Calling the impersonation routine, impersonating "B": success
Now let's check if it really is as it pretended to be:
- et voila, the file was created
Code: Select all
;Stripped down from sample by El Choni
;http://forums.purebasic.com/english/viewtopic.php?t=14727&highlight=
Username$ = "b"
Domain$ = "."
Password$ = "mypassword"
Procedure u(string$)
sLen = Len(string$)
uLen = (sLen<<1)+2
*uBuffer = AllocateMemory(uLen)
MultiByteToWideChar_(#CP_ACP, 0, string$, sLen, *uBuffer, uLen)
ProcedureReturn *uBuffer
EndProcedure
Procedure Error(message$, hToken)
wError = GetLastError_()
If wError
*ErrorBuffer = AllocateMemory(1024)
If *ErrorBuffer
FormatMessage_(#FORMAT_MESSAGE_FROM_SYSTEM, 0, wError, 0, *ErrorBuffer, 1024, 0)
message$+Chr(10)+PeekS(*ErrorBuffer)
FreeMemory(*ErrorBuffer)
EndIf
EndIf
If hToken:RevertToSelf_():CloseHandle_(hToken):EndIf
MessageRequester("Error", message$)
ProcedureReturn #FALSE
EndProcedure
!extrn _CreateProcessWithLogonW@44
Global *CreateProcessWithLogonW
!MOV dword [p_CreateProcessWithLogonW], _CreateProcessWithLogonW@44
Procedure ImpersonateUser(UserName$, Domain$, Password$)
If LogonUser_(@Username$, @Domain$, @Password$, 2, 0, @hToken)=0
ProcedureReturn Error("LogonUser", 0)
EndIf
If ImpersonateLoggedOnUser_(hToken)=0:
ProcedureReturn Error("ImpersonateLoggedOnUser", hToken)
EndIf
GetStartupInfo_(@si.STARTUPINFO)
;After impersonation
Result=CreateFile(0,"C:\ElChoni\UserB.txt")
If Result
Debug "Successful: impersonated user"
CloseFile(0)
Else
Debug "Error: impersonated user"
EndIf
RevertToSelf_()
CloseHandle_(hToken)
ProcedureReturn hProcess
EndProcedure
;Before impersonation
Result=CreateFile(0,"C:\ElChoni\UserA.txt")
If Result
Debug "Successful: main user"
CloseFile(0)
Else
Debug "Error: main user"
EndIf
ImpersonateUser(Username$,Domain$,Password$)
;Now reverted to state "before impersonation"
Isn't that what you mean to do (just chose a random built in function to make it easier to test. API should work as well)?
But:
The user that impersonates (here: A) needs to have the privilege ImpersonateUser!