Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++ и WinAPI

Войти
Регистрация
Восстановить пароль
 
_arty_
29 / 28 / 1
Регистрация: 10.07.2009
Сообщений: 317
#1

Как читать REG_RESOURCE_LIST значение - C++ WinAPI

12.10.2012, 13:59. Просмотров 955. Ответов 7
Метки нет (Все метки)

Здравствуйте, собственно по сабжу прошу поделиться примером в виду отсутствия таковых на MSDN, вроде бы для этого случая нужна функция RegQueryValueEx, но как я уже говорил - примеров не нашел.
Заранее спасибо!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.10.2012, 13:59
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как читать REG_RESOURCE_LIST значение (C++ WinAPI):

Как читать онлайн текст? - C++ WinAPI
У меня в онлайн приложении, есть окно. Там постоянно непрерывным потоком идет текстовая информация. Я бы хотел ее от туда считывать, для...

Что читать[C++] - C++
Всем привет! Подскажите что почитать самому, самому начинающему по С++

Читать за EOF - C++ WinAPI
Нужно сделать такую штуку: записать в конец .exe программы с помощью hex-редактора информацию, а во время выполнения программа используя...

Как строится ветвление, как читать данные, введённые с клавиатуры, как их потом применять - C++
Здравствуйте, уважаемые программисты! Не могли бы вы мне помочь? Мне 11 лет, и я учусь программировать на С++. Расскажите мне о...

Как из С++ передать данные в текстовый файл? и как читать текстовые файлы в С++? - C++
Задача такая: у меня есть текстовый файл, в котором из матлаба передано некоторое число N. как теперь это число прочитать? потом...

Как читать с файла каждую строку как структуру - C++
вопрос 1) как рассмотреть файл как последовательность битов.. вопрос 2) как читать с фаила каждую строку как структуру, например struct...

7
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
24621 / 16291 / 5004
Регистрация: 22.10.2011
Сообщений: 28,842
Записей в блоге: 5
12.10.2012, 15:31 #2
Цитата Сообщение от >arty< Посмотреть сообщение
в виду отсутствия таковых на MSDN
На social.msdn есть пример:
how to read REG_RESOURCE_LIST data from registry
0
_arty_
29 / 28 / 1
Регистрация: 10.07.2009
Сообщений: 317
12.10.2012, 16:32  [ТС] #3
Цитата Сообщение от UI Посмотреть сообщение
На social.msdn есть пример:
how to read REG_RESOURCE_LIST data from registry
За пример конечно спасибо, но у меня не получилось вытащить то что нужно, собственно пример вами приведённый, как раз то что мне и нужно (а именно получить размер ОЗУ), но он у меня не сработал - выводит символы с псевдографикой.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <conio>
#include <windows.h>
#include <string>
#include <stdlib.h>
 
using namespace std;
 
 
    int main () {
 
   HKEY hKey;
    DWORD dwType;
    DWORD dwSize;
    LPBYTE strRamSize[80];
 
 
RegOpenKeyEx(HKEY_LOCAL_MACHINE,"HARDWARE\\RESOURCEMAP\\System Resources\\Physical Memory",0,KEY_READ,&hKey);
RegQueryValueEx(hKey,".Translated",NULL,&dwType,(LPBYTE)strRamSize,&dwSize);
cout<<(char*)strRamSize;
getch();
RegCloseKey(hKey);
}
Приведение к другим типам также ничего не даёт.

Добавлено через 19 минут
Цитата Сообщение от >arty< Посмотреть сообщение
За пример конечно спасибо, но у меня не получилось вытащить то что нужно, собственно пример вами приведённый, как раз то что мне и нужно (а именно получить размер ОЗУ), но он у меня не сработал - выводит символы с псевдографикой.

Приведение к другим типам также ничего не даёт.
Нашёл код на Delphi и решил воспользоваться, но результат тот же - ничего:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
procedure TForm1.Button1Click(Sender: TObject);
begin
ReadREG_MULTI_SZ(HKEY_LOCAL_MACHINE,'HARDWARE\\RESOURCEMAP\\System Resources\\Physical Memory','.Translated', Memo1.Lines);
end;
 
procedure TForm1.ReadREG_MULTI_SZ(const CurrentKey: HKey; const Subkey,
  ValueName: string; Strings: TStrings);
  var
  valueType: DWORD;
  valueLen: DWORD;
  p, buffer: PChar;
  key: HKEY;
