RearsePoint
-
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_DFSUndefiniert (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<==
-