Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. GetPrivateProfileSectionNamesA returns 0

GetPrivateProfileSectionNamesA returns 0

Scheduled Pinned Locked Moved C / C++ / MFC
helptestingbeta-testingperformance
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H Offline
    H Offline
    hans sch
    wrote on last edited by
    #1

    I recently observed that a call to the GetPrivateProfileSectionNamesA WinAPI function returned 0. Postings on the internet suggest to check file existence, Windows INI file mapping, etc. To make the story short: The call works reliably after a Windows restart, and eventually fails (using the same INI file, and file name) after several program runs, where "fails" means "returns 0." The documentation does not indicate that GetLastError() returns anything useful in this case, but I called it nonetheless, and it returned 8 (ERROR_NOT_ENOUGH_MEMORY). That was the first time ever I worked with Vista Home, so I am wondering whether Vista Home has any limitiations with respect to memory or other resources, compared to XP Pro or Vista Pro where this problem never appeared. It may be that some resources used by third-party software are not released after a program crash - and the program crashed rather often during my testing/debugging sessions. Thanks for any suggestions - Hans

    CPalliniC 1 Reply Last reply
    0
    • H hans sch

      I recently observed that a call to the GetPrivateProfileSectionNamesA WinAPI function returned 0. Postings on the internet suggest to check file existence, Windows INI file mapping, etc. To make the story short: The call works reliably after a Windows restart, and eventually fails (using the same INI file, and file name) after several program runs, where "fails" means "returns 0." The documentation does not indicate that GetLastError() returns anything useful in this case, but I called it nonetheless, and it returned 8 (ERROR_NOT_ENOUGH_MEMORY). That was the first time ever I worked with Vista Home, so I am wondering whether Vista Home has any limitiations with respect to memory or other resources, compared to XP Pro or Vista Pro where this problem never appeared. It may be that some resources used by third-party software are not released after a program crash - and the program crashed rather often during my testing/debugging sessions. Thanks for any suggestions - Hans

      CPalliniC Offline
      CPalliniC Offline
      CPallini
      wrote on last edited by
      #2

      Could you please post the relevant code? :)

      If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
      This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
      [My articles]

      In testa che avete, signor di Ceprano?

      H 1 Reply Last reply
      0
      • CPalliniC CPallini

        Could you please post the relevant code? :)

        If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
        This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
        [My articles]

        H Offline
        H Offline
        hans sch
        wrote on last edited by
        #3

        Tried to boil the code down to the relevant parts.

        void ReadAllSections(const CString &sFileName, CStringArray &arrsSections)
        {
        static const DWORD k_dwBufferInc = 10;
        DWORD dwBufferSize = 0, dwReturnedLength;
        CString sBuffer; // using a CString as a buffer to simplify memory housekeeping

        // try to read the section names; increase buffer and retry if too small
        do
        {
            dwBufferSize += k\_dwBufferInc;
            dwReturnedLength = GetPrivateProfileSectionNames(sBuffer.GetBuffer(dwBufferSize - 1), dwBufferSize, sFileName);
        }
        while (dwReturnedLength == dwBufferSize - 2);
        
        arrsSections.RemoveAll();
        
        if (dwReturnedLength == 0)
        {
            // dwLastErr is 0 if the file or directory don't exist, or if it exists and contains no sections.
            // Sometimes, on a Vista Home PC, 8 is returned, although the file exists and contains sections.
            DWORD dwLastErr = GetLastError();
            AfxDebugBreak();
            return;
        }
        
        // split buffer into section names (I know this part could me more sophisticated)
        LPCTSTR pszCurrent = sBuffer;
        while (\*pszCurrent != \_T('\\0'))
        {
            arrsSections.Add(pszCurrent);
            pszCurrent += \_tcslen(pszCurrent) + 1;
        }
        

        }

        Let me point out once more that the AfxDebugBreak(); statement is not always executed, although always the same file name (and absolute directory) is used, and the same file is used (and exists) all the time. The MSDN documentation does not mention that a return value of 0 means failure, nor that GetLastError() should be called in that case.

        CPalliniC 1 Reply Last reply
        0
        • H hans sch

          Tried to boil the code down to the relevant parts.

          void ReadAllSections(const CString &sFileName, CStringArray &arrsSections)
          {
          static const DWORD k_dwBufferInc = 10;
          DWORD dwBufferSize = 0, dwReturnedLength;
          CString sBuffer; // using a CString as a buffer to simplify memory housekeeping

          // try to read the section names; increase buffer and retry if too small
          do
          {
              dwBufferSize += k\_dwBufferInc;
              dwReturnedLength = GetPrivateProfileSectionNames(sBuffer.GetBuffer(dwBufferSize - 1), dwBufferSize, sFileName);
          }
          while (dwReturnedLength == dwBufferSize - 2);
          
          arrsSections.RemoveAll();
          
          if (dwReturnedLength == 0)
          {
              // dwLastErr is 0 if the file or directory don't exist, or if it exists and contains no sections.
              // Sometimes, on a Vista Home PC, 8 is returned, although the file exists and contains sections.
              DWORD dwLastErr = GetLastError();
              AfxDebugBreak();
              return;
          }
          
          // split buffer into section names (I know this part could me more sophisticated)
          LPCTSTR pszCurrent = sBuffer;
          while (\*pszCurrent != \_T('\\0'))
          {
              arrsSections.Add(pszCurrent);
              pszCurrent += \_tcslen(pszCurrent) + 1;
          }
          

          }

          Let me point out once more that the AfxDebugBreak(); statement is not always executed, although always the same file name (and absolute directory) is used, and the same file is used (and exists) all the time. The MSDN documentation does not mention that a return value of 0 means failure, nor that GetLastError() should be called in that case.

          CPalliniC Offline
          CPalliniC Offline
          CPallini
          wrote on last edited by
          #4

          A call to CString::ReleaseBuffer must must follow each call to CString::GetBuffer. As side note, way don't you use a more aggressive technique for the buffer (for instance, starting with 256 bytes and doubling at each cycle)? :)

          If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
          This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
          [My articles]

          In testa che avete, signor di Ceprano?

          H 1 Reply Last reply
          0
          • CPalliniC CPallini

            A call to CString::ReleaseBuffer must must follow each call to CString::GetBuffer. As side note, way don't you use a more aggressive technique for the buffer (for instance, starting with 256 bytes and doubling at each cycle)? :)

            If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
            This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
            [My articles]

            H Offline
            H Offline
            hans sch
            wrote on last edited by
            #5

            Hi CPallini, thanks for your input... this is demo code, the production code uses more aggressive memory allocation. Doubling seems a bit of overkill to me; I start with like 1024 bytes and add steps of 1024. The point of adding just 10 is to show that the algorithm works and is not the cause of the problem. About ReleaseBuffer() - omitting it, in my understanding, may confuse CString operations but should not make an API call fail should it? :^)

            CPalliniC 1 Reply Last reply
            0
            • H hans sch

              Hi CPallini, thanks for your input... this is demo code, the production code uses more aggressive memory allocation. Doubling seems a bit of overkill to me; I start with like 1024 bytes and add steps of 1024. The point of adding just 10 is to show that the algorithm works and is not the cause of the problem. About ReleaseBuffer() - omitting it, in my understanding, may confuse CString operations but should not make an API call fail should it? :^)

              CPalliniC Offline
              CPalliniC Offline
              CPallini
              wrote on last edited by
              #6

              hans.sch wrote:

              About ReleaseBuffer() - omitting it, in my understanding, may confuse CString operations but should not make an API call fail should it?

              Nope, it shouldn't. However, any debugging should happen in the cleanest environment possible, I think (moreover, forgetting to call CString::ReleaseBuffer method can bring only troubles to you...). :)

              If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler. -- Alfonso the Wise, 13th Century King of Castile.
              This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong. -- Iain Clarke
              [My articles]

              In testa che avete, signor di Ceprano?

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups