首页 > 代码库 > DeviceIoControl:通过API访问设备驱动程序;并获取window文件/文件夹id

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);

 

DeviceIoControl:通过API访问设备驱动程序;并获取window文件/文件夹id