none
DeviceIoControl failing with acess denied for FSCTL_SET_REPARSE_POINT RRS feed

  • Question

  • I’m trying to set a reparse point on a file which is opened with the below attributes:

     

    Shared Mode          : None

    FSCCFileAttribute : 128 (0x80)

    Create Options       : 0x200060 (FILE_NON_DIRECTORY_FILE | FILE_OPEN_REPARSE_POINT)

    CreateDisposition    : (0x00000002)

     

    Setting the reparse point fails with an error 5 (Access is denied) internally by win32 API. IOCTL Packet is not sent out to the server.

     

    Instead of the below code if I simply use “CreateSymbolicLink” function  call, things works fine and link gets created.

    Could  anyone tell what is missed in the below code for sending the below IOCTL ?

    Note: I am running this app with administrative privilege

    ===================================================================================

    pReraseDatBuf->ReparseTag=IO_REPARSE_TAG_SYMLINK;

           pReraseDatBuf->ReparseDataLength = sizeof(pReraseDatBuf->SymbolicLinkReparseBuffer) + 2;

           pReraseDatBuf->Reserved = 0;

           pReraseDatBuf->SymbolicLinkReparseBuffer.SubstituteNameOffset = 0;

           pReraseDatBuf->SymbolicLinkReparseBuffer.SubstituteNameLength = 2;

           pReraseDatBuf->SymbolicLinkReparseBuffer.PrintNameOffset = 2;

           pReraseDatBuf->SymbolicLinkReparseBuffer.PrintNameLength = 2;

           pReraseDatBuf->SymbolicLinkReparseBuffer.Flags = 1;//SYMLINK_FLAG_RELATIVE;

          

           mbstowcs(pReraseDatBuf->SymbolicLinkReparseBuffer.PathBuffer, "W", 1);

           mbstowcs(pReraseDatBuf->SymbolicLinkReparseBuffer.PathBuffer + 1, "W", 1);

          

           bResult = DeviceIoControl(OpenList[fh_index].fhandle,

                                      FSCTL_SET_REPARSE_POINT,

                                        inBuffer,

                                        sizeof(REPARSE_DATA_BUFFER) + 2,

                                        NULL,                          // lpOutBuffer

                                        0,                             // nOutBufferSize

                                        NULL,                          // lpBytesReturned

                                        NULL);

     

           // Check for end of file.

           if (!bResult)

           {

                  // this is the end of the file

                  cout << "SET Reparse point Failed \n";

                  ErrorExitA(("set_reparse_point"));

           } else {

                  cout << endl << "Success"<< endl;

           }

    ===================================================================================


    Wednesday, July 9, 2014 6:39 AM

Answers

  • Well the file did have write permission and was opened with desired access "FILE_ALL_ACCESS". Open was granted for that req but still SET_REPRASE IOCTL was failing.

    Later i figured out that process needed to have "SE_RESTORE_NAME" priv.

    Calling the below code before opening the file, setting IO_REPARSE_TAG_SYMLINK works fine.

    =====================================================
      HANDLE hToken; TOKEN_PRIVILEGES tp;
      OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
      LookupPrivilegeValue(NULL,  SE_RESTORE_NAME ,  &tp.Privileges[0].Luid);
      tp.PrivilegeCount = 1;
      tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
      AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
      CloseHandle(hToken);
    ======================================================

    Thursday, July 10, 2014 5:50 AM

All replies

  • the docs say you must have write access on the file for this to work, http://msdn.microsoft.com/en-us/library/windows/desktop/aa364595(v=vs.85).aspx

    BTW, no need to call mbstowcs, this

    mbstowcs(pReraseDatBuf->SymbolicLinkReparseBuffer.PathBuffer, "W", 1);

    mbstowcs(pReraseDatBuf->SymbolicLinkReparseBuffer.PathBuffer + 1, "W", 1);

    can be

    pReraseDatBuf->SymbolicLinkReparseBuffer.PathBuffer[0] = L'W';

    pReraseDatBuf->SymbolicLinkReparseBuffer.PathBuffer[1] = L'W';


    d -- This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, July 9, 2014 9:41 PM
  • Well the file did have write permission and was opened with desired access "FILE_ALL_ACCESS". Open was granted for that req but still SET_REPRASE IOCTL was failing.

    Later i figured out that process needed to have "SE_RESTORE_NAME" priv.

    Calling the below code before opening the file, setting IO_REPARSE_TAG_SYMLINK works fine.

    =====================================================
      HANDLE hToken; TOKEN_PRIVILEGES tp;
      OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
      LookupPrivilegeValue(NULL,  SE_RESTORE_NAME ,  &tp.Privileges[0].Luid);
      tp.PrivilegeCount = 1;
      tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
      AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
      CloseHandle(hToken);
    ======================================================

    Thursday, July 10, 2014 5:50 AM