2011-09-14 17 views
4

ミューテックスハンドル、子プロセストラフコマンドライン、または他の方法で渡そうとしています。子プロセスにハンドルを渡す方法

どうすればいいですか? 子供からミューテックスにアクセスするにはどうしたらいいですか?

HANDLE ghMutex; 

    if(!CreateProcess(_T("C:\\Users\\Kumppler\\Documents\\Visual Studio 2010\\Projects\\teste3\\Debug\\teste3.exe"), // No module name (use command line) 
       aux2,        // Command line 
       NULL,        // Process handle not inheritable 
       NULL,        // Thread handle not inheritable 
       TRUE,        // Set handle inheritance to TRUE 
       STARTF_USESTDHANDLES,    // inherit the standard input, standard output, and standard error handles 
       NULL,        // Use parent's environment block 
       NULL,        // Use parent's starting directory 
       &si[j],       // Pointer to STARTUPINFO structure 
       &pi[j])       // Pointer to PROCESS_INFORMATION structure 
      )      

EDIT:

これは私が子プロセス作成しています方法です

私は複数の子プロセスのためにミューテックスを使用する必要があるが、それは大丈夫でしょうか?だからここ

は、私が今やっていることです:

HANDLE ghMutex; 
int mutex; 
char mutexstring[7]; 

mutex=(int)ghMutex; 
itoa(mutexValue,mutexString,10); 

私はmutexStringトラフコマンドラインを通過し、その後、子プロセスに戻ってそれを変換されます:

mutexValue=atoi(argv[2]); 

Mutex=(HANDLE)mutexValue; 

私の質問、(HANDLE)キャストをするのは大丈夫ですか?

答えて

5

つのオプション:

  1. あなたが名前付きオブジェクトを使用することができます。プロセスAは名前を持つミューテックスを作成し、プロセスBを生成します。プロセスBは同じ名前のOpenMutexまたはCreateMutexを呼び出し、同じミューテックスへのハンドルを取得します。

    名前の選択には欠点があります。名前の衝突があった場合、予期しない結果が得られます。攻撃者は同じ名前のミューテックスを作成し、サービス不能状態を引き起こす可能性があります。これに対処する1つの方法は、名前をランダムに生成することです。たとえば、プロセスAは名前のGUIDを生成し、そのGUID(文字列として)をプロセスBに渡すことができます。

  2. inheritanceを使用できます。子プロセスは、親プロセスから、mutexハンドルを含む多くのタイプのハンドルを継承できます。 bInheritHandlesパラメータをCreateProcessコマンド(サンプルがすでに行っている)に設定し、コマンドラインのハンドル(文字列として)の値を子プロセスに渡します。子プロセスは、コマンドライン文字列を値に変換して、単にそれを使用し始めることができます。値は両方のプロセスで同じです。

このテクニックには、名前付きオブジェクトテクニックと同じ欠点はありません。

継承(エラーチェック省略さ)の作業例:

#include <cstddef> 
#include <iostream> 
#include <string> 
#include <sstream> 
#include <windows.h> 

void DoParentWork() { 
    std::wcout << L"Parent: Creating an inheritable event..." << std::endl; 
    SECURITY_ATTRIBUTES security = { 
    sizeof(security), nullptr, /* bInheritHandle = */ TRUE 
    }; 
    HANDLE hEvent = ::CreateEventW(&security, /* bManualReset = */ TRUE, 
           /* bInitialState = */ FALSE, nullptr); 

    std::wstringstream ssCommand; 
    ssCommand << L"foo.exe " << reinterpret_cast<std::size_t>(hEvent); 
    std::wstring strCmd = ssCommand.str();; 

    std::wcout << L"Parent: Starting child process..." << std::endl; 
    STARTUPINFO start_info = {sizeof(start_info)}; 
    PROCESS_INFORMATION proc_info = {0}; 
    ::CreateProcessW(L"foo.exe", &strCmd[0], nullptr, nullptr, 
        /* bInheritHandles = */ TRUE, 0, nullptr, nullptr, 
        &start_info, &proc_info); 
    ::CloseHandle(proc_info.hThread); 
    ::CloseHandle(proc_info.hProcess); 

    std::wcout << L"Parent: Waiting for the child to signal the event." 
      << std::endl; 
    if (::WaitForSingleObject(hEvent, 10*1000) == WAIT_OBJECT_0) { 
    std::wcout << L"Parent: The event was signaled." << std::endl; 
    } else { 
    std::wcout << L"Parent: Timed out waiting for the event." 
       << std::endl; 
    } 
    ::CloseHandle(hEvent); 
} 

void DoChildWork(const char *pszEvent) { 
    std::stringstream ss(pszEvent); 
    UINT_PTR iEvent; 
    ss >> iEvent; 
    HANDLE hEvent = reinterpret_cast<HANDLE>(iEvent); 
    std::cout << "Child: Event handle " 
      << reinterpret_cast<std::size_t>(hEvent) << std::endl; 
    ::Sleep(2000); 
    std::cout << "Child: Signalling the event." << std::endl; 
    ::SetEvent(hEvent); 
} 

int main(int cArgs, char *ppszArgs[]) { 
    if (cArgs > 1) DoChildWork(ppszArgs[1]); 
    else DoParentWork(); 
    return 0; 
} 
+0

+1の名前付きミューテックス。彼らは明らかな解決策です。衝突を避けるためにコマンドラインからGUIDを渡すのは大変です:すべてのプログラムでハードコーディングしてください:とにかくユニークです。 –

+0

"子プロセスは、コマンドライン文字列を値に戻し、単純にそれを使用して開始することができます。 – Caio

+0

@Serge - appTranslator:名前のハードコードには2つの問題があります。 (1)アプリケーションの1つのインスタンスに制限します。 (2)攻撃者があなたの前にミューテックスを作成した場合のサービス拒否の脆弱性(私の答えに記載されているように) –

-1

この目的のためにIPC(interporcess communication)を実行する必要があります。以下のようなウィンドウには多くのIPCの方法があります。

  1. クリップボード
  2. COM
  3. RPC
  4. DataCopy
  5. が...

は詳細についてはthis article in MSD Nを参照してください。

+0

このリストはランダムな順序であり、推薦に従ってソートされていないことを願っています:) – user786653

+0

@ user786653:オフコースです!!!! – hsalimi

1

子プロセスを作成する前にミューテックスを作成し、それを継承(CreateMutexのためlpMutexAttributesパラメータにTRUEにbInheritHandleを設定)しますどちらか。これにより、コマンドラインでハンドルを渡すことができます。

またはDuplicateHandleを使用し、ハンドルを他のメカニズム(たとえば、子プロセスのSTDINとしてパイプを使用)で渡します。

+0

これは機能しません。 HANDLEを文字列としてシリアライズして子に渡すことはできません。私はこれをしようとしましたが、動作しません。実際の例で間違っていることを自由に感じてください。 – jcoffland

+0

@jcofflandできることは確かですが、回答ごとに複製する必要があります –

関連する問題