DeviceIoControl:通过API访问设备驱动程序;并获取window文件/文件夹id
1.设备句柄可以用API函数CreateFile获得。它的原型为
HANDLE CreateFile(
LPCTSTR lpFileName, // 文件名/设备路径
DWORD dwDesiredAccess, // 访问方式
DWORD dwShareMode, // 共享方式
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // 安全描述符指针
DWORD dwCreationDisposition, // 创建方式
DWORD dwFlagsAndAttributes, // 文件属性及标志
HANDLE hTemplateFile // 模板文件的句柄
);
2.DeviceIoControl的函数原型为
BOOL DeviceIoControl(
HANDLE hDevice, // 设备句柄
DWORD dwIoControlCode, // 控制码
LPVOID lpInBuffer, // 输入数据缓冲区指针
DWORD nInBufferSize, // 输入数据缓冲区长度
LPVOID lpOutBuffer, // 输出数据缓冲区指针
DWORD nOutBufferSize, // 输出数据缓冲区长度
LPDWORD lpBytesReturned, // 输出数据实际长度单元长度
LPOVERLAPPED lpOverlapped // 重叠操作结构指针
);
3.通过DeviceIoControl获取硬盘的基本参数示例
#include <windows.h> #include <winioctl.h> BOOL GetDriveGeometry(DISK_GEOMETRY *pdg) { HANDLE hDevice; // handle to the drive to be examined BOOL bResult; // results flag DWORD junk; // discard results hDevice = CreateFile("////.//PhysicalDrive0", // drive to open 0, // no access to the drive FILE_SHARE_READ | // share mode FILE_SHARE_WRITE, NULL, // default security attributes OPEN_EXISTING, // disposition 0, // file attributes NULL); // do not copy file attributes if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive { return (FALSE); } bResult = DeviceIoControl(hDevice, // device to be queried IOCTL_DISK_GET_DRIVE_GEOMETRY, // operation to perform NULL, 0, // no input buffer pdg, sizeof(*pdg), // output buffer &junk, // # bytes returned (LPOVERLAPPED) NULL); // synchronous I/O CloseHandle(hDevice); return (bResult); } int main(int argc, char *argv[]) { DISK_GEOMETRY pdg; // disk drive geometry structure BOOL bResult; // generic results flag ULONGLONG DiskSize; // size of the drive, in bytes bResult = GetDriveGeometry (&pdg); if (bResult) { printf("Cylinders = %I64d/n", pdg.Cylinders); printf("Tracks per cylinder = %ld/n", (ULONG) pdg.TracksPerCylinder); printf("Sectors per track = %ld/n", (ULONG) pdg.SectorsPerTrack); printf("Bytes per sector = %ld/n", (ULONG) pdg.BytesPerSector); DiskSize = pdg.Cylinders.QuadPart * (ULONG)pdg.TracksPerCylinder * (ULONG)pdg.SectorsPerTrack * (ULONG)pdg.BytesPerSector; printf("Disk size = %I64d (Bytes) = %I64d (Mb)/n", DiskSize, DiskSize / (1024 * 1024)); } else { printf("GetDriveGeometry failed. Error %ld./n", GetLastError()); } return ((int)bResult); }
注:以上是从别的地方参考获取的,至于地址已经忘了,见谅~
4.获取window文件/文件夹id,如打开中的doc文件也可获取到
在window下,每个文件/文件夹都有一个专属的id,即便是拷贝的一个相同的文件,在window下的id都是不一样的。不过,office的文件会有所不同,如果你用office的文件执行了修改并保存,其实它的实际操作是你打开文件时,会创建一个缓存文件,然后当你修改完成并保存后,它会把当前的文件拷贝并到缓存文件中、删除原文件、重命名缓存文件,其实就相当于创建一个新的文件。所以,修改office文件,它window的id是会变化的。
但其它的文件则是唯一的。下面是获取的方法:
HANDLE hFile = INVALID_HANDLE_VALUE; DWORD cbOut; FILE_OBJECTID_BUFFER buf = {0}; QFileInfo file(filePath); if (file.isDir()) { hFile = CreateFile((wchar_t*)filePath.utf16(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE , NULL, //security attributes OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | //<- the required priviliges for this flag are: SE_BACKUP_NAME and SE_RESTORE_NAME. CPrivilegeEnabler takes care of that. NULL, NULL); } else { hFile = CreateFile((wchar_t*)filePath.utf16(), 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); } if(hFile == INVALID_HANDLE_VALUE) { Q_DEBUG() << QString("CreateFile (%1) failed with: %2").arg(filePath).arg(GetLastError()); fileID = ""; return ret; } if (DeviceIoControl(hFile, FSCTL_CREATE_OR_GET_OBJECT_ID, NULL, 0, &buf, sizeof(buf), &cbOut, NULL)) //DeviceIoControl仅支持NTFS { GUID guid; CopyMemory(&guid, &buf.ObjectId, sizeof(GUID)); WCHAR szGuid[39]; StringFromGUID2(guid, szGuid, 39); fileID = QString::fromStdWString(szGuid); ret = true; } CloseHandle(hFile);