Код (Text): #include <windows.h> #include <winioctl.h> #include <stdio.h> #include <iostream> //#include "ntdddisc.h" using namespace std; void ErrorExit(LPTSTR lpszFunction) { TCHAR szBuf[80]; LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); wsprintf(szBuf, "%s failed with error %d: %s", lpszFunction, dw, lpMsgBuf); MessageBox(NULL, szBuf, "Error", MB_OK); LocalFree(lpMsgBuf); ExitProcess(dw); } int main(int argc, char *argv[]) { PARTITION_INFORMATION pinf; DRIVE_LAYOUT_INFORMATION dli; int size_dli = sizeof(dli)+(7*sizeof(pinf)); BOOL bResult, pResult; HANDLE hDevice1, hDevice2; DWORD junk2; LPDWORD junk1; hDevice1 = CreateFile("\\\\.\\PHYSICALDRIVE0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice1 == INVALID_HANDLE_VALUE) { return (FALSE); } hDevice2 = CreateFile("\\\\.\\G:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice2 == INVALID_HANDLE_VALUE) { return (FALSE); } pResult = DeviceIoControl(hDevice1, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0, &dli, size_dli, (LPDWORD)&junk1, (LPOVERLAPPED) NULL); bResult = DeviceIoControl(hDevice2, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &pinf, sizeof(pinf), &junk2, NULL); CloseHandle(hDevice1); CloseHandle(hDevice2); // if (bResult) // { // printf("StartingOffset:\t\t%I64d\n", pinf.StartingOffset); // printf("PartitionLength:\t%I64d\n", pinf.PartitionLength); // cout << "HiddenSectors:\t\t" << (ULONG)pinf.HiddenSectors << endl; // cout << "PartitionNumber:\t" << (ULONG)pinf.PartitionNumber << endl; // cout << "PartitionType:\t\t" << (ULONG)pinf.PartitionType << endl; // cout << "BootIndicator:\t\t" << (ULONG)pinf.BootIndicator << endl; // cout << "RecognizedPartition:\t" << (ULONG)pinf.RecognizedPartition << endl; // cout << "RewritePartition:\t" << (ULONG)pinf.RewritePartition << endl; // } // else // { // ErrorExit(0); // } if (pResult) { printf("Number of partiton = %ld\n", (ULONG) dli.PartitionCount); // cout << "PartitionCount:\t" << (ULONG)dli.PartitionEntry[1].PartitionNumber << endl; } else { ErrorExit(0); } // return ((int)bResult); } Пытаюсь получить информацию о разделах (всего их у меня 7, включая сам жёсткий диск) используя IOCTL_DISK_GET_DRIVE_LAYOUT. Выдаётся ошибка 998: Неверная попытка доступа к адресу памяти... Не могу вкурить, моск растерян совершенно
Код (Text): #include <windows.h> #include <winioctl.h> #include <stdio.h> #include <iostream> //#include "ntdddisc.h" using namespace std; void ErrorExit(LPTSTR lpszFunction) { TCHAR szBuf[80]; LPVOID lpMsgBuf; DWORD dw = GetLastError(); FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL ); wsprintf(szBuf, "%s failed with error %d: %s", lpszFunction, dw, lpMsgBuf); MessageBox(NULL, szBuf, "Error", MB_OK); LocalFree(lpMsgBuf); ExitProcess(dw); } int main(int argc, char *argv[]) { PARTITION_INFORMATION pinf; DRIVE_LAYOUT_INFORMATION dli; int size_dli = sizeof(dli)+(7*sizeof(pinf)); char * temp = new char[4096]; BOOL bResult, pResult; HANDLE hDevice1, hDevice2; DWORD junk2; LPDWORD junk1; hDevice1 = CreateFile("\\\\.\\PHYSICALDRIVE0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice1 == INVALID_HANDLE_VALUE) { return (FALSE); } hDevice2 = CreateFile("\\\\.\\G:", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hDevice2 == INVALID_HANDLE_VALUE) { return (FALSE); } pResult = DeviceIoControl(hDevice1, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0, (LPVOID) temp, (DWORD) 4096, (LPDWORD)&junk1, (LPOVERLAPPED) NULL); bResult = DeviceIoControl(hDevice2, IOCTL_DISK_GET_PARTITION_INFO, NULL, 0, &pinf, sizeof(pinf), &junk2, NULL); CloseHandle(hDevice1); CloseHandle(hDevice2); // if (bResult) // { // printf("StartingOffset:\t\t%I64d\n", pinf.StartingOffset); // printf("PartitionLength:\t%I64d\n", pinf.PartitionLength); // cout << "HiddenSectors:\t\t" << (ULONG)pinf.HiddenSectors << endl; // cout << "PartitionNumber:\t" << (ULONG)pinf.PartitionNumber << endl; // cout << "PartitionType:\t\t" << (ULONG)pinf.PartitionType << endl; // cout << "BootIndicator:\t\t" << (ULONG)pinf.BootIndicator << endl; // cout << "RecognizedPartition:\t" << (ULONG)pinf.RecognizedPartition << endl; // cout << "RewritePartition:\t" << (ULONG)pinf.RewritePartition << endl; // } // else // { // ErrorExit(0); // } if (pResult) { // DRIVE_LAYOUT_INFORMATION *ptr = (DRIVE_LAYOUT_INFORMATION *)dli; cout<<"partcount"<<(DRIVE_LAYOUT_INFORMATION *)dli.PartitionCount; // printf("Number of partiton = %ld\n", (ULONG) dli.PartitionCount); // cout << "PartitionCount:\t" << (ULONG)dli.PartitionEntry[1].PartitionNumber << endl; } else { ErrorExit(0); } // return ((int)bResult); } Проблему с памятью вроде решил, теперь пишет: Run-Time Check Failure #3 - The variable 'dli' is being used without being defined Вроде dli определял.......?
кажется проблема связана с тем что 1й раздел скрытый и windows его не монтирует... Видимо вместо CreateFile надо использовать что-то на уровне ядра, например NtOpen... Если пользовать CreateFile то программка не увидит разделов ext2/ext3 и иже с ними, неродными для Windows
Да ни при чём здесь скрытые разделы. DeviceIoControl записывает данные туда, куда ей сказали это делать, то есть в буфер temp. А переменная dli с буфером temp никак не связана. Правильный код был бы типа Код (Text): DRIVE_LAYOUT_INFORMATION* dlip; ... dlip = (DRIVE_LAYOUT_INFORMATION*)temp; cout << dlip->PartitionCount;