begin
 
  // Clear TStrings
  Strings.Clear; 
  // open the specified key
  if RegOpenKeyEx(CurrentKey, 
                  PChar(Subkey), 
                  0, KEY_READ, key) = ERROR_SUCCESS then 
  begin 
    // retrieve the type and data for a specified value name
    SetLastError(RegQueryValueEx(key, 
                 PChar(ValueName), 
                 nil, 
                 @valueType, 
                 nil, 
                 @valueLen)); 
    if GetLastError = ERROR_SUCCESS then 
      if valueType = 8 then 
      begin 
        GetMem(buffer, valueLen); 
        try 
          // receive the value's data (in an array).
          RegQueryValueEx(key, 
                          PChar(ValueName), 
                          nil, 
                          nil, 
                          PBYTE(buffer),
                          @valueLen); 
          // Add values to stringlist
          p := buffer; 
          while p^ <> #0 do 
          begin 
            Strings.Add(p); 
            Inc(p, lstrlen(p) + 1) 
          end 
        finally 
          FreeMem(buffer) 
        end 
      end 
      else 
        raise ERegistryException.Create('Stringlist expected/ String Liste erwartet...') 
    else 
      raise ERegistryException.Create('Cannot Read MULTI_SZ Value/'+ 
        'Kann den MULTI_SZ Wert nicht lesen...'); 
  end;
end;
Так как же всё таки правильно читать REG_RESOURCE_LIST значение?
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
24621 / 16291 / 5004
Регистрация: 22.10.2011
Сообщений: 28,842
Записей в блоге: 5
12.10.2012, 18:17 #4
Цитата Сообщение от >arty< Посмотреть сообщение
а именно получить размер ОЗУ
Нормально размер ОЗУ получаем:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{$mode delphi}
uses windows, registry;
 
const
   pszSubKey = 'Hardware\ResourceMap\System Resources\Physical Memory';
   pszValueName = '.Translated';
var
   myKey : HKEY;
 
   dwType, dwLength, dwIndex : DWORD;
   lpData, pmi : LPBYTE;
   dwBusCount, dwResourceCount : DWORD;
   ulTotalSize : ULONGLONG;
begin
   if RegOpenKey(HKEY_LOCAL_MACHINE, pszSubKey, myKey) = ERROR_SUCCESS then
   begin
      dwType := 0;
      lpData := nil;
      dwLength := 0;
 
      if RegQueryValueEx(myKey, pszValueName, 0, @dwType, nil, @dwLength) = ERROR_SUCCESS then
      begin
         GetMem(lpData, dwLength);
         RegQueryValueEx(myKey, pszValueName, 0, @dwType, lpData, @dwLength);
         RegCloseKey(myKey);
 
         dwBusCount := LPDWORD(lpData)^;
         if dwBusCount = 1 then // Это значение должно быть  = 1, иначе ошибка
         begin
            dwResourceCount := LPDWORD(lpData + 16)^;
            pmi := lpData + 24;
            ulTotalSize := 0;
 
            for dwIndex := 0 to dwResourceCount - 1 do
            begin
               Inc(ulTotalSize, LPDWORD(pmi + 8)^);
               Inc(pmi, 16);
            end;
         end;
         FreeMem(lpData);
      end;
   end;
   writeln(ulTotalSize div 1024 div 1024);
end.
(проверил на FPC, Дельфи запускать лень)

Аналогичный С++ ный код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
   ULONGLONG ulTotalSize = 0;
   HKEY hKey = NULL;
   LPCTSTR pszSubKey = _T("Hardware\\ResourceMap\\System Resources\\Physical Memory");
   LPCTSTR pszValueName = _T(".Translated");
   
   if(RegOpenKey(HKEY_LOCAL_MACHINE, pszSubKey, &hKey) == ERROR_SUCCESS)
   {
      DWORD dwType = 0;
      LPBYTE lpData = NULL;
      DWORD dwLength = 0;
     
      if(RegQueryValueEx(hKey, pszValueName, 0, &dwType, NULL, &dwLength) == ERROR_SUCCESS)
      {
         lpData = new BYTE[dwLength];
         RegQueryValueEx(hKey, pszValueName, 0, &dwType, lpData, &dwLength);
         RegCloseKey(hKey);
         
         DWORD dwBusCount = *(DWORD*)lpData;
         _ASSERT(dwBusCount == 1); // Должна быть 1-ца
       
         DWORD dwResourceCount = *(DWORD*)(lpData + 16);
         LPBYTE pmi = lpData + 24;
         
         for(DWORD dwIndex = 0; dwIndex < dwResourceCount; dwIndex++)
         {
            ulTotalSize += *(DWORD*)(pmi + 8);
            pmi += 16;
         }
         delete []lpData;
      }
   }
   // в ulTotalSize - размер памяти в байтах
