Я получаю неверный доступ к памяти, когда я запускаю следующий код
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, &FD);
if (INVALID_HANDLE_VALUE != hFind)
{
vector<wstring> 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, &rdata, dwBufSize, &bytesReturned, NULL))
{
if (IsReparseTagMicrosoft(rdata->ReparseTag))
{
if (rdata->ReparseTag == IO_REPARSE_TAG_SYMLINK)
{
printf("Symbolic-Link\n");
size_t slen = rdata->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
WCHAR *szSubName = new WCHAR[slen + 1];
wcsncpy_s(szSubName, slen + 1, &rdata->SymbolicLinkReparseBuffer.PathBuffer[rdata->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
szSubName[slen] = 0;
printf("SubstitutionName (len: %d): '%S'\n", rdata->SymbolicLinkReparseBuffer.SubstituteNameLength, szSubName);
delete[] szSubName;
size_t plen = rdata->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR);
WCHAR *szPrintName = new WCHAR[plen + 1];
wcsncpy_s(szPrintName, plen + 1, &rdata->SymbolicLinkReparseBuffer.PathBuffer[rdata->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
szPrintName[plen] = 0;
printf("PrintName (len: %d): '%S'\n", rdata->SymbolicLinkReparseBuffer.PrintNameLength, szPrintName);
delete[] szPrintName;
}
else if (rdata->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
{
printf("Mount-Point\n");
size_t slen = rdata->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
WCHAR *szSubName = new WCHAR[slen + 1];
wcsncpy_s(szSubName, slen + 1, &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_s(szPrintName, plen + 1, &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
{
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, &FD));
}
else
ErrorExit("FindFirstFile");
но следующий код работает нормально.
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, &dwRetLen, NULL);
if (bRet == FALSE)
{
printf(("DeviceIoControl failed with error: %d\n"), GetLastError());
CloseHandle(hFile);
return;
}
CloseHandle(hFile);
if (IsReparseTagMicrosoft(rdata->ReparseTag))
{
if (rdata->ReparseTag == IO_REPARSE_TAG_SYMLINK)
{
printf("Symbolic-Link\n");
size_t slen = rdata->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
WCHAR *szSubName = new WCHAR[slen + 1];
wcsncpy_s(szSubName, slen + 1, &rdata->SymbolicLinkReparseBuffer.PathBuffer[rdata->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(WCHAR)], slen);
szSubName[slen] = 0;
printf("SubstitutionName (len: %d): '%S'\n", rdata->SymbolicLinkReparseBuffer.SubstituteNameLength, szSubName);
delete[] szSubName;
size_t plen = rdata->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(WCHAR);
WCHAR *szPrintName = new WCHAR[plen + 1];
wcsncpy_s(szPrintName, plen + 1, &rdata->SymbolicLinkReparseBuffer.PathBuffer[rdata->SymbolicLinkReparseBuffer.PrintNameOffset / sizeof(WCHAR)], plen);
szPrintName[plen] = 0;
printf("PrintName (len: %d): '%S'\n", rdata->SymbolicLinkReparseBuffer.PrintNameLength, szPrintName);
delete[] szPrintName;
}
else if (rdata->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT)
{
printf("Mount-Point\n");
size_t slen = rdata->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR);
WCHAR *szSubName = new WCHAR[slen + 1];
wcsncpy_s(szSubName, slen + 1, &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_s(szPrintName, plen + 1, &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
{
printf("No Mount-Point or Symblic-Link...\n");
}
}
else
{
printf(("Not a Microsoft-reparse point - could not query data!\n"));
}
free(rdata);
Я пытаюсь получить данные повторного анализа для файлов в заданной папке. Это мое REPARSE_DATA_BUFFER
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;
Я не знаю, где я ошибся. Пожалуйста, помогите мне исправить мой первый код.
ваш код, содержащий 2 ошибки, как минимум
Вы безоговорочно звоните FSCTL_GET_REPARSE_POINT
для всех файлов, но вы должны сделать это только
if (FD.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {..}
в противном случае вы получили ERROR_NOT_A_REPARSE_POINT
в DeviceIoControl
а потом ErrorExit("DeviceIoControl");
казнены.
и вторая ошибка в этой строке:
DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, &rdata, dwBufSize, &bytesReturned, NULL)
&rdata
— !!
когда должно быть
DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, rdata, dwBufSize, &bytesReturned, NULL)
Других решений пока нет …