3

次のスレッドでJonによって提供されたコードは、私がやりたいことを正確に示しているようです。

Windows7のウェルカム画面でプロセスを実行する

残念ながら、それは私がまったく知らない言語であるC#で書かれています。コードをPascal(Windows 7上のLazarusの最近のバージョン)に翻訳しようとしています。行間を読んで、私はそれをたくさん持っているかもしれないと思います-しかし、それがその仕事をしなかったとき、私はそれが間違っているかどうかしかわかりません。現時点では、次の時点でコンパイルに失敗しています。

if (!DuplicateTokenEx(userToken, 0x10000000, ref tokenAttributes,   
SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenImpersonation,
out newToken)) {
log("ERROR: DuplicateTokenEx returned false - "

私のパスカルバージョン:

If Not DuplicateTokenEx(UserToken, MAXIMUM_ALLOWED, tokenAttributes,
SecurityImpersonation, TokenPrimary, newToken) then
  Writeln(DLog, 'Failed to duplicate security token'); 

Lazarusは、6つのパラメーターの5番目にエラーをスローします。

dmain.pas(189,110)エラー:引数番号に互換性のないタイプ。5:「TOKEN_TYPE」を取得しました。「_TOKEN_TYPE」が必要です。これは、パラメーターが何をしているのか理解していないことを示しています。(パラメーター5をTokenImpersonationに変更すると、同じエラーがスローされます。)

さらに下に行くと、私はさらに迷子になります。

tokPrivs.Privileges = new LUID_AND_ATTRIBUTES[1];
tokPrivs.Privileges[0].Luid = seDebugNameValue;
tokPrivs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

構造タイプLUID_AND_ATTRIBUTESがWindowsAPIにあることがわかりますが、Lazarusによって認識されていないようです。

要するに、私は暗闇の中で手探りしています。「C#for Pascalプログラマー」でグーグルを試しましたが、何も役に立ちませんでした。C#を学ぶことは簡単なことではないので、C#とObject Pascalの違い、およびこのコードの翻訳方法に関するヒントをいただければ幸いです。

編集:要求に応じて未完成のコード。

function RunOurProcess(ProgramName: String): Boolean;
var
StartInfo: TStartupInfo;
ProcInfo: TProcessInformation;
NewToken, Token, UserToken: THandle;
WPID: DWord;
ThreadAttributes, TokenAttributes: TSecurityAttributes;
TOKPrivs: TTokenPrivileges;
begin
    FillChar(StartInfo, SizeOf(TStartupInfo), #0);
    FillChar(ProcInfo, SizeOf(TProcessInformation), #0);
    StartInfo.cb:= SizeOf(TStartupInfo);
    { Insert handle of current desktop - without this, GUI app is not visible!
      To appear before logon, lpDesktop value should be 'winsta0\WinLogon' }
    StartInfo.lpDesktop:= PChar('winsta0\WinLogon');
    // Save the process ID of the WinLogon process
    WPID:= FindInProcesses('Winlogon.exe');
    // Get the handle of this
    Token:= OpenProcess(TOKEN_QUERY or TOKEN_IMPERSONATE or TOKEN_DUPLICATE, False, WPID);
    // Open a process token using the handle above
    If OpenProcessToken(Token, TOKEN_QUERY or TOKEN_IMPERSONATE or TOKEN_DUPLICATE, UserToken) then
    Writeln(DLog, 'Opened process token for WinLogon')
        else
    Writeln(DLog, 'Failed to open process token for WinLogon');
    // Create a new token
    NewToken:= 0;
    tokenAttributes.nLength:= SizeOf(tokenAttributes);
    threadAttributes.nLength:= SizeOf(threadAttributes);
    If Not DuplicateTokenEx(UserToken, MAXIMUM_ALLOWED, tokenAttributes, SecurityImpersonation, TokenImpersonation, newToken) then
    Writeln(DLog, 'Failed to duplicate security token');
    // Elevate the privileges of the token
    AdjustTokenPrivileges(NewToken, False, {NewState, BufferLength, PreviousState, ReturnLength});
    // LogOnUser
    // If successful, CreateProcessAsUser
    // In progress - code below needs to go before 'CreateProcessAsUser'
    StartInfo.cb:= SizeOf(TStartupInfo);
    // Insert handle of current desktop - without this, GUI app is not visible!
    StartInfo.lpDesktop:= PChar('winsta0\WinLogon');
end; // RunOurProcess            

「DuplicateTokenEx」の宣言を見つけようとすると、次のエラーが発生することに気付きました。

C:\ lazarus \ fpc \ 2.6.1 \ source \ packages \ winunits-jedi \ src \ jwawindows.pas(366,5)エラー:インクルードファイルが見つかりません「JwaLmErr.pp」

4

1 に答える 1

1

コンパイルの問題を解決する方法は次のとおりです。

の呼び出しDuplicateTokenExは、3番目のパラメーターで実際に失敗します。宣言を見ると、LPSECURITY_ATTRIBUTESどちらかです^TSecurityAttributes。現在、tokenAttributesはタイプでTSecurityAttributesあるため、そのアドレスを渡す必要があります。

If Not DuplicateTokenEx(..., @tokenAttributes, ...) then

そして同様にへの呼び出しでAdjustTokenPrivileges。C#コードは次のとおりです。

AdjustTokenPrivileges(newToken, false, ref tokPrivs, 0, IntPtr.Zero, IntPtr.Zero)

パスカルに翻訳すると、次のようになります。

AdjustTokenPrivileges(NewToken, False, @TOKPrivs, 0, nil, nil)

コードがあなたの問題を解決するかどうかはわかりません。それはこの質問の範囲を超えていると思います-少なくともそれは私の言い訳であり、私はそれに固執しています!

于 2013-03-23T20:43:20.043 に答える