レジストリ操作について教えてください

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
K.S

レジストリ操作について教えてください

#1

投稿記事 by K.S » 12年前

VC++2010
C言語
Win32API

ユーザー情報を登録するのにレジストリを使用したいと思っています。
ログイン用ダイアログのコールバック関数で

switch(msg)
{
case WM_INITDIALOG:
RegOpenKeyEx(HKEY_CURRENT_USER,TEXT("Software\\ソフト名"),0,KEY_ALL_ACCESS,&hkey);
name = "login_mail";
RegQueryValueEx(hkey,name,NULL,&dwType,(LPBYTE)(LPCTSTR)&data,&dwSize);
if(data)
{
strcpy(szBuf_mail,(LPCSTR)&data);
SetDlgItemText(hwnd,MAIL,(LPSTR)szBuf_mail);
}
省略

このように書き、ログイン用ダイアログ作成と同時にレジストリに登録情報があるかを見に行き、
情報が存在すればログインフォームのエディトボックスに投入されるようにしています。

次にログインフォームですが、

case WM_COMMAND:
switch(LOWORD(wp))
{
case ID_LOGIN://ログインボタン
GetDlgItemText(hwnd,ID_MAIL,(LPSTR)szBuf_mail,(int)sizeof(szBuf_mail));

RegOpenKeyEx(HKEY_CURRENT_USER,TEXT("Software\\ソフト名"),0,KEY_ALL_ACCESS,&hkey);

name = "login_mail";
RegSetValueEx(hkey,name,0,REG_SZ,(LPCSTR)szBuf_mail,(int)sizeof(szBuf_mail));

login_flag = LOGIN();
break;
}

レジストリに既に情報が登録されてようが、されてまいがレジストリに新しく情報登録させるようにしています。


1.レジストリに手動で書き込みしたあとにログイン用ダイアログを開くとフォームのエディトボックスに自動で登録情報が投入されます。
2.レジストリに書き込みがされてない状態でログイン用ダイアログを開くとフォームのエディトボックスには投入されていません。
3.フォームに自動投入されたり、手動で新しく入力してログインボタンを押すとレジストリに登録情報が書き込まれます。
4.レジストリにソフトで書き込みをしたあとにログイン用ダイアログを開くとエラーも何も出ずにソフトが終了してしまします。

質問はこの4番の部分の原因と対策を教えてほしいです。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: レジストリ操作について教えてください

#2

投稿記事 by softya(ソフト屋) » 12年前

codeタグをご利用下さい。ソースコードが見やすくなります。
http://dixq.net/board/board.html#k10
プレビューで表示を確認していただくとミスをする危険が減ります。

気になるのは、RegOpenKeyExなどの戻り値を確認していないのでエラーになっているのでは?と疑っています。
あとレジストリキーもない新規だとレジストリに書き込みが出来ていない気がするんですが、本当に出来ていますでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

K.S

Re: レジストリ操作について教えてください

#3

投稿記事 by K.S » 12年前

softya(ソフト屋) さんが書きました:codeタグをご利用下さい。ソースコードが見やすくなります。
http://dixq.net/board/board.html#k10
プレビューで表示を確認していただくとミスをする危険が減ります。

気になるのは、RegOpenKeyExなどの戻り値を確認していないのでエラーになっているのでは?と疑っています。
あとレジストリキーもない新規だとレジストリに書き込みが出来ていない気がするんですが、本当に出来ていますでしょうか?
ご指摘ありがとうございます。

レジストリキーはその前の段階で作成しています。
書き込みはレジストリエディタで書き込まれているのを確認済みです。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: レジストリ操作について教えてください

#4

投稿記事 by みけCAT » 12年前

変数dataの型は何ですか?
&がついているのが怪しい気がします。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: レジストリ操作について教えてください

#5

投稿記事 by softya(ソフト屋) » 12年前

ステップ実行とかはされていますか? どこで抜けてしまうか確認できると思うのですが。
あと、どうしても分からなければ出来るだけ簡単な再現コードを作ってみて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

K.S

Re: レジストリ操作について教えてください

#6

投稿記事 by K.S » 12年前

みけCAT さんが書きました:変数dataの型は何ですか?
&がついているのが怪しい気がします。
DWORDになっています。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: レジストリ操作について教えてください

#7

投稿記事 by みけCAT » 12年前

IDがID_MAILであるコントロール(おそらくメールの入力欄?)に半角2文字だけ入力し、テストしてみてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: レジストリ操作について教えてください

#8

投稿記事 by softya(ソフト屋) » 12年前

K.S さんが書きました:
みけCAT さんが書きました:変数dataの型は何ですか?
&がついているのが怪しい気がします。
DWORDになっています。
文字列をDWORDで受けていると言うことですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

K.S

Re: レジストリ操作について教えてください

#9

投稿記事 by K.S » 12年前

みけCAT さんが書きました:IDがID_MAILであるコントロール(おそらくメールの入力欄?)に半角2文字だけ入力し、テストしてみてください。
aaaと入力すると期待する結果が得られました。
しかし、自分のメールアドレス(30文字程度)を入力するとエラーも出ずに消えてしまいました。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: レジストリ操作について教えてください

#10

投稿記事 by みけCAT » 12年前

K.S さんが書きました:aaaと入力すると期待する結果が得られました。
しかし、自分のメールアドレス(30文字程度)を入力するとエラーも出ずに消えてしまいました。
予想通りの結果です。
DWORD型は4バイトのことが多いので、どう考えてもバッファが足りません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: レジストリ操作について教えてください

#11

投稿記事 by みけCAT » 12年前

RegQueryValueExを呼ぶ前に、dwSizeに代入している値はいくつですか?もしくは、どういう値を代入していますか?(~関数の戻り値など)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

K.S

Re: レジストリ操作について教えてください

#12

投稿記事 by K.S » 12年前

softya(ソフト屋) さんが書きました:
K.S さんが書きました:
みけCAT さんが書きました:変数dataの型は何ですか?
&がついているのが怪しい気がします。
DWORDになっています。
文字列をDWORDで受けていると言うことですか?
すみません。
別の関数内のdataを見てました。
正しくはLPSTR型です。

K.S

Re: レジストリ操作について教えてください

#13

投稿記事 by K.S » 12年前

みけCAT さんが書きました:RegQueryValueExを呼ぶ前に、dwSizeに代入している値はいくつですか?もしくは、どういう値を代入していますか?(~関数の戻り値など)
関数の戻り値にはしていません。
最初に
DWORD dwType;
としてるだけです。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: レジストリ操作について教えてください

#14

投稿記事 by みけCAT » 12年前

K.S さんが書きました:すみません。
別の関数内のdataを見てました。
正しくはLPSTR型です。
ポインタは、32ビットの環境なら4バイト、64ビットの環境なら8バイトのことが多いと思います。
バッファ不足には変わりありません。
K.S さんが書きました:関数の戻り値にはしていません。
最初に
DWORD dwType;
としてるだけです。
未初期化ですね。
一度RegQueryValueEx関数の仕様を見てみてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: レジストリ操作について教えてください

#15

投稿記事 by softya(ソフト屋) » 12年前

K.S さんが書きました:
softya(ソフト屋) さんが書きました: 文字列をDWORDで受けていると言うことですか?
すみません。
別の関数内のdataを見てました。
正しくはLPSTR型です。
変数名だけで間違いがおきて危険なので、型を表す名前にしたほうが良いですね。
RegQueryValueEx(hkey,name,NULL,&dwType,(LPBYTE)(LPCTSTR)&data,&dwSize);
だとdataがLPSTRだと&dataでポインタのポインタって事になりますので、キャストが強引でかつ&いらないです。
つまり引数の書き方が間違っていて大変危険です。
(LPBYTE)data
で通りませんか?

それとdataがLPSTRだそうですが、ポインタ値は代入済みですか?
ポインタ値が正しい値で、かつ呪文な文字列を受ける大きさの領域のポインタ値じゃないとメモリ破壊をすることになります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

K.S

Re: レジストリ操作について教えてください

#16

投稿記事 by K.S » 12年前

ちょっと気になったのですが、
メールの取得のすぐあとに同じような書き方でパスワードの取得もしています。

コード:

	switch(msg)
	{
		case WM_INITDIALOG:
			RegOpenKeyEx(HKEY_CURRENT_USER,TEXT("Software\\ソフト名"),0,KEY_ALL_ACCESS,&hkey);

			name = "login_mail";
			RegQueryValueEx(hkey,name,NULL,&dwType,(LPBYTE)(LPCTSTR)&data,&dwSize);

			if(data)
			{
				strcpy(szBuf_mail,(LPCSTR)&data);
				SetDlgItemText(hwnd,MAIL,(LPSTR)szBuf_mail);
			}

			name = "login_passwd";
			RegQueryValueEx(hkey,name,NULL,&dwType,(LPBYTE)(LPCTSTR)&data,&dwSize);

			if(data)
			{
				strcpy(szBuf_pass,(LPCSTR)&data);
				SetDlgItemText(hwnd,ID_PASS,(LPSTR)szBuf_pass);
			}

			RegCloseKey(hkey);
書き方はまったく一緒なのですが、メールの取得(ここで言う9~13行目)までをコメントアウトさせるとアプリケーションの終了はなく、
パスワードのエディトボックスの方に値が投入されます。
これはパスワードの長さに関係なく文字列が1文字でも30文字でもエラーにはなりません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: レジストリ操作について教えてください

#17

投稿記事 by softya(ソフト屋) » 12年前

K.S さんが書きました:ちょっと気になったのですが、
メールの取得のすぐあとに同じような書き方でパスワードの取得もしています。

書き方はまったく一緒なのですが、メールの取得(ここで言う9~13行目)までをコメントアウトさせるとアプリケーションの終了はなく、
パスワードのエディトボックスの方に値が投入されます。
これはパスワードの長さに関係なく文字列が1文字でも30文字でもエラーにはなりません。
たまたま動くことも有るので、それは何の保証にもなりません。
確かなことは、必要なバッファを必要なサイズだけ用意してなかったら、どんな動作をするかは保証できないということです。

【補足】あとC言語の文法を正しく使ってないと、も付け加えておきます。ポインタは色々と危険なのです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: レジストリ操作について教えてください

#18

投稿記事 by みけCAT » 12年前

投入された値は本当にレジストリに書き込まれているパスワードですか?
PasswordEyeで調べることができます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

“C言語何でも質問掲示板” へ戻る