RearsePoint



  • Wie kann das Zielverzeichnis eines Reparse_Point ermittelt werden ?

    Bis jetzt habe ich folgenden Code zusammen gesetzt:

    #include <winIOCtl.h> //DeviceIoControl
    
    HANDLE hFile; 
    
    char szOut[4]; 
    char *pOut; 
    
    unsigned long int* lpByte; 
    
    const char* MyFile = "C:\\Programme"; 
    
    hFile = CreateFile(MyFile, GENERIC_READ, 0, NULL, 
            OPEN_EXISTING, 0, NULL); 
    
    CloseHandle(hFile); 
    
    DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, NULL, pOut, 
                            sizeof(szOut), lpByte, NULL); 
    
    Form1->Caption = szOut;
    

    Ich bekomme aber kein Zielverzeichnis Zurück.

    _REPARSE_GUID_DATA_BUFFER* buffer;
    
    DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, buffer, NULL, pOut,
                            sizeof(buffer), lpByte, NULL);
    
    Form1->Caption = buffer->ReparseTag;
    

    Funktioniert auch nicht.

    Kennt sich jemand damit aus ???

    ==>Eisbeer<==







  • Woher bekomme ich dann den Pfad aus der Funktion DeviceIoControl?

    In deinem anderen Beispiel stand, dass das Ziel von C:\Programme mit \?\\C:\\Programme angesprochen werden kann.

    Wenn ich mit FindFirst das Verz. \?\\C:\\Programme angebe bekomme ich nichts angezeigt.

    Laut dem BSP. von ZDNET sollte dies ja ohne Probleme möglich sein. Nur wi ??

    ==>Eisbeer<==



  • Eisbeer schrieb:

    Woher bekomme ich dann den Pfad aus der Funktion DeviceIoControl?

    Vielleicht aus der "PREPARSE_DATA_BUFFER" Struktur?



  • Gibt´s dafür ein Beispiel ?

    Ich bekomme immer nur einen Zahlen-Wert zurück

    ==>Eisbeer<==



  • Poste doch mal Dein Beispiel... aber bitte ein vollständiges und keine Code-Fragmente mit denen man nix anfangen kann...



  • //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    
    //#include <winnt.h>
    
    #include <winIOCtl.h> //DeviceIoControl
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    HANDLE hFile;
    _REPARSE_GUID_DATA_BUFFER* buffer;
    
    char *pOut;
    unsigned long int* lpByte;
    
    const char* MyFile = "C:\\Programme";
    
    hFile = CreateFile(MyFile, GENERIC_READ, 0, NULL,
            OPEN_EXISTING, 0, NULL);
    
    CloseHandle(hFile);
    
    DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, buffer, NULL, pOut,
                            sizeof(buffer), lpByte, NULL);
    
    Form1->Caption = buffer->ReparseTag;
    }
    //---------------------------------------------------------------------------
    

    ==>Eisbeer<==



  • Warum verwendest Du "REPARSE_GUID_DATA_BUFFER"?
    Hast Du die Links je mals angeschaut?
    Wo hast Du "lpByte" initialisiert?
    Wo hast Du die Rückgabewerte abgefragt?



  • Natürlich habe ich mir die Beispiele angesehen

    !!! Mehrmals studiert !!!

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #pragma hdrstop
    
    #include "Unit1.h"
    
    //#include <winnt.h>
    
    #include <winIOCtl.h> //DeviceIoControl
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    __fastcall TForm1::TForm1(TComponent* Owner)
            : TForm(Owner)
    {
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    struct REPARSE_DATA_BUFFER {
        DWORD  ReparseTag;
        WORD   ReparseDataLength;
        WORD   Reserved;
        struct {
            WORD   SubstituteNameOffset;
            WORD   SubstituteNameLength;
            WORD   PrintNameOffset;
            WORD   PrintNameLength;
            WCHAR  PathBuffer[1];
        } SymbolicLinkReparseBuffer;
    };
    
    HANDLE hFile;
    REPARSE_DATA_BUFFER* buffer;
    
    const char* MyFile = "C:\\Programme";
    
    hFile = CreateFile(MyFile, GENERIC_READ, 0, NULL,
            OPEN_EXISTING, 0, NULL);
    
    CloseHandle(hFile);
    
    DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, buffer, NULL, NULL,
                            sizeof(buffer), NULL, NULL);
    
    buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
    
    AnsiString Pfad = buffer->ReparseTag;
    
    ShowMessage(Pfad);
    

    Beim Abfragen der Rückgabe-Werte habe ich ja das Problem immer nur eine Zahl zu bekommen und kein Verzeichnis.

    ==>Eisbeer<==



  • Wo wird der Speicher für "REPARSE_DATA_BUFFER" allokiert?
    Wo prüfst Du die Rückgabewerte der *Funktionen"?



  • Ich komme damit überhaupt nicht klar...

    ==>Eisbeer<==



  • Ich habe mich durch Seitenweise QuellCode und Internet-Seiten gelesen und verstehe immer noch nicht wie ich die Funktionen anwenden muss.

    Könnte mir das jemand erklären oder hat das schonmal gemacht ?
    Ein kleines Beispiel wäre ganz gut.

    Ich benutze den BcB 6. Dieser wirft mir beim compilieren der beispiele nur Fehlermeldungen um den Kopf.

    Es geht ja nur um 2 Win-API Auftrufe. Das kann doch nicht sooooo schwer sein...

    ==>Eisbeer<==



  • Also, extra für Dich:

    #include <windows.h>
    #include <tchar.h>
    #include <stdio.h>
    
    typedef struct _REPARSE_DATA_BUFFER {
      ULONG  ReparseTag;
      USHORT  ReparseDataLength;
      USHORT  Reserved;
      union {
        struct {
          USHORT  SubstituteNameOffset;
          USHORT  SubstituteNameLength;
          USHORT  PrintNameOffset;
          USHORT  PrintNameLength;
          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;
    
    #define REPARSE_DATA_BUFFER_HEADER_SIZE  FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer)
    
    #define MAXIMUM_REPARSE_DATA_BUFFER_SIZE  ( 16 * 1024 )
    
    // See: Setting the Backup and Restore Privileges
    // http://msdn2.microsoft.com/en-us/library/aa387705
    HRESULT ModifyPrivilege(IN LPCTSTR szPrivilege, IN BOOL fEnable)
    {
      HRESULT hr = S_OK;
      TOKEN_PRIVILEGES NewState;
      LUID             luid;
      HANDLE hToken    = NULL;
    
      // Open the process token for this process.
      if (!OpenProcessToken(GetCurrentProcess(),
        TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
        &hToken ))
      {
        _tprintf(_T("Failed OpenProcessToken\n"));
        return ERROR_FUNCTION_FAILED;
      }
    
      // Get the local unique ID for the privilege.
      if ( !LookupPrivilegeValue( NULL,
        szPrivilege,
        &luid ))
      {
        CloseHandle( hToken );
        _tprintf(_T("Failed LookupPrivilegeValue\n"));
        return ERROR_FUNCTION_FAILED;
      }
    
      // Assign values to the TOKEN_PRIVILEGE structure.
      NewState.PrivilegeCount = 1;
      NewState.Privileges[0].Luid = luid;
      NewState.Privileges[0].Attributes = 
        (fEnable ? SE_PRIVILEGE_ENABLED : 0);
    
      // Adjust the token privilege.
      if (!AdjustTokenPrivileges(hToken,
        FALSE,
        &NewState,
        0,
        NULL,
        NULL))
      {
        _tprintf(_T("Failed AdjustTokenPrivileges\n"));
        hr = ERROR_FUNCTION_FAILED;
      }
    
      // Close the handle.
      CloseHandle(hToken);
    
      return hr;
    }  // ModifyPrivilege
    
    int main()
    {
      HANDLE hFile;
      LPCTSTR szMyFile = _T("C:\\Programme");
    
    	DWORD dwFA = GetFileAttributes(szMyFile);
      if (dwFA & FILE_ATTRIBUTE_REPARSE_POINT)
        _tprintf(_T("'%s' is a reparse point\n"), szMyFile);
      else
        _tprintf(_T("'%s' is NOT a reparse point\n"), szMyFile);
    
      ModifyPrivilege(SE_BACKUP_NAME, TRUE);
    
      // Open the directory to query the reparse-data
      hFile = CreateFile(szMyFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL);
      if (hFile == INVALID_HANDLE_VALUE)
      {
        _tprintf(_T("Could not open dir '%s'; error: %d\n"), szMyFile, GetLastError());
        return 1;
      }
    
      DWORD dwBufSize = MAXIMUM_REPARSE_DATA_BUFFER_SIZE;
      REPARSE_DATA_BUFFER* rdata;
      rdata = (REPARSE_DATA_BUFFER*) malloc(dwBufSize);
    
      DWORD dwRetLen;
      BOOL bRet = DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, rdata, dwBufSize, &dwRetLen, NULL);
      if (bRet == FALSE)
      {
        _tprintf(_T("DeviceIoControl failed with error: %d\n"), GetLastError());
        CloseHandle(hFile);
        return 1;
      }
      CloseHandle(hFile);
    
      _tprintf(_T("ReparseTag: %d - "), rdata->ReparseTag);
      if (IsReparseTagMicrosoft(rdata->ReparseTag))
      {
        _tprintf(_T("MicrosoftTag - "));
      }
      if (IsReparseTagNameSurrogate(rdata->ReparseTag))
      {
        _tprintf(_T("NameSurrogate - "));
      }
    
      switch(rdata->ReparseTag)
      {
      case IO_REPARSE_TAG_MOUNT_POINT:
        _tprintf(_T("MOUNT_POINT\n"));
        break;
      case IO_REPARSE_TAG_HSM:
        _tprintf(_T("HSM\n"));
        break;
      case IO_REPARSE_TAG_SIS:
        _tprintf(_T("SIS\n"));
        break;
      case IO_REPARSE_TAG_SYMLINK:
        _tprintf(_T("SYMLINK\n"));
        break;
      case IO_REPARSE_TAG_DFSR:
        _tprintf(_T("DFSR\n"));
        break;
      case IO_REPARSE_TAG_DFS:
        _tprintf(_T("DFS\n"));
        break;
      default:
        _tprintf(_T("unknown\n"));
        break;
      }
    
      if (IsReparseTagMicrosoft(rdata->ReparseTag))
      {
        size_t slen = rdata->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
        WCHAR *szSubName = new WCHAR[slen+1];
        wcsncpy(szSubName, &rdata->MountPointReparseBuffer.PathBuffer[rdata->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
        szSubName[slen] = 0;
        printf("SubstitutionName (len: %d): '%S'\n", rdata->MountPointReparseBuffer.SubstituteNameLength, szSubName);
        delete [] szSubName;
    
        size_t plen = rdata->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR);
        WCHAR *szPrintName = new WCHAR[plen+1];
        wcsncpy(szPrintName, &rdata->MountPointReparseBuffer.PathBuffer[rdata->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
        szPrintName[plen] = 0;
        printf("PrintName (len: %d): '%S'\n", rdata->MountPointReparseBuffer.PrintNameLength, szPrintName);
        delete [] szPrintName;
      }
      else
      {
        _tprintf(_T("Not a Microsoft-reparse point - could not query data!\n"));
      }
    
      free(rdata);
    }
    

    Man beachte aber: Unter Vista läuft dies nur als *echter* Admin!



  • Ich habe den Code in der Mittagspause in ein Consolen-Programm gepackt, funktioniert in deiner Fassung genau wie er soll.
    ==> 👍 Vielen Dank 👍 <==

    In der Switch-Anweisung switch(rdata->ReparseTag) sind die Symbole

    IO_REPARSE_TAG_SYMLINK
    IO_REPARSE_TAG_DFSR
    IO_REPARSE_TAG_DFS

    Undefiniert (Header-Datei winnt.h Zeile 5357 Version 0082)

    Welche Winnt.h hattes du in dem obigen Beispiel benutzt ?

    //-------------------
    

    Gibt es eine Möglichkeit die gewünschte Information ohne ´echte Administrator-Rechte` zu erhalten ??
    Es wird ja schon das Privileg 'SE_BACKUP_NAME' gesetzt.
    Machbar ist es, nur wie ?

    //-------------------
    

    Wenn MyFile = "C:\\Programme\Gemeinsame Dateien"; ==> 'C:\Program Files\Common Files\' gibt es keine Ausgabe des PrintNames.

    Könntest du mir das erklären ?

    ==>Eisbeer<==



  • Winnt.h (VisualStudio 2008 / v0091)



  • Wenn Du mit VS2008 ein Default-Projekt anlegst und den Code dann reinkopierst sollte alles gehen.

    PS: Es muss aber wohl noch ein Weg ohne Admin-Rechte geben... muss ich aber auch zuerst sichen...



  • Funktioniert alles bis auf die Sache mit den Admin-Rechten unter Vista.

    Es ist komisch, dass die Anwendung das 'SE_BACKUP_NAME' Privileg braucht und dann trotzdem Admin-Rechte verlangt. Wenn das Privileg nicht gesetzt ist und das Programm als Admin läuft, funktioniert´s auch nicht...

    Admin-Rechte und trotzdem Privileg ? MSDN hat auch keinen Hinweis dazu.

    ==>Eisbeer<==




Anmelden zum Antworten