+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.h
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2006-2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
#ifndef __HOS__fatvol_h__
{
FATVOL_UINT uiClusterNum;
int iDirty;
- unsigned char *pubBuf;
} T_FATVOL_CLUSTERBUF;
C_VOLUMEOBJ VolumeObj; /* ボリュームオブジェクトを継承 */
HANDLE hBlockFile; /**< ブロックデバイスドライバのハンドル */
-
+
+ int iOpenCount;
+
int iFatType; /**< FATのタイプ */
FILE_POS Offset; /**< ディスクのオフセット */
FILE_POS DriveSize; /**< ドライブの総サイズ */
unsigned char *pubFatBuf; /**< FATのバッファリングメモリ */
unsigned char *pubFatDirty; /**< FATの更新フラグ */
- T_FATVOL_CLUSTERBUF *pClusterBuf;
+ T_FATVOL_CLUSTERBUF **ppClusterBuf;
int iClusterBufNum;
int iClusterBufIndex;
} C_FATVOL;
extern "C" {
#endif
-int FatVol_Create(C_FATVOL *self, HANDLE hBlockFile);
+int FatVol_Create(C_FATVOL *self, const char *pszPath);
void FatVol_Delete(C_DRVOBJ *self);
HANDLE FatVol_CreateFile(C_FATVOL *self, FATVOL_UINT uiCluster, HANDLE hDir, int iDirEntry, int iMode);
#endif /* __HOS__fatdrive_h__ */
-
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.c
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include "fatvol_local.h"
+
+
+/** クローズ */
+void FatVol_Close(C_DRVOBJ *pDrvObj, C_FILEOBJ *pFileObj)
+{
+ C_FATVOL *self;
+ C_FATFILE *pFile;
+
+ /* upper cast */
+ self = (C_FATVOL *)pDrvObj;
+ pFile = (C_FATFILE *)pFileObj;
+
+ /* クローズ処理 */
+ if ( --self->iOpenCount == 0 )
+ {
+ }
+
+ /* ディスクリプタ削除 */
+ SysMem_Free(pFile);
+}
+
+
+/* end of file */
FATVOL_UINT uiPos;
FATVOL_UINT uiSize;
- if ( uiCluster >= 0xffff0000 && (self->iFatType == FATVOL_TYPE_FAT12 || self->iFatType == FATVOL_TYPE_FAT16) )
+ if ( uiCluster >= 0xf0000000 && (self->iFatType == FATVOL_TYPE_FAT12 || self->iFatType == FATVOL_TYPE_FAT16) )
{
/* FAT12/16 のルートディレクトリを 0xf0000000 にマップ */
uiCluster -= 0xf0000000;
/* 読み出し位置移動 */
- uiPos = (self->RootDirSector + (uiCluster * self->SectorsPerCluster)) * self->BytesPerSector;
+ uiPos = (self->RootDirSector + (uiCluster * self->SectorsPerCluster)) * self->BytesPerSector + self->Offset;
if ( File_Seek(self->hBlockFile, uiPos, FILE_SEEK_SET) != uiPos )
{
return FATVOL_ERR_NG;
else
{
/* 読み出し位置移動 */
- uiPos = (self->Cluster0Sector + (uiCluster * self->SectorsPerCluster)) * self->BytesPerSector;
+ uiPos = (self->Cluster0Sector + (uiCluster * self->SectorsPerCluster)) * self->BytesPerSector + self->Offset;
if ( File_Seek(self->hBlockFile, uiPos, FILE_SEEK_SET) != uiPos )
{
return FATVOL_ERR_NG;
FATVOL_UINT uiPos;
FATVOL_UINT uiSize;
- if ( uiCluster >= 0xffff0000 && (self->iFatType == FATVOL_TYPE_FAT12 || self->iFatType == FATVOL_TYPE_FAT16) )
+ if ( uiCluster >= 0xf0000000 && (self->iFatType == FATVOL_TYPE_FAT12 || self->iFatType == FATVOL_TYPE_FAT16) )
{
- /* FAT12/16 のルートディレクトリを 0xffff0000 にマップ */
+ /* FAT12/16 のルートディレクトリを 0xf0000000 にマップ */
uiCluster -= 0xf0000000;
/* 書き出し位置移動 */
- uiPos = (self->RootDirSector + (uiCluster * self->SectorsPerCluster)) * self->BytesPerSector;
+ uiPos = (self->RootDirSector + (uiCluster * self->SectorsPerCluster)) * self->BytesPerSector + self->Offset;
if ( File_Seek(self->hBlockFile, uiPos, FILE_SEEK_SET) != uiPos )
{
return FATVOL_ERR_NG;
else
{
/* 書き出し位置移動 */
- uiPos = (self->Cluster0Sector + (uiCluster * self->SectorsPerCluster)) * self->BytesPerSector;
+ uiPos = (self->Cluster0Sector + (uiCluster * self->SectorsPerCluster)) * self->BytesPerSector + self->Offset;
if ( File_Seek(self->hBlockFile, uiPos, FILE_SEEK_SET) != uiPos )
{
return FATVOL_ERR_NG;
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.h
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2006-2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
#include <string.h>
#include "fatvol_local.h"
+
/* 仮想関数テーブル */
const T_VOLUMEOBJ_METHODS FatVol_VolumeObjMethods =
{
/* コンストラクタ */
-int FatVol_Create(C_FATVOL *self, HANDLE hBlockFile)
+int FatVol_Create(C_FATVOL *self, const char *pszPath)
{
unsigned char ubBuf[512];
int i;
-
- /* 親クラスコンストラクタ呼び出し */
- VolumeObj_Create(&self->VolumeObj, &FatVol_VolumeObjMethods);
+
+ /* ブロックデバイスのオープン */
+ self->hBlockFile = File_Open(pszPath, FILE_OPEN_READ | FILE_OPEN_WRITE);
+ if ( self->hBlockFile == HANDLE_NULL )
+ {
+ return FATVOL_ERR_NG;
+ }
- /* ドライブの設定 */
- self->hBlockFile = hBlockFile;
self->Offset = 0x33*512; /* 一時的に ちょいインチキ */
self->Cluster0Sector = self->RootDirSector
+ (((self->RootDirEntryNum * 32) + self->BytesPerSector - 1) / self->BytesPerSector)
- (2 * self->SectorsPerCluster); /**< クラスタ0の開始セクタ */
-
+
+ self->RootDirCluster = 0xf0000000;
+
/* FATバッファ準備 */
self->pubFatBuf = (unsigned char *)SysMem_Alloc(self->SectorPerFat * self->BytesPerSector);
self->pubFatDirty = (unsigned char *)SysMem_Alloc(self->SectorPerFat);
- /* FATバッファ準備 */
- File_Seek(self->hBlockFile, self->FatStartSector * self->BytesPerSector, FILE_SEEK_SET);
+ /* FAT読み出し */
+ File_Seek(self->hBlockFile, self->FatStartSector * self->BytesPerSector + self->Offset, FILE_SEEK_SET);
File_Read(self->hBlockFile, self->pubFatBuf, self->SectorPerFat * self->BytesPerSector);
memset(self->pubFatDirty, 0, self->SectorPerFat);
-
+
break;
case FATVOL_TYPE_FAT32:
/* クラスタバッファ取得 */
self->iClusterBufIndex = 0;
- self->iClusterBufNum = 32;
- self->pClusterBuf = (T_FATVOL_CLUSTERBUF *)SysMem_Alloc(sizeof(T_FATVOL_CLUSTERBUF) * self->iClusterBufNum);
+ self->iClusterBufNum = 8;
+ self->ppClusterBuf = (T_FATVOL_CLUSTERBUF **)SysMem_Alloc(sizeof(T_FATVOL_CLUSTERBUF *) * self->iClusterBufNum);
for ( i = 0; i < self->iClusterBufNum; i++ )
{
- self->pClusterBuf[i].uiClusterNum = FATVOL_CLUSTER_ENDMARKER;
- self->pClusterBuf[i].iDirty = 0;
- self->pClusterBuf[i].pubBuf = SysMem_Alloc(self->SectorsPerCluster * self->BytesPerSector);
+ self->ppClusterBuf[i] = SysMem_Alloc(sizeof(T_FATVOL_CLUSTERBUF) + self->SectorsPerCluster * self->BytesPerSector);
+ self->ppClusterBuf[i]->uiClusterNum = FATVOL_CLUSTER_ENDMARKER;
+ self->ppClusterBuf[i]->iDirty = 0;
}
+
+ /* 親クラスコンストラクタ呼び出し */
+ VolumeObj_Create(&self->VolumeObj, &FatVol_VolumeObjMethods);
return FATVOL_ERR_OK;
}
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.c
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include "fatvol_local.h"
+
+
+/** デストラクタ */
+void FatVol_Delete(C_DRVOBJ *pDrvObj)
+{
+}
+
+
+/* end of file */
--- /dev/null
+
+#include <stdio.h>
+#include "fatvol_local.h"
+
+
+HANDLE FatVol_FileCreate(C_FATVOL *self, FATVOL_UINT uiCluster, HANDLE hDir, int iDirEntry, int iMode)
+{
+ C_FATFILE *pFile;
+
+ /* create file descriptor */
+ if ( (pFile = SysMem_Alloc(sizeof(*pFile))) == NULL )
+ {
+ return HANDLE_NULL;
+ }
+ FileObj_Create(&pFile->FileObj, (C_DRVOBJ *)self, NULL);
+
+ /* 初期化 */
+ pFile->iMode = iMode;
+ pFile->uiStartCluster = uiCluster;
+ pFile->hDir = hDir;
+ pFile->iDirEntry = iDirEntry;
+
+ /* サイズ取得 */
+ if ( hDir != HANDLE_NULL )
+ {
+ pFile->FileSize = FatVol_GetFileSize(hDir, iDirEntry);
+ }
+
+ /* ファイルポインタ初期化 */
+ pFile->FilePos = 0;
+ pFile->uiCurrentCluster = pFile->uiStartCluster;
+
+
+ return (HANDLE)pFile;
+}
+
+
+/* end of file */
--- /dev/null
+
+#include <stdio.h>
+#include "fatvol_local.h"
+
+
+void FatVol_FileDelete(C_FATVOL *self, HANDLE hFile)
+{
+ C_FATFILE *pFile;
+
+ pFile = (C_FATFILE *)hFile;
+
+ FileObj_Delete(pFile);
+ SysMem_Free(pFile);
+}
+
+
+/* end of file */
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.c
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include "fatvol_local.h"
+
+
+FILE_ERR FatVol_Flush(C_DRVOBJ *pDrvObj, C_FILEOBJ *pFileObj)
+{
+ C_FATVOL *self;
+ C_FATFILE *pFile;
+
+ /* upper cast */
+ self = (C_FATVOL *)pDrvObj;
+ pFile = (C_FATFILE *)pFileObj;
+
+ return FILE_ERR_OK;
+}
+
+
+/* end of file */
unsigned long i;
/* FAT先頭へ移動 */
- File_Seek(self->hBlockFile, self->FatStartSector * self->BytesPerSector, FILE_SEEK_SET);
+ File_Seek(self->hBlockFile, self->FatStartSector * self->BytesPerSector + self->Offset, FILE_SEEK_SET);
for ( i = 0; i < self->FatNum; i++ )
{
for ( i = 0; i < self->iClusterBufNum; i++ )
{
/* 見つかれば既存バッファを返す */
- if ( self->pClusterBuf[i].uiClusterNum == uiCluster )
+ if ( self->ppClusterBuf[i]->uiClusterNum == uiCluster )
{
- *ppBuf = self->pClusterBuf[i].pubBuf;
+ *ppBuf = (char *)self->ppClusterBuf[i] + sizeof(T_FATVOL_CLUSTERBUF);
return FATVOL_ERR_OK;
}
}
/* 空のバッファを探す */
for ( i = 0; i < self->iClusterBufNum; i++ )
{
- if ( self->pClusterBuf[i].uiClusterNum == FATVOL_CLUSTER_ENDMARKER )
+ if ( self->ppClusterBuf[i]->uiClusterNum == FATVOL_CLUSTER_ENDMARKER )
{
break;
}
i = self->iClusterBufIndex++;
/* dirtyなら吐き出す */
- if ( self->pClusterBuf[i].iDirty )
+ if ( self->ppClusterBuf[i]->iDirty )
{
- if ( FatVol_ClusterWrite(self, self->pClusterBuf[i].uiClusterNum, self->pClusterBuf[i].pubBuf) != FATVOL_ERR_OK )
+ if ( FatVol_ClusterWrite(self, self->ppClusterBuf[i]->uiClusterNum, (char *)self->ppClusterBuf[i] + sizeof(T_FATVOL_CLUSTERBUF)) != FATVOL_ERR_OK )
{
return FATVOL_ERR_NG;
}
- self->pClusterBuf[i].iDirty = 0;
+ self->ppClusterBuf[i]->iDirty = 0;
}
- self->pClusterBuf[i].uiClusterNum = FATVOL_CLUSTER_ENDMARKER;
+ self->ppClusterBuf[i]->uiClusterNum = FATVOL_CLUSTER_ENDMARKER;
}
/* バッファに読み込み */
if ( iRead )
{
- if ( FatVol_ClusterRead(self, self->pClusterBuf[i].uiClusterNum, self->pClusterBuf[i].pubBuf) != FATVOL_ERR_OK )
+ if ( FatVol_ClusterRead(self, uiCluster, (char *)self->ppClusterBuf[i] + sizeof(T_FATVOL_CLUSTERBUF)) != FATVOL_ERR_OK )
{
return FATVOL_ERR_NG;
}
}
- self->pClusterBuf[i].iDirty = 0;
- self->pClusterBuf[i].uiClusterNum = uiCluster;
+ self->ppClusterBuf[i]->iDirty = 0;
+ self->ppClusterBuf[i]->uiClusterNum = uiCluster;
+
+ /* バッファ割り当て */
+ *ppBuf = (char *)self->ppClusterBuf[i] + sizeof(T_FATVOL_CLUSTERBUF);
+
return FATVOL_ERR_OK;
}
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.h
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2006-2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include <stdio.h>
+#include "fatvol_local.h"
+
+
+FILE_POS FatVol_GetFileSize(HANDLE hDir, int iDirEntry)
+{
+ unsigned char ubBuf[4];
+
+ File_Seek(hDir, 32*iDirEntry+28, FILE_SEEK_SET);
+ File_Read(hDir, ubBuf, 4);
+
+ return ubBuf[0] + (ubBuf[1] << 8) + (ubBuf[2] << 16) + (ubBuf[3] << 24);
+}
+
+
+/* end of file */
switch ( self->iFatType )
{
case FATVOL_TYPE_FAT12:
- /* 0xffff0000 からルートディレクトリをマップ */
- if ( uiCluster >= 0xffff0000 )
+ /* 0xf0000000 からルートディレクトリをマップ */
+ if ( uiCluster >= 0xf0000000 )
{
return uiCluster + 1;
}
break;
case FATVOL_TYPE_FAT16:
- /* 0xffff0000 からルートディレクトリをマップ */
- if ( uiCluster >= 0xffff0000 )
+ /* 0xf0000000 からルートディレクトリをマップ */
+ if ( uiCluster >= 0xf0000000 )
{
return uiCluster + 1;
}
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.c
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include "fatvol_local.h"
+
+
+FILE_ERR FatVol_IoControl(C_DRVOBJ *pDrvObj, C_FILEOBJ *pFileObj, int iFunc, void *pInBuf, FILE_SIZE InSize, const void *pOutBuf, FILE_SIZE OutSize)
+{
+ C_FATVOL *self;
+ C_FATFILE *pFile;
+
+ /* upper cast */
+ self = (C_FATVOL *)pDrvObj;
+ pFile = (C_FATFILE *)pFileObj;
+
+ switch ( iFunc )
+ {
+ case FILE_IOCTL_DIR_READ:
+ {
+ T_FILE_FILEINF *pFileInf;
+ unsigned char ubBuf[32];
+ char *p;
+ int i;
+
+ pFileInf = (T_FILE_FILEINF *)pInBuf;
+
+ do
+ {
+ /* 1エントリ読み出し */
+ if ( FatVol_Read(pDrvObj, pFileObj, ubBuf, 32) != 32 )
+ {
+ return FILE_ERR_NG;
+ }
+
+ /* 探索終了 */
+ if ( ubBuf[0] == 0x00 )
+ {
+ return FILE_ERR_NG;
+ }
+ } while ( ubBuf[0] == 0xe5 || ubBuf[0] == 0x2e );
+
+
+ /* ファイル名 */
+ p = pFileInf->szFileName;
+ for ( i = 0; i < 8; i++ )
+ {
+ if ( ubBuf[i] == ' ' || ubBuf[i] == '\0' )
+ {
+ break;
+ }
+ *p++ = ubBuf[i];
+ }
+
+ /* 拡張子 */
+ *p++ = '.';
+ for ( i = 0; i < 3; i++ )
+ {
+ if ( ubBuf[8+i] == ' ' || ubBuf[i] == '\0' )
+ {
+ break;
+ }
+ *p++ = ubBuf[8+i];
+ }
+ if ( *(p-1) == '.' )
+ {
+ p--;
+ }
+ *p++ = '\0';
+
+ /* 小文字化 */
+ p = pFileInf->szFileName;
+ for ( i = 0; p[i] != '\0'; i++ )
+ {
+ if ( p[i] >= 'A' && p[i] >= 'Z' )
+ {
+ p[i] += ('a' - 'A');
+ }
+ }
+
+ /* ファイルサイズ */
+ pFileInf->FileSize = ubBuf[28] + (ubBuf[29] << 8) + (ubBuf[30] << 16) + (ubBuf[31] << 24);
+
+ return FILE_ERR_OK;
+ }
+ break;
+ }
+
+ return FILE_ERR_NG;
+}
+
+
+/* end of file */
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.h
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2006-2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
#ifndef __HOS__fatvol_local_h__
#define FATVOL_TYPE_FAT32 3
+/* クラスタバッファ */
+typedef struct c_fatfile
+{
+ C_FILEOBJ FileObj; /* ボリュームオブジェクトを継承 */
+
+ int iMode; /* ファイルのモード */
+ FATVOL_UINT uiStartCluster; /* ファイルの先頭クラスタ */
+ HANDLE hDir; /* 所属するディレクトリのハンドル */
+ int iDirEntry; /* ディレクトリ内のエントリ位置 */
+
+ FILE_POS FilePos; /* ファイルポインタ */
+ FILE_POS FileSize; /* ファイルサイズ */
+
+ FATVOL_UINT uiCurrentCluster; /* 現在のクラスタ */
+} C_FATFILE;
+
+
#ifdef __cplusplus
extern "C" {
#endif
FILE_SIZE FatVol_Write(C_DRVOBJ *pDrvObj, C_FILEOBJ *pFileObj, const void *pData, FILE_SIZE Size);
FILE_ERR FatVol_Flush(C_DRVOBJ *pDrvObj, C_FILEOBJ *pFileObj);
-FILE_ERR FatVol_MakeDir(C_VOLUMEOBJ *self, const char *pszPath); /* サブディレクトリを作成 */
-FILE_ERR FatVol_Remove(C_VOLUMEOBJ *self, const char *pszPath); /* ファイルを削除 */
+FILE_ERR FatVol_MakeDir(C_VOLUMEOBJ *pVolObj, const char *pszPath); /* サブディレクトリを作成 */
+FILE_ERR FatVol_Remove(C_VOLUMEOBJ *pVolObj, const char *pszPath); /* ファイルを削除 */
+
+HANDLE FatVol_FileCreate(C_FATVOL *self, FATVOL_UINT uiCluster, HANDLE hDir, int iDirEntry, int iMode);
+void FatVol_FileDelete(C_FATVOL *self, HANDLE hFile);
+FILE_POS FatVol_GetFileSize(HANDLE hDir, int iDirEntry);
+void FatVol_SetFileSize(HANDLE hDir, int iDirEntry, FILE_POS Size);
-int FatVol_ClusterWrite(C_FATVOL *self, FATVOL_UINT uiCluster, const void *pBuf); /**< クラスタ書き込み */
-int FatVol_ClusterRead(C_FATVOL *self, FATVOL_UINT uiCluster, void *pBuf); /**< クラスタ読み込み */
+int FatVol_ClusterWrite(C_FATVOL *self, FATVOL_UINT uiCluster, const void *pBuf); /**< クラスタ書き込み */
+int FatVol_ClusterRead(C_FATVOL *self, FATVOL_UINT uiCluster, void *pBuf); /**< クラスタ読み込み */
int FatVol_GetClusterBuf(C_FATVOL *self, FATVOL_UINT uiCluster, void **ppBuf, int iRead);
int FatVol_RelClusterBuf(C_FATVOL *self, void *ppBuf, int iDirty);
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.c
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include "fatvol_local.h"
+
+
+/* サブディレクトリを作成 */
+FILE_ERR FatVol_MakeDir(C_VOLUMEOBJ *pVolObj, const char *pszPath)
+{
+ C_FATVOL *self;
+
+ /* upper cast */
+ self = (C_FATVOL *)pVolObj;
+
+ return FILE_ERR_OK;
+}
+
+
+/* end of file */
C_FATVOL *self;
unsigned char ubBuf[32];
FATVOL_UINT uiCluster;
- HANDLE hDir;
- HANDLE hFile;
- char szEntryName[8+3+1];
- int iEntryNameLen;
- char szName[8+3+1];
- int iNameLen;
- int iDirEntry;
- int i, j;
+ HANDLE hDir;
+ HANDLE hFile;
+ char szEntryName[8+3+1];
+ int iEntryNameLen;
+ char szName[8+3+1];
+ int iNameLen;
+ int iDirEntry;
+ int i, j;
/* upper cast */
self = (C_FATVOL *)pDrvObj;
/* ルートディレクトリを開く */
- hDir = FatVol_CreateFile(self, self->RootDirCluster, 0, 0, FILE_OPEN_READ | FILE_OPEN_WRITE | FILE_OPEN_DIR);
+ hDir = FatVol_FileCreate(self, self->RootDirCluster, HANDLE_NULL, 0, FILE_OPEN_READ | FILE_OPEN_WRITE | FILE_OPEN_DIR);
for ( ; ; )
{
+ if ( pszPath[iNameLen] == '\0' )
+ {
+ break;
+ }
+
/* 名前の部分を検索 */
for ( iNameLen = 0; pszPath[iNameLen] != '\0'; iNameLen++ )
{
if ( pszPath[iNameLen] == '/' )
{
- szName[iNameLen] = '\0';
break;
}
szName[iNameLen] = pszPath[iNameLen];
}
}
+ szName[iNameLen] = '\0';
/* ディレクトリエントリを検索 */
iDirEntry = -1;
}
szEntryName[iEntryNameLen++] = (char)ubBuf[8+j];
}
- szEntryName[iEntryNameLen++] = '\0';
+ szEntryName[iEntryNameLen] = '\0';
if ( iEntryNameLen > 2 && szEntryName[iEntryNameLen-1] == '.' )
{
szEntryName[--iEntryNameLen] = '\0';
}
+ /* 名前比較 */
if ( strcmp(szEntryName, szName) == 0 )
{
iDirEntry = i;
break;
}
- File_Close(hDir);
+
+ /* ディレクトリを閉じる */
+ FatVol_FileDelete(self, hDir);
/* サブディレクトリがなければエラー */
if ( iDirEntry < 0 || !(ubBuf[0x0b] & 0x10) )
}
/* サブディレクトリを開く */
- hDir = FatVol_CreateFile(self, uiCluster, 0, 0, FILE_OPEN_READ | FILE_OPEN_WRITE | FILE_OPEN_DIR);
+ hDir = FatVol_FileCreate(self, uiCluster, HANDLE_NULL, 0, FILE_OPEN_READ | FILE_OPEN_WRITE | FILE_OPEN_DIR);
pszPath += iNameLen;
}
+ /* ディレクトリを開くなら */
+ if ( iMode & FILE_OPEN_DIR )
+ {
+ return hDir;
+ }
+
+
/* 既存ファイルがあれば */
if ( iDirEntry >= 0 )
{
- hFile = FatVol_CreateFile(self, uiCluster, hDir, iDirEntry, iMode);
+ hFile = FatVol_FileCreate(self, uiCluster, hDir, iDirEntry, iMode);
if ( hFile == HANDLE_NULL )
{
- File_Close(hDir);
+ FatVol_FileDelete(self, hDir);
}
return hFile;
}
- File_Close(hDir);
return HANDLE_NULL;
}
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.c
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include <string.h>
+#include "fatvol_local.h"
+
+
+/** %jp{読出し} */
+FILE_SIZE FatVol_Read(C_DRVOBJ *pDrvObj, C_FILEOBJ *pFileObj, void *pBuf, FILE_SIZE Size)
+{
+ C_FATVOL *self;
+ C_FATFILE *pFile;
+ unsigned char *pubBuf;
+ FILE_SIZE ReqSize;
+ FATVOL_UINT uiCluster;
+
+ /* upper cast */
+ self = (C_FATVOL *)pDrvObj;
+ pFile = (C_FATFILE *)pFileObj;
+
+ pubBuf = (unsigned char *)pBuf;
+
+ /* サイズチェック */
+ if ( !(pFile->iMode & FILE_OPEN_DIR) )
+ {
+ if ( Size > pFile->FileSize - pFile->FilePos )
+ {
+ /* サイズ更新されていないかディレクトリテーブルを参照するべき? */
+
+ /* サイズクリップ */
+ Size = pFile->FileSize - pFile->FilePos;
+ }
+ }
+
+ /* 要求読み出し量保存 */
+ ReqSize = Size;
+
+ /* 読み出し */
+ uiCluster = pFile->uiCurrentCluster;
+ while ( Size > 0 && (pFile->FilePos < pFile->FileSize || (pFile->iMode & FILE_OPEN_DIR)) )
+ {
+ FILE_POS ReadStart;
+ FILE_SIZE ReadSize;
+ unsigned char *pubClusterBuf;
+
+ /* クラスタチェック */
+ if ( uiCluster == FATVOL_CLUSTER_ENDMARKER )
+ {
+ break;
+ }
+
+ /* 転送位置計算 */
+ ReadStart = pFile->FilePos % self->BytesPerSector;
+ ReadSize = self->BytesPerSector - ReadStart;
+ if ( ReadSize > Size )
+ {
+ ReadSize = Size;
+ }
+
+ /* バッファ取得 */
+ if ( FatVol_GetClusterBuf(self, uiCluster, (void **)&pubClusterBuf, 1) != FATVOL_ERR_OK )
+ {
+ break;
+ }
+ pFile->uiCurrentCluster = uiCluster;
+
+ /* 転送 */
+ memcpy(pubBuf, &pubClusterBuf[ReadStart], ReadSize);
+
+ /* バッファ開放 */
+ FatVol_RelClusterBuf(self, pubClusterBuf, 0);
+
+ /* サイズ更新 */
+ pFile->FilePos += ReadSize;
+ pubBuf += ReadSize;
+ Size -= ReadSize;
+
+ /* 次のクラスタに進む */
+ uiCluster = FatVol_GetNextCluster(self, uiCluster);
+ }
+
+ return ReqSize - Size;
+}
+
+
+/* end of file */
T_FATVOL_CLUSTERBUF *pClusterBuf;
/* バッファ情報取得 */
- pClusterBuf = (T_FATVOL_CLUSTERBUF *)((char *)pBuf - offsetof(T_FATVOL_CLUSTERBUF, pubBuf));
+ pClusterBuf = (T_FATVOL_CLUSTERBUF *)((char *)pBuf - sizeof(T_FATVOL_CLUSTERBUF));
- pClusterBuf->iDirty = iDirty;
+ if ( iDirty )
+ {
+ pClusterBuf->iDirty = iDirty;
+ }
return FATVOL_ERR_OK;
}
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.c
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include "fatvol_local.h"
+
+
+FILE_ERR FatVol_Remove(C_VOLUMEOBJ *pVolObj, const char *pszPath)
+{
+ C_FATVOL *self;
+
+ /* upper cast */
+ self = (C_FATVOL *)pVolObj;
+
+ return FILE_ERR_OK;
+}
+
+
+/* end of file */
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.c
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include "fatvol_local.h"
+
+
+FILE_POS FatVol_Seek(C_DRVOBJ *pDrvObj, C_FILEOBJ *pFileObj, FILE_POS Offset, int iOrign)
+{
+ C_FATVOL *self;
+ C_FATFILE *pFile;
+
+ /* upper cast */
+ self = (C_FATVOL *)pDrvObj;
+ pFile = (C_FATFILE *)pFileObj;
+
+ return FILE_ERR_NG;
+}
+
+
+/* end of file */
--- /dev/null
+/**
+ * Hyper Operating System Application Framework
+ *
+ * @file fatvol.c
+ * @brief %jp{FATボリューム用デバイスドライバ}
+ *
+ * Copyright (C) 2007 by Project HOS
+ * http://sourceforge.jp/projects/hos/
+ */
+
+
+#include "fatvol_local.h"
+
+
+/** %jp{書き込み} */
+FILE_SIZE FatVol_Write(C_DRVOBJ *pDrvObj, C_FILEOBJ *pFileObj, const void *pData, FILE_SIZE Size)
+{
+ C_FATVOL *self;
+ C_FATFILE *pFile;
+
+ /* upper cast */
+ self = (C_FATVOL *)pDrvObj;
+ pFile = (C_FATFILE *)pFileObj;
+
+ return 0;
+}
+
+
+/* end of file */
/* データの送信 */
int StreamBuf_SendData(
C_STREAMBUF *self, /* クラスポインタ */
- void *data, /* 送信データ */
+ const void *data, /* 送信データ */
int len) /* 送信データサイズ */
{
void *buf; /* バッファアドレス */
{
int tail;
- *p_buf = (void *)(self->buf + self->tail); /* 受信バッファ先頭番地の格納 */
+ *p_buf = (void *)(self->buf + self->head); /* 受信バッファ先頭番地の格納 */
tail = self->tail;
if ( tail < self->head ) /* データがバッファ末尾で折り返されているか */
void StreamBuf_ClearBuf(
C_STREAMBUF *self) /* クラスポインタ */
{
- self->head = 0;
- self->tail = 0;
+ self->head = self->tail;
+}
+
+
+int StreamBuf_RefDataSize(C_STREAMBUF *self)
+{
+ int head;
+ int tail;
+
+ head = self->head;
+ tail = self->tail;
+
+ if ( head <= tail )
+ {
+ return tail - head;
+ }
+ else
+ {
+ return self->bufsz + tail - head;
+ }
+}
+
+
+int StreamBuf_RefFreeSize(C_STREAMBUF *self)
+{
+ return StreamBuf_RefMaxSize(self) - StreamBuf_RefDataSize(self);
}
{
unsigned char *buf; /* バッファ領域の先頭アドレス */
int bufsz; /* バッファ領域のサイズ */
- int head; /* データの先頭 */
- int tail; /* データの末尾 */
+ volatile int head; /* データの先頭 */
+ volatile int tail; /* データの末尾 */
} C_STREAMBUF;
#endif
/* 生成/削除 */
-void StreamBuf_Create(C_STREAMBUF *self, int bufsz, void *buf); /* バッファの生成 */
-#define StreamBuf_Delete(self) do {} while(0) /* バッファの削除 */
+void StreamBuf_Create(C_STREAMBUF *self, int bufsz, void *buf); /* バッファの生成 */
+#define StreamBuf_Delete(self) do {} while(0) /* バッファの削除 */
/* データ送信 */
-int StreamBuf_SendData(C_STREAMBUF *self, void *data, int len); /* データの送信 */
-int StreamBuf_GetBuf(C_STREAMBUF *self, void **p_buf); /* 送信用バッファの取得(省コピー) */
-void StreamBuf_SendBuf(C_STREAMBUF *self, int len); /* バッファ内のデータの送信(省コピー) */
-int StreamBuf_SendChar(C_STREAMBUF *self, int chr); /* 1キャラクタの送信 */
+int StreamBuf_SendData(C_STREAMBUF *self, const void *data, int len); /* データの送信 */
+int StreamBuf_GetBuf(C_STREAMBUF *self, void **p_buf); /* 送信用バッファの取得(省コピー) */
+void StreamBuf_SendBuf(C_STREAMBUF *self, int len); /* バッファ内のデータの送信(省コピー) */
+int StreamBuf_SendChar(C_STREAMBUF *self, int chr); /* 1キャラクタの送信 */
/* データ受信 */
-int StreamBuf_RecvData(C_STREAMBUF *self, void *data, int len); /* データの受信 */
-int StreamBuf_RecvBuf(C_STREAMBUF *self, void **p_buf); /* 受信したデータの入ったバッファの取得(省コピー) */
-void StreamBuf_RelBuf(C_STREAMBUF *self, int len); /* 受信用バッファの解放(省コピー) */
-int StreamBuf_RecvChar(C_STREAMBUF *self); /* 1キャラクタの受信 */
+int StreamBuf_RecvData(C_STREAMBUF *self, void *data, int len); /* データの受信 */
+int StreamBuf_RecvBuf(C_STREAMBUF *self, void **p_buf); /* 受信したデータの入ったバッファの取得(省コピー) */
+void StreamBuf_RelBuf(C_STREAMBUF *self, int len); /* 受信用バッファの解放(省コピー) */
+int StreamBuf_RecvChar(C_STREAMBUF *self); /* 1キャラクタの受信 */
/* 制御 */
-void StreamBuf_ClearBuf(C_STREAMBUF *self); /* バッファのクリア */
-#define StreamBuf_RefMaxSize(self) ((self)->bufsz - 1) /* 最大格納可能サイズ参照 */
+void StreamBuf_ClearBuf(C_STREAMBUF *self); /* バッファのクリア */
+#define StreamBuf_RefMaxSize(self) ((self)->bufsz - 1) /* 最大格納可能サイズ参照 */
#define StreamBuf_RefBufAddr(self) ((self)->buf)
#define StreamBuf_RefBufSize(self) ((self)->bufsz)
+int StreamBuf_RefDataSize(C_STREAMBUF *self);
+int StreamBuf_RefFreeSize(C_STREAMBUF *self);
#ifdef __cplusplus
}
typedef unsigned long FILE_TIME; /* 読み書き時のサイズ用の時刻型定義 */
struct c_drvobj;
-struct c_volobj;
-
/* ファイル情報 */
FILE_ERR File_AddDevice(const char *pszName, struct c_drvobj *pDrvObj); /* デバイスドライバの登録 */
FILE_ERR File_RemoveDevice(const char *pszName); /* デバイスドライバの削除 */
-FILE_ERR File_AddVolume(const char *pszName, struct c_volobj *pVolObj); /* ボリュームのマウント */
+FILE_ERR File_AddVolume(const char *pszName, struct c_drvobj *pVolObj); /* ボリュームのマウント */
FILE_ERR File_RemoveVolume(const char *pszName); /* ボリュームのアンマウント */
/* ボリュームデバイスの追加 */
-FILE_ERR File_AddVolume(const char *pszName, struct c_volobj *pVolObj)
+FILE_ERR File_AddVolume(const char *pszName, struct c_drvobj *pVolObj)
{
+ C_FILE *self;
+
+ self = &g_File;
+
+ /* ルートディレクトリの下にボリュームを登録 */
+ SysVol_AddDevice(&self->RootVol, pszName, (C_DRVOBJ *)pVolObj, FILE_ATTR_DIR);
-
- return FILE_ERR_NG;
+ return FILE_ERR_OK;
}