Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > RegQueryValueEx


Автор: kapusta007 31.5.2017, 21:50
при повторном использовании   RegQueryValueEx к новому имени, значению выдает ошибку ERROR_MORE_DATA . с RegGetValue тоже самое.  буфер в несколько раз больше.
что делать? в чем может быть ошибка?
Код

BOOL DisplayJobs (void)

/* Scan the job database file, reporting on the status of all jobs.
    In the process remove all jobs that no longer exist in the system. */
{
    HANDLE  hProcess, hFile;
    //JM_JOB jobRecord;
    HKEY hResult;
    DWORD jobNumber = 0, exitCode, regOpen, regCreate, Dispos, rSet, rGetId, rGetComm, val, sizebuf, ProcessID;
    TCHAR jobMgtFileName[MAX_PATH], Key[MAX_PATH], SubKey[MAX_PATH], Nid[20] = { "ID" }, NCommandLine[20] = { "COMMAND" },CommandLine[1024], buf[10], c[1024];
    OVERLAPPED regionStart;
    WIN32_FIND_DATA  fFile;
    
    if (!GetJobMgtRegit(Key, SubKey)) return -1;
    

    

    __try {
    do
    {         regOpen = RegOpenKeyEx(HKEY_CURRENT_USER, SubKey, NULL, KEY_ALL_ACCESS, &hResult);
             if (regOpen != ERROR_SUCCESS)
             {
                 ReportError(_T("Cannot open Register : "), 0, 1);
                 regCreate = RegCreateKeyEx(HKEY_CURRENT_USER, SubKey, NULL, NULL, 
                                                  REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hResult, &Dispos);
                if (regCreate != ERROR_SUCCESS)
                if (Dispos == REG_OPENED_EXISTING_KEY)
                         ReportError(_T(" Key is Open "), 1, 1);
                     else
                         ReportError(_T("Filed open and create reg: "), 2, 1);
              }  
    
        _tcscpy_s(NCommandLine, 20, "COMMAND");
        memset(CommandLine, 0xcc, 1024);
        _itoa_s(jobNumber, buf, 10, 10);
        _tcscat_s(NCommandLine, _tcslen(NCommandLine) + 10, buf);
        rGetComm = RegQueryValueEx(hResult, NCommandLine, NULL, &val, CommandLine, &sizebuf);

        //rGetComm = RegGetValue(HKEY_CURRENT_USER, SubKey , NCommandLine, RRF_RT_ANY, NULL, CommandLine, &sizebuf);
        if (rGetComm != ERROR_SUCCESS)
            if (rGetComm == ERROR_MORE_DATA) {
                ReportError(_T("Cannot Get Command : "), 0, 1); break;}

     
        _tcscpy_s(Nid, 20, "ID");
        _itoa_s(jobNumber, buf, 10, 10);
        _tcscat_s(Nid, _tcslen(Nid) + 10, buf);
        rGetId = RegQueryValueEx(hResult, Nid, NULL, NULL, &ProcessID, &sizebuf);
        //rGetId = RegGetValue(HKEY_CURRENT_USER, SubKey, Nid, RRF_RT_ANY, NULL, &ProcessID, &sizebuf);
        if (rGetId != ERROR_SUCCESS)
        {
            ReportError(_T("Cannot Get ID : "), 0, 1); break;
        }

        /* jobNumber won't exceed MAX_JOBS_ALLOWED as the file is
                        not allowed to grow that long */
        hProcess = NULL;
        if (ProcessID == 0)  continue; 
                    /* Obtain process status. */
        hProcess = OpenProcess (PROCESS_ALL_ACCESS, FALSE, ProcessID);
        if (hProcess != NULL) {
            GetExitCodeProcess (hProcess, &exitCode);
            CloseHandle (hProcess);
        }
        if (NULL == hProcess)
        { /* Back up one record. */
          /* SetFilePoiner is more convenient here than SetFilePointerEx since the move is a short shift from the current position */
            _tcscpy_s(Nid, 20, "ID");
            _itoa_s(jobNumber, buf, 10, 10);
            _tcscat_s(Nid, _tcslen(Nid) + 10, buf);
            rSet = RegSetValueEx(hResult, Nid, NULL, REG_DWORD, &ProcessID, sizeof(ProcessID));
            if (rSet != ERROR_SUCCESS)
                ReportError(_T("cannot set ID: "), 0, 1);

            _tcscpy_s(NCommandLine, 20, "COMMAND");
            _itoa_s(jobNumber, buf, 10, 10);
            _tcscat_s(NCommandLine, _tcslen(NCommandLine) + 10, buf);
            rSet = RegSetValueEx(hResult, NCommandLine, NULL, REG_SZ, CommandLine, _tcslen(CommandLine));
            if (rSet != ERROR_SUCCESS)
                ReportError(_T("cannot set Command: "), 0, 1);
        }

        jobNumber++;
                    /* Show the job status. */
        _tprintf (_T (" [%d] "), jobNumber);
        if (NULL == hProcess)
            _tprintf (_T (" Done"));
        else if (exitCode != STILL_ACTIVE)
            _tprintf (_T ("+ Done"));
        else _tprintf (_T ("      "));
                    /* Show the command. */
        _tprintf (_T (" %s\n"), CommandLine);

        /* Remove processes that are no longer in system. */

        
        if (RegCloseKey(HKEY_CURRENT_USER) != ERROR_SUCCESS)
            ReportError(_T("Error close reg"), 0, 1);
    } while (rGetComm==ERROR_SUCCESS&&rGetId==ERROR_SUCCESS); /* End of while. */
    }  /* End of try.   */
    
    __finally {        /* Release the lock on the file. */
        RegCloseKey(hResult);
    }

    return TRUE;
}



Автор: kapusta007 1.6.2017, 00:42
все решилось. добавил функцию RegQueryInfoKey и перед каждым вызовом RegQueryValueEx обновляю последний ее параметр LPDWORD lpcbData; sizebuf = MaxValLen ;
Код

if (RegQueryInfoKey(hResult, NULL, NULL, NULL, &lSubK, &MaxSubKLen, NULL, &NumVals, &MaxValNameLen, &MaxValLen, NULL, NULL) != ERROR_SUCCESS)
            ReportError(_T("Cannot get info key :"), 0, 1);

        sizebuf = MaxValLen ;
                rGetComm = RegQueryValueEx(hResult, NCommandLine, NULL, &val, CommandLine, &sizebuf);

Автор: volatile 1.6.2017, 11:45
Цитата(kapusta007 @  1.6.2017,  00:42 Найти цитируемый пост)
добавил функцию RegQueryInfoKey и перед каждым вызовом RegQueryValueEx обновляю последний ее параметр LPDWORD lpcbData; sizebuf = MaxValLen ;

Неправилное решение, и строго говоря опасное. Нужно просто:

Цитата(kapusta007 @  1.6.2017,  00:42 Найти цитируемый пост)
if (RegQueryInfoKey(hResult, NULL, NULL, NULL, &lSubK, &MaxSubKLen, NULL, &NumVals, &MaxValNameLen, &MaxValLen, NULL, NULL) != ERROR_SUCCESS)
            ReportError(_T("Cannot get info key :"), 0, 1);

        sizebuf = MaxValLen ;

        sizebuf = sizeof CommandLine;

                rGetComm = RegQueryValueEx(hResult, NCommandLine, NULL, &val, CommandLine, &sizebuf);


читаем в MSDN о последнем параметре RegQueryValueEx
Цитата(MSDN)
lpcbData 
A pointer to a variable that specifies the size of the buffer pointed to by the lpData parameter, in bytes.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)