Whenever you impersonate a running thread and create a new thread while impersonating, your new thread will not get impersonated, too. The new thread will run without any thread token and thus a called function will use the process token instead. So you have to impersonate the new thread again. Ignoring that fact may lead to problems if the process as a high access level (SYSTEM, Administrator) and the new thread touches resources e.g. files. These files are opened with higher privileges, even if the user usually cannot access them.

The sample shows how we can spawn a token for the new thread exclusively.

procedure ThreadFunc(Data : Pointer)
var Token : TJwSecurityToken;
begin
  Token := TJwSecurityToken(Data);
  try
    Token.ImpersonateLoggedOnUser;
    …
    …
  except
    //check here the problem
    //and inform the thread creator
    //To raise an exception within a thread does end it immediately.
  end;
  Token.Free;
end;

var Token, Token2 : TJwSecurityToken;
begin
  …
  try
    Token.ImpersonateLoggedOnUser;
    //the new thread will not run in Token context
    //get a second handle to the token for the thread
    Token2 := TJwSecurityToken.CreateDuplicateExistingToken(Token.TokenHandle, TOKEN_ALL_ACCESS, true);
    CreateThread(…, @ThreadFunc, Pointer(Token2));
    …
  finally
    Token.Free;
  end;