⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ncfile.c

📁 演示如何通过DeviceIoControl来读写硬盘的示例demo
💻 C
字号:
/*
  Notice:      Copyright(c)  - All Rights Reserved    
  
  $Source: H:/SrcBak/cvsroot/clone/protocol/common/ncfile.c,v $ 
  $Author: Snowtree $ 
  $Revision: 1.5 $ 
  $Date: 2006/06/12 15:51:27 $ 
  
*/

/**
  \brief: network clone file module 
  
  
*/
#ifdef _WIN32
#include <windows.h>
#include <winioctl.h>
#else
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <linux/hdreg.h>
#endif

#include "ncfile.h"

// for win32, read/write to hard disk, the buffer must align to sector size
#ifdef _WIN32
#define DISK_BUFFER_SIZE    1024 * 8
static u8   DiskBuffer[DISK_BUFFER_SIZE];
#endif

#define IOCTL_DISK_GET_DRIVE_GEOMETRY_EX	CTL_CODE(0x00000007, 0x0028, METHOD_BUFFERED, FILE_ANY_ACCESS)

typedef struct _DISK_GEOMETRY_EX {
  DISK_GEOMETRY  Geometry;
  LARGE_INTEGER  DiskSize;
  UCHAR  Data[1];
} DISK_GEOMETRY_EX, *PDISK_GEOMETRY_EX;

int NCFileOpen (const char *file, int oflags)
{
    int handle;

#ifdef _WIN32

    if (oflags == NC_O_WRONLY)
        oflags = GENERIC_WRITE;
    else if (oflags == NC_O_RDWR)
        oflags = GENERIC_READ | GENERIC_WRITE;
    else
        oflags = GENERIC_READ;    

    handle = (int)CreateFile(file, 
                       oflags,                              // access flags
                       FILE_SHARE_READ | FILE_SHARE_WRITE,  // share mode
                       NULL,                                // default security attributes
                       OPEN_EXISTING,                       // disposition
                       0,                                   // file attributes
                       NULL);                               // don't copy any file's attributes
                       
#else
    if (oflags == NC_O_WRONLY)
        oflags = O_WRONLY | O_CREAT;
    else if (oflags == NC_O_RDWR)
        oflags = O_RDWR | O_CREAT;
    else
        oflags = O_RDONLY;

    handle = open(file, oflags | O_LARGEFILE);
#endif

    return handle;
}


int NCFileClose(int handle)
{
#ifdef _WIN32
    return CloseHandle((HANDLE)handle);
#else
    return close(handle);
#endif
}

int NCFileRead (int handle, void *buffer, u32 count, s64 position)
{    
#ifdef _WIN32
    //LARGE_INTEGER pos, newpos;
	LONG	pos;
    DWORD         len;
    int rc;

    pos = (LONG) position & ~0x1FF;
    
    //rc = SetFilePointerEx((HANDLE)handle, pos, &newpos, FILE_BEGIN);
	rc = SetFilePointer((HANDLE)handle, pos, NULL, FILE_BEGIN);

    len = (count + 511) & ~511;
    if (len > DISK_BUFFER_SIZE)
        len = DISK_BUFFER_SIZE;            

    if (ReadFile((HANDLE)handle, DiskBuffer, len, (LPDWORD)&len, NULL))
    {
        len = min(count, len);

        memcpy(buffer, DiskBuffer + (position & 0x1FF), len);
    
        return len;
    }
    else
        return -1;
    
#else
    lseek(handle, position, SEEK_SET);
    return read(handle, buffer, count);
#endif
}

int NCFileWrite(int handle, void *buffer, u32 count, s64 position)
{
#if 1
    return count;
#else
#ifdef _WIN32
    long low, high;

    low  = (LONG)position;
    high = (LONG)(position >> 32);
    SetFilePointer((HANDLE)handle, low, &high, FILE_BEGIN);

    if (WriteFile((HANDLE)handle, buffer, count, (LPDWORD)&count, NULL))
        return count;
    else
        return -1;
#else
    lseek(handle, position, SEEK_SET);
    return write(handle, buffer, count);
#endif

#endif
}

s64 NCFileSize(int handle)
{
#ifdef _WIN32
    //LARGE_INTEGER       size;
	DWORD       size;

    //if (GetFileSizeEx((HANDLE)handle, &size))
	if (GetFileSize((HANDLE)handle, &size))
        return (s64) size;
    else
    {
        DISK_GEOMETRY_EX    geometry;
        DWORD               len;
        
        // maybe the file is a disk     
        if (DeviceIoControl((HANDLE)handle, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, 
            NULL, 0, &geometry, sizeof(geometry), &len, NULL))            
            return geometry.DiskSize.QuadPart;
        else
            return 0;
    }

#else
    struct stat stat;

    if (fstat(handle, &stat))
        return stat.st_size;
    else
    {
        /**
            should use HDIO_GETGEO_BIG and struct hd_geometry_big instead, 
         but 2T disk should be ok currently.
        */
        struct hd_geometry geometry; 

        if (ioctl(handle, HDIO_GETGEO, &geometry) == 0)
            return (s64)geometry.cylinders * geometry.heads * geometry.sectors * 512;
        else        
            return 0;
    }
#endif
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -