0

Windows XP の起動時にリモート サーバーとファイルを同期する C++ プログラムがあります。公開鍵ファイルを開く必要がある関数は、fopen() で失敗します。プログラムを自分で (エクスプローラー内から) 起動すると、すべて正常に動作します。しかし、スタートアップ キーをレジストリに追加すると、機能が失敗します。

デバッガーでコードをトレースしたところ、CreateFileA() の呼び出しまでは問題ありませんでした。CreateFileA は FILE_NOT_FOUND を返します。

fopen() への呼び出しを削除し、CreateFileA() への直接呼び出しに置き換えました。次に、SECURITY_ATTRIBUTES を NULL に変更した後、CreateFileA() の呼び出しが機能します。

問題は、暗号化に使用しているサードパーティのライブラリが、ファイルから読み取ったデータだけでなく、FILE* オブジェクトを必要とすることです。どうすれば問題を解決できますか?

現在使用しているコードは次のとおりです。

if( !GetModuleFileNameA(NULL, Path, MAX_PATH) ){
    delete [] buf;
    delete [] Path;
    return strerror( errno );
}

rPath = Path;

delete [] Path;

ret = rPath.find_last_of( '\\' );

if( ret == string::npos ){
    delete [] buf;
    return strerror( errno );
}

ret++;

rPath.erase( rPath.begin() + ret, rPath.begin() + rPath.size() - ret );

rPath += "rsa_pub.txt";

if( ( f = fopen( rPath.c_str(), "rb" ) ) == NULL ){  // fails when started from registry
    delete [] buf;
    return strerror( errno );
}

編集:

この問題に対するハッカーの解決策を見つけました。ランタイム ライブラリを解放してからリロードすると、問題は解決します。ただし、これは非常にエレガントなソリューションではありません。dllを削除して再ロードせずにランタイムをリセットすることはおそらく可能ですか?

4

1 に答える 1

1

あなたのrPath.erase電話はあまり意味がないようです

rPath.erase( rPath.begin() + ret, rPath.begin() + rPath.size() - ret );

それは何をすることになっていますか?

ここでは、こちらの(iterator, iterator)バージョンを使用してeraseいます。位置から始まる文字列の末尾部分を消去しようとしていると思いますret。その場合、私はそれが次のように見えると予想します

rPath.erase( rPath.begin() + ret, rPath.end() );

(position, length)のバージョンを使用する場合はerase、次のようになります。

rPath.erase( ret, rPath.size() - ret );

しかし、あなたの特定の使用法は、2つの奇妙なハイブリッドのように見えます。その電話で何をしようとしていますか?

プログラムのGetModuleFileNameA起動方法に応じて、おそらく異なる文字列が返されるため、コードが「機能している」ように見える場合があります。

于 2012-04-20T16:37:50.543 に答える