Search code examples
c#pinvoke

Attempted to read or write to protected memory with GetClassName


I am currently writing an explorer.exe wrapper (the folder view, not the other one) and I have a list of IntPtr from User32.dll#EnumChildWindows. When I loop through the IntPtrs, regardless of which IntPtr is selected I get System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. after using GetClassName:

        string name0;
        foreach (IntPtr ptr in list) {
            
            name0="";
            if (GetClassName(ptr,out name0,(IntPtr)14)!=IntPtr.Zero) //exception here on GetClassName
                if (name0=="SysTreeView32") { this.QuickAccessTreeView=ptr; break; } 
            
        }

I presume this is intentional for protection purposes but it might not be. If it is, my question is: what is a way to work around this? It isn't like I am trying to retrieve much information, just the class name of the control. If it isn't intentional then my question is why isn't this working?


Solution

  • You are passing the buffer size 14, but the name0 variable is empty. You must pre-allocate the memory, pass the correct buffer size and check the return value of the function:

    1. Make sure your PInvoke signature is correct for GetClassName.

      [DllImport("user32.dll", SetLastError = true, EntryPoint = "GetClassNameW", CharSet = CharSet.Unicode)]
      static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
      
    2. As stated in the documentation, the function returns zero in case of fail.

      var className = new StringBuilder(256);
      if(GetClassName(ptr, className, className.Capacity)>0)
      {
         // do more processing
      }