0
_arty_
29 / 28 / 1
Регистрация: 10.07.2009
Сообщений: 317
12.10.2012, 21:20  [ТС] #5
Цитата Сообщение от UI Посмотреть сообщение
Нормально размер ОЗУ получаем:
Аналогичный С++ ный код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
   ULONGLONG ulTotalSize = 0;
   HKEY hKey = NULL;
   LPCTSTR pszSubKey = _T("Hardware\\ResourceMap\\System Resources\\Physical Memory");
   LPCTSTR pszValueName = _T(".Translated");
   
   if(RegOpenKey(HKEY_LOCAL_MACHINE, pszSubKey, &hKey) == ERROR_SUCCESS)
   {
      DWORD dwType = 0;
      LPBYTE lpData = NULL;
      DWORD dwLength = 0;
     
      if(RegQueryValueEx(hKey, pszValueName, 0, &dwType, NULL, &dwLength) == ERROR_SUCCESS)
      {
         lpData = new BYTE[dwLength];
         RegQueryValueEx(hKey, pszValueName, 0, &dwType, lpData, &dwLength);
         RegCloseKey(hKey);
         
         DWORD dwBusCount = *(DWORD*)lpData;
         _ASSERT(dwBusCount == 1); // Должна быть 1-ца
       
         DWORD dwResourceCount = *(DWORD*)(lpData + 16);
         LPBYTE pmi = lpData + 24;
         
         for(DWORD dwIndex = 0; dwIndex < dwResourceCount; dwIndex++)
         {
            ulTotalSize += *(DWORD*)(pmi + 8);
            pmi += 16;
         }
         delete []lpData;
      }
   }
   // в ulTotalSize - размер памяти в байтах
Спасибо сработало, но хотелось бы получить пояснение по этому куску кода:
C++
1
2
3
4
5
6
7
8
9
10
   DWORD dwBusCount = *(DWORD*)lpData;
         _ASSERT(dwBusCount == 1); // Должна быть 1-ца
         DWORD dwResourceCount = *(DWORD*)(lpData + 16);
         LPBYTE pmi = lpData + 24; 
         
         for(DWORD dwIndex = 0; dwIndex < dwResourceCount; dwIndex++)
         {
            ulTotalSize += *(DWORD*)(pmi + 8);
            pmi += 16;
         }
Добавлено через 2 часа 24 минуты


Добавлено через 15 секунд
Нашел ещё вот это, но не знаю насколько будет правильно дважды открывать один и тот же ключ разными функциями - открываем одной и передаем хэндл следующей:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>
#include <conio>
#include <windows.h>
#include <string>
#include <stdlib.h>
#include <stdio.h>
#pragma hdrstop
 
//---------------------------------------------------------------------------
 
#pragma argsused
int main(int argc, char* argv[])
{
 
HKEY hKey;
 
    HKEY hKey2;
 
    DWORD dwType;
 
    DWORD dwSize=100;
 
    DWORD strRamSize;
 
   RegOpenKey(HKEY_LOCAL_MACHINE, "Hardware\\ResourceMap\\System Resources\\Physical Memory", &hKey);
    RegOpenKeyEx(hKey2,"HARDWARE\\RESOURCEMAP\\System Resources\\Physical Memory",0,KEY_READ,&hKey2);
 
    RegQueryValueEx(hKey2,".Translated",NULL,&dwType,(LPSTR)&strRamSize,&dwSize);
 
    printf ("RAM in MBytes: %i",((strRamSize/1024)/1024));
 
    getch();
 
    return 0;
}
В итоге пишет 2047 MB (хотя должно быть вроде 2048, но если учитывать что видеоадаптер у меня может увеличивать свою память из ОЗУ, то я могу допустить такую погрешность...).
В случае описанном тобой показывает вообще 2012 MB RAM.
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
24621 / 16291 / 5004
Регистрация: 22.10.2011
Сообщений: 28,842
Записей в блоге: 5
12.10.2012, 23:20 #6
>arty<, структура информации, записанной в этом ключе реестра расписана у Remko Weijnen-а в блоге. Почему такой разброс значений понятия не имею. У меня всю память показывает полностью.
0
_arty_
29 / 28 / 1
Регистрация: 10.07.2009
Сообщений: 317
13.10.2012, 00:13  [ТС] #7
Цитата Сообщение от UI Посмотреть сообщение
>arty<, структура информации, записанной в этом ключе реестра расписана у Remko Weijnen-а в блоге. Почему такой разброс значений понятия не имею. У меня всю память показывает полностью.
Ну я уже упоминал что видеоадаптер автоматически заимствует видеопамять под свои нужды из ОЗУ.

Добавлено через 45 минут
Честно, прочитав пост в блоге - так и не разобрался в куске кода что я приводил выше, но понял что для начала мы получили количество элементов (адресов), а затем получили их десятичное представление и просто сложили, но почему именно так:

C++
1
2
3
4
5
6
7
8
      DWORD dwResourceCount = *(DWORD*)(lpData + 16);
         LPBYTE pmi = lpData + 24; //для чего?
         
         for(DWORD dwIndex = 0; dwIndex < dwResourceCount; dwIndex++)
         {
            ulTotalSize += *(DWORD*)(pmi + 8); //тот же самый вопрос...
            pmi += 16; //тот же самый вопрос...
         }
Прошу помочь, если Вы об этом знаете - не оставьте пожалуйста без комментария.
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
24621 / 16291 / 5004
Регистрация: 22.10.2011
Сообщений: 28,842
Записей в блоге: 5
13.10.2012, 04:22 #8
lpData - это весть прочитанный блок, все поля (я сейчас ориентируюсь на то, что написано в блоге, названия все тоже будут оттуда). То есть, начало lpData - это начало поля Count в CM_RESOURCE_LIST. Если добавить смещение в 24 байта - то придем куда? Правильно: к (Memory: RDD_Memory) в структуре CM_PARTIAL_RESOURCE_DESCRIPTOR. То есть, к тому, что, собственно, нужно складывать. Это насчет первого "для чего"

Второе: в структуре CM_PARTIAL_RESOURCE_DESCRIPTOR имеем 8 байт (PHYSICAL_ADDRESS - это тот же LARGE_INTEGER, то есть, Int64 разбитый на LowPart/HighPart, то есть именно 8 байт) начального адреса, и, чтобы добраться до размера памяти, надо эти 8 байт пропустить, правильно? Пропускаем.

Третье: откуда взялось смещение в 16 байт? Пропускаем само поле Length из RDD_MEMORY, размер которого = 4 байта. Дальше идет следующий элемент массива PartialDescriptors из CM_PARTIAL_RESOURCE_LIST. Чтобы опять попасть к полю Length в RDD_MEMORY, надо пропустить еще поля ResType (UCHAR = 1 байт), ShareDisposition (UCHAR = 1 байт) и Flags (USHORT = 2 байта) из CM_PARTIAL_RESOURCE_DESCRIPTOR. И не забыть пропустить адрес следующего блока, т.е., его поле Start (8 байт). Просуммируй всё, что выделено, получишь 16 байт.
1
13.10.2012, 04:22
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.10.2012, 04:22
Привет! Вот еще темы с ответами:

Как читать строки - C++
Как считать строку с пробелами в с++.Нашел способ с getline , но там фишка в чем придется все вводить через гетлайн.А как вводить одно...

Как читать программу на С++? - C++
Приветствую вас, дорогие форумчане! У меня вот такой вопрос: Как легко читать программу? т.е. как перевести из исходного кода в русский...

Как читать матрицу.... - Delphi
Как читать матрицу вот таким образом Изображение

Как читать реестр? - Visual Basic
У меня такая задача: в реестре нужно прочитать все, что лежит по адресу HKEY_LOCAL_MACHINESOFTWAREMicrosoftProtected Storage System...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.