TNB Library
TnbRegistryAccessor.h
[詳解]
1#pragma once
11#include "TnbAccessor.h"
12#include "TnbDntStr.h"
13
14
15
16#ifndef _TnbDOXYGEN //Document作成用シンボル
17 #ifndef REG_QWORD
18 #define REG_QWORD (11) // 64-bit number
19 #endif
20#endif
21
22
23
24//TNB Library
25namespace TNB
26{
27
28
29
30#ifndef _TnbDOXYGEN //Document作成用シンボル
32struct TPhRegCloseKey
33{
34 void operator()(HKEY P) { ::RegCloseKey(P); }
35};
36#endif
37
38
39
53
54
55
85{
86 DEFSUPER(CAbstractAccessor);
87public:
88
94 explicit CRegistryAccessor(const CRegKeyHandle& hhParentKey, REGSAM dwRegSam = KEY_ALL_ACCESS)
95 : m_hhParentKey(hhParentKey), m_dwRegSam(dwRegSam)
96 {
97 }
98
105 CRegistryAccessor(const CRegKeyHandle& hhParentKey, LPCTSTR lpszSectionName, REGSAM dwRegSam = KEY_ALL_ACCESS)
106 {
107 CRegistryAccessor rg(hhParentKey, dwRegSam);
108 m_hhParentKey = rg.GetHandle(lpszSectionName);
109 m_dwRegSam = dwRegSam;
110 }
111
115 virtual ~CRegistryAccessor(void)
116 {
117 }
118
125 void SetBase(const CRegKeyHandle& hhParentKey)
126 {
127 m_hhParentKey = hhParentKey;
128 m_strSection.Empty();
129 m_hhKey.Null();
130 }
131
136 const CRegKeyHandle& GetBase(void) const
137 {
138 return m_hhParentKey;
139 }
140
146 bool IsValid(void) const
147 {
148 HKEY h = m_hhParentKey;
149 return h != NULL;
150 }
151
157 const CRegKeyHandle& GetHandle(LPCTSTR lpszSectionName) const
158 {
159 m_SetSectionName(lpszSectionName);
160 m_Create();
161 return m_hhKey;
162 }
163
168 virtual CStr GetTypeName(void) const
169 {
170 return _T("Registry");
171 }
172
179 virtual bool Flush(void)
180 {
181 if ( m_hhKey.IsNull() )
182 {
183 return false;
184 }
185 return ::RegFlushKey(m_hhKey) == ERROR_SUCCESS;
186 }
187
193 virtual CStrVector EnumSectionNames(LPCTSTR lpszSectionName = NULL) const
194 {
195 if ( lpszSectionName == NULL || *lpszSectionName == 0 )
196 {
197 return m_EnumSections(m_hhParentKey);
198 }
199 m_SetSectionName(lpszSectionName);
200 if ( m_Open() != 0 )
201 {
202 return CStrVector();
203 }
204 return m_EnumSections(m_hhKey);
205 }
206
213 virtual bool DeleteSection(LPCTSTR lpszSectionName)
214 {
215 m_Close();
216 DWORD r = ms_RegDeleteKeyNT(m_hhParentKey, lpszSectionName);
217 ::SetLastError(r);
218 return r == ERROR_SUCCESS;
219 }
220
227 virtual CStrVector EnumKeyNames(LPCTSTR lpszSectionName) const
228 {
229 m_SetSectionName(lpszSectionName);
230 CStrVector vstrRc;
231 if ( m_Open() != 0 )
232 {
233 return vstrRc;
234 }
235 LONG lRc;
236 DWORD dwIndex = 0;
237 CStr strName;
238 DWORD dwNameLength;
239 while ( true )
240 {
241 dwNameLength = E_BufferSize;
242 lRc = ::RegEnumValue(
243 m_hhKey, // 問い合わせ対象のキーのハンドル
244 dwIndex, // 取得するべきレジストリエントリのインデックス番号
245 strName.GetBuffer(dwNameLength),
246 // レジストリエントリ名が格納されるバッファ
247 &dwNameLength, // レジストリエントリ名バッファのサイズ
248 0, // 予約済み
249 NULL, // レジストリエントリのデータのタイプ
250 NULL, // レジストリエントリのデータが格納されるバッファ
251 NULL // データバッファのサイズ
252 );
253 strName.ReleaseBuffer();
254 if ( lRc == ERROR_NO_MORE_ITEMS )
255 {
256 break;
257 }
258 if ( lRc != ERROR_SUCCESS )
259 {
260 vstrRc.Invalid();
261 return vstrRc;
262 }
263 vstrRc.Add(strName);
264 dwIndex++;
265 }
266 return vstrRc;
267 }
268
275 virtual EKind GetKeyKind(LPCTSTR lpszSectionName, LPCTSTR lpszKey) const
276 {
277 m_SetSectionName(lpszSectionName);
278 if ( m_Open() != 0 )
279 {
280 return EK_Nothing;
281 }
282 DWORD dwType;
283 DWORD dwLength;
284 LONG lRc = ::RegQueryValueEx(
285 m_hhKey, // キーのハンドル
286 lpszKey, // レジストリエントリ名
287 NULL, // 予約済み
288 &dwType, // データ型が格納されるバッファ
289 NULL, // データが格納されるバッファ
290 &dwLength // データバッファのサイズ
291 );
292 EKind eKind = EK_Nothing;
293 if ( lRc == ERROR_SUCCESS )
294 {
295 switch ( dwType )
296 {
297 case REG_QWORD:// 64 ビット値
298 eKind = EK_Longlong;
299 break;
300 case REG_DWORD:// 32 ビット値
301 eKind = EK_Dword;
302 break;
303 case REG_MULTI_SZ:// NULL で終わる複数の文字列からなる 1 つの配列
304 eKind = EK_PluralStrings;
305 break;
306 case REG_EXPAND_SZ:// 環境変数の展開前の表記("%PATH%" など)を保持している、NULL で終わる文字列
307 eKind = EK_String;
308 break;
309 case REG_SZ:// NULL で終わる文字列
310 eKind = EK_String;
311 break;
312 case REG_BINARY:// Free form binary
313 eKind = EK_Binary;
314 break;
315 }
316 }
317 return eKind;
318 }
319
326 virtual CValue QueryValue(LPCTSTR lpszSectionName, LPCTSTR lpszKey) const
327 {
328 CValue v;
329 DWORD dwGetType;
330 CByteVector vb;
331 switch ( GetKeyKind(lpszSectionName, lpszKey) )
332 {
333 case EK_Nothing://存在しない
334 break;
335 case EK_String://文字列
336 vb = m_Query(lpszKey, REG_SZ, REG_EXPAND_SZ, &dwGetType);
337 if ( vb.IsValid() )
338 {
339 CStr str = reinterpret_cast<LPCTSTR>(vb.ReferBuffer());
340 #ifndef _WIN32_WCE
341 if ( dwGetType == REG_EXPAND_SZ )
342 {
343 // 環境変数の展開前の表記("%PATH%" など)を保持している、NULL で終わる文字列
344 DWORD l = ::ExpandEnvironmentStrings(str, NULL, 0);
345 if ( l > 0 )
346 {
347 CStr s;
348 ::ExpandEnvironmentStrings(str, s.GetBuffer(l + 1), l + 1);
349 s.ReleaseBuffer();
350 str = s;
351 }
352 }
353 #endif
354 v = CValue(str);
355 }
356 break;
357 case EK_PluralStrings://複数の文字列群
358 vb = m_Query(lpszKey, REG_MULTI_SZ, REG_MULTI_SZ);
359 if ( vb.IsValid() )
360 {
362 dntstr.SetDntStr(reinterpret_cast<LPCTSTR>(vb.ReferBuffer()));
363 v = CValue(dntstr.ToStrVector());
364 }
365 break;
366 case EK_Binary://バイナリ
367 vb = m_Query(lpszKey, REG_BINARY, REG_BINARY);
368 if ( vb.IsValid() )
369 {
370 v = CValue(vb);
371 }
372 break;
373 case EK_Dword://32Bit Unsigned Integer
374 vb = m_Query(lpszKey, REG_DWORD, REG_DWORD);
375 if ( vb.IsValid() )
376 {
377 ASSERTLIB(sizeof(DWORD) == vb.GetSize());
378 v = CValue(*(reinterpret_cast<const DWORD*>(vb.ReferBuffer())));
379 }
380 break;
381 case EK_Longlong://64Bit Signed Integer
382 vb = m_Query(lpszKey, REG_QWORD, REG_QWORD);
383 if ( vb.IsValid() )
384 {
385 ASSERTLIB(sizeof(LONGLONG) == vb.GetSize());
386 v = CValue(*(reinterpret_cast<const LONGLONG*>(vb.ReferBuffer())));
387 }
388 break;
389 default:
390 ASSERT(false);
391 break;
392 }
393 return v;
394 }
395
404 virtual bool WriteValue(LPCTSTR lpszSectionName, LPCTSTR lpszKey, const IAccessor::CValue& value)
405 {
406 m_SetSectionName(lpszSectionName);
407 bool r = false;
408 switch ( value.GetKind() )
409 {
410 case EK_Nothing://存在しない
411 r = m_Delete(lpszKey);
412 break;
413 case EK_String://文字列
414 {
415 CStr s = value.QueryString();
416 r = m_Write(lpszKey, REG_SZ, LPCTSTR(s), (s.GetLength() + 1) * sizeof(TCHAR));
417 }
418 break;
419 case EK_PluralStrings://複数の文字列群
420 {
422 dntstr.Set(value.QueryPluralStrings());
423 r = m_Write(lpszKey, REG_MULTI_SZ, LPCTSTR(dntstr), ToDword(dntstr.GetSize()) * sizeof(TCHAR));
424 }
425 break;
426 case EK_Binary://バイナリ
427 {
428 const CByteVector& vb = value.QueryData();
429 r = m_Write(lpszKey, REG_BINARY, vb.ReferBuffer(), ToDword(vb.GetSize()));
430 }
431 break;
432 case EK_Dword://32Bit Unsigned Integer
433 {
434 DWORD dw = value.QueryDword();
435 r = m_Write(lpszKey, REG_DWORD, &dw, sizeof(DWORD));
436 }
437 break;
438 case EK_Longlong://64Bit Signed Integer
439 {
440 LONGLONG ll = value.QueryLonglong();
441 r = m_Write(lpszKey, REG_QWORD, &ll, sizeof(LONGLONG));
442 }
443 break;
444 default:
445 ASSERT(false);
446 break;
447 }
448 return r;
449 }
450
451private:
452 enum { E_BufferSize = 1024 };
453 REGSAM m_dwRegSam;
454 mutable CRegKeyHandle m_hhParentKey;
455 mutable CStr m_strSection;
456 mutable CRegKeyHandle m_hhKey;
458 void m_Close(void) const
459 {
460 m_hhKey.Null();
461 }
467 LONG m_Create(void) const
468 {
469 if ( m_Open() == 0 )
470 {
471 return 0;
472 }
473 HKEY hKey;
474 DWORD dwDisposition;
475 LONG lRc = ::RegCreateKeyEx(
476 m_hhParentKey, // 開いている親キーのハンドル
477 m_strSection, // 開くべきサブキーの名前
478 0, // 予約済み
479 NULL, // クラス名
480 0, // 特別なオプション
481 m_dwRegSam, // セキュリティアクセスマスク
482 NULL, // 継承の指定
483 &hKey, // [out] 開くことに成功したサブキーのハンドル
484 &dwDisposition // [out] 既存かどうか示す値
485 );
486 if ( lRc == ERROR_SUCCESS )
487 {
488 m_hhKey = hKey;
489 }
490 else
491 {
492 m_hhKey.Null();
493 }
494 return lRc;
495 }
501 LONG m_Open(void) const
502 {
503 if ( ! m_hhKey.IsNull() )
504 {
505 return 0;
506 }
507 HKEY hKey;
508 LONG lRc = ::RegOpenKeyEx(
509 m_hhParentKey, // 開いている親キーのハンドル
510 m_strSection, // 開くべきサブキーの名前
511 0, // 予約済み
512 m_dwRegSam, // セキュリティアクセスマスク
513 &hKey // 開くことに成功したサブキーのハンドル
514 );
515 if ( lRc == ERROR_SUCCESS )
516 {
517 m_hhKey = hKey;
518 }
519 else
520 {
521 m_hhKey.Null();
522 }
523 return lRc;
524 }
526 void m_SetSectionName(LPCTSTR lpszSectionName) const
527 {
528 if ( m_strSection != lpszSectionName )
529 {
530 m_Close();
531 m_strSection = lpszSectionName;
532 }
533 }
538 CStrVector m_EnumSections(HKEY hKey) const
539 {
540 CStrVector vstrRc;
541 LONG lRc;
542 DWORD dwIndex = 0;
543 CStr strName;
544 DWORD dwNameLength;
545 FILETIME tFileTime;
546 while ( true )
547 {
548 dwNameLength = E_BufferSize;
549 lRc = ::RegEnumKeyEx(
550 hKey, // 列挙するべきキーのハンドル
551 dwIndex, // サブキーのインデックス番号
552 strName.GetBuffer(dwNameLength + 1),
553 // サブキー名が格納されるバッファ
554 &dwNameLength, // サブキー名バッファのサイズ
555 NULL, // 予約済み
556 NULL, // クラス名が格納されるバッファ
557 NULL, // クラス文字列バッファのサイズ
558 &tFileTime // 最終書き込み時刻
559 );
560 strName.ReleaseBuffer();
561 if ( lRc == ERROR_NO_MORE_ITEMS )
562 {
563 break;
564 }
565 if ( lRc != ERROR_SUCCESS )
566 {
567 vstrRc.Invalid();
568 return vstrRc;
569 }
570 vstrRc.Add(strName);
571 dwIndex++;
572 }
573 return vstrRc;
574 }
583 CByteVector m_Query(LPCTSTR lpszKey, DWORD dwTyp1, DWORD dwTyp2, DWORD* _pdwGetType = NULL) const
584 {
585 CByteVector vbResult;
586 if ( m_Open() != 0 )
587 {
588 vbResult.Invalid();
589 return vbResult;
590 }
591 DWORD dwType;
592 DWORD dwLength;
593 LONG lRc = ::RegQueryValueEx(
594 m_hhKey, // キーのハンドル
595 lpszKey, // レジストリエントリ名
596 NULL, // 予約済み
597 &dwType, // データ型が格納されるバッファ
598 NULL, // データが格納されるバッファ
599 &dwLength // データバッファのサイズ
600 );
601 if ( lRc != ERROR_SUCCESS )
602 {
603 vbResult.Invalid();
604 return vbResult;
605 }
606 if ( _pdwGetType != NULL )
607 {
608 *_pdwGetType = dwType;
609 }
610 if ( dwType != dwTyp1 && dwType != dwTyp2 )
611 {
612 vbResult.Invalid();
613 return vbResult;
614 }
615 if ( dwLength > 0 )
616 {
617 lRc = ::RegQueryValueEx(
618 m_hhKey, // キーのハンドル
619 lpszKey, // レジストリエントリ名
620 NULL, // 予約済み
621 &dwType, // データ型が格納されるバッファ
622 vbResult.GetBuffer(dwLength), // データが格納されるバッファ
623 &dwLength // データバッファのサイズ
624 );
625 vbResult.ReleaseBuffer();
626 if ( lRc != ERROR_SUCCESS )
627 {
628 vbResult.Invalid();
629 }
630 }
631 return vbResult;
632 }
642 bool m_Write(LPCTSTR lpszKey, DWORD dwTyp, LPCVOID lpcData, size_t dwLen)
643 {
644 LONG lRc = 0xFFFFFFFF;
645 if ( m_Create() == 0 )
646 {
647 lRc = ::RegSetValueEx(m_hhKey, lpszKey, NULL, dwTyp, static_cast<const BYTE*>(lpcData), ToDword(dwLen));
648 }
649 return (lRc == ERROR_SUCCESS);
650 }
657 bool m_Delete(LPCTSTR lpszKey)
658 {
659 LONG lRc = 0xFFFFFFFF;
660 if ( m_Open() == 0 )
661 {
662 lRc = ::RegDeleteValue(m_hhKey, lpszKey);
663 }
664 return lRc == ERROR_SUCCESS;
665 }
673 static DWORD ms_RegDeleteKeyNT(HKEY hStartKey , LPCTSTR pKeyName)
674 {
675 DWORD dwRtn = 0;
676 const int MAX_KEY_LENGTH = 256;
677 CWorkMemT<TCHAR> subKey(MAX_KEY_LENGTH); // (256) this should be dynamic.
678 HKEY hKey = NULL;
679 if ( pKeyName != NULL && STRLIB::GetLen(pKeyName) > 0 )
680 {
681 dwRtn = ::RegOpenKeyEx(hStartKey, pKeyName, 0, KEY_ENUMERATE_SUB_KEYS | DELETE, &hKey);
682 if ( dwRtn == ERROR_SUCCESS )
683 {
684 while ( dwRtn == ERROR_SUCCESS )
685 {
686 DWORD dwSubKeyLength = MAX_KEY_LENGTH;
687 dwRtn = ::RegEnumKeyEx(
688 hKey,
689 0, // always index zero
690 subKey,
691 &dwSubKeyLength,
692 NULL,
693 NULL,
694 NULL,
695 NULL
696 );
697 if ( dwRtn == ERROR_NO_MORE_ITEMS )
698 {
699 ::RegCloseKey(hKey);
700 hKey = NULL;
701 dwRtn = ::RegDeleteKey(hStartKey, pKeyName);
702 break;
703 }
704 else if ( dwRtn == ERROR_SUCCESS )
705 {
706 dwRtn = ms_RegDeleteKeyNT(hKey, subKey);
707 }
708 }
709 if ( hKey != NULL )
710 {
711 ::RegCloseKey(hKey);
712 hKey= NULL;
713 }
714 }
715 }
716 else
717 {
718 dwRtn = ERROR_BADKEY;
719 }
720 return dwRtn;
721 }
722};
723
724
725
726}; // TNB
情報アクセス関係のヘッダ
Double Null Terminate(DNT)型文字列操作関係のヘッダ
情報アクセス抽象クラス.
Definition: TnbAccessor.h:967
Double Null Terminate(DNT)型文字列管理
Definition: TnbDntStr.h:61
void Set(LPCTSTR lpszStr)
[設定] 代入
Definition: TnbDntStr.h:141
size_t GetSize(void) const
[取得] DNT型文字列数種特
Definition: TnbDntStr.h:213
void SetDntStr(LPCTSTR lpszzDntStr, TCHAR tcSepaChar=0)
[設定] 代入
Definition: TnbDntStr.h:109
CStrVector ToStrVector(void) const
[取得] 文字列配列取得.
Definition: TnbDntStr.h:223
bool IsNull(void) const
[確認] NULLチェック
void Null(void)
[設定] 開放.
レジストリアクセスクラス
virtual CStr GetTypeName(void) const
[取得] タイプ名取得
virtual bool Flush(void)
[操作] フラッシュ.
virtual CStrVector EnumKeyNames(LPCTSTR lpszSectionName) const
[取得] 名前一覧取得
bool IsValid(void) const
[取得] 有効確認.
virtual bool WriteValue(LPCTSTR lpszSectionName, LPCTSTR lpszKey, const IAccessor::CValue &value)
[設定] 情報設定
CRegistryAccessor(const CRegKeyHandle &hhParentKey, REGSAM dwRegSam=KEY_ALL_ACCESS)
コンストラクタ
const CRegKeyHandle & GetHandle(LPCTSTR lpszSectionName) const
[取得] 対象ハンドル取得
void SetBase(const CRegKeyHandle &hhParentKey)
[設定] ベース指定
virtual bool DeleteSection(LPCTSTR lpszSectionName)
[削除] 指定セクション削除
const CRegKeyHandle & GetBase(void) const
[取得] 親ハンドル取得
virtual CValue QueryValue(LPCTSTR lpszSectionName, LPCTSTR lpszKey) const
[取得] 情報取得
virtual EKind GetKeyKind(LPCTSTR lpszSectionName, LPCTSTR lpszKey) const
[取得] 情報取種取得
CRegistryAccessor(const CRegKeyHandle &hhParentKey, LPCTSTR lpszSectionName, REGSAM dwRegSam=KEY_ALL_ACCESS)
コンストラクタ
virtual ~CRegistryAccessor(void)
デストラクタ
virtual CStrVector EnumSectionNames(LPCTSTR lpszSectionName=NULL) const
[取得] セクション名一覧取得
void ReleaseBuffer(void)
[操作] 割り当てたバッファを開放.
Definition: TnbStr.h:954
size_t GetLength(void) const
[取得] 文字列長
Definition: TnbStr.h:518
void Empty(void)
[削除] 空化
Definition: TnbStr.h:197
TYP * GetBuffer(size_t iLength=0)
[操作] 書き込みバッファ要求.
Definition: TnbStr.h:914
virtual size_t GetSize(void) const
[取得] サイズ取得
Definition: TnbVector.h:368
TYP * GetBuffer(size_t size=0)
[操作] データアドレス取得
Definition: TnbVector.h:745
void ReleaseBuffer(void)
[操作] データの管理を元に戻す.
Definition: TnbVector.h:805
void Invalid(void)
[操作] 無効状態にする
Definition: TnbVector.h:604
bool IsValid(void) const
[確認] 有効チェック
Definition: TnbVector.h:687
virtual const TYP * ReferBuffer(void) const
[取得] データアドレス取得
Definition: TnbVector.h:664
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
Definition: TnbVector.h:383
情報アクセスの汎用値保持クラス.
Definition: TnbAccessor.h:100
CStr QueryString(void) const
[取得] 文字列情報取得
Definition: TnbAccessor.h:185
LONGLONG QueryLonglong(void) const
[取得] 数値情報取得
Definition: TnbAccessor.h:253
CByteVector QueryData(void) const
[取得] バイナリ情報取得
Definition: TnbAccessor.h:229
DWORD QueryDword(void) const
[取得] 数値情報取得
Definition: TnbAccessor.h:243
CStrVector QueryPluralStrings(void) const
[取得] 文字列群情報取得
Definition: TnbAccessor.h:214
EKind GetKind(void) const
[取得] 情報取種取得
Definition: TnbAccessor.h:171
TNB::CPointerHandleBaseT< HKEY, TPhRegCloseKey > CRegKeyHandle
HKEY型ハンドルテンプレート
TNB::CVectorT< CStr > CStrVector
文字列配列管理クラス
Definition: TnbStrVector.h:31
size_t GetLen(LPCSTR lpsz)
[計算] 文字列長計算(ASCII/SJIS用)
Definition: TnbStrLib.h:44
DWORD ToDword(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:395
TNB Library
Definition: TnbDoxyTitle.txt:2
ファイルタイム型.
Definition: TnbTime.h:893
EKind
値型の種類.
Definition: TnbAccessor.h:80
@ EK_String
文字列
Definition: TnbAccessor.h:82
@ EK_Binary
バイナリ
Definition: TnbAccessor.h:84
@ EK_Dword
32Bit Unsigned Integer
Definition: TnbAccessor.h:85
@ EK_PluralStrings
複数の文字列群
Definition: TnbAccessor.h:83
@ EK_Nothing
存在しない
Definition: TnbAccessor.h:81
@ EK_Longlong
64Bit Signed Integer
Definition: TnbAccessor.h:86