title: DeviceIoControl Invalid access to memory location
body: <p>I am getting invalid access to memory location when I run the following code</p>
  
  <pre><code>WIN32_FIND_DATAW FD;
  WCHAR cPath[MAX_PATH], cFindPath[MAX_PATH];
  
  if (!GetCurrentDirectoryW(MAX_PATH, cPath))
      ErrorExit("GetCurrentDirectory");
  else
      printf("Current Path: %s\n", cPath);
  
  StringCchCopyW(cFindPath, MAX_PATH, cPath);
  StringCchCatW(cFindPath, MAX_PATH, L"\\*");
  
  BOOL bsuccess;
  
  HANDLE hFind = FindFirstFileW(cFindPath, &amp;FD);
  
  if (INVALID_HANDLE_VALUE != hFind)
  {
      vector&lt;wstring&gt; links;
      do
      {
          WCHAR  fullFileName[MAX_PATH];
          StringCchPrintfW(fullFileName, MAX_PATH, L"\\\\?\\%s\\%s", cPath, FD.cFileName);
  
          DWORD dwBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
          REPARSE_DATA_BUFFER* rdata;
          rdata = (REPARSE_DATA_BUFFER*)malloc(dwBufSize);
  
          DWORD bytesReturned;
          HANDLE hFile = CreateFileW(fullFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
          if (INVALID_HANDLE_VALUE != hFile)
          {
              if (DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, &amp;rdata, dwBufSize, &amp;bytesReturned, NULL))
              {
                  if (IsReparseTagMicrosoft(rdata-&gt;ReparseTag))
                  {
  
                      if (rdata-&gt;ReparseTag == IO_REPARSE_TAG_SYMLINK)
                      {
                          printf("Symbolic-Link\n");
                          size_t slen = rdata-&gt;SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
                          WCHAR *szSubName = new WCHAR[slen + 1];
                          wcsncpy_s(szSubName, slen + 1, &amp;rdata-&gt;SymbolicLinkReparseBuffer.PathBuffer[rdata-&gt;SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
                          szSubName[slen] = 0;
                          printf("SubstitutionName (len: %d): '%S'\n", rdata-&gt;SymbolicLinkReparseBuffer.SubstituteNameLength, szSubName);
                          delete[] szSubName;
  
                          size_t plen = rdata-&gt;SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR);
                          WCHAR *szPrintName = new WCHAR[plen + 1];
                          wcsncpy_s(szPrintName, plen + 1, &amp;rdata-&gt;SymbolicLinkReparseBuffer.PathBuffer[rdata-&gt;SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
                          szPrintName[plen] = 0;
                          printf("PrintName (len: %d): '%S'\n", rdata-&gt;SymbolicLinkReparseBuffer.PrintNameLength, szPrintName);
                          delete[] szPrintName;
                      }
                      else if (rdata-&gt;ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
                      {
                          printf("Mount-Point\n");
                          size_t slen = rdata-&gt;MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
                          WCHAR *szSubName = new WCHAR[slen + 1];
                          wcsncpy_s(szSubName, slen + 1, &amp;rdata-&gt;MountPointReparseBuffer.PathBuffer[rdata-&gt;MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
                          szSubName[slen] = 0;
                          printf("SubstitutionName (len: %d): '%S'\n", rdata-&gt;MountPointReparseBuffer.SubstituteNameLength, szSubName);
                          delete[] szSubName;
  
                          size_t plen = rdata-&gt;MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
                          WCHAR *szPrintName = new WCHAR[plen + 1];
                          wcsncpy_s(szPrintName, plen + 1, &amp;rdata-&gt;MountPointReparseBuffer.PathBuffer[rdata-&gt;MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
                          szPrintName[plen] = 0;
                          printf("PrintName (len: %d): '%S'\n", rdata-&gt;MountPointReparseBuffer.PrintNameLength, szPrintName);
                          delete[] szPrintName;
                      }
                      else
                      {
                          printf("No Mount-Point or Symblic-Link...\n");
                      }
                  }
                  else
                  {
                      printf("Not a Microsoft-reparse point - could not query data!\n");
                  }
                  free(rdata);
              }
              else
                  ErrorExit("DeviceIoControl");
          }
  
          CloseHandle(hFile);
  
  
      } while (FindNextFileW(hFind, &amp;FD));
  }
  else
      ErrorExit("FindFirstFile");
  </code></pre>
  
  <p>but the following code works fine.</p>
  
  <pre><code>HANDLE hFile;
  LPCTSTR szMyFile = ("C:\\Documents and Settings");  // Mount-Point (JUNCTION)
  //LPCTSTR szMyFile = _T("C:\\Users\\All Users");  // Symbolic-Link (SYMLINKD)
  
  hFile = CreateFile(szMyFile, FILE_READ_EA, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
  if (hFile == INVALID_HANDLE_VALUE)
  {
      printf(("Could not open dir '%s'; error: %d\n"), szMyFile, GetLastError());
      return;
  }
  
  // Allocate the reparse data structure
  DWORD dwBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
  REPARSE_DATA_BUFFER* rdata;
  rdata = (REPARSE_DATA_BUFFER*)malloc(dwBufSize);
  
  // Query the reparse data
  DWORD dwRetLen;
  BOOL bRet = DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, rdata, dwBufSize, &amp;dwRetLen, NULL);
  if (bRet == FALSE)
  {
      printf(("DeviceIoControl failed with error: %d\n"), GetLastError());
      CloseHandle(hFile);
      return;
  }
  CloseHandle(hFile);
  
  if (IsReparseTagMicrosoft(rdata-&gt;ReparseTag))
  {
      if (rdata-&gt;ReparseTag == IO_REPARSE_TAG_SYMLINK)
      {
          printf("Symbolic-Link\n");
          size_t slen = rdata-&gt;SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
          WCHAR *szSubName = new WCHAR[slen + 1];
          wcsncpy_s(szSubName, slen + 1, &amp;rdata-&gt;SymbolicLinkReparseBuffer.PathBuffer[rdata-&gt;SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
          szSubName[slen] = 0;
          printf("SubstitutionName (len: %d): '%S'\n", rdata-&gt;SymbolicLinkReparseBuffer.SubstituteNameLength, szSubName);
          delete[] szSubName;
  
          size_t plen = rdata-&gt;SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR);
          WCHAR *szPrintName = new WCHAR[plen + 1];
          wcsncpy_s(szPrintName, plen + 1, &amp;rdata-&gt;SymbolicLinkReparseBuffer.PathBuffer[rdata-&gt;SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
          szPrintName[plen] = 0;
          printf("PrintName (len: %d): '%S'\n", rdata-&gt;SymbolicLinkReparseBuffer.PrintNameLength, szPrintName);
          delete[] szPrintName;
      }
      else if (rdata-&gt;ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
      {
          printf("Mount-Point\n");
          size_t slen = rdata-&gt;MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
          WCHAR *szSubName = new WCHAR[slen + 1];
          wcsncpy_s(szSubName, slen + 1, &amp;rdata-&gt;MountPointReparseBuffer.PathBuffer[rdata-&gt;MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
          szSubName[slen] = 0;
          printf("SubstitutionName (len: %d): '%S'\n", rdata-&gt;MountPointReparseBuffer.SubstituteNameLength, szSubName);
          delete[] szSubName;
  
          size_t plen = rdata-&gt;MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
          WCHAR *szPrintName = new WCHAR[plen + 1];
          wcsncpy_s(szPrintName, plen + 1, &amp;rdata-&gt;MountPointReparseBuffer.PathBuffer[rdata-&gt;MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
          szPrintName[plen] = 0;
          printf("PrintName (len: %d): '%S'\n", rdata-&gt;MountPointReparseBuffer.PrintNameLength, szPrintName);
          delete[] szPrintName;
      }
      else
      {
          printf("No Mount-Point or Symblic-Link...\n");
      }
  }
  else
  {
      printf(("Not a Microsoft-reparse point - could not query data!\n"));
  }
  free(rdata);
  </code></pre>
  
  <p>I am trying to get the reparse data for the files in a given folder. This is my <code>REPARSE_DATA_BUFFER</code></p>
  
  <pre><code>typedef struct _REPARSE_DATA_BUFFER {
  ULONG  ReparseTag;
  USHORT  ReparseDataLength;
  USHORT  Reserved;
  union {
      struct {
          USHORT  SubstituteNameOffset;
          USHORT  SubstituteNameLength;
          USHORT  PrintNameOffset;
          USHORT  PrintNameLength;
          ULONG   Flags; // it seems that the docu is missing this entry (at least 2008-03-07)
          WCHAR  PathBuffer[1];
      } SymbolicLinkReparseBuffer;
      struct {
          USHORT  SubstituteNameOffset;
          USHORT  SubstituteNameLength;
          USHORT  PrintNameOffset;
          USHORT  PrintNameLength;
          WCHAR  PathBuffer[1];
      } MountPointReparseBuffer;
      struct {
          UCHAR  DataBuffer[1];
      } GenericReparseBuffer;
  };
  } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
  </code></pre>
  
  <p>I Dont know where I went wrong. Please help me fix my first code.</p>