📄 ncfile.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 + -