PDA

View Full Version : گفتگو: کار با Registry در MFC



zahmatkesh8519
چهارشنبه 31 خرداد 1391, 13:37 عصر
در رجیستری ولیو ها نوع هایی مختلفی دارند . یکی از این نوع ها REG_BINARY می باشد .
برای دریافت این مقدار از متغییر از نوع CString استفاده می شود .
تکه کد زیر در صورتی که نوع Value این نوع باشد آن را در MessageBox نمایش می دهد .
البته مقدماتی هم دارد که از آوردنش اجتناب کردم .
حالا کاراکتر هایی که نمایش می دهد دارای کاراکتر های اضافی "cd" یا "cdcd" می باشد .

چطور خروجی درست را می توان بدست آورد ؟

نمونه کد :
CString TempCSt;
if (type == REG_BINARY) //get Binary DAta Keys
{

ULONG length=0;
CRegKey key;
SubKeyCString = L"HKEY_USERS\\.DEFAULT\\.A";
if(ERROR_SUCCESS == key.Open(hkeySrcRoot, NULL , KEY_READ))
{
// read the value, length will contain the size after the call
if (ERROR_SUCCESS != key.QueryBinaryValue(&ValueName[0], &ValueData, &length))
{
CString strRet;
for (int i = 0; i < (int) length ; i++)
{
CString str;
//str.Format(L"%c", ValueData[i]);
str= ValueData[i];
//if (str != L"cdcd" )
strRet += str;
}
AfxMessageBox(strRet);

// error occurred
length = 0;

}

}
}

در برنامه های نمایش داده های فایل به صورت HEX یا در هنگام نمایش Value هایی از این نوع داده ها به دو نحود ( در تصویر زیر می بینید ) نمایش داده می شود . اگر درست بگویم سمت راستی رشته و سمت چپی رشته های معادل آن است .
چطور می توان ضمن دستیابی که متن Hex متن معادل CString آن را نیز برست آورد ؟

mehdi.mousavi
پنج شنبه 01 تیر 1391, 00:24 صبح
سلام.
کدی که نوشته اید ایرادهای فراوانی داره، اما مهمترینش نحوه آدرس کردن HKEY_USERS هستش. من کد شما رو از نو نوشتم:


ULONG length = 0;

CRegKey key;
if(key.Open(HKEY_USERS, _T(".DEFAULT\\.A"), KEY_READ) != ERROR_SUCCESS)
return;

LPCTSTR lpNameValue = _T("x");
if (key.QueryBinaryValue(lpNameValue, NULL, &length) != ERROR_SUCCESS)
return;

BYTE *p = new BYTE[length + 1];

CString str;
if (key.QueryBinaryValue(lpNameValue, p, &length) == ERROR_SUCCESS)
{
for(int i = 0; i < length; i++)
str.AppendFormat(_T("%c"), p[i]);
}

delete[] p;


موفق باشید.

پاورقی: دقت کنید، اولین Call ام به QueryBinaryValue چون پارامتر دومش NULL هستش، فقط طول اون کلید رو بهم برمیگردونه، در نتیجه میتونه یه ضرب داده ها رو بخونم. اگر اینکارو نکنم، ممکنه ERROR_MORE_DATA برگرده و ... بنابراین من ابتدا اونو با پارامتر NULL فراخوانی میکنم، اندازه اش رو که فهمیدم، از heap به اون میزان حافظه Allocate میکنم و سپس با فراخوانی مججد اون متود، داده های Binary موجود در کلید رو میخونم.

zahmatkesh8519
پنج شنبه 01 تیر 1391, 16:24 عصر
تشکر آقای موسوی .
الان درست شد ممنونم .

یه سوال : چون آدرس کلید ها رو نمی تونم بدم ، از تابع ShRegGetPath برای بدست آوردن آدرس هر کلید استفاده کردم .
پارامتر های این تابع به صورت زیر هست :
LSTATUS SHRegGetPath(
__in HKEY hkey,
__in LPCTSTR pszSubkey,
__in LPCTSTR pszValue,
__out LPTSTR pszPath,
DWORD dwFlags
);

Parameters

hkey [in]
Type: HKEY

A handle to a key that is currently open, or a registry root key.

pszSubkey [in]
Type: LPCTSTR

A pointer to a null-terminated string that contains the name of the subkey.

pszValue [in]
Type: LPCTSTR

A pointer to a null-terminated string that contains the name of the value that holds the unexpanded path string.

pszPath [out]
Type: LPTSTR

A buffer to hold the expanded path. You should set the size of this buffer to MAX_PATH to ensure that it is large enough to hold the returned string.

dwFlags
Type: DWORD

Reserved.

Return value

Type: LSTATUS

Returns ERROR_SUCCESS if successful, or a Windows error code otherwise.
اینم کدی هست که برای استفادش اجراش کردم ، پارامتر سوم رو متوجه نشدم چی باید بدم ، مشکلش کجاست؟


TCHAR pszPath[MAX_PATH];
DWORD result = SHRegGetPath( hkeySrcRoot,ValueName,L"q",pszPath,0);

if (result != ERROR_SUCCESS)
{
/* handle error */
}

الان بجای پارامتر سوم باید نام ولیو رو بدم؟!

zahmatkesh8519
پنج شنبه 01 تیر 1391, 16:38 عصر
در کتاب the managing windows 2000 registry از انتشارات O'reilly درباره این تابع صحبت کرده ولی باز این پارامتر رو جا انداخته!
برای دسترسی آن لاینبه کتاب به این لینک (http://anselmo.homeunix.net/ebooks/mwin2reg/main.html) سر بزنین و برای دیدن بخشی از کتاب که در این باره داره صحبت می کنه این لینک (http://anselmo.homeunix.net/ebooks/mwin2reg/ch08-87338.html#ch08-40382) رو ببینین و در اون به دنبال کلمه SHRegGetPath لینک[/URL] رو ببینین و در اون به دنبال کلمه SHRegGetPath (یا SHRegSetPath) بگردین .
-----
الان دیدم که این تابع کارش چیز دیگه ای هست .
SHRegGetPath
Retrieves a file path from the registry, expanding environment variables as needed.

این هم یه نمونه کد ، از این تابع برای کسی که بعدا سرچ می کنه :
TCHAR pszPath[MAX_PATH]=L"D:\\ss.txt"; // Buffer is properly sized
DWORD result = SHRegGetPath( hkeySrcRoot,ValueName,L"q" ,pszPath,0);
if (result == ERROR_SUCCESS)
{
Keyaddress = pszPath ;
}
else if (result != ERROR_SUCCESS)
{
/* handle error */
}