- PR -

WindowsServer2003リモートデスクトップで共有メモリ

1
投稿者投稿内容
ぱぱまま
会議室デビュー日: 2007/07/31
投稿数: 4
投稿日時: 2007-07-31 22:44
初めて利用するためスレッド立てる場所間違っていましたら申し訳ありません。
主題の件でご質問があります。

【概要】
サーバ(WindowsServer2003)にログインして共有メモリ(CreateFileMapping)の作成を行います。
次にMapViewOfFileした後に何かしらのデータを書き込みます。
そこでクライアント(試験ではXP)のパソコンよりリモートデスクトップでサーバへ
接続&ログインを行います。(試験ではサーバのログインユーザと同じものでログイン)
リモートデスクトップの中で共有メモリーをOpenFileMapping→MapViewOfFileして
サーバで書き込んだデータを参照したい。
リモートデスクトップなので実際にはクライアントもサーバのメモリ上で動作している
という考えで実装を行っています。

【質問】
そもそもリモートデスクトップで入ったユーザーでプロセスを起動した場合、サーバ側の共有メモリを
参照すること(ユーザー間で参照)はできるのでしょうか?
windows98のころは共有メモリ(CreateFileMapping)で作成されるアドレスはどのプロセスでも同じアドレスで
参照できたようです。(http://techtips.belution.com/ja/vc/0001/)
なので今回もいけるかなと思ったのですが、NT系はどうも違うようなのですが。。。(勉強不足です)
サンプルでは同じ名前"GlobalTEST"でCreateFileMappingおよびOpenFileMappingをしますが、
そうもリモートデスクトップのクライアント側ではサーバで作成した"GlobalTEST"をOpenFileMappingできていません。
なのでそれぞれ新規に"GlobalTEST"でCreateFileMappingをしてしまっています。
オープンの仕方が悪いのか?生成の仕方が悪いのか?はたまた根本的にやり方が間違っているのか
ぜひ皆さんのご意見をお願い致します。


---[サーバ]--------------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>

main()
{
int cnt1;
int cnt2;
char buff[1000];
HANDLE hFileMapping; // マッピングオブジェクト のハンドル
void *pLocalShared; // ファイルがマップされたビューの開始アドレス
char buf[4] = "TEST";
char name[50];

// 共有メモリ名称作成
memset(&name, 0, sizeof(name));
memcpy(&name, "Global", sizeof(name));
strcat(name, buf);

// 共有メモリをまずはopenする
hFileMapping = OpenFileMapping(PAGE_READWRITE, FALSE, name);
if(hFileMapping == NULL)
{
// 共有メモリがない場合createする
hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(buff), name);
}

for(cnt1=0; cnt1<100; cnt1++)
{
// マップする
pLocalShared = (void*)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);

// 定周期で共有メモリへ書き込む
Sleep(3000);
memset(buff,0,sizeof(buff));
for(cnt2=0; cnt2<cnt1; cnt2++)
{
strcat(buff,"1");
}

// 書き込んだ結果を表示する
memcpy(pLocalShared, buff, sizeof(buff));
printf("%s\n",pLocalShared);

// アンマップする
UnmapViewOfFile(pLocalShared);
//CloseHandle(hFileMapping);
}
}


---[クライアント]--------------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>

main()
{
int cnt1;
char buff[1000];
HANDLE hFileMapping; // マッピングオブジェクト のハンドル
void *pLocalShared; // ファイルがマップされたビューの開始アドレス
char buf[4] = "TEST";
char name[50];

// 共有メモリ名称作成
memset(&name, 0, sizeof(name));
memcpy(&name, "Global", sizeof(name));
strcat(name, buf);

// 共有メモリをまずはopenする
hFileMapping = OpenFileMapping(PAGE_READWRITE, FALSE, name);
if(hFileMapping == NULL)
{
// 共有メモリがない場合createする
hFileMapping = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(buff), name);
}

for(cnt1=0; cnt1<100; cnt1++)
{
// マップする
pLocalShared = (void*)MapViewOfFile(hFileMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);

// 定周期で表示する
Sleep(3000);
printf("%s\n",pLocalShared);

// アンマップする
UnmapViewOfFile(pLocalShared);
//CloseHandle(hFileMapping);
}
}

todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2007-08-01 20:32
引用:

サンプルでは同じ名前"GlobalTEST"でCreateFileMappingおよびOpenFileMappingをしますが、



"Global/TEST"では?

OpenFileMapping
http://msdn.microsoft.com/library/ja/jpmemory/html/_win32_openfilemapping.asp
ぱぱまま
会議室デビュー日: 2007/07/31
投稿数: 4
投稿日時: 2007-08-01 20:42
コメントありがとうございます。
ご指摘の箇所は私も気になりまして「/」を入れて確認しました。
ただ結果はかわらずでした。
CreateFileしてファイル経由でCreateFileMappingする方法は
何とか実装できましたが、共有メモリじゃないですよね、ファイルって…。
そんなに遅くならないならそれでもいいかなと諦め状態です(涙)
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-08-01 21:19
引用:

ぱぱままさんの書き込み (2007-08-01 20:42) より:
CreateFileしてファイル経由でCreateFileMappingする方法は
何とか実装できましたが、共有メモリじゃないですよね、ファイルって…。


いいえ、それも共有ファイルですよ。任意の仮想メモリファイルを共有メモリにマップして利用するか、規定の仮想メモリファイルを共有メモリとしてマップするかの違いでしかありません。どちらもパフォーマンス的には差はないですよ。

「出来ません。」じゃなくてどんなエラーになったのかエラーコードくらい書きなさい。おそらくアクセス権関係のエラーじゃないですか?別のユーザー空間に属する名前つきオブジェクトを操作するためには、アクセス権の操作が必要なはずですので。

ファイル名を指定すればOKなのは、ファイルに対するアクセス権で処理されるからでしょう。
ぱぱまま
会議室デビュー日: 2007/07/31
投稿数: 4
投稿日時: 2007-08-01 21:36
甕星さんコメントありがとうです。
共有ファイルであることは分かったのですが、なるほど、マッピングするってことは
「共有メモリ」と解釈していいんですね。ありがとうございます、一安心。

そして「…じゃなくてどんなエラーになったのか…」の件ですが、
言葉が足りずすみません、エラーにならないんです。
単にサーバーでCreateFileMappingした"Global/TEST"をリモートデスクトップログイン
側でOpenFileMappingできない(つまりは名前付ファイルを認識できていない)ようです。
あっそうか、それがエラーなのか…。戻り値のhFileMappingがオール0です。
その後のCreateFileMappingの処理が走りますがまったく同じ名前で生成できてしまいます。
ユーザーが違うからでしょうか。。。

コメントいただけるとすごく安心します。どうもです。
1

スキルアップ/キャリアアップ(JOB@IT)