mirror of
https://github.com/rvtr/ctr_firmware.git
synced 2025-10-31 07:51:08 -04:00
(shirait) nfs(wiifs)ライブラリ追加
git-svn-id: file:///Volumes/Transfer/gigaleak_20231201/2020-09-30%20-%20paladin.7z/paladin/ctr_firmware@283 b871894f-2f95-9b40-918c-086798483c85
This commit is contained in:
parent
56c174c989
commit
080e5d5613
66
trunk/firmware/build/libraries/nfs/ARM11/Makefile
Normal file
66
trunk/firmware/build/libraries/nfs/ARM11/Makefile
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#! make -f
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Project: CtrBrom - libraries - nfs
|
||||||
|
# File: Makefile
|
||||||
|
#
|
||||||
|
# Copyright 2008-2009 Nintendo. All rights reserved.
|
||||||
|
#
|
||||||
|
# These coded instructions, statements, and computer programs contain
|
||||||
|
# proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
# Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
# not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
# in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
#
|
||||||
|
# $Date:: $
|
||||||
|
# $Rev$
|
||||||
|
# $Author$
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
SUBMAKES =
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# build ARM & THUMB libraries
|
||||||
|
FIRM_CODEGEN_ALL ?= TRUE
|
||||||
|
|
||||||
|
#-------------------------------------------
|
||||||
|
#BROM_INCDIR = $(CTRBROM_ROOT)/include $(CTRBROM_ROOT)/build/libraries/fatfs/common/include ../common/include
|
||||||
|
#GINCLUDES = $(CTRBROM_ROOT)/include $(CTRFIRM_ROOT)/include $(CTRALL_ROOT)/include $(CTRBROM_ROOT)/build/libraries/fatfs/common/include ../common/include
|
||||||
|
INCDIR = $(BROM_ROOT)/include $(FIRM_ROOT)/include $(FIRM_ROOT)/build/libraries/nfs/common/include \
|
||||||
|
../common/include ../common/include/client ../common/include/driver_interface \
|
||||||
|
$(FIRM_ROOT)/include/firm/fatfs
|
||||||
|
#INCDIR = $(CTRBROM_ROOT)/include ../common/include
|
||||||
|
SRCDIR = ../common/src ../common/src/client ../common/src/driver_interface
|
||||||
|
SRCS = \
|
||||||
|
wfskrn_Api.cpp wfskrn_Area.cpp wfskrn_BCache.cpp wfskrn_BitField.cpp \
|
||||||
|
wfskrn_Dir.cpp wfskrn_DirApi.cpp wfskrn_DirCheck.cpp \
|
||||||
|
wfskrn_DirFind.cpp wfskrn_DirNodeStack.cpp wfskrn_DirRxTree.cpp \
|
||||||
|
wfskrn_EPTree.cpp wfskrn_Errors.cpp wfskrn_FreeBlkAlloc.cpp \
|
||||||
|
wfskrn_FTree.cpp wfskrn_Handles.cpp wfskrn_Heap.cpp wfskrn_Mutex.cpp \
|
||||||
|
wfskrn_PathCache.cpp wfskrn_Permission.cpp wfskrn_Permission_AccessList.cpp \
|
||||||
|
wfskrn_Permission_File.cpp wfskrn_Permission_Iop.cpp \
|
||||||
|
wfskrn_PTree.cpp wfskrn_SubBlkAlloc.cpp wfskrn_Trans.cpp wfskrn_Utils.cpp \
|
||||||
|
wfskrn_Volume.cpp my_wfskrn_Device.cpp \
|
||||||
|
wfs_Client_Common.cpp randomlib.cpp wfs_Debug.cpp \
|
||||||
|
wfs_Heap.cpp wfs_Mutex.cpp wfs_Names.cpp wfs_PathNames.cpp \
|
||||||
|
wfscli_Handles.cpp WinOSReport.cpp wfs_AsyncUtils.cpp \
|
||||||
|
drnand.c \
|
||||||
|
#------------------------------------------------
|
||||||
|
#MACRO_FLAGS += --c90
|
||||||
|
|
||||||
|
TARGET_LIB = libnfs$(FIRM_LIBSUFFIX).a
|
||||||
|
|
||||||
|
include $(CTRFIRM_ROOT)/build/buildtools/commondefs
|
||||||
|
|
||||||
|
INSTALL_TARGETS = $(TARGETS)
|
||||||
|
INSTALL_DIR = $(FIRM_INSTALL_LIBDIR)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
do-build: $(TARGETS)
|
||||||
|
|
||||||
|
include $(CTRFIRM_ROOT)/build/buildtools/modulerules
|
||||||
|
|
||||||
|
#===== End of Makefile =====
|
||||||
53
trunk/firmware/build/libraries/nfs/ARM9/Makefile
Normal file
53
trunk/firmware/build/libraries/nfs/ARM9/Makefile
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#! make -f
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Project: CtrBrom - libraries_sp - nfs
|
||||||
|
# File: Makefile
|
||||||
|
#
|
||||||
|
# Copyright 2008-2009 Nintendo. All rights reserved.
|
||||||
|
#
|
||||||
|
# These coded instructions, statements, and computer programs contain
|
||||||
|
# proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
# Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
# not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
# in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
#
|
||||||
|
# $Date:: $
|
||||||
|
# $Rev$
|
||||||
|
# $Author$
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SUBDIRS =
|
||||||
|
#SUBMAKES = Makefile.CALLTRACE \
|
||||||
|
# Makefile.FUNCTIONCOST
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# build ARM & THUMB libraries
|
||||||
|
CTR_CODEGEN_ALL ?= TRUE
|
||||||
|
|
||||||
|
# Codegen for sub processer
|
||||||
|
CTR_PROC = ARM9
|
||||||
|
|
||||||
|
SRCDIR = . ../common
|
||||||
|
|
||||||
|
SRCS = \
|
||||||
|
|
||||||
|
TARGET_LIB = libnfs_sp$(CTR_LIBSUFFIX).a
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
include $(CTRFIRM_ROOT)/build/buildtools/commondefs
|
||||||
|
|
||||||
|
INSTALL_TARGETS = $(TARGETS)
|
||||||
|
INSTALL_DIR = $(CTR_INSTALL_LIBDIR)
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
do-build: $(TARGETS)
|
||||||
|
|
||||||
|
include $(CTRFIRM_ROOT)/build/buildtools/modulerules
|
||||||
|
|
||||||
|
|
||||||
|
#===== End of Makefile =====
|
||||||
34
trunk/firmware/build/libraries/nfs/Makefile
Normal file
34
trunk/firmware/build/libraries/nfs/Makefile
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#! make -f
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Project: CtrBrom - libraries - mi
|
||||||
|
# File: Makefile
|
||||||
|
#
|
||||||
|
# Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
#
|
||||||
|
# These coded instructions, statements, and computer programs contain
|
||||||
|
# proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
# Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
# not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
# in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
#
|
||||||
|
# $Date:: $
|
||||||
|
# $Rev$
|
||||||
|
# $Author$
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
include $(CTRFIRM_ROOT)/build/buildtools/commondefs
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
SUBDIRS = ARM11
|
||||||
|
|
||||||
|
#ifdef CTR_WITH_ARM9
|
||||||
|
#SUBDIRS += ARM9
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
include $(CTRFIRM_ROOT)/build/buildtools/modulerules
|
||||||
|
|
||||||
|
|
||||||
|
#===== End of Makefile =====
|
||||||
@ -0,0 +1,37 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: WinOSReport.h
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: WinOSReport.h,v $
|
||||||
|
Revision 1.6 2008/08/27 04:50:50 nakanose_jin
|
||||||
|
add function and defines
|
||||||
|
|
||||||
|
Revision 1.5 2007/11/02 00:21:11 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
extern FILE *fpOSReport;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef void (*OSReportCallback) (const char *log);
|
||||||
|
|
||||||
|
void DebugPrintCallback(const char *pStr);
|
||||||
|
void DebugPrintCallback2(const char *pStr);
|
||||||
|
|
||||||
|
OSReportCallback SetOSReportPrintCallback(OSReportCallback cb);
|
||||||
|
|
||||||
|
void InitMyOSReport();
|
||||||
|
void MyOSReport(const char *format, ...);
|
||||||
|
void MyOSPanic(const char* file, int line , const char* msg, ...);
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: Revolution WFS library
|
||||||
|
File: wfs_Server.h - Server API
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Server.h,v $
|
||||||
|
Revision 1.4 2008/01/10 05:33:20 nakanose_jin
|
||||||
|
validatePathName => validateDirectory
|
||||||
|
|
||||||
|
Revision 1.3 2007/11/02 00:21:56 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFS_SERVER_H__
|
||||||
|
#define __WFS_SERVER_H__
|
||||||
|
|
||||||
|
#include <wfs.h>
|
||||||
|
|
||||||
|
WFSResult WFSSRVInit(void *pWorkSpaceBuffer, u32 nWorkSpaceSize);
|
||||||
|
WFSResult WFSSRVGetDeviceInfo(const utf8 *sDeviceName, WFSDeviceInfo *pDi);
|
||||||
|
WFSResult WFSSRVMountDevice(const utf8 *sDeviceName, utf8 *sVolumeIdBuffer);
|
||||||
|
WFSResult WFSSRVUnmountVolume(const utf8 *sVolumeId);
|
||||||
|
WFSResult WFSSRVInitializeDevice(const utf8 *sDeviceName);
|
||||||
|
WFSResult WFSSRVGetVolumeId(const utf8 *sDeviceName, utf8 *sVolumeId);
|
||||||
|
WFSResult WFSSRVGetFreeSpaceSize(const utf8 *sPathName, u64 *pSize);
|
||||||
|
WFSResult WFSSRVCreateDirectory(const utf8 *sPathName, u32 nFlags, u64 nQuota);
|
||||||
|
WFSResult WFSSRVCreateAndOpenFile(const utf8 *sPathName, u32 nFlags, u32 nPreAllocateSize, WFSFileHandle *pFh);
|
||||||
|
WFSResult WFSSRVGetAttributes(const utf8 *sPathName, WFSFileAttributes *pFa);
|
||||||
|
WFSResult WFSSRVChangePermissions(const utf8 *sPathName, u32 nFlags);
|
||||||
|
WFSResult WFSSRVDelete(const utf8 *sPathName);
|
||||||
|
WFSResult WFSSRVMoveLocal(const utf8 *sSrcPathName, const utf8 *sDstPathName);
|
||||||
|
WFSResult WFSSRVOpenFile(const utf8 *sPathName, WFSAccess nDesiredAccess, WFSFileHandle *pFh);
|
||||||
|
WFSResult WFSSRVReadFile(WFSFileHandle fh, void *pFileDataBuffer, u32 nSize);
|
||||||
|
WFSResult WFSSRVWriteFile(WFSFileHandle fh, const void *pFileData, u32 nSize);
|
||||||
|
WFSResult WFSSRVCloseFile(WFSFileHandle fh, u8 bTruncateFlag);
|
||||||
|
WFSResult WFSSRVSearchDirectoryFirst(const utf8 *sPattern, WFSSearchDirectoryHandle *pSdh, WFSFileInfo *pFi);
|
||||||
|
WFSResult WFSSRVSearchDirectoryNext(WFSSearchDirectoryHandle sdh, WFSFileInfo *pFi);
|
||||||
|
WFSResult WFSSRVSearchDirectoryClose(WFSSearchDirectoryHandle sdh);
|
||||||
|
WFSResult WFSSRVDebugSetTitleID(u64 nTID);
|
||||||
|
u64 WFSSRVDebugGetTitleID();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Functions in the WFS API that are NOT in the WFS Server API:
|
||||||
|
|
||||||
|
// void WFSSetAttachDeviceCallback(utf8 *sDeviceNameBuffer, WFSDeviceCallback cbAttachDevice, void *pUserData);
|
||||||
|
// void WFSGetAttachDeviceCallback(utf8 **psDeviceName, WFSDeviceCallback *pCbAttachDevice, void **ppUserData);
|
||||||
|
// void WFSSetDetachDeviceCallback(utf8 *sDeviceNameBuffer, WFSDeviceCallback cbDetachDevice, void *pUserData);
|
||||||
|
// void WFSGetDetachDeviceCallback(utf8 **psDeviceName, WFSDeviceCallback *pCbDetachDevice, void **ppUserData);
|
||||||
|
|
||||||
|
// WFSResult WFSSetCurrentDirectory(const utf8 *sPathName);
|
||||||
|
// This function is replaced with:
|
||||||
|
WFSResult WFSSRVValidateDirectory(const utf8 *sPathName);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// WFSResult WFSGetCurrentDirectory(utf8 *sAbsPathNameBuffer, s32 nBufferSize);
|
||||||
|
// WFSResult WFSSetFilePosition(WFSFileHandle fh, WFSFileSize nFilePosition);
|
||||||
|
// WFSResult WFSGetFilePosition(WFSFileHandle fh, WFSFileSize *pFilePosition);
|
||||||
|
// WFSResult WFSGetFileSize(WFSFileHandle fh, WFSFileSize *pFileSize);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif //define __WFS_SERVER_H__
|
||||||
@ -0,0 +1,382 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: Revolution WFSSrv library API = shim layer in RVL version and RPC
|
||||||
|
layer in WFSDEV version.
|
||||||
|
File: wfsdev_Defs.h - Definitions common to WFS client and server
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfssrv_Defs.h,v $
|
||||||
|
Revision 1.34 2008/12/03 00:17:36 kondo_masahiro
|
||||||
|
Added a argument of WFSSrvFlush().
|
||||||
|
|
||||||
|
Revision 1.33 2008/10/21 10:45:09 kondo_masahiro
|
||||||
|
Added new function WFSWriteFileAndDiscard
|
||||||
|
|
||||||
|
Revision 1.32 2008/09/29 01:06:26 kondo_masahiro
|
||||||
|
Added the argument of WFSSrvInit().
|
||||||
|
|
||||||
|
Revision 1.31 2008/07/18 02:59:44 ueno
|
||||||
|
Renamed WFSDeletePermissions() -> WFSDeleteAccessListEntry().
|
||||||
|
|
||||||
|
Revision 1.30 2008/07/17 05:08:41 kondo_masahiro
|
||||||
|
Added WFSSRV_ATTACH_DETACH
|
||||||
|
|
||||||
|
Revision 1.29 2008/07/15 08:43:53 nakanose_jin
|
||||||
|
change arg order
|
||||||
|
|
||||||
|
Revision 1.28 2008/07/14 07:15:46 ueno
|
||||||
|
Implemented WFSGetAccessListAsync(), WFSSetAccessListEntryAsync() and WFSDeletePermissionsAsync().
|
||||||
|
|
||||||
|
Revision 1.27 2008/07/10 06:12:33 nakanose_jin
|
||||||
|
add permissions API
|
||||||
|
|
||||||
|
Revision 1.26 2008/05/22 08:05:49 ueno
|
||||||
|
Added WFSSrvDebugAclTest to run accesslist test.
|
||||||
|
|
||||||
|
Revision 1.25 2008/05/09 14:03:09 nakanose_jin
|
||||||
|
canceling => reduce settitleid argument
|
||||||
|
|
||||||
|
Revision 1.23 2008/04/19 05:52:03 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.22 2008/04/15 02:47:27 ueno
|
||||||
|
Added WFSSrvGetPermissionForUser() and WFSSrvSetPermissionForUser().
|
||||||
|
|
||||||
|
Revision 1.21 2008/03/28 14:14:20 nakanose_jin
|
||||||
|
chance spec of debug proc
|
||||||
|
|
||||||
|
Revision 1.20 2008/02/20 08:10:10 nakanose_jin
|
||||||
|
add WFSExecDebugProcedure
|
||||||
|
|
||||||
|
Revision 1.19 2008/02/08 04:42:00 paul
|
||||||
|
Changed WFSSrvUnmountVolume parameter bForce to WFSBool
|
||||||
|
|
||||||
|
Revision 1.18 2008/02/07 13:02:18 nakanose_jin
|
||||||
|
WFSUnmountVolume : Add force-close option (but only in detach condition)
|
||||||
|
|
||||||
|
Revision 1.17 2008/01/10 05:33:20 nakanose_jin
|
||||||
|
validatePathName => validateDirectory
|
||||||
|
|
||||||
|
Revision 1.16 2007/12/25 14:00:36 ueno
|
||||||
|
Added WFSSrvConnectToServer() to connect to the server again.
|
||||||
|
|
||||||
|
Revision 1.15 2007/12/12 07:51:29 paul
|
||||||
|
Added WFSSrvGetFileSize
|
||||||
|
|
||||||
|
Revision 1.14 2007/12/10 02:51:36 paul
|
||||||
|
Added function codes for WFSSRV_SET_HOME_DIRECTORY, WFSSRV_SET_CURRENT_DIRECTORY. (These do not need to be implemented in the actual server, both call WFSSrvValidatePathName)
|
||||||
|
|
||||||
|
Revision 1.13 2007/11/30 09:43:09 nakanose_jin
|
||||||
|
refine for multi client
|
||||||
|
|
||||||
|
Revision 1.12 2007/11/21 04:17:28 wayne.wong
|
||||||
|
Many changes that included single request/result RPC messages, bug fixes, code factoring, and English C comment adjustments.
|
||||||
|
1. Combined RPC messages into a single request message and single result
|
||||||
|
message. Except for file reads and writes.
|
||||||
|
2. Fixed+factored some Endianess code.
|
||||||
|
3. Enabled larger TCP/IP data transfer size. Previous setting was artifically small
|
||||||
|
to test the code to perform large transfers.
|
||||||
|
4. Changed the volume id parameters utf8*->WFSVolumeId for SrvGetVolumeId
|
||||||
|
and SrvMountDevice. More consistent with the way we send this type at the
|
||||||
|
RPC layer.
|
||||||
|
5. Changed a couple Japanese comments to be compatible with English
|
||||||
|
comments. In particular, the "//" comment with a backslash at the end of
|
||||||
|
the line causes the next line of code to be ignored.
|
||||||
|
6. Removed Windows-specific debugging output defines for RVL build.
|
||||||
|
|
||||||
|
Revision 1.11 2007/11/16 21:54:26 paul
|
||||||
|
Fixed WFSSrvCloseFile to pass nNewSize instead of bTruncateFlag
|
||||||
|
|
||||||
|
Revision 1.10 2007/11/16 02:15:57 wayne.wong
|
||||||
|
Added enumeration and stubs for WFSFlush call.
|
||||||
|
|
||||||
|
Revision 1.9 2007/11/02 00:21:02 paul
|
||||||
|
started logging changes in the file
|
||||||
|
Added StartPosition to WFSSrvReadFile, WFSSrvWriteFile
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFSSRV_DEFS_H__
|
||||||
|
#define __WFSSRV_DEFS_H__
|
||||||
|
|
||||||
|
#include "wfs_Defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enumeration of functions.
|
||||||
|
// Used by the client to specify functions implemented on the server, or
|
||||||
|
// by the server to specify functions implemented on the client.
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// server -> client
|
||||||
|
|
||||||
|
WFSSRV_ATTACH_DEVICE,
|
||||||
|
WFSSRV_DETACH_DEVICE,
|
||||||
|
|
||||||
|
// client -> server
|
||||||
|
|
||||||
|
WFSSRV_INIT,
|
||||||
|
WFSSRV_EXIT,
|
||||||
|
|
||||||
|
WFSSRV_GET_DEVICE_INFO,
|
||||||
|
WFSSRV_MOUNT_DEVICE,
|
||||||
|
WFSSRV_UNMOUNT_VOLUME,
|
||||||
|
WFSSRV_INITIALIZE_DEVICE,
|
||||||
|
WFSSRV_GET_VOLUME_ID,
|
||||||
|
WFSSRV_GET_FREE_SPACE_SIZE,
|
||||||
|
WFSSRV_FLUSH,
|
||||||
|
|
||||||
|
WFSSRV_CREATE_DIRECTORY,
|
||||||
|
WFSSRV_SEARCH_DIRECTORY_FIRST,
|
||||||
|
WFSSRV_SEARCH_DIRECTORY_NEXT,
|
||||||
|
WFSSRV_SEARCH_DIRECTORY_CLOSE,
|
||||||
|
|
||||||
|
WFSSRV_SET_HOME_DIRECTORY,
|
||||||
|
WFSSRV_SET_CURRENT_DIRECTORY,
|
||||||
|
|
||||||
|
WFSSRV_VALIDATE_PATH_NAME,
|
||||||
|
WFSSRV_DELETE,
|
||||||
|
WFSSRV_MOVE_LOCAL,
|
||||||
|
WFSSRV_GET_ATTRIBUTES,
|
||||||
|
WFSSRV_CHANGE_PERMISSIONS,
|
||||||
|
|
||||||
|
WFSSRV_CREATE_AND_OPEN_FILE,
|
||||||
|
WFSSRV_OPEN_FILE,
|
||||||
|
WFSSRV_GET_FILE_SIZE,
|
||||||
|
WFSSRV_CLOSE_FILE,
|
||||||
|
WFSSRV_READ_FILE,
|
||||||
|
WFSSRV_WRITE_FILE,
|
||||||
|
WFSSRV_WRITE_FILE_AND_DISCARD,
|
||||||
|
|
||||||
|
WFSSRV_GET_PERMISSIONS,
|
||||||
|
WFSSRV_SET_PERMISSIONS,
|
||||||
|
|
||||||
|
WFSSRV_GET_ACL,
|
||||||
|
WFSSRV_SET_ACL_ENTRY,
|
||||||
|
WFSSRV_DELETE_ACL_ENTRY,
|
||||||
|
|
||||||
|
WFSSRV_SET_TITLE_ID,
|
||||||
|
WFSSRV_TEST,
|
||||||
|
WFSSRV_EXEC_DEBUG,
|
||||||
|
|
||||||
|
WFSSRV_ATTACH_DETACH,
|
||||||
|
|
||||||
|
WFSSRV_DEBUG_ACLTEST // [check]
|
||||||
|
|
||||||
|
} WFSSrvFunc;
|
||||||
|
|
||||||
|
|
||||||
|
typedef u16 WFSSrvFileHandle;
|
||||||
|
typedef u16 WFSSrvSearchDirectoryHandle;
|
||||||
|
|
||||||
|
#ifndef WFSDEV_SERVER
|
||||||
|
|
||||||
|
// The WFSDev server must distinguish between multiple clients.
|
||||||
|
// This can be done by assigning a ClientId based on the client's IP address,
|
||||||
|
// which the server learns whenever it receives a request from a client via sockets.
|
||||||
|
|
||||||
|
// Note: ClientId is orthogonal to TitleId.
|
||||||
|
// There can be multiple clients with the same TitleId.
|
||||||
|
// The same client could change TitleId while the server is running.
|
||||||
|
|
||||||
|
// The home directory is only stored on the client side.
|
||||||
|
// The TitleId, however, is determined by a function in IOS.
|
||||||
|
// (except for the fake debug/wfsdev version)
|
||||||
|
//
|
||||||
|
// This allows a system application built on top of wfs to specify the home directory for
|
||||||
|
// an app prior to launching it.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Path Names
|
||||||
|
// The client<->server API uses absolute WFS path names, becuase the server does not know about
|
||||||
|
// "Current Directory" or "Home Directory".
|
||||||
|
// The absolute path name does not include the full windows path name, it is a WFS path name.
|
||||||
|
|
||||||
|
// For example: "/vol/ABCDEFG/titles/1234/JAKK/gamesave/save1.bin"
|
||||||
|
// On windows, this could map to:
|
||||||
|
// "C:/my_project/my_wfs_device/titles/1234/JAKK/gamesave/save1.bin"
|
||||||
|
// There would be a file called:
|
||||||
|
// "C:/my_project/my_wfs_device/.Wfs" which contains: "Volume Name: ABCDEFG"
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvInit(void *pWorkSpaceBuffer, u32 nWorkSpaceSize);
|
||||||
|
// Contact the WFSSrv server so that it can initialize state for this client.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvExit(void);
|
||||||
|
// Inform the WFSSrv server that this client is terminating.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvInitializeDevice(const WFSDeviceName *pDevName);
|
||||||
|
// pDevName (IN) pointer to device name struct.
|
||||||
|
// Server would create a volume (deleting any existing data within the device assigned to this folder).
|
||||||
|
// The server could have a GUI to allow device attach to be simulated.
|
||||||
|
// It depends on the usage model but this may not be necessary for game developers, so low priority.
|
||||||
|
// (Assuming a system app mounts the drive and assigns home directory in advance, so the
|
||||||
|
// game can access an already-mounted device from the start).
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetDeviceInfo(const WFSDeviceName *pDevName, WFSDeviceInfo *pDi);
|
||||||
|
// pDevName (IN) A pointer to a device name struct.
|
||||||
|
// pDi (OUT) A pointer to a WFSDeviceInfo struct to receive the device information.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvMountDevice(const WFSDeviceName *pDevName, WFSVolumeId *pVolumeIdBuffer);
|
||||||
|
// pDevName (IN) A pointer to a device name struct.
|
||||||
|
// pVolumeIdBuffer (OUT) A pointer to a WFSVolumeId buffer
|
||||||
|
|
||||||
|
WFSResult WFSSrvUnmountVolume(const WFSVolumeId *pVolumeId, WFSBool bForce);
|
||||||
|
// pVolumeId (IN) A pointer to a struct containing a mounted Volume Id.
|
||||||
|
// bForce (IN) If set to true, forces the volume to be unmounted regardless of open files.
|
||||||
|
// NOTE: This flag is only valid if the device is currently detached. Un-flushed data will be lost.
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetVolumeId(const WFSDeviceName *pDevName, WFSVolumeId *sVolumeIdBuffer);
|
||||||
|
// pDevName (IN) A pointer to a device name struct.
|
||||||
|
// sVolumeIdBuffer (OUT) A pointer to a WFSVolumeId buffer
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetFreeSpaceSize(const WFSPathName *pAbsPathName, u64 *pSize);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory.
|
||||||
|
// pSize (OUT) A pointer to a u64 to receive the free space size value.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvFlush(const WFSVolumeId *pVolumeId);
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetAttributes(const WFSPathName *pAbsPathName, WFSFileAttributes *pFa);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory.
|
||||||
|
// pFa (OUT) A pointer to a WFSFileAttributes struct which will be overwritten with the attributes of the specified file or directory.
|
||||||
|
|
||||||
|
WFSResult WFSSrvChangePermissions(const WFSPathName *pAbsPathName, u32 nFlags, u32 nMask);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory.
|
||||||
|
// nFlags (IN) The new permissions flags that are to be set. Should be a combination of the permission flags: WFS_PERM_*
|
||||||
|
// nMask (IN) A mask to specify which flags to change.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvCreateDirectory(const WFSPathName *pAbsPathName, u32 nFlags, u64 nQuota);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory.
|
||||||
|
// nFlags (IN) Should be a combination of the permission flags: WFS_PERM_*. Note: WFS_FLAG_DIRECTORY will be set
|
||||||
|
// whether it is included or not.
|
||||||
|
// nQuota (IN) This parameter that can be used to restrict the total size of the hierarchy beneath the
|
||||||
|
// new directory. A quota of 0 means there is no size restriction, i.e. the quota is Infinity.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSearchDirectoryFirst(const WFSPathName *pPattern, WFSSrvSearchDirectoryHandle *pSsdh, WFSFileInfo *pFi);
|
||||||
|
// pPattern (IN) A pointer to a struct specifying the search pattern as an absolute path name.
|
||||||
|
// pSsdh (OUT) A pointer to a WFSSrvSearchDirectoryHandle handle which is overwritten by the server.
|
||||||
|
// pFi (OUT) A pointer to a WFSFileInfo struct which will be overwritten with the details of the
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSearchDirectoryNext(WFSSrvSearchDirectoryHandle ssdh, WFSFileInfo *pFi);
|
||||||
|
// ssdh (IN) A WFSSrvSearchDirectoryHandle which was created by WFSSrvSearchDirectoryFirst.
|
||||||
|
// pFi (OUT) A pointer to a WFSFileInfo struct which will be overwritten with the details of the
|
||||||
|
// next file which matches the search pattern.
|
||||||
|
//
|
||||||
|
// If they have read permission on the directory, they can list all files/dirs in that directory. Directory read
|
||||||
|
// access was already checked by WFSSrvSearchDirectoryFirst. While they can list the directory contents, they may
|
||||||
|
// not be able to access all contained files/dirs.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSearchDirectoryClose(WFSSrvSearchDirectoryHandle ssdh);
|
||||||
|
// ssdh (IN) A WFSSrvSearchDirectoryHandle which was returned by WFSSrvSearchDirectoryFirst.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvValidateDirectory(const WFSPathName *pAbsPathName);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory to validate.
|
||||||
|
// Returns WFS_RESULT_OK if the specified pathname exists, and is accessible to the current title
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvDelete(const WFSPathName *pAbsPathName);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file or directory to delete.
|
||||||
|
|
||||||
|
WFSResult WFSSrvMoveLocal(const WFSPathName *pSrcAbsPathName, const WFSPathName *pDstAbsPathName);
|
||||||
|
// pSrcAbsPathName (IN) A pointer to a struct containing the absolute pathname of the source file or directory.
|
||||||
|
// pDstAbsPathName (IN) A pointer to a struct containing the absolute pathname of the destination file or directory.
|
||||||
|
// Moves or renames the source file/directory to the destination pathname. This function does not work across volumes.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvCreateAndOpenFile(const WFSPathName *pAbsPathName, u32 nFlags, WFSContentIdx nCidx, WFSFileSize nPreAllocateSize, WFSSrvFileHandle *pSfh);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file to create and open.
|
||||||
|
// nFlags (IN) Should be a combination of the permission flags: WFS_PERM_*
|
||||||
|
// nCidx (IN) The content idx, used to control access to purchased content.
|
||||||
|
// nPreAllocateSize (IN) The amount of disk-space to pre-allocate for the file. Hint to the file system.
|
||||||
|
// pSfh (OUT) A pointer to a server file handle which is overwritten by the server.
|
||||||
|
|
||||||
|
WFSResult WFSSrvOpenFile(const WFSPathName *pAbsPathName, WFSAccess nDesiredAccess, WFSSrvFileHandle *pSfh, WFSFileAttributes *pFa);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file to open.
|
||||||
|
// nDesiredAccess (IN) The kind of access that is required: should be one of the WFS_ACCESS_* options.
|
||||||
|
// pSfh (OUT) A pointer to a server file handle, which is overwritten by the server.
|
||||||
|
// pFa (OUT) A pointer to a WFSFileAttributes struct which will be overwritten by the server,
|
||||||
|
|
||||||
|
WFSResult WFSSrvCloseFile(WFSSrvFileHandle sfh, WFSFileSize nNewSize);
|
||||||
|
// sfh (IN) The server file handle which was returned when the file was opened.
|
||||||
|
// nNewSize (IN) This value may be set to truncate the size of a file.
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetFileSize(WFSSrvFileHandle sfh, WFSFileSize *pNewSize);
|
||||||
|
// sfh (IN) The server file handle which was returned when the file was opened.
|
||||||
|
// pNewSize (OUT) A pointer to a WFSFileSize variable which is overwritten by the current file size.
|
||||||
|
|
||||||
|
s32 WFSSrvReadFile(WFSSrvFileHandle sfh, void *pFileDataBuffer, WFSFileSize nStartPosition, s32 nSize);
|
||||||
|
// sfh (IN) The server file handle which was returned when the file was opened.
|
||||||
|
// pFileDataBuffer (OUT) Points to a buffer which will be overwritten with data from the file.
|
||||||
|
// nSize (IN) The number of bytes to be read.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvWriteFile(WFSSrvFileHandle sfh, const void *pFileData, WFSFileSize nStartPosition, WFSFileSize nSize, WFSBool bDiscard);
|
||||||
|
// sfh (IN) The server file handle which was returned when the file was opened.
|
||||||
|
// pFileData (IN) Points to the data to be written to the file.
|
||||||
|
// nSize (IN) The number of bytes to be written.
|
||||||
|
// bDiscard (IN) If it is true, the user buffer is used as work buffer.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSetTitleId(WFSTitleId titleId,WFSGroupId groupId);
|
||||||
|
// titleId (IN) the title id which is the low 32 bits of the OSTitleId which can be obtained be ESP_GetTitleId()
|
||||||
|
// groupId (IN) the group id from the TMD, which can be obtained by ES_GetTmd()
|
||||||
|
// This function informs the server of the title id and group id of the application linked to this instance of the client.
|
||||||
|
|
||||||
|
WFSResult WFSSrvExecDebugProcedure( u32 cmd , void *arg0 , void *arg1 );
|
||||||
|
// cmd (IN) special command No.
|
||||||
|
// arg0,arg1 (IN/OUT) parameters of special command.
|
||||||
|
// This function let the server do special tasks.
|
||||||
|
|
||||||
|
WFSResult WFSSrvConnectToServer(void);
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetPermissionForUser(const WFSPathName *pAbsPathName, u32 *pFlags, WFSTitleId titleId);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file or the directory.
|
||||||
|
// pFlags (OUT) A pointer to a u32 which will be overwritten with the permissions the specified title id has to
|
||||||
|
// access or modify the specified file or directory. See wfstypes.h for WFS_PERM* flag definitions.
|
||||||
|
// titleId (IN) Title id of the application for which permissions are being set.
|
||||||
|
|
||||||
|
WFSResult WFSSrvSetPermissionForUser(const WFSPathName *pAbsPathName, u32 nFlags, u32 nMask, WFSTitleId titleId);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file or the directory.
|
||||||
|
// nFlags (IN) The new permissions flags that are to be set. Should be a combination of the permission flags: WFS_PERM_* (see wfstypes.h)
|
||||||
|
// nMask (IN) The mask determines which flags will be changed. NewAttributes = (OldAttributes & ~nMask) | (nFlags & nMask)
|
||||||
|
// titleId (IN) Title id of the application for which permissions are being set.
|
||||||
|
|
||||||
|
WFSResult WFSSrvDeleteAccessListEntry(const WFSPathName *pAbsPathName, WFSTitleId titleId, WFSTitleId entryCreatorId);
|
||||||
|
WFSResult WFSSrvSetAccessListEntry(const WFSPathName *pAbsPathName, u32 nFlags, u32 nMask, WFSTitleId titleId);
|
||||||
|
s32 WFSSrvGetAccessList(const WFSPathName *pAbsPathName, WFSAccessListEntry *pAccessList, u32 nMaxElements);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSetWorkspace(void *pWorkSpaceBuffer, u32 nWorkSpaceSize);
|
||||||
|
|
||||||
|
#ifdef ACL_TEST
|
||||||
|
WFSResult WFSSrvDebugAclTest(u32 testNo, void *arg0, void *arg1);
|
||||||
|
#endif // ACL_TEST
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //define __WFSSRV_DEFS_H__
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef _RANDOMLIB_H
|
||||||
|
#define _RANDOMLIB_H
|
||||||
|
|
||||||
|
#include "revolution.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
#if _IOP
|
||||||
|
#include "types.h"
|
||||||
|
#else
|
||||||
|
#include "revolution/types.h"
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wfs_Platform.h"
|
||||||
|
|
||||||
|
void RandomInitialise(int ij, int kl);
|
||||||
|
double RandomUniform(void);
|
||||||
|
double RandomGaussian(double mean, double stddev);
|
||||||
|
int RandomInt(int lower, int upper);
|
||||||
|
double RandomDouble(double lower, double upper);
|
||||||
|
u32 RandomU32();
|
||||||
|
|
||||||
|
#define NUM_UNIQUE_RANDOM_SEEDS_U32 0x382C7A42
|
||||||
|
void RandomSetSeedU32(u32 nSeed);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_AsyncUtils.h - mutual exclusion for multi-thread case
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_AsyncUtils.h,v $
|
||||||
|
Revision 1.6 2008/04/19 05:52:50 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.5 2007/11/09 01:19:54 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
Revision 1.4 2007/11/02 00:25:49 paul
|
||||||
|
started logging changes in the file
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_AsyncUtils_h
|
||||||
|
#define wfs_AsyncUtils_h
|
||||||
|
|
||||||
|
#include "wfs_PathNames.h"
|
||||||
|
#include "wfs_Mutex.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_ASYNC_UTILS 0 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_ASYNC_UTILS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WFSCLI_WRITE_ASYNC_PARAM_AND_INC_PTR(ptr,Type,var) *((Type*)ptr)=var; ptr=(void*)((size_t)pPtr + sizeof(Type))
|
||||||
|
#define WFSCLI_WRITE_ASYNC_PARAM(ptr,Type,var) *((Type*)ptr)=var
|
||||||
|
#define WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(ptr,Type,var) Type var=*((Type*)ptr); ptr=(void*)((size_t)pPtr + sizeof(Type))
|
||||||
|
#define WFSCLI_DECLARE_AND_READ_ASYNC_PARAM(ptr,Type,var) Type var=*((Type*)ptr);
|
||||||
|
#define WFSCLI_READ_ASYNC_PARAM_AND_INC_PTR(ptr,Type,var) var=*((Type*)ptr); ptr=(void*)((size_t)pPtr + sizeof(Type))
|
||||||
|
#define WFSCLI_READ_ASYNC_PARAM(ptr,Type,var) var=*((Type*)ptr)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct WFSAsyncParamHdr WFSAsyncParamHdr;
|
||||||
|
typedef struct WFSAsyncParamHdrAnchor WFSAsyncParamHdrAnchor;
|
||||||
|
typedef struct WFSAsyncParamHdrLink WFSAsyncParamHdrLink;
|
||||||
|
typedef struct WFSAsyncParamGlobals WFSAsyncParamGlobals;
|
||||||
|
|
||||||
|
struct WFSAsyncParamHdrLink {
|
||||||
|
WFSAsyncParamHdr *pNext;
|
||||||
|
WFSAsyncParamHdr *pPrev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WFSAsyncParamHdrAnchor {
|
||||||
|
WFSAsyncParamHdr *pHead;
|
||||||
|
WFSAsyncParamHdr *pTail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WFSAsyncParamHdr {
|
||||||
|
WFSAsyncParamHdrLink l;
|
||||||
|
u32 nSize; // Size of parameters including this header
|
||||||
|
void *cb;
|
||||||
|
void *pUserData;
|
||||||
|
u8 nFunction; // Values are defined in wfssrv_Defs.h
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WFSAsyncGlobals {
|
||||||
|
WFSAsyncParamHdrAnchor anchor;
|
||||||
|
WFSThread asyncExecThread;
|
||||||
|
void *pAsyncExecStack;
|
||||||
|
WFSMutex mxAccessTheParamQueue;
|
||||||
|
WFSCond condParamQueueEmpty;
|
||||||
|
WFSCond condParamQueueNotEmpty;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void WFSAsyncUtilsInit();
|
||||||
|
|
||||||
|
void WFSAsyncUtilsClose();
|
||||||
|
|
||||||
|
WFSResult WFSPrepareAsyncCall(void **ppPtr, u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize);
|
||||||
|
|
||||||
|
WFSResult WFSPrepareAsyncCallWithPathName(void **ppPtr, const utf8 *sInPathName,
|
||||||
|
WFSPathNameType nPathType, u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize);
|
||||||
|
|
||||||
|
WFSResult WFSPrepareMoveLocalAsyncCall(void **ppPtr, const utf8 *sSrcPathName, const utf8 *sDstPathName,
|
||||||
|
WFSPathNameType nPathType, u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize);
|
||||||
|
|
||||||
|
WFSResult WFSPrepareAsyncCallWithDeviceName(void **ppPtr, const utf8 *sDeviceName,
|
||||||
|
u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize);
|
||||||
|
|
||||||
|
WFSResult WFSPrepareAsyncCallWithVolumeId(void **ppPtr, const utf8 *sVolumeId,
|
||||||
|
u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize);
|
||||||
|
|
||||||
|
#endif //define wfs_AsyncUtils_h
|
||||||
@ -0,0 +1,65 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Client.h - Internal definitions for the PPC side of the WFS API
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Client.h,v $
|
||||||
|
Revision 1.4 2007/11/02 00:20:34 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// File created 2007.08.29
|
||||||
|
|
||||||
|
#ifndef wfs_Client_h
|
||||||
|
#define wfs_Client_h
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_WFS_CLIENT 1
|
||||||
|
#else
|
||||||
|
#define _DEBUG_WFS_CLIENT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wfs_Heap.h"
|
||||||
|
#include "wfs_AsyncUtils.h"
|
||||||
|
#include "wfscli_Handles.h"
|
||||||
|
#include "wfssrv_Defs.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool bMutexInitialized;
|
||||||
|
WFSMutex mxAccessDeviceCallbackGlobals;
|
||||||
|
utf8 *pAttachDeviceNameBuffer;
|
||||||
|
WFSDeviceCallback cbAttachDevice;
|
||||||
|
void *pAttachDeviceUserData;
|
||||||
|
|
||||||
|
utf8 *pDetachDeviceNameBuffer;
|
||||||
|
WFSDeviceCallback cbDetachDevice;
|
||||||
|
void *pDetachDeviceUserData;
|
||||||
|
} WFSDeviceCallbackGlobals;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
bool bLibInitialized;
|
||||||
|
void *pWorkSpaceBuffer;
|
||||||
|
WFSHeap heap;
|
||||||
|
WFSCliHandles hnd;
|
||||||
|
WFSAsyncGlobals ag;
|
||||||
|
WFSPathGlobals pg;
|
||||||
|
WFSDeviceCallbackGlobals dcg;
|
||||||
|
} WFSClientGlobals;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSSrvFunc nFunction;
|
||||||
|
WFSPath pathAbs;
|
||||||
|
} WFSFuncParams_OnePathName;
|
||||||
|
|
||||||
|
extern WFSClientGlobals wcg;
|
||||||
|
|
||||||
|
#endif //wfs_Client_h
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Config.h - project-wide configuration settings governing resource allocations etc.
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Config.h,v $
|
||||||
|
Revision 1.8 2008/11/04 06:07:16 ueno
|
||||||
|
Changed the maximum number of file handles and search handles to 32.
|
||||||
|
|
||||||
|
Revision 1.7 2008/09/29 01:06:04 kondo_masahiro
|
||||||
|
Added several macros.
|
||||||
|
|
||||||
|
Revision 1.6 2008/07/09 02:52:33 paul
|
||||||
|
Increased maximum number of File & Directory Search handles
|
||||||
|
|
||||||
|
Revision 1.5 2008/05/12 20:30:22 paul
|
||||||
|
Added handle defs
|
||||||
|
|
||||||
|
Revision 1.4 2007/11/05 18:38:42 paul
|
||||||
|
WFSDEV flag is now defined in makefile / projectfile
|
||||||
|
|
||||||
|
Revision 1.3 2007/11/02 00:25:29 paul
|
||||||
|
started logging changes in the file
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Config_h
|
||||||
|
#define wfs_Config_h
|
||||||
|
|
||||||
|
|
||||||
|
// Define WFSDEV in the makefile/project settings to compile the WFS DEV version of the client
|
||||||
|
#ifdef WFSDEV
|
||||||
|
#define _WFSDEV 1
|
||||||
|
#else
|
||||||
|
#define _WFSDEV 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// This determines the maximum number of asynchronous calls that can be outstanding before a busy error occurs
|
||||||
|
//#define WFS_MAX_OUTSTANDING_ASYNC_CALLS 4
|
||||||
|
// Now it is determined by the amount of memory the user supplies with WFSInit
|
||||||
|
|
||||||
|
#define WFSCLI_WORK_SPACE_SIZE (40*1024)
|
||||||
|
#define WFS_ASYNC_EXEC_STACK_SIZE (16*1024) // client common code async handler thread
|
||||||
|
|
||||||
|
// WFSDEV-specific
|
||||||
|
#define WFSDEV_CALLBACK_THREAD_STACK_SIZE (16*1024) // client thread for server-initiated callbacks; for WFSDEV implementation
|
||||||
|
#define WFSDEV_MAX_CLIENTS (5) // maximum number of clients that the server can support simultaneously
|
||||||
|
|
||||||
|
#define WFSCLI_FILE_HANDLE_IDX_BITS 5
|
||||||
|
#define WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS 5
|
||||||
|
|
||||||
|
#endif //wfs_Config_h
|
||||||
@ -0,0 +1,81 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Defs.h
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Defs.h,v $
|
||||||
|
Revision 1.14 2008/11/05 15:11:45 ueno
|
||||||
|
Fixed WFS_ROUND_DOWN().
|
||||||
|
|
||||||
|
Revision 1.13 2008/07/11 05:27:22 kondo_masahiro
|
||||||
|
Fixed WFS_ROUND_UP / DOWN
|
||||||
|
|
||||||
|
Revision 1.11 2008/04/19 05:52:44 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.10 2007/12/28 07:33:23 nakanose_jin
|
||||||
|
fix bug
|
||||||
|
|
||||||
|
Revision 1.9 2007/12/26 10:17:44 paul
|
||||||
|
WFS_RANGE_CHK, WFS_INDEX_COUNT ’ljÁ
|
||||||
|
|
||||||
|
Revision 1.8 2007/11/06 22:44:18 paul
|
||||||
|
added wfs_Errors.h to list of included headers
|
||||||
|
|
||||||
|
Revision 1.7 2007/11/05 18:39:16 paul
|
||||||
|
removed unused macro
|
||||||
|
|
||||||
|
Revision 1.6 2007/11/02 00:24:51 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Defs_h
|
||||||
|
#define wfs_Defs_h
|
||||||
|
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x500
|
||||||
|
|
||||||
|
#include "revolution/wfs.h"
|
||||||
|
#include "wfs_Platform.h"
|
||||||
|
#include "wfs_Config.h"
|
||||||
|
#include "wfs_Errors.h"
|
||||||
|
#include "wfs_Types.h"
|
||||||
|
|
||||||
|
#if !_IOP
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WFS_ROUND_UP(v,x) (((v)+(x)-1)&-((signed)x))
|
||||||
|
#define WFS_ROUND_DOWN(v,x) ((v)&-((signed)x))
|
||||||
|
|
||||||
|
#define WFS_RANGE_CHK(val,min,max) (((val)>=(min))&&((val)<(max)))
|
||||||
|
#define WFS_INDEX_COUNT(array) (size_t)(sizeof(array)/sizeof(array[0]))
|
||||||
|
|
||||||
|
#define BYTES2BITS(b) ((b)<<3)
|
||||||
|
|
||||||
|
#ifndef swap_typ
|
||||||
|
#define swap_typ(Typ,a,b) { Typ t=a; a=b; b=t; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#ifndef _ASSERT
|
||||||
|
#define _ASSERT(x) ASSERT(x)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifndef _ASSERT
|
||||||
|
#define _ASSERT(x)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // wfs_defs_h
|
||||||
@ -0,0 +1,151 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Error_h
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Errors.h,v $
|
||||||
|
Revision 1.8 2008/07/11 19:14:01 paul
|
||||||
|
Updated to match latest wfsError.h
|
||||||
|
|
||||||
|
Revision 1.7 2007/12/04 05:59:11 paul
|
||||||
|
bug fix
|
||||||
|
|
||||||
|
Revision 1.6 2007/11/21 22:18:13 paul
|
||||||
|
Added WFS_INTERNAL_RESULT_ALREADY_MOUNTED
|
||||||
|
|
||||||
|
Revision 1.5 2007/11/06 22:44:53 paul
|
||||||
|
Added macro to do validation checks for NULL pointers passed in
|
||||||
|
|
||||||
|
Revision 1.4 2007/11/02 00:24:24 paul
|
||||||
|
started logging changes in the file
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Error_h
|
||||||
|
#define wfs_Error_h
|
||||||
|
|
||||||
|
#define WFSReturnOnError(x) { WFSResult nResult = x; if (nResult < WFS_RESULT_OK) return nResult; }
|
||||||
|
#define WFSReturnOnInternalError(x) { WFSInternalResult nResult = x; if (nResult < WFS_INTERNAL_RESULT_OK) return nResult; }
|
||||||
|
#define WFSReturnOnNullParameter(p) { if (p == NULL) return WFS_RESULT_INVALID; }
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WFS_INTERNAL_RESULT_OK = 0, // Success
|
||||||
|
|
||||||
|
// Errors that are usually detected in the client, and would result in the server not being called:
|
||||||
|
WFS_INTERNAL_RESULT_BUSY = -1, // The request queue is full.
|
||||||
|
WFS_INTERNAL_RESULT_OUT_OF_MEMORY = -2, // The client does not have enough memory to complete the requested operation. (May be due to too many outstanding aysnc calls).
|
||||||
|
WFS_INTERNAL_RESULT_INVALID = -3, // The function parameters were invalid, e.g. File name is too long, Path is too long or too deep.
|
||||||
|
WFS_INTERNAL_RESULT_ACCESS = -4, // Trying to write to a file which was opened for read-only access, or vice versa.
|
||||||
|
WFS_INTERNAL_RESULT_LIB_NOT_INITIALIZED = -5, // The WFS client has not been initialized. Please call WFSInit(..) (This error message is omitted from the list of return values).
|
||||||
|
WFS_INTERNAL_RESULT_LIB_INITIALIZED = -6, // The WFS client has already been initialized.
|
||||||
|
WFS_INTERNAL_RESULT_FILE_TOO_BIG = -7, // The current write/append request would push the file over the size limit.
|
||||||
|
WFS_INTERNAL_RESULT_NO_CHANGE_SIZE = -8, // The requested operation would cause the file size to change, but this file has WFS_PERM_NO_CHANGE_SIZE flag set.
|
||||||
|
|
||||||
|
// Errors that cannot usually be detected early, and would be passed via nResult to the Async callbacks:
|
||||||
|
WFS_INTERNAL_RESULT_MEDIA_ERROR = -9, // The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
WFS_INTERNAL_RESULT_DEV_UNUSABLE = -10, // Attached device is not accessible, e.g. because it is an unsupported device, or has an unknown format.
|
||||||
|
WFS_INTERNAL_RESULT_DEV_NOT_INITIALIZED = -11, // Device not formatted, or does not yet contain a Wii volume
|
||||||
|
WFS_INTERNAL_RESULT_DEV_IN_USE = -12, // Trying to initialize a device which is in use (mounted) by one or more clients.
|
||||||
|
WFS_INTERNAL_RESULT_VOL_ID_ERROR = -13, // Attempted to mount a device with the same unique ID as an already mounted device (This could happen if the User backs up an entire Wii partition using a PC)
|
||||||
|
WFS_INTERNAL_RESULT_WRITE_PROTECTED = -14, // Device is physically write protected (e.g. USB Flash memory, SD Card).
|
||||||
|
WFS_INTERNAL_RESULT_ALREADY_MOUNTED = -15, // The device is already mounted.
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_PERMISSION = -16, // Permission flags do not permit the requested access from this application.
|
||||||
|
WFS_INTERNAL_RESULT_PERMISSION_CL = -17, // Permission error caused by control level problems.
|
||||||
|
WFS_INTERNAL_RESULT_ACL_FULL = -18, // The access list is full.
|
||||||
|
WFS_INTERNAL_RESULT_ACL_ENTRY_NOT_FOUND = -19, // The specified entry does not exist in the access list.
|
||||||
|
WFS_INTERNAL_RESULT_AUTHENTICATION = -20, // Trying to access content on a different Wii, which does not have the required access rights.
|
||||||
|
WFS_INTERNAL_RESULT_CORRUPTION = -21, // A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_DIRECTORY_QUOTA = -22, // One of the ancestor directories would exceed its quota.
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_MAX_HANDLES = -23, // The maximum number of concurrent file handles / search handles are already in use.
|
||||||
|
WFS_INTERNAL_RESULT_ALREADY_EXISTS = -24, // The file or directory being created already exists.
|
||||||
|
WFS_INTERNAL_RESULT_NOT_FOUND = -25, // The specified file or directory or device does not exist.
|
||||||
|
WFS_INTERNAL_RESULT_NOT_EMPTY = -26, // The specified directory cannot be deleted because it is not empty.
|
||||||
|
WFS_INTERNAL_RESULT_NOT_FILE = -27, // The specified path is directory instead of a file.
|
||||||
|
WFS_INTERNAL_RESULT_NOT_DIRECTORY = -28, // The specified path is a file instead of a directory
|
||||||
|
WFS_INTERNAL_RESULT_FILE_OPEN = -39, // The file is open. Cannot delete, move, rename, change permissions of an open file. Cannot open a file more than once unless all opens are WFS_ACCESS_READ.
|
||||||
|
WFS_INTERNAL_RESULT_LOCKED = -30, // Cannot perform the requested operation since the file or directory is locked by an existing operation.
|
||||||
|
WFS_INTERNAL_RESULT_RESOURCE_LIMIT_EXCEEDED = -31, // A resource limit prevents this function call. Try smaller values.
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_DIR_ENTRY_FOUND = -40, // The search string was matched and pointed to an entry
|
||||||
|
WFS_INTERNAL_RESULT_DIR_NODE_STRING_PREFIX = -41, // The search string ended early during comparison with a node sub string. (So this name is a prefix of existing names)
|
||||||
|
WFS_INTERNAL_RESULT_DIR_CHOICE_PREFIX = -42, // The search string ended at the end of a node sub string, but the node did not have a termination choice. (This name is a prefix of existing names)
|
||||||
|
WFS_INTERNAL_RESULT_DIR_NODE_STRING_MISMATCH = -43, // A mismatch was encountered while comparing the search string to a sub node prefix string.
|
||||||
|
WFS_INTERNAL_RESULT_DIR_NODE_CHOICE_NOT_FOUND = -44, // A mismatch was encountered while comparing a character of the search string with a set of choices for that character.
|
||||||
|
WFS_INTERNAL_RESULT_DIR_BLK_FULL = -45, // Unable to insert the specified string to the radix tree, due to lack of space in the block.
|
||||||
|
|
||||||
|
// These result codes are not errors, but normal return values for the path cache functions
|
||||||
|
WFS_INTERNAL_RESULT_SRV_END_OF_PATH = -60, // Last part of path name parsed
|
||||||
|
WFS_INTERNAL_RESULT_SRV_PATH_DEPTH_1 = -61, // Path was of depth 1, such as "/something"
|
||||||
|
WFS_INTERNAL_RESULT_SRV_PATH_DEV = -62, // Path was "/dev"
|
||||||
|
WFS_INTERNAL_RESULT_SRV_PATH_VOL = -63, // Path was "/vol"
|
||||||
|
WFS_INTERNAL_RESULT_SRV_PATH_VOL_ROOT = -64, // Path was a volume root path, such as "/vol/xxxxxxx/"
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_PTREE_ENTRY_FOUND = -70,
|
||||||
|
WFS_INTERNAL_RESULT_PTREE_ENTRY_NOT_FOUND = -71,
|
||||||
|
WFS_INTERNAL_RESULT_PTREE_FULL = -72,
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_DEVICE_ERROR = -200,
|
||||||
|
WFS_INTERNAL_RESULT_DEVICE_INVALID_PARAMETER = -201,
|
||||||
|
WFS_INTERNAL_RESULT_DEVICE_NOT_FOUND = -202,
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_ERROR = -300, // unspecified error
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_RESOURCE_LIMIT = -301, // exhausted resources
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_INVALID_PARAMETER = -302, // at least one argument is invalid
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_NO_MEMORY = -303, // could not malloc
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_NOT_FOUND = -304, // sector is not cached
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_MAX_DEVICES = -305, // max devices alreay allocated
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_INVALID_DEVICE = -306, // device not found/open
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_INVALID_HANDLE = -307, // invalid device handle
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_INVALID_VOLUME = -308, // invalid volume ID (not mapped)
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_ALREADY_MAPPED = -309, // vol or devH already mapped
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_ALLOC = -310, // cannot alloc (no mem, or pmem error)
|
||||||
|
WFS_INTERNAL_RESULT_BCACHE_PMEM = -311, // cannot read or write to pmem device
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_VOLUME_ERROR = -400, // unspecified volume error
|
||||||
|
WFS_INTERNAL_RESULT_VOLUME_INVALID_PARAMETER = -401, // at least one argument is invalid
|
||||||
|
WFS_INTERNAL_RESULT_VOLUME_BCACHE_ALLOC = -402, // cannot allocate a page/block in memory
|
||||||
|
WFS_INTERNAL_RESULT_VOLUME_BCACHE_CONFIG = -403, // block cache not configured correctly
|
||||||
|
WFS_INTERNAL_RESULT_VOLUME_ID = -404, // bad volume ID or not initialized
|
||||||
|
WFS_INTERNAL_RESULT_VOLUME_CORRUPT_MR = -405, // the MR (or its free lists) are corrupted
|
||||||
|
WFS_INTERNAL_RESULT_VOLUME_AREA_ALLOC = -406, // area allocation cannot be satisfied
|
||||||
|
WFS_INTERNAL_RESULT_VOLUME_DEVICE_PARAMETER = -407, // parameters incompatible with device
|
||||||
|
WFS_INTERNAL_RESULT_VOLUME_NOT_MAPPED = -408, // volume is not mapped; invalid volume ID
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_TRANSACTION_ERROR = -500, // unspecified transaction error
|
||||||
|
WFS_INTERNAL_RESULT_TRANSACTION_INVALID_PARAMETER= -501,
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_ACL_ERROR = -600, // unspecified error
|
||||||
|
WFS_INTERNAL_RESULT_ACL_INVALID_PARAMETER = -601, // at least one argument is invalid
|
||||||
|
WFS_INTERNAL_RESULT_ACL_MAX_ENTRIES = -602, // max entries already in the access list.
|
||||||
|
WFS_INTERNAL_RESULT_ACL_BUFFER_TOO_SMALL = -603, // buffer is too small to store an access list.
|
||||||
|
WFS_INTERNAL_RESULT_ACL_CACHE = -610, // cannot allocate a cache.
|
||||||
|
WFS_INTERNAL_RESULT_ACL_FILE = -620, // cannot create, modify or delete the access list file.
|
||||||
|
WFS_INTERNAL_RESULT_ACL_ACLDIR_INCONSISTENT = -621, // access list files and indexlist are inconsistent.
|
||||||
|
WFS_INTERNAL_RESULT_ACL_FILENAME = -630, // cannot convert acl filename <=> acl content.
|
||||||
|
WFS_INTERNAL_RESULT_ACL_NAMEDIR_INCONSISTENT = -631, // access name files and indexlist are inconsistent.
|
||||||
|
WFS_INTERNAL_RESULT_ACL_HANDLE = -640, // cannot allocate an access list handle.
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_AREA_ERROR = -700, // unspecified area error
|
||||||
|
WFS_INTERNAL_RESULT_AREA_INVALID_PARAMETER = -701,
|
||||||
|
WFS_INTERNAL_RESULT_AREA_BCACHE_ALLOC = -702, // cannot allocate a page/block in memory
|
||||||
|
WFS_INTERNAL_RESULT_AREA_CORRUPT_HDR = -703, // the area header is corrupted
|
||||||
|
WFS_INTERNAL_RESULT_AREA_VOLUME_NOT_MAPPED = -704, // volume is not mapped; invalid volume ID
|
||||||
|
WFS_INTERNAL_RESULT_AREA_ALLOC = -705, // area allocation cannot be satisfied
|
||||||
|
|
||||||
|
WFS_INTERNAL_RESULT_NOT_IMPLEMENTED = -1026, // The requested function has not yet been implemented //ToDo: This error should be removed from the final API
|
||||||
|
WFS_INTERNAL_RESULT_UNKNOWN = -1027, // Unexpected error - could be caused by a bug in the file system.
|
||||||
|
WFS_INTERNAL_RESULT_FATAL_ERROR = -1028 // May be caused by critical metadata corruption.
|
||||||
|
} WFSInternalResult;
|
||||||
|
|
||||||
|
#define WFSSetLastError(nErr) (wkg.nLastErr = (nErr))
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Heap.h - memory allocation functions
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Heap.h,v $
|
||||||
|
Revision 1.8 2008/04/19 05:52:37 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.7 2007/12/26 04:26:41 paul
|
||||||
|
changed pAllocator to &allocator
|
||||||
|
|
||||||
|
Revision 1.6 2007/12/26 04:13:56 paul
|
||||||
|
Changed RVL version of WFSHeap
|
||||||
|
|
||||||
|
Revision 1.5 2007/12/26 00:19:25 paul
|
||||||
|
Added WFSHeapDestroy()
|
||||||
|
|
||||||
|
Revision 1.4 2007/11/02 00:23:58 paul
|
||||||
|
started logging changes in the file
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Heap_h
|
||||||
|
#define wfs_Heap_h
|
||||||
|
|
||||||
|
|
||||||
|
#include "wfs_Defs.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_HEAP 0 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_HEAP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
typedef HANDLE WFSHeap;
|
||||||
|
|
||||||
|
#elif _TWL
|
||||||
|
|
||||||
|
#define WFS_HEAP_DEFAULT_ALIGNMENT 32
|
||||||
|
|
||||||
|
typedef OSHeapHandle WFSHeap;
|
||||||
|
|
||||||
|
#elif _RVL
|
||||||
|
|
||||||
|
#include <revolution/mem.h>
|
||||||
|
#define WFS_HEAP_DEFAULT_ALIGNMENT 32
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MEMAllocator allocator;
|
||||||
|
MEMHeapHandle handle;
|
||||||
|
} WFSHeap;
|
||||||
|
|
||||||
|
#elif _IOP
|
||||||
|
|
||||||
|
#define WFSHeap IOSHeapId
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void WFSCreateHeap(WFSHeap *pHeap, void *pBase, size_t nSize);
|
||||||
|
void *WFSHeapAlloc(WFSHeap *pHeap, size_t nSize);
|
||||||
|
void WFSHeapFree(WFSHeap *pHeap, void *pAddr);
|
||||||
|
void WFSHeapDestroy(WFSHeap *pHeap);
|
||||||
|
|
||||||
|
#endif //define wfs_Heap_h
|
||||||
@ -0,0 +1,179 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Mutex.h - mutual exclusion for multi-thread case
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Mutex.h,v $
|
||||||
|
Revision 1.11 2008/04/19 05:52:30 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.10 2007/12/27 01:43:38 ueno
|
||||||
|
Added WFSIsThreadTerminated() and WFSJoinThread().
|
||||||
|
|
||||||
|
Revision 1.9 2007/12/25 13:59:47 ueno
|
||||||
|
Added WFSSuspendThread().
|
||||||
|
|
||||||
|
Revision 1.8 2007/11/21 04:17:28 wayne.wong
|
||||||
|
Many changes that included single request/result RPC messages, bug fixes, code factoring, and English C comment adjustments.
|
||||||
|
1. Combined RPC messages into a single request message and single result
|
||||||
|
message. Except for file reads and writes.
|
||||||
|
2. Fixed+factored some Endianess code.
|
||||||
|
3. Enabled larger TCP/IP data transfer size. Previous setting was artifically small
|
||||||
|
to test the code to perform large transfers.
|
||||||
|
4. Changed the volume id parameters utf8*->WFSVolumeId for SrvGetVolumeId
|
||||||
|
and SrvMountDevice. More consistent with the way we send this type at the
|
||||||
|
RPC layer.
|
||||||
|
5. Changed a couple Japanese comments to be compatible with English
|
||||||
|
comments. In particular, the "//" comment with a backslash at the end of
|
||||||
|
the line causes the next line of code to be ignored.
|
||||||
|
6. Removed Windows-specific debugging output defines for RVL build.
|
||||||
|
|
||||||
|
Revision 1.7 2007/11/02 00:23:33 paul
|
||||||
|
started logging changes in the file
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Mutex_h
|
||||||
|
#define wfs_Mutex_h
|
||||||
|
|
||||||
|
#include "wfs_Defs.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_MUTEX 0 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_MUTEX 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HANDLE hHandle;
|
||||||
|
} WFSMutex;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HANDLE hAutoResetEvent;
|
||||||
|
//HANDLE hManualResetEvent;
|
||||||
|
} WFSCond;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HANDLE hThread;
|
||||||
|
} WFSThread;
|
||||||
|
|
||||||
|
void WFSInitMutex(WFSMutex *mutex);
|
||||||
|
void WFSLockMutex(WFSMutex *mutex);
|
||||||
|
bool WFSTryLockMutex(WFSMutex *mutex);
|
||||||
|
void WFSUnlockMutex(WFSMutex *mutex);
|
||||||
|
|
||||||
|
void WFSInitCond(WFSCond *pCond);
|
||||||
|
void WFSSignalCond(WFSCond *pCond);
|
||||||
|
void WFSWaitCond(WFSCond *pCond, WFSMutex* pMx);
|
||||||
|
void WFSResetCond(WFSCond *pCond);
|
||||||
|
|
||||||
|
typedef LPTHREAD_START_ROUTINE WFSThreadFunc;
|
||||||
|
|
||||||
|
bool WFSCreateThread(WFSThread *thread,
|
||||||
|
WFSThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority);
|
||||||
|
|
||||||
|
s32 WFSResumeThread(WFSThread *pThread);
|
||||||
|
void WFSCancelThread(WFSThread *pThread);
|
||||||
|
void WFSExitThread(void *pVal);
|
||||||
|
s32 WFSSuspendThread(WFSThread *pThread);
|
||||||
|
bool WFSIsThreadTerminated(WFSThread *thread);
|
||||||
|
bool WFSJoinThread(WFSThread *thread, void** val);
|
||||||
|
|
||||||
|
#elif _TWL
|
||||||
|
|
||||||
|
#define WFSMutex OSMutex
|
||||||
|
#define WFSCond OSEvent
|
||||||
|
#define WFSThread OSThread
|
||||||
|
|
||||||
|
#define WFSInitMutex osInitMutex
|
||||||
|
#define WFSLockMutex osLockMutex
|
||||||
|
#define WFSTryLockMutex osTryLockMutex
|
||||||
|
#define WFSUnlockMutex osUnlockMutex
|
||||||
|
|
||||||
|
//#define WFSInitCond osInitCond
|
||||||
|
//#define WFSSignalCond osSignalCond
|
||||||
|
//#define WFSWaitCond osWaitCond
|
||||||
|
//#define WFSResetCond(x) // This function does nothing on RVL, only needed for Windows
|
||||||
|
|
||||||
|
typedef void *(*WFSThreadFunc)(void *);
|
||||||
|
|
||||||
|
bool WFSCreateThread(WFSThread *thread,
|
||||||
|
WFSThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority);
|
||||||
|
|
||||||
|
s32 WFSResumeThread(WFSThread *pThread);
|
||||||
|
void WFSCancelThread(WFSThread *pThread);
|
||||||
|
void WFSExitThread(void *pVal);
|
||||||
|
s32 WFSSuspendThread(WFSThread *pThread);
|
||||||
|
bool WFSIsThreadTerminated(WFSThread *thread);
|
||||||
|
bool WFSJoinThread(WFSThread *thread, void** val);
|
||||||
|
|
||||||
|
void WFSInitCond(WFSCond *pCond);
|
||||||
|
void WFSSignalCond(WFSCond *pCond);
|
||||||
|
void WFSWaitCond(WFSCond *pCond, WFSMutex* pMx);
|
||||||
|
void WFSResetCond(WFSCond *pCond);
|
||||||
|
/*
|
||||||
|
#define WFSResumeThread OSResumeThread
|
||||||
|
#define WFSCancelThread OSCancelThread
|
||||||
|
#define WFSExitThread OSExitThread
|
||||||
|
#define WFSSuspendThread OSSuspendThread
|
||||||
|
#define WFSIsThreadTerminated OSIsThreadTerminated
|
||||||
|
#define WFSJoinThread OSJoinThread
|
||||||
|
*/
|
||||||
|
#elif _RVL
|
||||||
|
|
||||||
|
#define WFSMutex OSMutex
|
||||||
|
#define WFSCond OSCond
|
||||||
|
#define WFSThread OSThread
|
||||||
|
|
||||||
|
#define WFSInitMutex OSInitMutex
|
||||||
|
#define WFSLockMutex OSLockMutex
|
||||||
|
#define WFSTryLockMutex OSTryLockMutex
|
||||||
|
#define WFSUnlockMutex OSUnlockMutex
|
||||||
|
|
||||||
|
#define WFSInitCond OSInitCond
|
||||||
|
#define WFSSignalCond OSSignalCond
|
||||||
|
#define WFSWaitCond OSWaitCond
|
||||||
|
#define WFSResetCond(x) // This function does nothing on RVL, only needed for Windows
|
||||||
|
|
||||||
|
typedef void *(*WFSThreadFunc)(void *);
|
||||||
|
|
||||||
|
bool WFSCreateThread(WFSThread *thread,
|
||||||
|
WFSThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority);
|
||||||
|
|
||||||
|
#define WFSResumeThread OSResumeThread
|
||||||
|
#define WFSCancelThread OSCancelThread
|
||||||
|
#define WFSExitThread OSExitThread
|
||||||
|
#define WFSSuspendThread OSSuspendThread
|
||||||
|
#define WFSIsThreadTerminated OSIsThreadTerminated
|
||||||
|
#define WFSJoinThread OSJoinThread
|
||||||
|
|
||||||
|
#elif _IOP
|
||||||
|
|
||||||
|
// dummy
|
||||||
|
typedef void *WFSMutex;
|
||||||
|
typedef void *WFSThread;
|
||||||
|
typedef void *WFSCond;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //define wfs_Mutex_h
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Names.h - global name types used by the WFS project
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Names.h,v $
|
||||||
|
Revision 1.5 2008/02/25 05:32:50 paul
|
||||||
|
Reverted to previous version - changed defs instead.
|
||||||
|
|
||||||
|
Revision 1.3 2007/11/06 22:43:48 paul
|
||||||
|
changed include
|
||||||
|
|
||||||
|
Revision 1.2 2007/11/02 00:22:34 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Names_h
|
||||||
|
#define wfs_Names_h
|
||||||
|
|
||||||
|
#include "wfs_Defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if (WFS_MAX_PATH_NAME_SIZE<256)
|
||||||
|
typedef u8 WFSPathNameLengthType;
|
||||||
|
#elif (WFS_MAX_PATH_NAME_SIZE<65536)
|
||||||
|
typedef u16 WFSPathNameLengthType;
|
||||||
|
#else
|
||||||
|
typedef u32 WFSPathNameLengthType;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSPathNameLengthType nLen; // This is the length of the string not including the NULL terminator
|
||||||
|
utf8 sStr[WFS_MAX_PATH_NAME_SIZE+1];
|
||||||
|
} WFSPathName;
|
||||||
|
|
||||||
|
WFSResult WFSSetPathName(WFSPathName *pPathName, const utf8 *sPathName);
|
||||||
|
|
||||||
|
|
||||||
|
#if (WFS_MAX_FILE_NAME_SIZE<256)
|
||||||
|
typedef u8 WFSFileNameLengthType;
|
||||||
|
#elif (WFS_MAX_FILE_NAME_SIZE<65536)
|
||||||
|
typedef u16 WFSFileNameLengthType;
|
||||||
|
#else
|
||||||
|
typedef u32 WFSFileNameLengthType;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSFileNameLengthType nLen; // This is the length of the string not including the NULL terminator
|
||||||
|
utf8 sStr[WFS_MAX_FILE_NAME_SIZE+1];
|
||||||
|
} WFSFileName;
|
||||||
|
|
||||||
|
WFSResult WFSSetFileName(WFSFileName *pFileName, const utf8 *sFileName);
|
||||||
|
|
||||||
|
|
||||||
|
#if (WFS_MAX_DEVICE_NAME_SIZE<256)
|
||||||
|
typedef u8 WFSDeviceNameLengthType;
|
||||||
|
#elif (WFS_MAX_DEVICE_NAME_SIZE<65536)
|
||||||
|
typedef u16 WFSDeviceNameLengthType;
|
||||||
|
#else
|
||||||
|
typedef u32 WFSDeviceNameLengthType;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSDeviceNameLengthType nLen; // This is the length of the string not including the NULL terminator
|
||||||
|
utf8 sStr[WFS_MAX_DEVICE_NAME_SIZE+1];
|
||||||
|
} WFSDeviceName;
|
||||||
|
|
||||||
|
WFSResult WFSSetDeviceName(WFSDeviceName *pDeviceName, const utf8 *sDeviceName);
|
||||||
|
|
||||||
|
|
||||||
|
#if (WFS_MAX_VOLUME_ID_SIZE<256)
|
||||||
|
typedef u8 WFSVolumeIdLengthType;
|
||||||
|
#elif (WFS_MAX_VOLUME_ID_SIZE<65536)
|
||||||
|
typedef u16 WFSVolumeIdLengthType;
|
||||||
|
#else
|
||||||
|
typedef u32 WFSVolumeIdLengthType;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSVolumeIdLengthType nLen; // This is the length of the string not including the NULL terminator
|
||||||
|
utf8 sStr[WFS_MAX_VOLUME_ID_SIZE+1];
|
||||||
|
} WFSVolumeId;
|
||||||
|
|
||||||
|
WFSResult WFSSetVolumeId(WFSVolumeId *pVolumeId, const utf8 *sVolumeId);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //define wfs_Names_h
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_PathNames.h - Functions for concatenating relative and absolute pathnames
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_PathNames.h,v $
|
||||||
|
Revision 1.10 2008/08/19 14:05:40 nakanose_jin
|
||||||
|
smash pathnames bug
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/19 20:44:58 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.8 2007/12/10 02:50:11 paul
|
||||||
|
Added debug output
|
||||||
|
|
||||||
|
Revision 1.7 2007/11/09 01:20:52 paul
|
||||||
|
Added a new path name type to allow validation of path name depth for paths ending in directories
|
||||||
|
|
||||||
|
Revision 1.6 2007/11/02 01:09:26 paul
|
||||||
|
updated path type
|
||||||
|
|
||||||
|
Revision 1.5 2007/11/02 00:20:16 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// File created by Paul Donnelly on 2007.10.05
|
||||||
|
|
||||||
|
#ifndef wfs_PathNames_h
|
||||||
|
#define wfs_PathNames_h
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_PATHNAMES 0 // change to 1 locally if debug info required. (should be 0 for checkin)
|
||||||
|
#else
|
||||||
|
#define _DEBUG_PATHNAMES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wfs_Mutex.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// Initial states
|
||||||
|
PATH_TYPE_REL_OR_ABS=0, // Path name can be a relative or absolute file or directory
|
||||||
|
PATH_TYPE_REL_OR_ABS_DIR, // Path name can be a relative or absolute directory
|
||||||
|
PATH_TYPE_ABS_DIR_ONLY, // Path name must be an absolute directory
|
||||||
|
PATH_TYPE_PATTERN // Path name (pattern) can be relative or absolute and may include wild cards in file name part.
|
||||||
|
} WFSPathNameType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u16 nNumParts;
|
||||||
|
WFSPathNameLengthType aPart[WFS_MAX_PATH_DEPTH+1];
|
||||||
|
} WFSPathPartOffsetArray;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSPathPartOffsetArray ppoa;
|
||||||
|
WFSPathName pn;
|
||||||
|
} WFSPath;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSMutex mxAccessPathGlobals;
|
||||||
|
WFSPath pathHome, pathCurrent;
|
||||||
|
} WFSPathGlobals;
|
||||||
|
|
||||||
|
void WFSPathInit();
|
||||||
|
|
||||||
|
WFSResult WFSPathResolve(WFSPathName *pPnOutAbs, WFSPathPartOffsetArray *pPpoaOutAbs, const utf8 *sInPathName, WFSPathNameType nPathType);
|
||||||
|
|
||||||
|
WFSResult WFSPathValidate(WFSPath *pPath);
|
||||||
|
|
||||||
|
void WFSPathCopy(WFSPathName *pPnDst, WFSPathPartOffsetArray *pPpoaDst, WFSPathName *pPnSrc, WFSPathPartOffsetArray *pPpoaSrc, bool bAppendSeparator, bool bNullTermination);
|
||||||
|
|
||||||
|
#endif //define wfs_PathNames_h
|
||||||
@ -0,0 +1,161 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Platform.h - low level definitions and types that are primarily platform dependent
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Platform.h,v $
|
||||||
|
Revision 1.13 2008/08/28 00:20:35 nakanose_jin
|
||||||
|
lets standard exception style
|
||||||
|
|
||||||
|
Revision 1.11 2008/08/27 04:50:50 nakanose_jin
|
||||||
|
add function and defines
|
||||||
|
|
||||||
|
Revision 1.10 2008/07/17 05:56:25 kondo_masahiro
|
||||||
|
Added #define SNPRINTF
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/24 23:19:15 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.8 2008/04/22 00:59:59 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.6 2007/11/21 04:17:28 wayne.wong
|
||||||
|
Many changes that included single request/result RPC messages, bug fixes, code factoring, and English C comment adjustments.
|
||||||
|
1. Combined RPC messages into a single request message and single result
|
||||||
|
message. Except for file reads and writes.
|
||||||
|
2. Fixed+factored some Endianess code.
|
||||||
|
3. Enabled larger TCP/IP data transfer size. Previous setting was artifically small
|
||||||
|
to test the code to perform large transfers.
|
||||||
|
4. Changed the volume id parameters utf8*->WFSVolumeId for SrvGetVolumeId
|
||||||
|
and SrvMountDevice. More consistent with the way we send this type at the
|
||||||
|
RPC layer.
|
||||||
|
5. Changed a couple Japanese comments to be compatible with English
|
||||||
|
comments. In particular, the "//" comment with a backslash at the end of
|
||||||
|
the line causes the next line of code to be ignored.
|
||||||
|
6. Removed Windows-specific debugging output defines for RVL build.
|
||||||
|
|
||||||
|
Revision 1.5 2007/11/17 03:05:38 paul
|
||||||
|
removed #include "WinOSReport.h" from NDEV version
|
||||||
|
|
||||||
|
Revision 1.4 2007/11/05 18:39:52 paul
|
||||||
|
removed kernel-specific definitions
|
||||||
|
|
||||||
|
Revision 1.3 2007/11/02 00:22:23 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Platform_h
|
||||||
|
#define wfs_Platform_h
|
||||||
|
|
||||||
|
#include <firm.h>
|
||||||
|
|
||||||
|
#define TWL 1
|
||||||
|
//--twl modified
|
||||||
|
#if 1
|
||||||
|
#define _OSX 0
|
||||||
|
#define _WIN32 0
|
||||||
|
#define _TWL 1
|
||||||
|
#define _RVL 0
|
||||||
|
#define _IOP 0
|
||||||
|
#else
|
||||||
|
//--twl modified
|
||||||
|
#ifdef OSX
|
||||||
|
#define _OSX 1
|
||||||
|
#define _WIN32 0
|
||||||
|
#define _RVL 0
|
||||||
|
#define _IOP 0
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
#define _OSX 0
|
||||||
|
#define _WIN32 1
|
||||||
|
#define _RVL 0
|
||||||
|
#define _IOP 0
|
||||||
|
#else
|
||||||
|
#ifdef IOP
|
||||||
|
#define _OSX 0
|
||||||
|
#define _WIN32 0
|
||||||
|
#define _RVL 0
|
||||||
|
#define _IOP 1
|
||||||
|
#else // RVL
|
||||||
|
#define _OSX 0
|
||||||
|
#define _WIN32 0
|
||||||
|
#define _RVL 1
|
||||||
|
#define _IOP 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif //twl modified
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
// #define UNALIGNED __unaligned
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
#define OSReport printf
|
||||||
|
#include "WinOSReport.h"
|
||||||
|
#define OSPanic MyOSPanic
|
||||||
|
#define SNPRINTF _snprintf
|
||||||
|
#elif _OSX
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
#define OSReport printf
|
||||||
|
#include "WinOSReport.h"
|
||||||
|
#define OSPanic MyOSReport
|
||||||
|
#define SNPRINTF snprintf
|
||||||
|
//-- twl modified
|
||||||
|
#elif _TWL
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
#define MyOSReport osTPrintf
|
||||||
|
#define InitMyOSReport()
|
||||||
|
#define SNPRINTF OS_SNPrintf
|
||||||
|
#define STRNLEN( str, maxlen ) stdStrLen(str)
|
||||||
|
//-- twl modified
|
||||||
|
#elif _RVL
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
#define max(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#define min(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#define MyOSReport OSReport
|
||||||
|
#define InitMyOSReport()
|
||||||
|
#define SNPRINTF snprintf
|
||||||
|
#elif _IOP
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
#define max(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#define min(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#define MyOSReport printf
|
||||||
|
#define InitMyOSReport()
|
||||||
|
#define SNPRINTF snprintf
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
#ifndef BIG_ENDIAN
|
||||||
|
#ifdef WIN32
|
||||||
|
#define BIG_ENDIAN 0
|
||||||
|
#elif TWL
|
||||||
|
#define BIG_ENDIAN 0
|
||||||
|
#else
|
||||||
|
#define BIG_ENDIAN 1
|
||||||
|
#endif // WIN32
|
||||||
|
#endif // BIG_ENDIAN
|
||||||
|
|
||||||
|
|
||||||
|
#endif //define wfs_Platform_h
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Types.h - global types used by the WFS project
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Types.h,v $
|
||||||
|
Revision 1.5 2008/04/19 05:52:09 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.4 2007/11/02 23:14:04 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
Revision 1.3 2007/11/02 22:35:50 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
Revision 1.2 2007/11/02 00:21:35 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Types_h
|
||||||
|
#define wfs_Types_h
|
||||||
|
|
||||||
|
//typedef char utf8;
|
||||||
|
|
||||||
|
#include "wfs_Names.h"
|
||||||
|
|
||||||
|
#endif //define wfs_Types_h
|
||||||
@ -0,0 +1,130 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Handles.h - Module for file handles and search directory handles
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfscli_Handles.h,v $
|
||||||
|
Revision 1.10 2008/10/07 06:42:05 ueno
|
||||||
|
Modified WFSCliFileInfoAlloc to set WFSCLI_HANDLE_ALLOCATED in order to indicate the handle is allocated.
|
||||||
|
|
||||||
|
Revision 1.9 2008/07/09 02:51:29 paul
|
||||||
|
Fixed comments
|
||||||
|
|
||||||
|
Revision 1.8 2008/05/12 20:30:41 paul
|
||||||
|
Updated handle defs
|
||||||
|
|
||||||
|
Revision 1.7 2007/11/02 00:19:58 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// File created by Paul Donnelly on 2007.10.06
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef wfs_Handles_h
|
||||||
|
#define wfs_Handles_h
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_WFS_HANDLES 1
|
||||||
|
#else
|
||||||
|
#define _DEBUG_WFS_HANDLES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wfs_Defs.h"
|
||||||
|
#include "wfs_Mutex.h"
|
||||||
|
|
||||||
|
#define WFSCLI_MAX_FILE_HANDLES (1<<WFSCLI_FILE_HANDLE_IDX_BITS)
|
||||||
|
#define WFSCLI_MAX_SEARCH_DIR_HANDLES (1<<WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
|
||||||
|
/* Adding WFS_MAX_OUTSTANDING_ASYNC_CALLS so that we guarantee a handle is always available on the client side
|
||||||
|
#define WFSCLI_MAX_FILE_HANDLES (16 + WFS_MAX_OUTSTANDING_ASYNC_CALLS)
|
||||||
|
#define WFSCLI_MAX_SEARCH_DIR_HANDLES (4 + WFS_MAX_OUTSTANDING_ASYNC_CALLS)
|
||||||
|
|
||||||
|
#define WFSCLI_FILE_HANDLE_IDX_BITS WFS_NUM_BITS_REQUIRED(WFSCLI_MAX_FILE_HANDLES)
|
||||||
|
#define WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS WFS_NUM_BITS_REQUIRED(WFSCLI_MAX_SEARCH_DIR_HANDLES)*/
|
||||||
|
|
||||||
|
#define WFSCLI_FILE_HANDLE_INC (1<<(16+WFSCLI_FILE_HANDLE_IDX_BITS))
|
||||||
|
#define WFSCLI_SEARCH_DIR_HANDLE_INC (1<<(16+WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS))
|
||||||
|
|
||||||
|
#define WFSCLI_HANDLE_MASK 0xFFFF0000
|
||||||
|
#define WFSCLI_HANDLE_COUNTER_MASK 0x1FFF0000
|
||||||
|
#define WFSCLI_FILE_HANDLE_TT_FIELD 0x00000000
|
||||||
|
#define WFSCLI_SEARCH_DIR_HANDLE_TT_FIELD 0x20000000
|
||||||
|
#define WFSCLI_HANDLE_ALLOCATED 0x0000FFFF // set WFSCliFileInfo.nNext to represent this handle is in use.
|
||||||
|
|
||||||
|
|
||||||
|
// Internal binary format of WFSFileHandle (u32)
|
||||||
|
//
|
||||||
|
// 0TTcccccccCCCCCCssssssssssSSSSSS
|
||||||
|
//
|
||||||
|
// 0 = always 0 (Number of bits = 1 )
|
||||||
|
// T = type of handle: 00 for FileHandle (Number of bits = 2 )
|
||||||
|
// c = incrementally assigned by client (Number of bits = 13 - WFSCLI_FILE_HANDLE_IDX_BITS)
|
||||||
|
// C = idx of aCliFileInfo array (Number of bits = WFSCLI_FILE_HANDLE_IDX_BITS)
|
||||||
|
// s = incrementally assigned by server (Number of bits = 16 - WFSCLI_FILE_HANDLE_IDX_BITS)
|
||||||
|
// S = idx of aSrvFileInfo array (Number of bits = WFSCLI_FILE_HANDLE_IDX_BITS)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 nNext;
|
||||||
|
WFSMutex mxAccessCliFileInfo;
|
||||||
|
WFSFileHandle nHandle;
|
||||||
|
WFSFileAttributes fa;
|
||||||
|
WFSFileSize nPosition;
|
||||||
|
WFSFileSize nPreAllocateSize;
|
||||||
|
u8 nAccess;
|
||||||
|
} WFSCliFileInfo;
|
||||||
|
|
||||||
|
|
||||||
|
// Internal binary format of WFSSearcDirHandle (u32)
|
||||||
|
//
|
||||||
|
// 0TTcccccccCCCCCCssssssssssSSSSSS
|
||||||
|
//
|
||||||
|
// 0 = always 0 (Number of bits = 1 )
|
||||||
|
// T = type of handle: 01 for SearchDirHandle (Number of bits = 2 )
|
||||||
|
// c = incrementally assigned by client (Number of bits = 13 - WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
// C = idx of aCliSearchDirInfo array (Number of bits = WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
// s = incrementally assigned by server (Number of bits = 16 - WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
// S = idx of aSrvSearchDirInfo array (Number of bits = WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 nNext;
|
||||||
|
WFSSearchDirectoryHandle nHandle;
|
||||||
|
} WFSCliSearchDirInfo;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSFileHandle nFileHandleCounter; // Counter for cccc field of file handle.
|
||||||
|
WFSSearchDirectoryHandle nSearchDirHandleCounter; // Counter for cccc field of search directory handle.
|
||||||
|
u32 nFirstFreeFileHandle; // Index of the first free element of aClientFileInfo
|
||||||
|
u32 nFirstFreeSearchDirHandle; // Index of the first free element of aClientSearchDirInfo
|
||||||
|
u32 nNumUsedFileHandles;
|
||||||
|
u32 nNumUsedSearchDirHandles;
|
||||||
|
//u32 nFirstUsedFileHandle; // Index of the first used element of aClientFileInfo
|
||||||
|
//u32 nFirstUsedSearchDirHandle; // Index of the first used element of aClientSearchDirInfo
|
||||||
|
WFSMutex mxAccessTheFileInfo;
|
||||||
|
WFSMutex mxAccessTheSearchDirInfo;
|
||||||
|
WFSCliFileInfo aCliFileInfo[WFSCLI_MAX_FILE_HANDLES];
|
||||||
|
WFSCliSearchDirInfo aCliSearchDirInfo[WFSCLI_MAX_SEARCH_DIR_HANDLES];
|
||||||
|
} WFSCliHandles;
|
||||||
|
|
||||||
|
|
||||||
|
void WFSCliInitHandles();
|
||||||
|
|
||||||
|
WFSResult WFSGetCliFileInfo(WFSCliFileInfo **ppFi, WFSFileHandle fh);
|
||||||
|
WFSResult WFSGetCliSearchDirInfo(WFSCliSearchDirInfo **ppSdi, WFSSearchDirectoryHandle sdh);
|
||||||
|
|
||||||
|
WFSResult WFSCliFileInfoAlloc(WFSCliFileInfo **ppFi);
|
||||||
|
WFSResult WFSCliSearchDirInfoAlloc(WFSCliSearchDirInfo **ppSdi);
|
||||||
|
|
||||||
|
void WFSCliFileInfoFree(WFSCliFileInfo *pFi);
|
||||||
|
void WFSCliSearchDirInfoFree(WFSCliSearchDirInfo *pSdi);
|
||||||
|
|
||||||
|
#endif //define wfs_Handles_h
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef __NFS_DRNAND_H__
|
||||||
|
#define __NFS_DRNAND_H__
|
||||||
|
|
||||||
|
#include <brom.h>
|
||||||
|
#include <firm.h>
|
||||||
|
|
||||||
|
#define NFS_DEVCTL_GET_GEOMETRY 0
|
||||||
|
#define NFS_DEVCTL_FORMAT 1
|
||||||
|
#define NFS_DEVCTL_REPORT_REMOVE 2
|
||||||
|
#define NFS_DEVCTL_CHECKSTATUS 3
|
||||||
|
#define NFS_DEVCTL_WARMSTART 4
|
||||||
|
#define NFS_DEVCTL_POWER_RESTORE 5
|
||||||
|
#define NFS_DEVCTL_POWER_LOSS 6
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __NFS_DRNAND_H__
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: TWL - SD driver
|
||||||
|
File: sdmc.h
|
||||||
|
|
||||||
|
Copyright 2006-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Date:: #$
|
||||||
|
$Rev$
|
||||||
|
$Author$
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __SDMC_H__
|
||||||
|
#define __SDMC_H__
|
||||||
|
|
||||||
|
#include <rtfs.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
SDスペック構造体
|
||||||
|
*********************************************/
|
||||||
|
typedef struct {
|
||||||
|
u32 csd_ver2_flag; //CSDフォーマットバージョン(SDHCのときは1)
|
||||||
|
u32 memory_capacity; //data areaのサイズ(512Byte単位)
|
||||||
|
u32 protected_capacity; //protected areaのサイズ(512Byte単位)
|
||||||
|
u32 card_capacity; //カード全体のサイズ(512Byte単位)
|
||||||
|
|
||||||
|
u32 adjusted_memory_capacity; //memory_capacityをシリンダ(heads*secptrack)の倍数に調整したサイズ(cylinders*heads*secptrackになる)
|
||||||
|
|
||||||
|
u16 heads;
|
||||||
|
u16 secptrack;
|
||||||
|
u16 cylinders;
|
||||||
|
u16 SC; //sectors per cluster
|
||||||
|
u16 BU;
|
||||||
|
u16 RDE; //number of root dir entries(512 fix)
|
||||||
|
u32 SS; //sector size(512 fix)
|
||||||
|
u32 RSC; //reserved sector count(1 fix)
|
||||||
|
// u32 TS; //total sectors
|
||||||
|
u16 FATBITS; //16 or 32
|
||||||
|
u16 SF; //sectors per FAT
|
||||||
|
u32 SSA; //sectors in system area
|
||||||
|
u32 NOM; //sectors in master boot record
|
||||||
|
} SdmcSpec;
|
||||||
|
|
||||||
|
|
||||||
|
/*FATパラメータ TODO:SdmcSpecを統合すること*/
|
||||||
|
typedef struct {
|
||||||
|
u32 device_capacity; //デバイス全体のサイズ(512Byte単位)
|
||||||
|
u32 adjusted_device_capacity;
|
||||||
|
|
||||||
|
u32 memory_capacity; //data areaのサイズ(512Byte単位)
|
||||||
|
u32 adjusted_memory_capacity; //memory_capacityをシリンダ(heads*secptrack)の倍数に調整したサイズ(cylinders*heads*secptrackになる)
|
||||||
|
|
||||||
|
u16 volume_cylinders;
|
||||||
|
|
||||||
|
u16 heads;
|
||||||
|
u16 secptrack;
|
||||||
|
u16 cylinders;
|
||||||
|
u16 SC; //sectors per cluster
|
||||||
|
u16 BU;
|
||||||
|
u16 RDE; //number of root dir entries(512 fix)
|
||||||
|
u16 padding;
|
||||||
|
u32 SS; //sector size(512 fix)
|
||||||
|
u32 RSC; //reserved sector count(1 fix)
|
||||||
|
u16 FATBITS; //16 or 32
|
||||||
|
u16 SF; //sectors per FAT
|
||||||
|
u32 SSA; //sectors in system area
|
||||||
|
u32 NOM; //sectors in master boot record
|
||||||
|
|
||||||
|
u32 begin_sect;
|
||||||
|
} FATSpec;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /*__SDMC_H__*/
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
File: msc_api.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
typedef u32 MSCError;
|
||||||
|
|
||||||
|
#define IOS_ERROR_MSC_OK 0
|
||||||
|
|
||||||
|
#define IOS_ERROR_MSC_DEVICE_DETACH -8001
|
||||||
|
#define IOS_ERROR_MSC_COMMAND_FAILED -8002
|
||||||
|
#define IOS_ERROR_MSC_PHASE_ERROR -8003
|
||||||
|
#define IOS_ERROR_MSC_INVALID_CBW_SIGNATURE -8004
|
||||||
|
#define IOS_ERROR_MSC_INVALID_CBW_TAG -8005
|
||||||
|
|
||||||
|
#define IOS_ERROR_MSC_HASH_INCONSISTENT -8101
|
||||||
|
|
||||||
|
#if _IOP
|
||||||
|
IOSError MscCheckCswError(HardDisc *p_hd, IOSError ie);
|
||||||
|
#endif
|
||||||
|
|
||||||
@ -0,0 +1,190 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: Revolution WFS library
|
||||||
|
File: wfs_Debug.h - debugging routines for WFS implementation
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Debug.h,v $
|
||||||
|
Revision 1.16 2008/10/30 06:10:29 kondo_masahiro
|
||||||
|
Added WFSDEBUG_CMD_AREA_AND_DIR_CHECK_DISK
|
||||||
|
|
||||||
|
Revision 1.15 2008/10/14 03:00:34 nakanose_jin
|
||||||
|
(none)
|
||||||
|
|
||||||
|
Revision 1.14 2008/09/18 10:25:33 nakanose_jin
|
||||||
|
add new WFSDEBUG_CMD_*
|
||||||
|
|
||||||
|
Revision 1.13 2008/08/29 01:14:57 kondo_masahiro
|
||||||
|
Added a flag WFSDEBUG_CMD_KRN_INIT_AREA_SECTORS.
|
||||||
|
|
||||||
|
Revision 1.11 2008/06/26 00:21:30 kondo_masahiro
|
||||||
|
Added #define WFSDEBUG_CMD_SHIM_WORKSPACE.
|
||||||
|
|
||||||
|
Revision 1.10 2008/05/23 02:00:33 nakanose_jin
|
||||||
|
add new command
|
||||||
|
|
||||||
|
Revision 1.9 2008/05/10 04:20:22 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.8 2008/05/08 11:40:58 nakanose_jin
|
||||||
|
move WFSDebugSetTitleID wfsPerm.h => wfs_Debug.h
|
||||||
|
|
||||||
|
Revision 1.7 2008/05/07 13:27:12 nakanose_jin
|
||||||
|
fix comment
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/25 12:06:38 nakanose_jin
|
||||||
|
add cmd (0x2)
|
||||||
|
|
||||||
|
Revision 1.5 2008/04/18 07:53:33 nakanose_jin
|
||||||
|
merging acl
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/03 07:11:05 nakanose_jin
|
||||||
|
add extern C
|
||||||
|
|
||||||
|
Revision 1.3 2008/03/31 04:24:58 nakanose_jin
|
||||||
|
add comments
|
||||||
|
|
||||||
|
Revision 1.2 2008/03/31 00:58:52 nakanose_jin
|
||||||
|
add args for debugproc
|
||||||
|
|
||||||
|
Revision 1.1 2008/03/26 01:11:50 nakanose_jin
|
||||||
|
WFS Debug functions for tool develpment
|
||||||
|
|
||||||
|
Revision 1.6 2008/02/20 08:10:10 nakanose_jin
|
||||||
|
add WFSExecDebugProcedure
|
||||||
|
|
||||||
|
Revision 1.5 2007/12/17 13:29:14 nakanose_jin
|
||||||
|
add debug utility function
|
||||||
|
|
||||||
|
Revision 1.4 2007/11/02 00:25:10 paul
|
||||||
|
started logging changes in the file
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <revolution/wfs.h>
|
||||||
|
// #include "wfs_Defs.h"
|
||||||
|
|
||||||
|
#ifndef __WFS_DEBUG_H__
|
||||||
|
#define __WFS_DEBUG_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSDebugSetTitleId
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
WFSResult WFSDebugSetTitleId(WFSTitleId titleId);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// titleId .. Title Id is assigned per application. Determines the ownership & access permissions of files.
|
||||||
|
// A value of WFS_ROOT_ID can be specified for SYSTEM level access to all files.
|
||||||
|
// groupId .. Group Id determines the GROUP access to files. Usually corresponds to a Company Id.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// Possible return values for WFSDebugSetTitleId:
|
||||||
|
// WFS_RESULT_OK .. The search handle has been closed successfully.
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// Allows the application to specify it's WFS Title Id, which will be used to determine access permissions to WFS files.
|
||||||
|
// NOTE: This function is for testing and debugging purposes only, and will be removed from the final API.
|
||||||
|
// NOTE: This function only affects WFS. It does not change the real Title Id.
|
||||||
|
// ToDo: This function should be removed before releasing to developers.
|
||||||
|
|
||||||
|
/*
|
||||||
|
* for debug purpose only.
|
||||||
|
*/
|
||||||
|
WFSResult WFSDebugSrvTest(const char* deviceName);
|
||||||
|
WFSResult WFSDebugCloseServerSocket(void);
|
||||||
|
WFSResult WFSDebugCloseCallbackSocket(void);
|
||||||
|
|
||||||
|
const char *WFSDebug_GetResultString(WFSResult result);
|
||||||
|
WFSResult WFSExecDebugProcedure( u32 cmd , void *arg0 , void *arg1 );
|
||||||
|
const static u32 WFSDEBUG_CMD_DELETE_DEVICEROOT = 0;
|
||||||
|
const static u32 WFSDEBUG_CMD_DELETE_PATH = 1;
|
||||||
|
const static u32 WFSDEBUG_CMD_CLOSE_ALLFILE = 2;
|
||||||
|
const static u32 WFSDEBUG_CMD_DUMP_PERMISSION = 3;
|
||||||
|
const static u32 WFSDEBUG_CMD_SET_AUTO_FORMAT_ON_ATTACH = 4;
|
||||||
|
const static u32 WFSDEBUG_CMD_ATTACH = 5;
|
||||||
|
const static u32 WFSDEBUG_CMD_ATTACH_WRITE_PROTECTED = 6;
|
||||||
|
const static u32 WFSDEBUG_CMD_DETACH = 7;
|
||||||
|
const static u32 WFSDEBUG_CMD_PUSH_PATH = 8;
|
||||||
|
const static u32 WFSDEBUG_CMD_EXEC_BAT = 9; //
|
||||||
|
const static u32 WFSDEBUG_CMD_TOUCH = 10;
|
||||||
|
|
||||||
|
|
||||||
|
//#define WFSDEBUG_CMD_KRN_INIT_VIRTUAL_DISK 0x10
|
||||||
|
#define WFSDEBUG_CMD_KRN_INIT_AREA_SECTORS 0x10
|
||||||
|
#define WFSDEBUG_CMD_KRN_INIT_CACHE 0x11
|
||||||
|
#define WFSDEBUG_CMD_DIR_CHECK_DNS_EMPTY 0x12
|
||||||
|
#define WFSDEBUG_CMD_SHIM_WORKSPACE 0x13
|
||||||
|
#define WFSDEBUG_CMD_AREA_AND_DIR_CHECK_DISK 0x14
|
||||||
|
|
||||||
|
#define WFSDEBUG_CMD_DEVICE_ATTACH_DETACH 0x20
|
||||||
|
#define WFSDEBUG_CMD_DEVICE_PSEUDO_DETACH 0x21
|
||||||
|
#define WFSDEBUG_CMD_DEVICE_PSEUDO_HASH_INCONSISTENT 0x22
|
||||||
|
#define WFSDEBUG_CMD_DEVICE_SET_FLAGS 0x23
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
WFSDEBUG_CMD_DELETE_DEVICEROOT
|
||||||
|
brief: 指定パスを削除
|
||||||
|
arg0 : ターゲットデバイス名 ( "msc1" 等 )
|
||||||
|
arg1 : -
|
||||||
|
|
||||||
|
WFSDEBUG_CMD_DELETE_PATH
|
||||||
|
brief: 指定パスを削除(マウント中でなくてもよい)
|
||||||
|
arg0 : ターゲットデバイス名 ( "msc1" 等)
|
||||||
|
arg1 : ターゲットパス *1 ( "/titles" 等)
|
||||||
|
|
||||||
|
WFSDEBUG_CMD_CLOSE_ALLFILE
|
||||||
|
brief: オープンされたままのファイルを全て閉じます。
|
||||||
|
arg0 : ターゲットボリューム名
|
||||||
|
arg1 : -
|
||||||
|
|
||||||
|
WFSDEBUG_CMD_DUMP_PERMISSION
|
||||||
|
brief: 指定パスのパーミッション情報表示 (マウント中でなくてもよい)
|
||||||
|
arg0 : ターゲットデバイス名 ( "msc1" 等)
|
||||||
|
arg1 : ターゲットパス *1 ( "/titles" 等)
|
||||||
|
|
||||||
|
WFSDEBUG_CMD_SET_AUTO_FORMAT_ON_ATTACH
|
||||||
|
brief: アタッチ時にデバイスが未フォーマットであれば必要なシステム情報を付加する/しない (default:する)
|
||||||
|
arg0 : true/false
|
||||||
|
arg1 : -
|
||||||
|
|
||||||
|
WFSDEBUG_CMD_ATTACH
|
||||||
|
WFSDEBUG_CMD_ATTACH_WRITE_PROTECTED
|
||||||
|
brief: 指定デバイスをアタッチします。WFSDevAttach.exe [-p] arg0 arg1 と同等です。
|
||||||
|
arg0 : ターゲットデバイス名 ( ex. "msc1")
|
||||||
|
arg1 : 仮想ボリュームルートの物理パス ( ex. "D:\iifstest\msc01" )
|
||||||
|
|
||||||
|
WFSDEBUG_CMD_DETACH
|
||||||
|
brief: 指定デバイスをデタッチします。WFSDevAttach.exe -d arg0 と同等です。
|
||||||
|
arg0 : ターゲットデバイス名 ( ex. "msc1")
|
||||||
|
arg1 : -
|
||||||
|
|
||||||
|
WFSDEBUG_CMD_EXEC_BAT
|
||||||
|
brief: 任意のコマンドを実行。
|
||||||
|
使用に際しては安全上の理由から必要最小限にとどめることを推奨します。
|
||||||
|
バッチファイル内の操作で誤って重要ファイルを消したりしないよう重々ご注意下さい。
|
||||||
|
arg0 : ターゲット実行ファイル ( 絶対パス指定のみ。ex. "H:\\iifstest\\bin\\ready_testLongPathName.bat" )
|
||||||
|
arg1 : ターゲット実行時パス ( 絶対パス指定のみ。指定無し(NULL)でもOK。ex. "H:\\iifstest\\bin" )
|
||||||
|
|
||||||
|
|
||||||
|
*1 : ボリュームルートをルートとする仮想パス
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __WFS_DEBUG_H__
|
||||||
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef _RANDOMLIB_H
|
||||||
|
#define _RANDOMLIB_H
|
||||||
|
|
||||||
|
#include "revolution.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
#if _IOP
|
||||||
|
#include "types.h"
|
||||||
|
#else
|
||||||
|
#include "revolution/types.h"
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "wfs_Platform.h"
|
||||||
|
|
||||||
|
void RandomInitialise(int ij, int kl);
|
||||||
|
double RandomUniform(void);
|
||||||
|
double RandomGaussian(double mean, double stddev);
|
||||||
|
int RandomInt(int lower, int upper);
|
||||||
|
double RandomDouble(double lower, double upper);
|
||||||
|
u32 RandomU32();
|
||||||
|
|
||||||
|
#define NUM_UNIQUE_RANDOM_SEEDS_U32 0x382C7A42
|
||||||
|
void RandomSetSeedU32(u32 nSeed);
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef __REVOLUTION_H__
|
||||||
|
#define __REVOLUTION_H__
|
||||||
|
|
||||||
|
#include <brom.h>
|
||||||
|
#include <firm.h>
|
||||||
|
#include <revolution/wfsError.h>
|
||||||
|
//#include <mem/allocator.h>
|
||||||
|
//#include <mem/heapCommon.h>
|
||||||
|
|
||||||
|
typedef u32 OSPriority;
|
||||||
|
|
||||||
|
#define ASSERT SDK_ASSERT
|
||||||
|
|
||||||
|
//typedef BOOL bool;
|
||||||
|
//typedef BOOL WFSBool;
|
||||||
|
|
||||||
|
#endif // __REVOLUTION_H__
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: MEM library
|
||||||
|
File: mem.h
|
||||||
|
Programmers: Takano Makoto
|
||||||
|
|
||||||
|
Copyright 2005 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __MEM_H__
|
||||||
|
#define __MEM_H__
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <revolution/mem/heapCommon.h>
|
||||||
|
#include <revolution/mem/expHeap.h>
|
||||||
|
#include <revolution/mem/frameHeap.h>
|
||||||
|
#include <revolution/mem/unitHeap.h>
|
||||||
|
#include <revolution/mem/allocator.h>
|
||||||
|
#include <revolution/mem/list.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* __MEM_H__ */
|
||||||
|
#endif
|
||||||
1444
trunk/firmware/build/libraries/nfs/common/include/revolution/wfs.h
Normal file
1444
trunk/firmware/build/libraries/nfs/common/include/revolution/wfs.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,98 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: Revolution WFS library
|
||||||
|
File: wfserror.h
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfsError.h,v $
|
||||||
|
Revision 1.6 2008/09/26 12:04:33 ueno
|
||||||
|
Changed WFS_RESULT_* to be equal to WFSKRN_RESULT_* to guarantee the casts.
|
||||||
|
|
||||||
|
Revision 1.5 2008/07/11 19:02:21 paul
|
||||||
|
Removed WFS_RESULT_DIRECTORY_FULL. Fixed comments and reordered slightly.
|
||||||
|
|
||||||
|
Revision 1.4 2008/07/10 07:03:19 nakanose_jin
|
||||||
|
add permissions API
|
||||||
|
|
||||||
|
Revision 1.3 2008/07/02 06:52:43 nakanose_jin
|
||||||
|
bye inheritance & dev_full error
|
||||||
|
|
||||||
|
Revision 1.2 2008/06/25 00:58:19 nakanose_jin
|
||||||
|
add control level error
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/08 18:25:40 paul
|
||||||
|
Moved error definitions from wfs.h to this header file.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFS_ERROR_H__
|
||||||
|
#define __WFS_ERROR_H__
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// WFS error codes
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
typedef enum {
|
||||||
|
WFS_RESULT_OK = 0, // Success
|
||||||
|
|
||||||
|
// Errors that can usually be detected early, and if detected, would result in the Async callback not being called:
|
||||||
|
WFS_RESULT_BUSY = -1, // Too many requests, try waiting then calling again.
|
||||||
|
WFS_RESULT_OUT_OF_MEMORY = -2, // The library does not have enough memory to complete the requested operation. (May be due to too many outstanding aysnc calls).
|
||||||
|
WFS_RESULT_INVALID = -3, // The function parameters were invalid, e.g. File name is too long, Path is too long or too deep.
|
||||||
|
WFS_RESULT_ACCESS = -4, // Trying to write to a file which was opened for read-only access, or vice versa.
|
||||||
|
WFS_RESULT_LIB_NOT_INITIALIZED = -5, // The WFS library has not been initialized. Please call WFSInit() (This error is checked in functions that require the library to be initialized, but only in the debug versions).
|
||||||
|
WFS_RESULT_LIB_ALREADY_INITIALIZED = -6, // The WFS library has already been initialized.
|
||||||
|
WFS_RESULT_FILE_TOO_BIG = -7, // The current write/append request would push the file over the size limit.
|
||||||
|
WFS_RESULT_NO_CHANGE_SIZE = -8, // The requested operation would cause the file size to change, but this file has WFS_PERM_NO_CHANGE_SIZE flag set.
|
||||||
|
|
||||||
|
// Errors that cannot usually be detected early, and would be passed via nResult to the Async callbacks:
|
||||||
|
WFS_RESULT_MEDIA_ERROR = -9, // The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
WFS_RESULT_DEV_UNUSABLE = -10, // Attached device is not accessible, e.g. because it is an unsupported device, or has an unknown format.
|
||||||
|
WFS_RESULT_DEV_NOT_INITIALIZED = -11, // Device not formatted, or does not yet contain a WFS volume
|
||||||
|
WFS_RESULT_DEV_IN_USE = -12, // Trying to initialize a device which is in use (mounted) by one or more clients.
|
||||||
|
WFS_RESULT_VOL_ID_ERROR = -13, // Attempted to mount a volume with the same unique Id as an already mounted volume (This could happen if the User backs up an entire WFS volume using a PC)
|
||||||
|
WFS_RESULT_WRITE_PROTECTED = -14, // Device is physically write protected (e.g. USB Flash memory, SD Card)
|
||||||
|
WFS_RESULT_ALREADY_MOUNTED = -15, // The device is already mounted
|
||||||
|
|
||||||
|
WFS_RESULT_PERMISSION = -16, // Permission flags do not permit the requested access from this application.
|
||||||
|
WFS_RESULT_PERMISSION_CL = -17, // Permission error caused by control level problems.
|
||||||
|
WFS_RESULT_ACL_FULL = -18, // The access list is full.
|
||||||
|
WFS_RESULT_ACL_ENTRY_NOT_FOUND = -19, // The specified entry does not exist in the access list.
|
||||||
|
WFS_RESULT_AUTHENTICATION = -20, // Trying to access content on a different Wii, which does not have the required access rights.
|
||||||
|
WFS_RESULT_CORRUPTION = -21, // A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
|
||||||
|
WFS_RESULT_DIRECTORY_QUOTA = -22, // One of the ancestor directories would exceed its quota.
|
||||||
|
|
||||||
|
WFS_RESULT_MAX_HANDLES = -23, // The maximum number of concurrent file handles / search handles are already in use.
|
||||||
|
WFS_RESULT_ALREADY_EXISTS = -24, // The file or directory being created already exists.
|
||||||
|
WFS_RESULT_NOT_FOUND = -25, // The specified file, directory or device does not exist.
|
||||||
|
WFS_RESULT_NOT_EMPTY = -26, // The specified directory cannot be deleted because it is not empty.
|
||||||
|
WFS_RESULT_NOT_FILE = -27, // The specified path is directory instead of a file.
|
||||||
|
WFS_RESULT_NOT_DIRECTORY = -28, // The specified path is a file instead of a directory.
|
||||||
|
WFS_RESULT_FILE_OPEN = -29, // The file is open. Cannot delete, move, rename, change permissions of an open file. Cannot open a file more than once unless all opens are WFS_ACCESS_READ.
|
||||||
|
WFS_RESULT_LOCKED = -30, // Cannot perform the requested operation since the file or directory is locked by an existing operation.
|
||||||
|
WFS_RESULT_RESOURCE_LIMIT_EXCEEDED = -31, // A resource limit prevents this function call. Try smaller values.
|
||||||
|
|
||||||
|
WFS_RESULT_NOT_IMPLEMENTED = -1026, // The requested function has not yet been implemented //ToDo: This error should be removed from the final API
|
||||||
|
WFS_RESULT_UNKNOWN = -1027, // Unexpected error - could be caused by a bug in the file system.
|
||||||
|
WFS_RESULT_FATAL_ERROR = -1028 // May be caused by critical metadata corruption.
|
||||||
|
|
||||||
|
} WFSResult;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //define __WFS_ERROR_H__
|
||||||
@ -0,0 +1,462 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: Revolution WFS library
|
||||||
|
File: wfsperm.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfsPerm.h,v $
|
||||||
|
Revision 1.20 2008/09/18 10:26:24 nakanose_jin
|
||||||
|
fix comments
|
||||||
|
|
||||||
|
Revision 1.19 2008/08/29 02:24:46 nakanose_jin
|
||||||
|
add comments
|
||||||
|
|
||||||
|
Revision 1.18 2008/08/06 04:12:45 nakanose_jin
|
||||||
|
add PERMISSION_CL,ACL_ENTRY_NOT_FOUND,ACL_FULL comment
|
||||||
|
|
||||||
|
Revision 1.17 2008/07/18 00:33:03 paul
|
||||||
|
Added descriptions of functions. Rename WFSDeletePermissions() -> WFSDeleteAccessListEntry().
|
||||||
|
|
||||||
|
Revision 1.16 2008/07/17 05:07:02 kondo_masahiro
|
||||||
|
inline -> static inline
|
||||||
|
|
||||||
|
Revision 1.15 2008/07/15 08:28:47 nakanose_jin
|
||||||
|
change define value
|
||||||
|
|
||||||
|
Revision 1.14 2008/07/14 07:22:51 ueno
|
||||||
|
Renamed WFSSetAccessList() by WFSSetAccessListEntry().
|
||||||
|
|
||||||
|
Revision 1.13 2008/07/11 09:46:03 ueno
|
||||||
|
Added async functions.
|
||||||
|
|
||||||
|
Revision 1.12 2008/07/11 09:19:36 ueno
|
||||||
|
Fixed a typo.
|
||||||
|
|
||||||
|
Revision 1.11 2008/07/10 07:03:18 nakanose_jin
|
||||||
|
add permissions API
|
||||||
|
|
||||||
|
Revision 1.10 2008/07/02 06:52:43 nakanose_jin
|
||||||
|
bye inheritance & dev_full error
|
||||||
|
|
||||||
|
Revision 1.9 2008/06/23 02:58:31 nakanose_jin
|
||||||
|
separate relative from absolute
|
||||||
|
|
||||||
|
Revision 1.8 2008/06/16 18:23:50 ueno
|
||||||
|
Removed WFSCreateAccessList().
|
||||||
|
|
||||||
|
Revision 1.7 2008/06/05 14:08:06 ueno
|
||||||
|
Revised permission APIs.
|
||||||
|
|
||||||
|
Revision 1.6 2008/05/08 11:41:02 nakanose_jin
|
||||||
|
move WFSDebugSetTitleID wfsPerm.h => wfs_Debug.h
|
||||||
|
|
||||||
|
Revision 1.5 2008/05/07 13:26:55 nakanose_jin
|
||||||
|
fix ambiguous definision
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/29 01:14:52 ueno
|
||||||
|
Removed WFS_DEBUG_SYSTEM_PROCESS_ID.
|
||||||
|
Added WFS_ROOT_ID and WFS_EVERYONE_ID.
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/23 09:21:24 ueno
|
||||||
|
Revised directory permission (change -> add).
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/18 07:54:12 nakanose_jin
|
||||||
|
merging acl
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/08 18:27:19 paul
|
||||||
|
Moved permissions related declarations from wfs.h to this header file. Changed permissions API to support access lists.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFS_PERM_H__
|
||||||
|
#define __WFS_PERM_H__
|
||||||
|
|
||||||
|
// Permission Flags Which apply to Files only:
|
||||||
|
|
||||||
|
#include <revolution/wfstypes.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// permissions
|
||||||
|
#define WFS_PERM_CHANGE_SIZE 0x0001
|
||||||
|
#define WFS_PERM_WRITE 0x0002
|
||||||
|
#define WFS_PERM_READ 0x0004
|
||||||
|
#define WFS_PERM_ADD_OR_DELETE_FILE 0x0008
|
||||||
|
#define WFS_PERM_ADD_OR_DELETE_SUBDIR 0x0010
|
||||||
|
#define WFS_PERM_LIST 0x0020
|
||||||
|
#define WFS_PERM_DELETE_OR_MOVE 0x0040
|
||||||
|
|
||||||
|
// reserved
|
||||||
|
#define WFS_PERM_RESERVED0 0x0080
|
||||||
|
#define WFS_PERM_RESERVED1 0x0100
|
||||||
|
#define WFS_PERM_RESERVED2 0x0200
|
||||||
|
#define WFS_PERM_RESERVED3 0x0400
|
||||||
|
#define WFS_PERM_RESERVED4 0x0800
|
||||||
|
|
||||||
|
// control level
|
||||||
|
/* ŒÃ‚¢’è‹`
|
||||||
|
#define WFS_PERM_CL0 0x0000 // 0
|
||||||
|
#define WFS_PERM_CL_MINUS_1 0x7000 // -1
|
||||||
|
#define WFS_PERM_CL_MINUS_2 0x6000 // -2
|
||||||
|
#define WFS_PERM_CL_MINUS_3 0x5000 // -3
|
||||||
|
#define WFS_PERM_CL_MINUS_4 0x4000 // -4
|
||||||
|
#define WFS_PERM_CL_MASK 0x7000
|
||||||
|
*/
|
||||||
|
#define WFS_PERM_CL_MINUS_0 0xE000 // 0
|
||||||
|
#define WFS_PERM_CL_MINUS_1 0xC000 // -1
|
||||||
|
#define WFS_PERM_CL_MINUS_2 0xA000 // -2
|
||||||
|
#define WFS_PERM_CL_MINUS_3 0x8000 // -3
|
||||||
|
#define WFS_PERM_CL_0 0x0000 // 0 (absolute)
|
||||||
|
#define WFS_PERM_CL_1 0x2000 // 1 (absolute)
|
||||||
|
#define WFS_PERM_CL_2 0x4000 // 2 (absolute)
|
||||||
|
#define WFS_PERM_CL_3 0x6000 // 3 (absolute)
|
||||||
|
|
||||||
|
#define WFS_PERM_CL_MASK 0xE000
|
||||||
|
#define WFS_PERM_CL_SHIFT 13
|
||||||
|
#define WFS_PERM_CL_RELATIVE_BIT 0x8000
|
||||||
|
|
||||||
|
static inline u32 WFS_PERM_GET_CL_ABSOLUTE(u32 perm)
|
||||||
|
{
|
||||||
|
// ASSERT( 0 == (WFS_PERM_CL_RELATIVE_BIT & perm) );
|
||||||
|
return ((perm & WFS_PERM_CL_MASK) >> WFS_PERM_CL_SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 WFS_PERM_SET_CL_ABSOLUTE(u32 perm , s32 cl)
|
||||||
|
{
|
||||||
|
// ASSERT( (cl >= 0) && (cl <= 3) );
|
||||||
|
perm = (perm & ~WFS_PERM_CL_MASK) | (cl << WFS_PERM_CL_SHIFT);
|
||||||
|
return perm;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 WFS_PERM_SET_CL_RELATIVE(u32 perm , s32 cl)
|
||||||
|
{
|
||||||
|
// ASSERT( (cl <= 0) && (cl >= -3) );
|
||||||
|
perm = (perm & ~WFS_PERM_CL_MASK) | ((7 + cl) << WFS_PERM_CL_SHIFT);
|
||||||
|
return perm;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define WFS_PERM_DIR_FULL (WFS_PERM_CHANGE_SIZE | WFS_PERM_WRITE | WFS_PERM_READ | \
|
||||||
|
WFS_PERM_ADD_OR_DELETE_FILE | WFS_PERM_ADD_OR_DELETE_SUBDIR | \
|
||||||
|
WFS_PERM_LIST | WFS_PERM_DELETE_OR_MOVE)
|
||||||
|
#define WFS_PERM_FILE_FULL (WFS_PERM_CHANGE_SIZE | WFS_PERM_WRITE | WFS_PERM_READ | WFS_PERM_DELETE_OR_MOVE)
|
||||||
|
|
||||||
|
#define WFS_PERM_FULL 0xFFFF // this is special keyword. it will be converted to a appropriate value in internal
|
||||||
|
|
||||||
|
typedef u32 WFSTitleId;
|
||||||
|
typedef u32 WFSGroupId;
|
||||||
|
|
||||||
|
#define WFS_ROOT_ID 0UL
|
||||||
|
#define WFS_EVERYONE_ID 0x80000000
|
||||||
|
|
||||||
|
typedef struct WFSAccessListEntry {
|
||||||
|
u32 titleId;
|
||||||
|
u32 entryCreatorId;
|
||||||
|
u32 permissions;
|
||||||
|
} WFSAccessListEntry;
|
||||||
|
|
||||||
|
#define WFS_ACL_ENTRY_NET_SIZE (sizeof(u32) + sizeof(u32) + sizeof(u16)) // smaller than sizeof(WFSKrnAccessListEntry).
|
||||||
|
#define WFS_ACL_MAX_ENTRIES (WFS_MAX_FILE_NAME_SIZE - sizeof(u32)*2)/(WFS_ACL_ENTRY_NET_SIZE*2)
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSChangePermissions, WFSChangePermissionsAsync
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
WFSResult WFSChangePermissions (const utf8 *sPathName, u32 nFlags, u32 nMask);
|
||||||
|
WFSResult WFSChangePermissionsAsync(const utf8 *sPathName, u32 nFlags, u32 nMask, void *pUserData, WFSResultCallback cb);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// sPathName .. Absolute or relative path name of the file or directory whose permissions are to be changed.
|
||||||
|
// See "WFS Path Names" for rules about path names.
|
||||||
|
// nFlags .. The new permissions flags that are to be set. Should be a combination of the permission flags: WFS_PERM_*
|
||||||
|
// nMask .. The mask determines which flags will be changed. NewAttributes = (OldAttributes & ~nMask) | (nFlags & nMask)
|
||||||
|
// NOTE: The mask bits for bits which are never allowed to be changed, such as WFS_FLAG_IS_A_DIRECTORY are automatically set to 0.
|
||||||
|
// pUserData .. Arbitrary user data that is passed to the callback function.
|
||||||
|
// cb .. Pointer to a callback function to receive the result of WFSChangePermissionsAsync.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// Possible return values for WFSChangePermissions:
|
||||||
|
// WFS_RESULT_OK .. The permissions were updated successfully.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name is too long, Path is too deep.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card).
|
||||||
|
// WFS_RESULT_PERMISSION .. The requested change was not allowed due to the existing permissions settings.
|
||||||
|
// WFS_RESULT_PERMISSION_CL .. You cant set the requested permission because you dont have a appropriate control level.
|
||||||
|
// WFS_RESULT_ACL_FULL .. You cant set the requested permission because the target access list is full.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory does not exist.
|
||||||
|
// WFS_RESULT_RESOURCE_LIMIT_EXCEEDED .. Too much accesslist variations generated , so quota resource are drained.
|
||||||
|
// Possible immediate return values for WFSChangePermissionsAsync:
|
||||||
|
// WFS_RESULT_OK .. Change permissions request was dispatched successfully. The callback will be called in this case only.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_OUT_OF_MEMORY .. The library does not have enough memory to dispatch the request. (May be due to too many outstanding aysnc calls).
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name is too long, Path is too deep.
|
||||||
|
// Possible values of nResult passed to WFSChangePermissionsAsync callback:
|
||||||
|
// WFS_RESULT_OK .. The permissions were updated successfully.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card).
|
||||||
|
// WFS_RESULT_PERMISSION .. Only the owner of a file or directory can change its permission flags.
|
||||||
|
// WFS_RESULT_PERMISSION_CL .. You cant set the requested permission because you dont have a appropriate control level.
|
||||||
|
// WFS_RESULT_ACL_FULL .. You cant set the requested permission because the target access list is full.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory does not exist.
|
||||||
|
// WFS_RESULT_RESOURCE_LIMIT_EXCEEDED .. Too much accesslist variations generated , so quota resource are drained.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// These functions can be used to change one's own permissions to access a specified file or directory.
|
||||||
|
// However the permissions can only be set within the bounds granted by superior users.
|
||||||
|
// (The purpose is to allow a user to specify a file as read-only, which is common in existing file systems).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSSetPermissionsForUser, WFSSetPermissionsForUserAsync
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
WFSResult WFSSetPermissionsForUser (const utf8 *sPathName, u32 nFlags, u32 nMask, WFSTitleId titleId);
|
||||||
|
WFSResult WFSSetPermissionsForUserAsync(const utf8 *sPathName, u32 nFlags, u32 nMask, WFSTitleId titleId, void *pUserData, WFSResultCallback cb);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// sPathName .. Absolute or relative path name of the file or directory whose permissions are to be changed.
|
||||||
|
// See "WFS Path Names" for rules about path names.
|
||||||
|
// nFlags .. The new permissions flags that are to be set. Should be a combination of the permission flags: WFS_PERM_*
|
||||||
|
// nMask .. The mask determines which flags will be changed. NewAttributes = (OldAttributes & ~nMask) | (nFlags & nMask)
|
||||||
|
// titleId .. The title id of the application for which permissions are being set.
|
||||||
|
// pUserData .. Arbitrary user data that is passed to the callback function.
|
||||||
|
// cb .. Pointer to a callback function to receive the result of WFSSetPermissionsForUserAsync.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// Possible return values for WFSSetPermissionsForUser:
|
||||||
|
// WFS_RESULT_OK .. The permissions were updated successfully.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name is too long, Path is too deep.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card).
|
||||||
|
// WFS_RESULT_PERMISSION .. The requested change was not allowed due to the existing permissions settings.
|
||||||
|
// WFS_RESULT_PERMISSION_CL .. You cant set the requested permission because you dont have a appropriate control level.
|
||||||
|
// WFS_RESULT_ACL_FULL .. You cant set the requested permission because the target access list is full.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_DIRECTORY_QUOTA .. This operation would cause one of the ancestor directories to exceed its quota.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory does not exist.
|
||||||
|
// WFS_RESULT_RESOURCE_LIMIT_EXCEEDED .. Too much accesslist variations generated , so quota resource are drained.
|
||||||
|
// Possible immediate return values for WFSSetPermissionsForUserAsync:
|
||||||
|
// WFS_RESULT_OK .. Change permissions request was dispatched successfully. The callback will be called in this case only.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_OUT_OF_MEMORY .. The library does not have enough memory to dispatch the request. (May be due to too many outstanding aysnc calls).
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name is too long, Path is too deep.
|
||||||
|
// Possible values of nResult passed to WFSSetPermissionsForUserAsync callback:
|
||||||
|
// WFS_RESULT_OK .. The permissions were updated successfully.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card).
|
||||||
|
// WFS_RESULT_PERMISSION .. Only the owner of a file or directory can change its permission flags.
|
||||||
|
// WFS_RESULT_PERMISSION_CL .. You cant set the requested permission because you dont have a appropriate control level.
|
||||||
|
// WFS_RESULT_ACL_FULL .. You cant set the requested permission because the target access list is full.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_DIRECTORY_QUOTA .. This operation would cause one of the ancestor directories to exceed its quota.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory does not exist.
|
||||||
|
// WFS_RESULT_RESOURCE_LIMIT_EXCEEDED .. Too much accesslist variations generated , so quota resource are drained.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// Use these functions to specify or change the permissions that a particular title id will have to access or modify the specified file or directory.
|
||||||
|
// NOTE: The permissions are specified as absolute values. However these are represented on access lists as permissions relative to the granter.
|
||||||
|
// This function operates in such a way as to only create access list entries when necessary, and remove them if possible.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSGetPermissionsForUser (const utf8 *sPathName, u32 *pFlags, WFSTitleId titleId);
|
||||||
|
WFSResult WFSGetPermissionsForUserAsync(const utf8 *sPathName, WFSTitleId titleId, void *pUserData, WFSGetPermissionsForUserCallback cb);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// sPathName .. Absolute or relative path name of a file or directory.
|
||||||
|
// See "WFS Path Names" for rules about path names.
|
||||||
|
// pFlags .. A pointer to a u32 which will be overwritten with the permissions the specified title id has to
|
||||||
|
// access or modify the specified file or directory.
|
||||||
|
// titleId .. The title id of the application for which permissions are being set.
|
||||||
|
// pUserData .. Arbitrary user data that is passed to the callback function.
|
||||||
|
// cb .. Pointer to a callback function to receive the result of WFSGetPermissionsForUserAsync.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// Possible return values for WFSGetPermissionsForUser:
|
||||||
|
// WFS_RESULT_OK .. The specified file or directory was found. The permissions were calculated and copied to *pFlags.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name too long, Path is too deep.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card. Note: Write errors can occur even for read operations).
|
||||||
|
// WFS_RESULT_PERMISSION .. Permission flags of the target or its parent directory do not permit requested access from this application.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory was not found.
|
||||||
|
// Possible immediate return values for WFSGetPermissionsForUserAsync:
|
||||||
|
// WFS_RESULT_OK .. The request was dispatched successfully. The callback will be called in this case only.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_OUT_OF_MEMORY .. The library does not have enough memory to dispatch the request. (May be due to too many outstanding aysnc calls).
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name too long, Path is too deep.
|
||||||
|
// Possible values of nResult passed to WFSGetPermissionsForUserAsync callback:
|
||||||
|
// WFS_RESULT_OK .. The specified file or directory was found and its permissions were calculated and passed as the nFlags parameter.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card. Note: Write errors can occur even for read operations).
|
||||||
|
// WFS_RESULT_PERMISSION .. Permission flags of the target or its parent directory do not permit requested access from this application.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory was not found.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// Use these functions to read the permissions of a file or directory for a particular user (title id).
|
||||||
|
// The permissions values returned are absolute values resulting from inheritance and permissions granted by superior users.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
s32 WFSGetAccessList (const utf8 *sPathName, WFSAccessListEntry *pAccessList, u32 nMaxEntries);
|
||||||
|
WFSResult WFSGetAccessListAsync(const utf8 *sPathName, WFSAccessListEntry *pAccessList, u32 nMaxEntries, void *pUserData, WFSGetAccessListCallback cb);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// sPathName .. Absolute or relative path name of a file or directory.
|
||||||
|
// See "WFS Path Names" for rules about path names.
|
||||||
|
// pAccessList .. A pointer to an array of WFSAccessListEntry structs which will be overwritten with the access list entries.
|
||||||
|
// nMaxEntries .. The maximum number of access list entries that the array can hold.
|
||||||
|
// pUserData .. Arbitrary user data that is passed to the callback function.
|
||||||
|
// cb .. Pointer to a callback function to receive the result of WFSGetAccessListAsync.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// Possible return values for WFSGetAccessList:
|
||||||
|
// >= 0 .. The number of access list entries that were successfully copied to the specified array.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name too long, Path is too deep.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card. Note: Write errors can occur even for read operations).
|
||||||
|
// WFS_RESULT_PERMISSION .. Permission flags of the target or its parent directory do not permit requested access from this application.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_DIRECTORY_QUOTA .. This operation would cause one of the ancestor directories to exceed its quota.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory was not found.
|
||||||
|
// Possible immediate return values for WFSGetAccessListAsync:
|
||||||
|
// WFS_RESULT_OK .. The request was dispatched successfully. The callback will be called in this case only.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_OUT_OF_MEMORY .. The library does not have enough memory to dispatch the request. (May be due to too many outstanding aysnc calls).
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name too long, Path is too deep.
|
||||||
|
// Possible values of nResult passed to WFSGetAccessListAsync callback:
|
||||||
|
// >= 0 .. The number of access list entries that were successfully copied to the specified array.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card. Note: Write errors can occur even for read operations).
|
||||||
|
// WFS_RESULT_PERMISSION .. Permission flags of the target or its parent directory do not permit requested access from this application.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_DIRECTORY_QUOTA .. This operation would cause one of the ancestor directories to exceed its quota.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory was not found.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// Use these functions to read the raw access list for a file or directory.
|
||||||
|
// The raw access list contains only relative values of permissions and control level. (relative to the permission granter)
|
||||||
|
// The actual permission to access files and directories depends on the absolute values of permissions and control level,
|
||||||
|
// which are calculated by following inheritance and the permission-granting links back to root.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSetAccessListEntry (const utf8 *sPathName, u32 nFlags, u32 nMask, WFSTitleId titleId);
|
||||||
|
WFSResult WFSSetAccessListEntryAsync(const utf8 *sPathName, u32 nFlags, u32 nMask, WFSTitleId titleId, void *pUserData, WFSResultCallback cb);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// sPathName .. Absolute or relative path name of a file or directory.
|
||||||
|
// See "WFS Path Names" for rules about path names.
|
||||||
|
// titleId .. The title id of the application for which permissions are being set.
|
||||||
|
// nFlags .. The new permissions flags that are to be set. Should be a combination of the permission flags: WFS_PERM_*
|
||||||
|
// pUserData .. Arbitrary user data that is passed to the callback function.
|
||||||
|
// cb .. Pointer to a callback function to receive the result of WFSSetAccessListEntryAsync.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// Possible return values for WFSSetAccessListEntry:
|
||||||
|
// WFS_RESULT_OK .. The specified file or directory was found, and the specified access list entry was created or updated.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name too long, Path is too deep.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card. Note: Write errors can occur even for read operations).
|
||||||
|
// WFS_RESULT_PERMISSION_CL .. You cant set the requested permission because you dont have a appropriate control level.
|
||||||
|
// WFS_RESULT_ACL_FULL .. You cant set the requested permission because the target access list is full.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_DIRECTORY_QUOTA .. This operation would cause one of the ancestor directories to exceed its quota.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory was not found.
|
||||||
|
// WFS_RESULT_RESOURCE_LIMIT_EXCEEDED .. Too much accesslist variations generated , so quota resource are drained.
|
||||||
|
// Possible immediate return values for WFSSetAccessListEntryAsync:
|
||||||
|
// WFS_RESULT_OK .. The request was dispatched successfully. The callback will be called in this case only.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_OUT_OF_MEMORY .. The library does not have enough memory to dispatch the request. (May be due to too many outstanding aysnc calls).
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name too long, Path is too deep.
|
||||||
|
// Possible values of nResult passed to WFSSetAccessListEntryAsync callback:
|
||||||
|
// WFS_RESULT_OK .. The specified file or directory was found, and the specified access list entry was created or updated.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card. Note: Write errors can occur even for read operations).
|
||||||
|
// WFS_RESULT_PERMISSION .. Permission flags of the target or its parent directory do not permit requested access from this application.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_DIRECTORY_QUOTA .. This operation would cause one of the ancestor directories to exceed its quota.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory was not found.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// Use these functions to create or update a raw access list entry.
|
||||||
|
// Raw access list entries contain only relative values of permissions and control level. (relative to the permission granter)
|
||||||
|
// The actual permission to access files and directories depends on the absolute values of permissions and control level,
|
||||||
|
// which are calculated by following inheritance and the permission-granting links back to root.
|
||||||
|
// NOTE: SetPermissionsForUser() can be used to specify permissions using absolute values.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSDeleteAccessListEntry (const utf8 *sPathName, WFSTitleId titleId , WFSTitleId entryCreatorId);
|
||||||
|
WFSResult WFSDeleteAccessListEntryAsync(const utf8 *sPathName, WFSTitleId titleId , WFSTitleId entryCreatorId, void *pUserData, WFSResultCallback cb);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// sPathName .. Absolute or relative path name of a file or directory.
|
||||||
|
// See "WFS Path Names" for rules about path names.
|
||||||
|
// titleId .. The title id of the application for which permissions are being removed.
|
||||||
|
// entryCreatorId .. The title id of the application which created the access list entry (the permission granter).
|
||||||
|
// pUserData .. Arbitrary user data that is passed to the callback function.
|
||||||
|
// cb .. Pointer to a callback function to receive the result of WFSDeletePermissionsAsync.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// Possible return values for WFSDeletePermissions:
|
||||||
|
// WFS_RESULT_OK .. The specified file or directory was found. The permissions were calculated and copied to *pFlags.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name too long, Path is too deep.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card. Note: Write errors can occur even for read operations).
|
||||||
|
// WFS_RESULT_PERMISSION .. Permission flags of the target or its parent directory do not permit requested access from this application.
|
||||||
|
// WFS_RESULT_ACL_ENTRY_NOT_FOUND .. the target access list entry does not exist.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory was not found.
|
||||||
|
// Possible immediate return values for WFSDeletePermissionsAsync:
|
||||||
|
// WFS_RESULT_OK .. The request was dispatched successfully. The callback will be called in this case only.
|
||||||
|
// WFS_RESULT_BUSY .. Too many requests, try waiting then calling again.
|
||||||
|
// WFS_RESULT_OUT_OF_MEMORY .. The library does not have enough memory to dispatch the request. (May be due to too many outstanding aysnc calls).
|
||||||
|
// WFS_RESULT_INVALID .. The function parameters were invalid, e.g. File name too long, Path is too deep.
|
||||||
|
// Possible values of nResult passed to WFSDeletePermissionsAsync callback:
|
||||||
|
// WFS_RESULT_OK .. The specified file or directory was found and its permissions were calculated and passed as the nFlags parameter.
|
||||||
|
// WFS_RESULT_MEDIA_ERROR .. The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
// WFS_RESULT_WRITE_PROTECTED .. Device is physically write protected (e.g. USB Flash memory, SD Card. Note: Write errors can occur even for read operations).
|
||||||
|
// WFS_RESULT_PERMISSION .. Permission flags of the target or its parent directory do not permit requested access from this application.
|
||||||
|
// WFS_RESULT_CORRUPTION .. A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
// WFS_RESULT_NOT_FOUND .. The specified file or directory was not found.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// Use these functions to delete a specified access list entry.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //define __WFS_PERM_H__
|
||||||
@ -0,0 +1,209 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: Revolution WFS library
|
||||||
|
File: wfstypes.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfstypes.h,v $
|
||||||
|
Revision 1.13 2008/12/10 06:55:11 kondo_masahiro
|
||||||
|
Added the new device types WFS_DEVTYPE_USB_MSC_??.
|
||||||
|
|
||||||
|
Revision 1.12 2008/12/03 00:13:29 kondo_masahiro
|
||||||
|
Added WFS_MAX_WORK_SPACE_SIZE and fixed WFS_MIN_WORK_SPACE_SIZE
|
||||||
|
|
||||||
|
Revision 1.11 2008/10/23 11:16:20 nakanose_jin
|
||||||
|
Open and Search should give a invalid file handle if he fails to execute.
|
||||||
|
|
||||||
|
Revision 1.10 2008/09/26 09:32:36 kondo_masahiro
|
||||||
|
Marged with revision 1.8
|
||||||
|
|
||||||
|
Revision 1.9 2008/09/26 09:29:54 kondo_masahiro
|
||||||
|
Changed WFS_MIN_WORK_SPACE_SIZE.
|
||||||
|
|
||||||
|
Revision 1.8 2008/07/30 03:57:46 paul
|
||||||
|
Fixed WFS_FLAG_CONTIGUOUS_AREA comment
|
||||||
|
|
||||||
|
Revision 1.7 2008/07/25 09:46:56 ooizumi
|
||||||
|
Fixed WFSAccess definition.
|
||||||
|
|
||||||
|
Revision 1.6 2008/07/11 09:46:03 ueno
|
||||||
|
Added async functions.
|
||||||
|
|
||||||
|
Revision 1.5 2008/06/20 18:35:39 paul
|
||||||
|
Added WFS_MIN_DIRECTORY_QUOTA, WFS_FLAG_CONTIGUOUS_AREA
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/29 01:14:52 ueno
|
||||||
|
Removed WFS_DEBUG_SYSTEM_PROCESS_ID.
|
||||||
|
Added WFS_ROOT_ID and WFS_EVERYONE_ID.
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/08 18:24:30 paul
|
||||||
|
Moved callbacks and other type definitions from wfs.h into this header file. Moved permissions flags to wfsPerm.h
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/25 05:35:41 paul
|
||||||
|
Reduced WFS_MAX_FILE_NAME_SIZE and WFS_MAX_PATH_NAME_SIZE to make structs multiples of 32 bytes, and also allow space for a NULL terminator so we dont have to change existing code.
|
||||||
|
|
||||||
|
Revision 1.1 2008/01/17 07:51:43 ooizumi
|
||||||
|
Moved several definitions from wfs.h.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFSTYPES_H__
|
||||||
|
#define __WFSTYPES_H__
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// wfstypes.h - Wii File System (WFS) API
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#include <revolution.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// WFS attributes
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
#define WFS_MAX_FILE_SIZE 4294967295 // ((u32)-1)
|
||||||
|
#define WFS_MAX_PATH_DEPTH 31 // (ToDo: Directories must keep track of their deepest sub-path, so we can validate directory move requests)
|
||||||
|
|
||||||
|
// The following represent the maximum size of string fields in Bytes, not including the terminating NULL character.
|
||||||
|
#define WFS_MAX_FILE_NAME_SIZE 254 // Does not include the path, just the file name.
|
||||||
|
#define WFS_MAX_PATH_NAME_SIZE 509 // (ToDo: Directories must keep track of their longest sub-path, so we can validate directory move/rename requests)
|
||||||
|
#define WFS_MAX_DEVICE_NAME_SIZE 15 // maximum size of a device name
|
||||||
|
#define WFS_MAX_VOLUME_ID_SIZE 7 // maximum size of WFS Volume Id string (This is a randomly assigned string of characters, e.g., 1a2b3c4)
|
||||||
|
|
||||||
|
#define WFS_MAX_WORK_SPACE_SIZE ((512+40+40) * 1024) // Used for user data cache, shim layer queueing parameters and async thread stack / queueing async parameters.
|
||||||
|
#define WFS_MIN_WORK_SPACE_SIZE ((144+40+40) * 1024)
|
||||||
|
#define WFS_MIN_DIRECTORY_QUOTA (1024 * 1024)
|
||||||
|
#define WFS_INVALID_HANDLE_VALUE ((u32)-1)
|
||||||
|
|
||||||
|
|
||||||
|
typedef char utf8; // ToDo: Perhaps utf8 should be changed to WFSChar?
|
||||||
|
typedef u32 WFSFileTime; // Time in seconds since 00:00, 1st January, 2000
|
||||||
|
typedef u32 WFSFileSize; // Size of file
|
||||||
|
typedef u32 WFSContentIdx; // Used to identify files which belong to the same unit of purchased content, and control access to them
|
||||||
|
typedef u8 WFSBool;
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// WFS devices
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Possible WFS device states:
|
||||||
|
// 1. Valid - valid WFS volume exists
|
||||||
|
// 2. Unusable - bad device
|
||||||
|
// 3. Unknown format (e.g., FAT12, NTFS, HFS)
|
||||||
|
// 4. Uninitialized - recognized format (FAT32), but not enough free space for a WFS volume
|
||||||
|
|
||||||
|
// Whenever a compatible device is attached, we check to see if a WFS volume already exists. If not,
|
||||||
|
// we try to create it automatically. If it is not created, then the device must not have enough space.
|
||||||
|
|
||||||
|
#define WFS_DEVFLAG_UNUSABLE 1 // Device is unusable (e.g. unknown format, unsupported device)
|
||||||
|
#define WFS_DEVFLAG_WRITE_PROTECTED 2 // Device is physically write protected
|
||||||
|
#define WFS_DEVFLAG_NOT_INITIALIZED 4 // Device not formatted or does not yet contain a WFS volume
|
||||||
|
#define WFS_DEVFLAG_NOT_MOUNTED 8 // Device has not yet been mounted
|
||||||
|
|
||||||
|
// ToDo: Can we force this enum to be u8?
|
||||||
|
typedef enum {
|
||||||
|
WFS_DEVTYPE_NONE = 0x00,
|
||||||
|
WFS_DEVTYPE_SD = 0x01,
|
||||||
|
WFS_DEVTYPE_USB_MSC_10 = 0x02, // MSC device with USB1.0
|
||||||
|
WFS_DEVTYPE_USB_MSC_11 = 0x03, // MSC device with USB1.1
|
||||||
|
WFS_DEVTYPE_USB_MSC_20 = 0x04, // MSC device with USB2.0
|
||||||
|
WFS_DEVTYPE_EXT_SD = 0x05,
|
||||||
|
WFS_DEVTYPE_NAND = 0x06
|
||||||
|
} WFSDevType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u64 nDevTotalCapacity; // Total capacity of underlying device in bytes
|
||||||
|
u8 nDevType; // One of WFS_DEVTYPE_*
|
||||||
|
u8 nDevFlags; // Combination of WFS_DEVFLAG_*
|
||||||
|
} WFSDeviceInfo;
|
||||||
|
|
||||||
|
// ToDo: Should consider the case of users making an exact copy of a WFS volume causing two devices to
|
||||||
|
// have the same "unique" device Id. This may be an unavoidable problem.
|
||||||
|
// We can return WFS_RESULT_VOL_ID_ERROR if we attempt to mount a device with the same Id as an existing device.
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// WFSFileHandle, WFSSearchDirectoryHandle
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef u32 WFSFileHandle;
|
||||||
|
typedef u32 WFSSearchDirectoryHandle;
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// WFSFileInfo
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
WFSFileSize nFileSize; // Assuming this is a file
|
||||||
|
u32 nNumEntries; // Assuming this is a directory
|
||||||
|
};
|
||||||
|
u32 nFlags; // Includes the permissions for the requesting user: WFS_PERM* and directory status flag: WFS_FLAG_IS_A_DIRECTORY
|
||||||
|
WFSContentIdx nCidx;
|
||||||
|
WFSFileTime timeCreated;
|
||||||
|
WFSFileTime timeUpdated;
|
||||||
|
} WFSFileAttributes;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSFileAttributes attr;
|
||||||
|
utf8 sFileName[WFS_MAX_FILE_NAME_SIZE+1];
|
||||||
|
} WFSFileInfo;
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// WFS File Attributes
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
|
||||||
|
// The following flags are not stored per-title id, but they are included along with the permissions for the current title id in the nFlags field of WFSFileAttributes
|
||||||
|
#define WFS_FLAG_IS_A_DIRECTORY 0x80000000 // This flag can not be changed after creation.
|
||||||
|
#define WFS_FLAG_CONTIGUOUS_AREA 0x40000000 // Specifies that a directory has a contiguous set of blocks allocated to it, and is a self-contained area
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// WFSAccess
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
typedef enum {
|
||||||
|
WFS_ACCESS_READ = 0x01,
|
||||||
|
WFS_ACCESS_WRITE = 0x02,
|
||||||
|
WFS_ACCESS_RW = 0x03 // WFS_ACCESS_READ | WFS_ACCESS_WRITE
|
||||||
|
} WFSAccess;
|
||||||
|
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
// WFS callback types
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
typedef void (*WFSResultCallback )(WFSResult nResult, void *pUserData);
|
||||||
|
typedef void (*WFSDeviceCallback )(const utf8 *sDeviceName, void *pUserData); // For attach/detach callbacks
|
||||||
|
typedef void (*WFSDeviceInfoCallback )(WFSResult nResult, const utf8 *sDeviceName, WFSDeviceInfo *pDi, void *pUserData);
|
||||||
|
typedef void (*WFSDeviceVolumeCallback )(WFSResult nResult, const utf8 *sDeviceName, utf8 *sVolumeId, void *pUserData);
|
||||||
|
typedef void (*WFSUnmountVolumeCallback )(WFSResult nResult, const utf8 *sVolumeId, void *pUserData);
|
||||||
|
typedef void (*WFSInitializeDeviceCallback)(WFSResult nResult, const utf8 *sDeviceName, void *pUserData);
|
||||||
|
typedef void (*WFSFileOpCallback )(WFSResult nResult, WFSFileHandle fh, void *pUserData);
|
||||||
|
typedef void (*WFSGetFileSizeCallback )(WFSResult nResult, u32 nFileSize, WFSFileHandle fh, void *pUserData);
|
||||||
|
typedef void (*WFSReadFileCallback )(s32 nResultOrNumBytesRead, WFSFileHandle fh, void *pUserData);
|
||||||
|
typedef void (*WFSGetFreeSpaceCallback )(WFSResult nResult, u64 nSize, void *pUserData);
|
||||||
|
typedef void (*WFSGetAttributesCallback )(WFSResult nResult, const WFSFileAttributes *pFa, void *pUserData);
|
||||||
|
typedef void (*WFSSearchDirectoryCallback )(WFSResult nResult, WFSSearchDirectoryHandle sdh, const WFSFileInfo *pFi, void *pUserData);
|
||||||
|
typedef void (*WFSSearchDirectoryCloseCallback)(WFSResult nResult, WFSSearchDirectoryHandle sdh, void *pUserData);
|
||||||
|
typedef void (*WFSGetPermissionsForUserCallback)(WFSResult nResult, u32 nFlags, void *pUserData);
|
||||||
|
typedef void (*WFSGetAccessListCallback )(s32 nResultOrNumAclEntries, void *pUserData);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //define __WFSTYPES_H__
|
||||||
166
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Api.h
Normal file
166
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Api.h
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Api.h - global types used by the WFS kernel
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Api.h,v $
|
||||||
|
Revision 1.13 2008/12/04 00:42:37 ooizumi
|
||||||
|
Changed definition name to enable permission.
|
||||||
|
|
||||||
|
Revision 1.12 2008/09/28 23:30:00 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.11 2008/08/29 00:13:19 kondo_masahiro
|
||||||
|
Removed gPtr and gSize.
|
||||||
|
|
||||||
|
Revision 1.10 2008/07/25 02:54:16 paul
|
||||||
|
Added TransInfo lists to wkg
|
||||||
|
|
||||||
|
Revision 1.9 2008/07/17 22:43:08 paul
|
||||||
|
removed SubBlkTracker
|
||||||
|
|
||||||
|
Revision 1.8 2008/07/17 22:14:25 paul
|
||||||
|
Added rootDirAttr
|
||||||
|
|
||||||
|
Revision 1.7 2008/07/17 04:37:45 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP.
|
||||||
|
|
||||||
|
Revision 1.6 2008/07/09 01:06:24 paul
|
||||||
|
Added some definitions to support lists of mounted volumes. Moved block cache memory buffer into wkg.
|
||||||
|
|
||||||
|
Revision 1.5 2008/06/09 18:16:25 paul
|
||||||
|
added devAttr
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/12 19:19:05 paul
|
||||||
|
Added SubBlkTracker
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 17:28:32 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:07 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/23 00:55:23 paul
|
||||||
|
Updated WFSKrnGlobals
|
||||||
|
|
||||||
|
Revision 1.5 2008/04/19 05:50:11 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/29 02:38:02 kondo_masahiro
|
||||||
|
Fixed code to accept IOP compiler
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/28 02:38:02 kondo_masahiro
|
||||||
|
Fixed code to accept PPC compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/27 07:27:11 paul
|
||||||
|
made areaHdrRoot a global so it could be accessed from debug code in wfskrn_Dir.cpp
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/27 11:40:03 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Api_h
|
||||||
|
#define wfskrn_Api_h
|
||||||
|
|
||||||
|
#include "revolution/wfs.h"
|
||||||
|
#include "wfskrn_Config.h"
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
#include "wfskrn_Heap.h"
|
||||||
|
#include "wfskrn_Handles.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_Bcache.h"
|
||||||
|
#include "wfskrn_Volume.h"
|
||||||
|
#include "wfskrn_PathCache.h"
|
||||||
|
#include "wfskrn_PTree.h"
|
||||||
|
#include "wfskrn_Device.h"
|
||||||
|
#include "wfskrn_Volume.h"
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct VolumeLink_ {
|
||||||
|
struct VolumeInfo_ *pNext;
|
||||||
|
struct VolumeInfo_ *pPrev;
|
||||||
|
} VolumeLink;
|
||||||
|
|
||||||
|
typedef struct VolumeInfo_ {
|
||||||
|
VolumeLink vl;
|
||||||
|
struct DeviceInfo_ *pDevInfo;
|
||||||
|
VolumeHdr vh;
|
||||||
|
#if _DEBUG
|
||||||
|
WFSVolumeId volId;
|
||||||
|
#endif
|
||||||
|
AreaInfo rootAreaInfo;
|
||||||
|
DirEntryAttrHdr rootAttr;
|
||||||
|
u32 nClientsMountedBy; // A bit vector. Up to 32 clients represented by a bit each.
|
||||||
|
bool bDetached;
|
||||||
|
} VolumeInfo;
|
||||||
|
|
||||||
|
|
||||||
|
#define WFSKRN_MAX_VOLUMES (WFSKRN_MAX_DEVICES + WFSKRN_MAX_MOUNTED_VOLUMES)
|
||||||
|
#define WFS_STATIC_MEM_TOTAL_SIZE (WFS_BLK_CACHE_SIZE + WFS_BCACHE_META_DATA_SIZE + WFS_STATIC_HEAP_SIZE + WFS_STATIC_MEM_ALIGNMENT)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 *pBlkCache;
|
||||||
|
u8 *pHeapData;
|
||||||
|
bool bKrnInitialized;
|
||||||
|
bool bMountedDeviceWasDetached;
|
||||||
|
WFSKrnHeap heap;
|
||||||
|
|
||||||
|
//WFSKrnStrHashTbl strHTbl;
|
||||||
|
PathCache pathCache;
|
||||||
|
PTreeHdr ptreeHdr;
|
||||||
|
PTreeAllocator ptreeAllocator;
|
||||||
|
|
||||||
|
WFSBlkAdr nRootDirBlkAdr;
|
||||||
|
|
||||||
|
u32 nNumDevices;
|
||||||
|
DeviceInfo aDevInfo[WFSKRN_MAX_DEVICES];
|
||||||
|
VolumeInfo aVolInfo[WFSKRN_MAX_VOLUMES];
|
||||||
|
VolumeLink mountedVolListAnchor;
|
||||||
|
VolumeInfo *pMountedVolListAnchor; // double link list
|
||||||
|
VolumeInfo *pFreeVolList; // single link list (stack)
|
||||||
|
|
||||||
|
DirEntryAttrHdr rootDirAttr;
|
||||||
|
DirEntryAttrHdr volDirAttr;
|
||||||
|
DirEntryAttrHdr devDirAttr;
|
||||||
|
DirEntryAttrHdr devAttr;
|
||||||
|
|
||||||
|
#if _WIN32 || PERM_TEST
|
||||||
|
WFSTitleId nDebugTitleId;
|
||||||
|
#endif
|
||||||
|
TransInfo aTransInfo[WFSKRN_MAX_ACTIVE_TRANSACTIONS];
|
||||||
|
TransInfoLink activeTransListAnchor;
|
||||||
|
TransInfo *pActiveTransListAnchor;
|
||||||
|
TransInfo *pTransInfoFreeList;
|
||||||
|
|
||||||
|
WFSKrnHandles hnd;
|
||||||
|
WFSFileTime time;
|
||||||
|
|
||||||
|
u8 aStaticMem[WFS_STATIC_MEM_TOTAL_SIZE]; // it includes block cache for meta block and heap data.
|
||||||
|
} WFSKrnGlobals;
|
||||||
|
|
||||||
|
|
||||||
|
extern WFSKrnGlobals wkg;
|
||||||
|
|
||||||
|
extern DirItr gDi;
|
||||||
|
|
||||||
|
extern AreaInfo *pAhInit;
|
||||||
|
extern WFSBlkAdr *pBaInit;
|
||||||
|
|
||||||
|
//extern u8 *gpPtr; // Pointer of vdsk memory
|
||||||
|
//extern u32 gSize; // Size of vdsk memory
|
||||||
|
|
||||||
|
extern u8 *gpHeapPtr; // Pointer of heap memory
|
||||||
|
extern u32 gHeapSize; // Size of heap memory
|
||||||
|
|
||||||
|
#endif //define wfskrn_Api_h
|
||||||
328
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Area.h
Normal file
328
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Area.h
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Area.h - Module for managing contiguous disk areas
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Area.h,v $
|
||||||
|
Revision 1.24 2008/12/18 09:03:37 kondo_masahiro
|
||||||
|
Fixed function name and process from BCacheSetBlkAdr() to BCacheRemap()
|
||||||
|
|
||||||
|
Revision 1.23 2008/12/17 01:37:42 kondo_masahiro
|
||||||
|
Added function BCacheSetBlkAdr()
|
||||||
|
|
||||||
|
Revision 1.22 2008/11/26 01:46:19 kondo_masahiro
|
||||||
|
Fixed arguments of several functions in order to improve access speed.
|
||||||
|
|
||||||
|
Revision 1.21 2008/10/17 08:51:27 kondo_masahiro
|
||||||
|
Added the new MEDIUM size category (40KB-320KB)
|
||||||
|
|
||||||
|
Revision 1.20 2008/10/14 10:27:44 kondo_masahiro
|
||||||
|
Added codes to access very large size file data
|
||||||
|
|
||||||
|
Revision 1.19 2008/10/10 02:11:49 kondo_masahiro
|
||||||
|
Fixed a bug to access large files
|
||||||
|
|
||||||
|
Revision 1.18 2008/10/09 04:15:46 kondo_masahiro
|
||||||
|
Fixed member of AreaHdr and AreaInfo
|
||||||
|
|
||||||
|
Revision 1.17 2008/10/08 23:20:09 kondo_masahiro
|
||||||
|
Added codes to access large size file data
|
||||||
|
|
||||||
|
Revision 1.16 2008/09/28 23:30:08 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.15 2008/09/24 07:32:07 ueno
|
||||||
|
Added AclHdr{} to AreaHdr{} to save configuration of accesslists in a disk.
|
||||||
|
|
||||||
|
Revision 1.14 2008/08/27 09:53:34 paul
|
||||||
|
Changed information in area header slightly. Added nStride to alloc, free functions
|
||||||
|
|
||||||
|
Revision 1.13 2008/08/14 08:04:16 kondo_masahiro
|
||||||
|
Removed struct AreaHashHdr.
|
||||||
|
|
||||||
|
Revision 1.12 2008/08/07 10:42:39 ueno
|
||||||
|
Modified for BTREE_BASED_ALLOCATOR.
|
||||||
|
|
||||||
|
Revision 1.11 2008/08/05 04:17:15 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.10 2008/07/23 04:21:43 ueno
|
||||||
|
Modified AreaInfo{} for B-tree based allocator.
|
||||||
|
|
||||||
|
Revision 1.9 2008/07/17 04:54:33 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP.
|
||||||
|
|
||||||
|
Revision 1.8 2008/07/09 01:12:34 paul
|
||||||
|
Many changes to area structs - to allow directory module to write via block cache, support volume initialization and mounting exisiting volumes.
|
||||||
|
|
||||||
|
Revision 1.14 2008/04/28 20:20:57 wayne.wong
|
||||||
|
Changed the interface to block alloc slightly to return WFSKrnResult.
|
||||||
|
|
||||||
|
Revision 1.13 2008/04/26 05:51:56 wayne.wong
|
||||||
|
Fixed prototype name and arg type.
|
||||||
|
|
||||||
|
Revision 1.7 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/25 19:15:19 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/25 06:22:55 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/25 04:40:47 ueno
|
||||||
|
Added support for WFSDEV.
|
||||||
|
|
||||||
|
Revision 1.12 2008/04/26 01:23:55 wayne.wong
|
||||||
|
Moved area functionality from Volume to Area module. Changed implementation
|
||||||
|
to support small area sizes for a large mapped number of sectors. Added
|
||||||
|
block wrapper calls for Area and BCache calls.
|
||||||
|
|
||||||
|
Revision 1.11 2008/04/23 00:38:36 paul
|
||||||
|
Removed old defs
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/19 05:50:05 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/18 09:04:48 nakanose_jin
|
||||||
|
merging acl
|
||||||
|
|
||||||
|
Revision 1.8 2008/04/18 01:58:18 wayne.wong
|
||||||
|
Created separate Area types for persistent (hdr) and non-persistent (info) types.
|
||||||
|
Changed function names to be consistent with kernel naming convention.
|
||||||
|
Defines are included to support the previous naming, but will be deleted in
|
||||||
|
the future.
|
||||||
|
|
||||||
|
Revision 1.7 2008/03/11 03:18:39 wayne.wong
|
||||||
|
Added sector information to the area header.
|
||||||
|
|
||||||
|
Revision 1.6 2008/02/28 13:11:58 ueno
|
||||||
|
Revised to keep accesslist cache and indexlist handle in WFSAreaHdr{}.
|
||||||
|
|
||||||
|
Revision 1.5 2008/02/28 06:37:24 kondo_masahiro
|
||||||
|
Fixed code to accept PPC compiler
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/27 11:17:16 ueno
|
||||||
|
Added fields for accesslist development to WFSAreaHdr{}.
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/20 07:10:44 paul
|
||||||
|
Added WfsAreaFreeBlks function, WFSTransBlkAdr struct
|
||||||
|
|
||||||
|
Revision 1.2 2007/12/27 11:39:22 paul
|
||||||
|
preliminary API to help me proceed with the Dir module
|
||||||
|
|
||||||
|
Revision 1.1 2007/11/16 05:44:48 paul
|
||||||
|
first checkin
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Area_h
|
||||||
|
#define wfs_Area_h
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _CHECK_BLK_USAGE 0 // change to check for invalid area block and block cache usage
|
||||||
|
#define _CHECK_BLK_ALLOCATION 0
|
||||||
|
#else
|
||||||
|
#define _CHECK_BLK_USAGE 0
|
||||||
|
#define _CHECK_BLK_ALLOCATION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
#include "wfskrn_BCache.h"
|
||||||
|
#include "wfskrn_Permission_AccessList_Type.h"
|
||||||
|
|
||||||
|
///// The flag enables block cache. /////
|
||||||
|
#define AREA_ENABLE_BLK_CACHE 1
|
||||||
|
|
||||||
|
#if AREA_ENABLE_BLK_CACHE
|
||||||
|
#define BTREE_BASED_ALLOCATOR 1
|
||||||
|
#define LIST_BASED_ALLOCATOR 0
|
||||||
|
#define SIMPLE_ALLOCATOR 0
|
||||||
|
#else
|
||||||
|
#define BTREE_BASED_ALLOCATOR 0
|
||||||
|
#define LIST_BASED_ALLOCATOR 0
|
||||||
|
#define SIMPLE_ALLOCATOR 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if BTREE_BASED_ALLOCATOR
|
||||||
|
#include "wfskrn_FreeBlkAlloc_Type.h"
|
||||||
|
#endif // BTREE_BASED_ALLOCATOR
|
||||||
|
|
||||||
|
//#define AREA_SECTOR_SIZE 512
|
||||||
|
//#define AREA_SECTOR_SIZE_BITS 9
|
||||||
|
|
||||||
|
#define AREA_PAGE_SIZE (1<<WFS_LOG2_SMALL_BLK_SIZE)
|
||||||
|
|
||||||
|
#define AREA_NULL (-1) // end marker for sxx types
|
||||||
|
|
||||||
|
// wfsVolumeAreaEntry attribute bits
|
||||||
|
#define AREA_EMPTY 0x0000 // empty, not initialized
|
||||||
|
#define AREA_ALLOCATED 0x0001 // set if allocated
|
||||||
|
#define AREA_START 0x0002 // set if start of an area
|
||||||
|
// #define AREA_FIRST 0x0004 // first area has overhead
|
||||||
|
#define AREA_OVERHEAD 0x0004 // area overhead; header(s) + entry list
|
||||||
|
|
||||||
|
#define AREA_FLAG_META_DATA 0
|
||||||
|
#define AREA_FLAG_USER_DATA BCACHE_FLAG_FILE_BLK
|
||||||
|
|
||||||
|
#ifndef _struct_WFSAccessListControlBlock_
|
||||||
|
#define _struct_WFSAccessListControlBlock_
|
||||||
|
typedef struct _WFSAccessListControlBlock WFSAccessListControlBlock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if LIST_BASED_ALLOCATOR
|
||||||
|
typedef WFSBlkAdr AreaEntryIdx;
|
||||||
|
|
||||||
|
// Area table entry. Describe the on a min-area sized granularity.
|
||||||
|
typedef struct _AreaEntry {
|
||||||
|
s16 nSizeIdx; // size enumeration
|
||||||
|
u16 nAttributes; // free
|
||||||
|
AreaEntryIdx nNextIdx; // abs area index/number of next in this list
|
||||||
|
AreaEntryIdx nPrevIdx; // abs area index/number of prev in this list
|
||||||
|
} AreaEntry;
|
||||||
|
|
||||||
|
typedef struct _AreaList {
|
||||||
|
u32 nAreaSize; // in sectors
|
||||||
|
AreaEntryIdx nHeadIdx; // index to heads of freelist
|
||||||
|
u32 nLen; // length; number of same-sized areas in list
|
||||||
|
} AreaList;
|
||||||
|
#endif //LIST_BASED_ALLOCATOR
|
||||||
|
|
||||||
|
#if !_IOP
|
||||||
|
namespace wfsdev_api{
|
||||||
|
struct tagSAreaInfo;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct AreaHdr_ {
|
||||||
|
// This is the part of the AreaInfo struct which is stored on disk
|
||||||
|
// ** Note: All block addresses and values must be independent of the absolute location of the area **
|
||||||
|
// ToDo: Move the on-disk generic meta-data header out of the headers
|
||||||
|
WFSMetaDataFlags nFlags; // 4 Bytes
|
||||||
|
WFSHashCode hash; // 20 bytes
|
||||||
|
WFSBlkAdr nRootBlkAdr; // Root directory block of the area relative to the start of the area
|
||||||
|
WFSBlkAdr nNumBlks; // Total size of the area in blocks (small blocks or meta data blocks)
|
||||||
|
#if LIST_BASED_ALLOCATOR
|
||||||
|
WFSBlkAdr nDataStartBlkAdr; // Block address of end of free list management area (relative to start of area)
|
||||||
|
u16 nMaxNumAreas; // maximum number of minimum-sized areas on device
|
||||||
|
#endif
|
||||||
|
#if BTREE_BASED_ALLOCATOR
|
||||||
|
FBATreeHdr freeBlkAllocHdr;
|
||||||
|
#endif // BTREE_BASED_ALLOCATOR
|
||||||
|
|
||||||
|
AclHdr aclHdr; // Block addresses of the root directories of accesslists and the namefiles.
|
||||||
|
|
||||||
|
u8 nLog2BlkSize; // Log to the base 2 of the block size (small blocks or meta data blocks)
|
||||||
|
u8 nLog2MediumBlkSize; // Log to the base 2 of the medium block size (for Wii, this value is 16)
|
||||||
|
u8 nLog2LargeBlkSize; // Log to the base 2 of the multiple between the large block size. (large blocks are used for large files only)
|
||||||
|
} AreaHdr;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
#if LIST_BASED_ALLOCATOR
|
||||||
|
AreaList aFreeList[WFSKRN_MAX_NUM_AREA_SIZES]; // freelists
|
||||||
|
#elif SIMPLE_ALLOCATOR
|
||||||
|
WFSBlkAdr nFirstFreeBlkAdr; // Block address of the first free block (relative to start of area)
|
||||||
|
WFSBlkAdr nNumFreeBlks;
|
||||||
|
u8 *pPtr; // pointer to a title area in memory
|
||||||
|
#endif
|
||||||
|
} AreaFreeListHdr;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct AreaInfo_ {
|
||||||
|
struct AreaInfo_ *pParent; // Points to the parent area info. NULL if this is the root area.
|
||||||
|
struct VolumeInfo_ *pVolInfo; // Points to the volume info
|
||||||
|
AreaHdr ah; // Area header information. This is a copy of the header stored on disk
|
||||||
|
AreaFreeListHdr *pAflh; // Pointer to the free list header
|
||||||
|
WFSBlkAdr nAbsStartBlkAdr; // Absolute block address of the first block of the area
|
||||||
|
WFSBlkAdr nRelStartBlkAdr; // block address of the first block of the area relative to the start of the parent area
|
||||||
|
u32 nBlkSize; // Block size in bytes (for meta data, and small file blocks). On Wii, block size is 8KB
|
||||||
|
u32 nMediumBlkSize; // Medium block size in bytes (for large file blocks). On Wii, medium block size is 64KB
|
||||||
|
u32 nLargeBlkSize; // Large block size in bytes (for large file blocks). On Wii, medium block size is 512KB
|
||||||
|
u32 nLog2BlksPerMediumBlk; // nLog2 number of small blocks in medium block
|
||||||
|
u32 nLog2BlksPerLargeBlk; // nLog2 number of small blocks in large block
|
||||||
|
u32 nLog2MediumBlkPerLargeBlk; // nLog2 number of medium blocks in large block
|
||||||
|
u32 nLargeBlkPtrSize; // Used in indirect block layout calculations
|
||||||
|
//u32 nMaxLargeBlkPtrsPerAttrSubBlk; // Determines when to switch file layout from large size category to very large size category
|
||||||
|
u32 nNumLargeBlkPtrsPerBlk; // Used to calculate number of indirect blocks needed to index into large files
|
||||||
|
u32 nNumMediumBlkPtrsPerBlk; // Used to calculate number of indirect blocks needed to index into medium files
|
||||||
|
|
||||||
|
#if LIST_BASED_ALLOCATOR
|
||||||
|
u32 nNumEntriesInFirstBlk; // Number of free-list entries in first block
|
||||||
|
u32 nNumEntriesPerBlk; // Number of free-list entries per block
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _CHECK_BLK_ALLOCATION
|
||||||
|
u32 *aBlkAllocState;
|
||||||
|
#endif
|
||||||
|
#if !_IOP
|
||||||
|
struct wfsdev_api::tagSAreaInfo *aclWrapper;
|
||||||
|
#endif
|
||||||
|
WFSAccessListControlBlock* accessListCb;
|
||||||
|
} AreaInfo;
|
||||||
|
|
||||||
|
|
||||||
|
// *** Old Area module API functions (only recording memory) ****
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult AreaAllocBlks(AreaInfo *pAreaInfo, WFSBlkAdr nRefBlkAdr, u32 nLog2BlkSize, u32 nNumBlks, WFSBlkAdr *aBlkAdr, s32 nStride);
|
||||||
|
WFSKrnResult AreaFreeBlks(AreaInfo *pAreaInfo, u32 nLog2BlkSize, u32 nNumBlks, WFSBlkAdr *pBlkAdr, s32 nStride);
|
||||||
|
WFSKrnResult AreaInvalidateBlks(AreaInfo *pAreaInfo, u32 nNumBlks, WFSBlkAdr *pBlkAdr, s32 nStride);
|
||||||
|
WFSBool AreaGetRegionBlkSize(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr);
|
||||||
|
void AreaSetRegionBlkSize(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, WFSBool bLargeBlk);
|
||||||
|
void AreaFindSubArea(utf8 *pPathName, AreaInfo *pAreaInfo);
|
||||||
|
void * AreaGetPhysicalBlk(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr);
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult AreaInit(AreaInfo *pAreaInfo); // Initializes the area, writes it's header and initial metadata to disk
|
||||||
|
WFSKrnResult AreaOpen(AreaInfo *pAreaInfo); // Opens and reads an existing area from disk
|
||||||
|
void AreaClose(AreaInfo *pAreaInfo); // Closes an area
|
||||||
|
|
||||||
|
|
||||||
|
// Display the free list information for an area. (for debug)
|
||||||
|
WFSKrnResult AreaFreelistPrint(AreaInfo *pAreaInfo);
|
||||||
|
|
||||||
|
// Allocate a sub-area.
|
||||||
|
WFSKrnResult AreaAllocSubArea(AreaInfo *pAreaInfo, // area to allocate from
|
||||||
|
WFSBlkAdr nNumBlks, // size of sub area expressed as the number of parent area small blocks
|
||||||
|
AreaInfo *pSubAreaInfo, // returned sub-area
|
||||||
|
u32 nFlags); //
|
||||||
|
|
||||||
|
|
||||||
|
// Free a sub-area
|
||||||
|
WFSKrnResult AreaFreeSubArea(AreaInfo *pAreaInfo, // area to free to
|
||||||
|
AreaInfo *pSubAreaInfo); // sub-area to free
|
||||||
|
|
||||||
|
|
||||||
|
// Block interface to block cache (BCache module)
|
||||||
|
WFSKrnResult AreaBlkAlloc (AreaInfo *pAreaInfo, WFSBlkAdr nRefBlkAdr, u32 nNumBlks, WFSBlkAdr aBlkAdr[]);
|
||||||
|
WFSKrnResult AreaBlkStore (AreaInfo *pAreaInfo, WFSBlkAdr blkAdr);
|
||||||
|
WFSKrnResult AreaBlkFlush (AreaInfo *pAreaInfo, WFSBlkAdr blkAdr);
|
||||||
|
WFSKrnResult AreaBlkInvalidate (AreaInfo *pAreaInfo, WFSBlkAdr blkAdr);
|
||||||
|
WFSKrnResult AreaBlkDirty (AreaInfo *pAreaInfo, WFSBlkAdr blkAdr);
|
||||||
|
WFSKrnResult AreaBlkPin (AreaInfo *pAreaInfo, WFSBlkAdr blkAdr);
|
||||||
|
WFSKrnResult AreaBlkUnpin (AreaInfo *pAreaInfo, WFSBlkAdr blkAdr);
|
||||||
|
u32 AreaBlkGetPinCount(AreaInfo *pAreaInfo, WFSBlkAdr blkAdr);
|
||||||
|
WFSKrnResult AreaBlkGetPtr(AreaInfo *pAreaInfo, WFSBlkAdr blkAdr, void** ppPtr);
|
||||||
|
WFSKrnResult AreaBlkSetValidSize(AreaInfo *pAreaInfo, WFSBlkAdr blkAdr, u32 nValidSize);
|
||||||
|
WFSKrnResult AreaBlkRemapCache(AreaInfo *pAreaInfo, WFSBlkAdr nSrcBlkAdr, WFSBlkAdr nDstBlkAdr, WFSBlkAdr nHashBlkAdr, u32 nHashOfs);
|
||||||
|
|
||||||
|
//#define _DEBUG_WFSKRN_AREA_
|
||||||
|
|
||||||
|
#ifdef _DEBUG_WFSKRN_AREA_
|
||||||
|
#define dbga(_s) (_s)
|
||||||
|
#else
|
||||||
|
#define dbga(_s)
|
||||||
|
#endif // _DEBUG_WFSKRN_BCACHE_
|
||||||
|
|
||||||
|
#endif //define wfs_Area_h
|
||||||
@ -0,0 +1,264 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_BCache.h - disk block buffer cache library
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_BCache.h,v $
|
||||||
|
Revision 1.16 2008/12/18 09:03:37 kondo_masahiro
|
||||||
|
Fixed function name and process from BCacheSetBlkAdr() to BCacheRemap()
|
||||||
|
|
||||||
|
Revision 1.15 2008/12/17 01:37:42 kondo_masahiro
|
||||||
|
Added function BCacheSetBlkAdr()
|
||||||
|
|
||||||
|
Revision 1.14 2008/12/10 08:20:01 ueno
|
||||||
|
Added BCacheDumpPinCount() for debug.
|
||||||
|
|
||||||
|
Revision 1.13 2008/12/03 00:04:53 kondo_masahiro
|
||||||
|
Added WFSBCacheStoreVolume and removed WFSBCacheFlushAll.
|
||||||
|
|
||||||
|
Revision 1.12 2008/11/26 01:46:19 kondo_masahiro
|
||||||
|
Fixed arguments of several functions in order to improve access speed.
|
||||||
|
|
||||||
|
Revision 1.11 2008/11/05 05:56:30 kondo_masahiro
|
||||||
|
Added BCacheSet/GetChainId()
|
||||||
|
|
||||||
|
Revision 1.10 2008/10/03 08:37:18 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP
|
||||||
|
|
||||||
|
Revision 1.9 2008/09/29 10:19:25 ueno
|
||||||
|
Revised to support multi-B-tree-based allocator.
|
||||||
|
|
||||||
|
Revision 1.8 2008/09/28 23:30:13 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.7 2008/08/27 23:17:41 paul
|
||||||
|
Added BCACHE_FLAG_FILE_BLK
|
||||||
|
|
||||||
|
Revision 1.6 2008/08/08 13:33:29 ueno
|
||||||
|
Added BCacheCheck2() to check freeblock allocator.
|
||||||
|
|
||||||
|
Revision 1.5 2008/08/05 04:17:20 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.4 2008/07/17 04:54:48 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP.
|
||||||
|
|
||||||
|
Revision 1.3 2008/07/09 01:15:33 paul
|
||||||
|
Changed block cache to use block address instead of sector address. Combined block cache globals into a single struct. Added a function to re-tag a cached block.
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/12 19:19:20 paul
|
||||||
|
Merged in Wayne's previous changes
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:07 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/26 01:07:36 wayne.wong
|
||||||
|
Removed dynamic memory allocation. User is now required to pass memory to
|
||||||
|
use for descriptor table. A function is added to calculate the size for the user.
|
||||||
|
Changed type name to be uniform with other modules.
|
||||||
|
|
||||||
|
Revision 1.8 2008/03/19 07:36:32 wayne.wong
|
||||||
|
Fixed a bug with sector tag matching at page granularity.
|
||||||
|
|
||||||
|
Revision 1.7 2008/03/11 03:12:27 wayne.wong
|
||||||
|
Tweaked interface a little. Most noteable is one can now specify whether a page
|
||||||
|
will be dirty upon allocation. This eliminates a possible second BCache call
|
||||||
|
to mark as dirty later.
|
||||||
|
|
||||||
|
Revision 1.6 2008/02/22 00:40:20 wayne.wong
|
||||||
|
Change BCache module's prefix for functions and types. Added some new functions.
|
||||||
|
|
||||||
|
Revision 1.5 2008/02/20 07:44:37 paul
|
||||||
|
Changed names to start with PMem
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/05 03:13:56 wayne.wong
|
||||||
|
Added WfsBCacheGetConfig() call.
|
||||||
|
|
||||||
|
Revision 1.3 2008/01/30 03:52:33 wayne.wong
|
||||||
|
Added WfsBCacheValidVolume() call.
|
||||||
|
|
||||||
|
Revision 1.2 2008/01/18 06:12:45 wayne.wong
|
||||||
|
Refined api. Block(page) cache now matches on the tuple (volumeId, sector).
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/31 21:19:57 wayne.wong
|
||||||
|
Initial version.
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _wfskrn_BCache_h_
|
||||||
|
#define _wfskrn_BCache_h_
|
||||||
|
|
||||||
|
#include "wfskrn_Volume.h"
|
||||||
|
#include "wfskrn_Device.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
|
||||||
|
#define BCACHE_FLAG_INVALID 0x00
|
||||||
|
#define BCACHE_FLAG_READ 0x01
|
||||||
|
#define BCACHE_FLAG_DIRTY 0x02
|
||||||
|
#define BCACHE_FLAG_PINNED 0x04
|
||||||
|
#define BCACHE_FLAG_VALID 0x08
|
||||||
|
#define BCACHE_FLAG_FILE_BLK 0x10
|
||||||
|
|
||||||
|
#define BCACHE_GROUP_ID_METABLK 0x00
|
||||||
|
#define BCACHE_GROUP_ID_USERBLK_8K 0x01
|
||||||
|
#define BCACHE_GROUP_ID_USERBLK_64K 0x02
|
||||||
|
|
||||||
|
#define BCACHE_NUM_OF_GROUP 3
|
||||||
|
|
||||||
|
// The block cache (BCache) caches metadata disk blocks in memory. The metadata disk
|
||||||
|
// block size blkSize (e.g., 8KB). The buffer cache is fully set-associative. Let us
|
||||||
|
// call a disk block in memory a page. If no invalid pages are available, pages are
|
||||||
|
// replaced with a global LRU policy. Pages can be allocated, loaded, stored, flushed,
|
||||||
|
// invalidated, and pinned. Pinned pages are not candidates for replacement. If all
|
||||||
|
// pages are pinned and a new page is needed, the wfsBCache call will fail until a page
|
||||||
|
// is unpinned or invalidated (thus, generating a possible victim page for replacement).
|
||||||
|
//
|
||||||
|
// Initially, other than the alloc/read call, the interface was with a u8*. Instead,
|
||||||
|
// let's try with the tuple (volumeId, a physical sector/LBA address). The sector
|
||||||
|
// will be aligned to a page granularity. Upon allocation, a pointer to the
|
||||||
|
// start of the page is returned, even if the sector address specified is in the
|
||||||
|
// middle of the page.
|
||||||
|
//
|
||||||
|
// Wayne - Why not use device handle instead of volumeId? What about the multi-client case
|
||||||
|
// where each client may have the a different device handle to the same volume?
|
||||||
|
// Or will this never happen?
|
||||||
|
//
|
||||||
|
|
||||||
|
typedef struct BCacheListNode_ {
|
||||||
|
void *pData;
|
||||||
|
struct BCacheListNode_ *pNext;
|
||||||
|
struct BCacheListNode_ *pPrev;
|
||||||
|
} BCacheListNode;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct BCacheList_ {
|
||||||
|
BCacheListNode *pHead;
|
||||||
|
BCacheListNode *pTail;
|
||||||
|
u16 nLen;
|
||||||
|
} BCacheList;
|
||||||
|
|
||||||
|
typedef struct BCacheGroup_ BCacheGroup;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
// ToDo: Later, it may be better to make the block cache use a pointer to the AreaInfo struct (which would
|
||||||
|
// have to be statically allocated and only reused after all of its blocks have been flushed from cache),
|
||||||
|
// plus the area-relative block address as the tag.
|
||||||
|
WFSBlkAdr nAbsBlkAdr; // tag1 - HDD physical absolute block address that is being cached
|
||||||
|
struct VolumeInfo_ *pVolInfo; // tag2 - pointer to volume struct2
|
||||||
|
DeviceInfo *pDevInfo;
|
||||||
|
u32 nState; // stored flags including BCACHE_FLAG_FILE_BLK and BCACHE_FLAG_SIZE_64K
|
||||||
|
u32 nPinCount;
|
||||||
|
u8 *pBlkPtr;
|
||||||
|
WFSBlkAdr nHashBlkAdr;
|
||||||
|
WFSHashCode *pHash;
|
||||||
|
BCacheGroup *pGroup;
|
||||||
|
u32 nValidSize;
|
||||||
|
u32 nChainId;
|
||||||
|
#if _CHECK_BLK_USAGE
|
||||||
|
u32 nCheckSum;
|
||||||
|
#endif
|
||||||
|
#if _DEBUG
|
||||||
|
u32 nDbgCommandCount;
|
||||||
|
#endif
|
||||||
|
} BCacheEntry;
|
||||||
|
|
||||||
|
struct BCacheGroup_{
|
||||||
|
u8 *pBCache; // start of actual page/block cache
|
||||||
|
BCacheEntry *pBCacheTable; // cache info entries
|
||||||
|
|
||||||
|
u8 *pMemCache; // starting address of cached pages
|
||||||
|
u32 nMemCacheSize; // size of cache, in bytes
|
||||||
|
u32 nLog2BlkSize; // base 2 logarithm of the block size for group
|
||||||
|
u32 nBlkSize; // block size for group (in bytes)
|
||||||
|
u32 nNumBlks; // size of cache in blocks
|
||||||
|
|
||||||
|
u32 nNumMapped; // number of mapped pages
|
||||||
|
u32 nNumInvalid; // number of invalid pages
|
||||||
|
u32 nNumPinned; // number of pinned pages
|
||||||
|
|
||||||
|
BCacheList bclInvalid; // head of invalid list
|
||||||
|
BCacheList bclLru; // LRU/MRU list; head=LRU; contains valid pages
|
||||||
|
BCacheList bclPinned; // pinned pages; contains valid pages
|
||||||
|
BCacheList bclFree;
|
||||||
|
BCacheListNode *pBclNodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct BCacheState_ {
|
||||||
|
// previously global variables:
|
||||||
|
u8 *pHeap;
|
||||||
|
u32 nHeapSize;
|
||||||
|
|
||||||
|
u32 nLog2UnitBlkSize; // base 2 logarithm of the block size for unit block
|
||||||
|
u32 nUnitBlkSize; // block size for unit block (in bytes)
|
||||||
|
|
||||||
|
u32 nNumGroups;
|
||||||
|
BCacheGroup aGroup[BCACHE_NUM_OF_GROUP];
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
bool bSkipCheckPin;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
BCacheList aHashTbl[WFSKRN_BCACHE_HASH_TABLE_SIZE]; // chained hash table
|
||||||
|
} BCacheGlobals;
|
||||||
|
|
||||||
|
extern BCacheGlobals bcg;
|
||||||
|
|
||||||
|
|
||||||
|
u32 BCacheMetadataMemSize(u32 memCacheSize, u32 nBlkSize); // calc pMem arg to BCacheInitLib
|
||||||
|
//WFSKrnResult BCacheInitLib (u8 *pMemCache, u32 memCacheSize, u32 nLog2BlkSize, u8 *pMem, u32 memSize);
|
||||||
|
WFSKrnResult BCacheInit (u32 nLog2UnitBlkSize, u8 *pMem, u32 nMemSize);
|
||||||
|
WFSKrnResult BCacheGroupInit (u32 nBCacheGroupId, u8 *pMemCache, u32 memCacheSize, u32 nLog2BlkSize);
|
||||||
|
WFSKrnResult BCacheGetState (BCacheGroup *pGroup);
|
||||||
|
WFSKrnResult BCacheMapVolume (struct VolumeInfo_ *pVolInfo, DeviceInfo *pDevInfo);
|
||||||
|
bool BCacheValidVolume (struct VolumeInfo_ *pVolInfo);
|
||||||
|
WFSKrnResult BCacheAlloc (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr, u32 nFlags, u32 nReadSize, u32 nBCacheGroupId,
|
||||||
|
WFSBlkAdr nHashBlkAdr, u32 nHashOfs, BCacheEntry** ppBce);
|
||||||
|
WFSKrnResult BCacheSetHash (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr, WFSBlkAdr nHashBlkAdr, u32 nHashOfs);
|
||||||
|
WFSKrnResult BCacheSetValidSize (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr, u32 nValidSize);
|
||||||
|
WFSKrnResult BCacheSetChainId (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr, u32 nChainId);
|
||||||
|
WFSKrnResult BCacheGetChainId (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr, u32 *pChainId);
|
||||||
|
WFSKrnResult BCacheRemap (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nSrcAbsBlkAdr, WFSBlkAdr nDstAbsBlkAdr, WFSBlkAdr nHashAbsBlkAdr, u32 nHashOfs);
|
||||||
|
void BCacheReTag (struct VolumeInfo_ *pOldVolInfo, WFSBlkAdr nOldAbsBlkAdr,
|
||||||
|
struct VolumeInfo_ *pNewVolInfo, WFSBlkAdr nNewAbsBlkAdr);
|
||||||
|
void* BCacheFind (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr); // find a page
|
||||||
|
WFSKrnResult BCacheStore (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr); // store page & mark clean
|
||||||
|
WFSKrnResult BCacheFlush (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr); // store & invalidate page
|
||||||
|
//WFSKrnResult BCacheFlushAll (); // flush all pages
|
||||||
|
WFSKrnResult BCacheStoreVolume (struct VolumeInfo_ *pVolInfo); // store a volume's pages
|
||||||
|
WFSKrnResult BCacheFlushVolume (struct VolumeInfo_ *pVolInfo); // flush a volume's pages
|
||||||
|
WFSKrnResult BCacheInvalidate (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr); // invalidate a page
|
||||||
|
WFSKrnResult BCacheInvalidateBlks (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr, u32 nNumBlks); // invalidate a page
|
||||||
|
WFSKrnResult BCacheTouch (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr); // make a page MRU
|
||||||
|
WFSKrnResult BCacheDirty (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr); // mark a page as modified
|
||||||
|
WFSKrnResult BCachePin (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr); // page cannot be evicted
|
||||||
|
WFSKrnResult BCacheUnpin (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr); // page now can be evicted
|
||||||
|
u32 BCacheGetPinCount (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr);
|
||||||
|
void* BCachePointer (struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr);
|
||||||
|
WFSKrnResult BCacheCheck ();
|
||||||
|
WFSKrnResult BCacheCheck2 ();
|
||||||
|
|
||||||
|
static inline
|
||||||
|
WFSKrnResult BCacheAllocMetaBlk(struct VolumeInfo_ *pVolInfo, WFSBlkAdr nAbsBlkAdr, u32 nFlags, BCacheEntry** ppBce)
|
||||||
|
{
|
||||||
|
return BCacheAlloc(pVolInfo, nAbsBlkAdr, nFlags, 1<<bcg.aGroup[BCACHE_GROUP_ID_METABLK].nLog2BlkSize, BCACHE_GROUP_ID_METABLK, nAbsBlkAdr, sizeof(WFSMetaDataFlags), ppBce);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 BCacheDumpPinCount ( void );
|
||||||
|
u32 BCacheSkipCheckPin ();
|
||||||
|
WFSKrnResult BCacheStopSkipCheckPin( u32 initialPinCount );
|
||||||
|
|
||||||
|
#if _DEBUG_WFSKRN_BCACHE_
|
||||||
|
#define dbgb(_s) (_s)
|
||||||
|
#else
|
||||||
|
#define dbgb(_s)
|
||||||
|
#endif // _DEBUG_WFSKRN_BCACHE_
|
||||||
|
|
||||||
|
#endif // _wfskrn_BCache_h_
|
||||||
@ -0,0 +1,193 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_BitField.h - functions for manipulating bitfields within bit arrays
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_BitField.h,v $
|
||||||
|
Revision 1.1 2008/04/22 04:39:07 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/05 03:09:45 paul
|
||||||
|
Added WfsSetBitField, WfsTestAndSetBitField
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/27 11:39:44 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_BitField_h
|
||||||
|
#define wfskrn_BitField_h
|
||||||
|
|
||||||
|
#ifndef max
|
||||||
|
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef min
|
||||||
|
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BITFIELD_USE_TEMPLATES 0
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
u32 WfsCalculateFieldSizeInBytes(u32 nVal);
|
||||||
|
u8 WfsCalculateFieldSizeInBits(u32 nVal);
|
||||||
|
|
||||||
|
#if BITFIELD_USE_TEMPLATES
|
||||||
|
template<int nNumBits> unsigned WfsReadBitField (unsigned *aBitArray, int nStartBit);
|
||||||
|
#endif
|
||||||
|
unsigned WfsReadBitField(unsigned *aBitArray, int nStartBit, int nNumBits);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// aBitArray is an array of machine sized unsigned int which are interpreted as a bit array.
|
||||||
|
// (The first bit of the array is the most significant bit of aBitArray[0])
|
||||||
|
// nStartBit is the bit offset in the bit array to start reading from.
|
||||||
|
// Pre Conditions: 1 <= nNumBits <= BITS_PER_INT
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// Returns a machine sized unsigned int whose least significant nNumBits are the extracted bit field.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function reads a bitfield of width nNumBits from a bit array.
|
||||||
|
// NOTE: It is up to the caller to mask off the least significant nNumBits bits of the return value
|
||||||
|
// if necessary, using a mask such as ((1<<nNumBits)-1).
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#if BITFIELD_USE_TEMPLATES
|
||||||
|
template<unsigned nNumBits> void WfsOverwriteBitField(unsigned *aBitArray, int nStartBit, unsigned nValue);
|
||||||
|
#endif
|
||||||
|
void WfsOverwriteBitField(unsigned *aBitArray, int nStartBit, unsigned nValue, int nNumBits, unsigned nMask);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// aBitArray is an array of machine sized words which are interpreted as a bit array.
|
||||||
|
// (The first bit of the array is the most significant bit of aBitArray[0])
|
||||||
|
// nValue is the value to write.
|
||||||
|
// nNumBits is the bit width of nValue.
|
||||||
|
// nStartBit is the bit offset in the bit array to start writing to.
|
||||||
|
// Pre Conditions: 1 <= nNumBits <= BITS_PER_INT; 0 < nValue < (1<<nNumBits)
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function overwrites a bitfield of width nNumBits in a bit array.
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void WfsSetBitField(unsigned *aBitArray, int nStartBit, int nNumBits);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// aBitArray is an array of machine sized words which are interpreted as a bit array.
|
||||||
|
// nStartBit is the first bit offset within the bit array to set.
|
||||||
|
// nNumBits is the number of bits to set.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function sets (makes equal to 1) a atring of bits from nStartBit to (nStartBit + nNumBits - 1) inclusive.
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
unsigned WfsTestAndSetBitField(unsigned *aBitArray, int nStartBit, int nNumBits);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// aBitArray is an array of machine sized words which are interpreted as a bit array.
|
||||||
|
// nStartBit is the first bit offset within the bit array to set.
|
||||||
|
// nNumBits is the number of bits to set.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function sets (makes equal to 1) a atring of bits from nStartBit to (nStartBit + nNumBits - 1) inclusive.
|
||||||
|
// It returns a non-zero value if any of the bits covered by the string were already set, and 0 otherwise.
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void WfsBitArrayInsertGap(unsigned *aBitArray, int nBitArrayLength, int nGapStartBit, int nNumGapBits);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// aBitArray is an array of machine sized words which are interpreted as a bit array.
|
||||||
|
// nBitArrayLength is the length of the array in bits.
|
||||||
|
// nGapStartBit is the bit offset within the bit array to insert the gap.
|
||||||
|
// nNumGapBits is the number of gap bits to insert.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function inserts a gap into a bit array.
|
||||||
|
// The string of bits from nGapStartBit to nEndBit are shifted nNumGapBits bits to the right,
|
||||||
|
// leaving a gap which is filled with 0s.
|
||||||
|
// NOTE: nNumGapBits can be larger than BITS_PER_INT.
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void WfsBitArrayDeleteBitField(unsigned *aBitArray, int nBitArrayLength, int nBitPos, int nNumBits);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// aBitArray is an array of machine sized words which are interpreted as a bit array.
|
||||||
|
// (The first bit of the array is the most significant bit of aBitArray[0])
|
||||||
|
// nBitArrayLength is the length of the array in bits.
|
||||||
|
// nBitPos is the bit offset within the bit array to start deleting from.
|
||||||
|
// nValue is the value to insert.
|
||||||
|
// nNumBits is the number of bits to delete.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function deletes a bitfield of width nNumBits from a bit array.
|
||||||
|
// The string of bits from nBitPos to nBitArrayLength are shifted nNumBits bits to the left,
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void WfsBitArrayInsertBitField(unsigned *aBitArray, int nBitArrayLength, int nInsertBit, int nNumBits, unsigned nValue);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// aBitArray is an array of machine sized words which are interpreted as a bit array.
|
||||||
|
// (The first bit of the array is the most significant bit of aBitArray[0])
|
||||||
|
// nBitArrayLength is the length of the array in bits.
|
||||||
|
// nInsertBit is the bit offset within the bit array to insert to.
|
||||||
|
// nValue is the value to insert.
|
||||||
|
// nNumBits is the bit width of nValue.
|
||||||
|
// Pre Conditions: 1 <= nNumBits <= BITS_PER_INT; 0 < nValue < (1<<nNumBits)
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function inserts a bitfield of width nNumBits into a bit array.
|
||||||
|
// The string of bits from nInsertBit to nBitArrayLength are shifted nNumBits bits to the right,
|
||||||
|
// and nValue is inserted in the resulting gap.
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void WfsBitFieldCopy(unsigned *aDstBitArray, int nDstOffset, unsigned *aSrcBitArray, int nSrcOffset, int nCopyLength);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// aDstBitArray is the destination bit array.
|
||||||
|
// nDstOffset is the bit offset within the destination bit array
|
||||||
|
// aSrcBitArray is the source bit array.
|
||||||
|
// nSrcOffset is the bit offset within the source bit array
|
||||||
|
// nCopyLength is the number of bits to copy
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function copies nCopyLength bits from a specified offset within a source bit array to a specified offset
|
||||||
|
// within a destination bit array.
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void WfsTestBitFieldModule();
|
||||||
|
|
||||||
|
#endif //wfskrn_BitField_h
|
||||||
@ -0,0 +1,167 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Config.h - kernel configuration settings governing resource allocations etc.
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Config.h,v $
|
||||||
|
Revision 1.18 2008/12/03 00:03:46 kondo_masahiro
|
||||||
|
Added WFS_MAX_USER_BLK_CACHE_SIZE and WFS_MIN_USER_BLK_CACHE_SIZE
|
||||||
|
|
||||||
|
Revision 1.17 2008/11/05 15:05:11 ueno
|
||||||
|
Reduced WFSKRN_BCACHE_HASH_TABLE_SIZE from 2957 to 47.
|
||||||
|
|
||||||
|
Revision 1.16 2008/11/04 06:11:07 ueno
|
||||||
|
Reduced WFS heap size to 8KB.
|
||||||
|
Changed the maximum number of file handles and search handles to 32.
|
||||||
|
|
||||||
|
Revision 1.15 2008/10/21 09:50:09 kondo_masahiro
|
||||||
|
Added new function WFSWriteFileAndDiscard
|
||||||
|
|
||||||
|
Revision 1.14 2008/10/17 08:51:27 kondo_masahiro
|
||||||
|
Added the new MEDIUM size category (40KB-320KB)
|
||||||
|
|
||||||
|
Revision 1.13 2008/10/08 23:20:09 kondo_masahiro
|
||||||
|
Added codes to access large size file data
|
||||||
|
|
||||||
|
Revision 1.12 2008/10/03 08:37:18 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP
|
||||||
|
|
||||||
|
Revision 1.11 2008/09/28 23:30:18 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.10 2008/08/27 23:45:02 paul
|
||||||
|
Changed name from WFS_LOG2_HASH_BLK_SIZE to WFS_LOG2_MAX_HASHABLE_BLK_SIZE
|
||||||
|
|
||||||
|
Revision 1.9 2008/08/14 08:08:40 kondo_masahiro
|
||||||
|
Removed several definitions related on wfskrn_Device.
|
||||||
|
|
||||||
|
Revision 1.8 2008/08/05 04:17:25 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.7 2008/07/25 02:53:10 paul
|
||||||
|
added WFSKRN_MAX_ACTIVE_TRANSACTIONS
|
||||||
|
|
||||||
|
Revision 1.6 2008/07/17 22:19:50 paul
|
||||||
|
changed comment
|
||||||
|
|
||||||
|
Revision 1.5 2008/07/09 01:25:15 paul
|
||||||
|
Changes related to block cache memory.
|
||||||
|
|
||||||
|
Revision 1.4 2008/06/09 18:08:48 paul
|
||||||
|
Increased maximum number of open directory searches to reflect the maximum path depth x 2 devices. Made corresponding change to size of path cache.
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 17:28:26 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:07 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/26 01:08:45 wayne.wong
|
||||||
|
Moved BCache parameters to here.
|
||||||
|
|
||||||
|
Revision 1.8 2008/04/23 00:36:39 paul
|
||||||
|
added defines for file/directory search handles
|
||||||
|
|
||||||
|
Revision 1.7 2008/04/19 05:50:00 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/05 03:07:07 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/20 07:16:15 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
Revision 1.3 2007/12/27 11:38:32 paul
|
||||||
|
added various config settings
|
||||||
|
|
||||||
|
Revision 1.2 2007/11/16 05:45:54 paul
|
||||||
|
Added definitions for areas and regions
|
||||||
|
|
||||||
|
Revision 1.1 2007/11/05 19:03:13 paul
|
||||||
|
first checkin
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Config_h
|
||||||
|
#define wfskrn_Config_h
|
||||||
|
|
||||||
|
#include "wfscli_Handles.h"
|
||||||
|
#include "wfssrv_Defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define WFS_VERSION_MAJOR 1 // version of WFS (1..255)
|
||||||
|
#define WFS_VERSION_MINOR 0 // (0..255)
|
||||||
|
|
||||||
|
// Block size is not static - can be set within the following range per device / area
|
||||||
|
|
||||||
|
#define WFS_LOG2_SMALL_BLK_SIZE 13 // Log to the base 2 of the small block size. (13 would correspond to 8KB)
|
||||||
|
#define WFS_LOG2_MEDIUM_BLK_SIZE 16 // Log to the base 2 of the medium block size. (16 corresponds to 64KB)
|
||||||
|
#define WFS_LOG2_LARGE_BLK_SIZE 19 // Log to the base 2 of the large block size. (19 corresponds to 512KB)
|
||||||
|
|
||||||
|
#define WFS_LOG2_SMALL_BLKS_PER_REGION 12 // A region is a fixed size subdivision of an area, which is split into either all small blocks or all large blocks
|
||||||
|
#define WFS_MIN_REGIONS_PER_AREA 2 // one for small and one for large blks
|
||||||
|
#define WFS_LOG2_MIN_REGION_SIZE (WFS_LOG2_SMALL_BLK_SIZE+WFS_LOG2_SMALL_BLKS_PER_REGION) // log2(bytes)
|
||||||
|
#define WFS_MIN_REGION_SIZE (1<<(WFS_LOG2_SMALL_BLK_SIZE+WFS_LOG2_SMALL_BLKS_PER_REGION))
|
||||||
|
#define WFS_LOG2_MIN_AREA_SIZE (WFS_MIN_REGION_SIZE*WFS_MIN_REGIONS_PER_AREA) // in bytes
|
||||||
|
#define WFS_MIN_AREA_SIZE (1<<(WFS_LOG2_MIN_AREA_SIZE)) // in bytes
|
||||||
|
|
||||||
|
#define WFS_LOG2_MAX_CACHE_STORED_FILE_BLK_SIZE 13
|
||||||
|
|
||||||
|
#define WFS_LOG2_MAX_HASHABLE_BLK_SIZE WFS_LOG2_MEDIUM_BLK_SIZE
|
||||||
|
|
||||||
|
#define WFS_DIR_NODE_STACK_ENTRY_POOL_ALLOC_UNIT 16 // Number of DirNodeStack structs to add to the pool when it runs out. Also used as initial allocation quantity. (42*12B == 504B). DirNodeStack entries are linked together in stacks and used for traversing directories.
|
||||||
|
|
||||||
|
#define WFS_LOG2_MAX_FILE_SIZE 32 // 4GB
|
||||||
|
|
||||||
|
#define WFS_STATIC_HEAP_SIZE (8 * 1024)
|
||||||
|
|
||||||
|
//#define WFS_BLK_CACHE_SIZE (512 * 1024)
|
||||||
|
#define WFS_BLK_CACHE_SIZE (512 * 256)
|
||||||
|
#define WFS_BCACHE_META_DATA_SIZE ( 8 * 1024) // Cache 512[KB], Block 8[KB] -> Metadata 3840[B]
|
||||||
|
#define WFS_STATIC_MEM_ALIGNMENT 512
|
||||||
|
|
||||||
|
#define WFS_MAX_USER_BLK_CACHE_SIZE (512 * 1024)
|
||||||
|
#define WFS_MIN_USER_BLK_CACHE_SIZE (144 * 1024)
|
||||||
|
|
||||||
|
// Special in-memory area at the top of WFS to hold "/dev", "/vol" directories
|
||||||
|
#define WFS_LOG2_PATH_CACHE_SIZE 15
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#define WFS_LOG2_MAX_AREA_SIZE 29
|
||||||
|
#else
|
||||||
|
#define WFS_LOG2_MAX_AREA_SIZE 34 // Max area size of 16GB
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WFSKRN_MAX_ACTIVE_TRANSACTIONS 4
|
||||||
|
#define WFSKRN_MAX_DEVICES 1
|
||||||
|
#define WFSKRN_MAX_MOUNTED_VOLUMES 1
|
||||||
|
#define WFSKRN_MAX_NUM_AREA_SIZES 10 // at least 5 (64MB, 256MB, 1GB, 4GB, and 16GB)
|
||||||
|
#define WFSKRN_MIN_AREA_SIZE (2*WFS_MIN_REGION_SIZE) // 64MB = 32MB + 32MB
|
||||||
|
|
||||||
|
#define WFSKRN_FILE_HANDLE_IDX_BITS 5
|
||||||
|
#define WFSKRN_SEARCH_DIR_HANDLE_IDX_BITS 5
|
||||||
|
|
||||||
|
#define WFSKRN_FILE_BUFFER_MEM_ALIGNMENT_SIZE 32
|
||||||
|
|
||||||
|
// block cache parameters
|
||||||
|
#define WFSKRN_BCACHE_HASH_TABLE_SIZE 47 // use for 512KB w/ 8KB pages?
|
||||||
|
#define WFSKRN_BCACHE_HASH_FN(_key) (_key % WFSKRN_BCACHE_HASH_TABLE_SIZE)
|
||||||
|
#define WFSKRN_BCACHE_HASH_LIST(_key) (gHash[WFSKRN_BCACHE_HASH_FN(_key)])
|
||||||
|
|
||||||
|
// parameter for CATEGORY VERY LARGE
|
||||||
|
#define WFSKRN_VERY_LARGE_MAP_NUM_INDIRECT_BLKS 8
|
||||||
|
|
||||||
|
#define PERMISSION_ENABLED
|
||||||
|
#define PERM_TEST 1
|
||||||
|
|
||||||
|
#endif //wfskrn_Config_h
|
||||||
107
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Defs.h
Normal file
107
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Defs.h
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Defs.h - kernel definitions
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Defs.h,v $
|
||||||
|
Revision 1.5 2008/11/05 15:05:44 ueno
|
||||||
|
Fixed a bug of WFS_ROUND_DOWN().
|
||||||
|
|
||||||
|
Revision 1.4 2008/10/17 08:51:27 kondo_masahiro
|
||||||
|
Added the new MEDIUM size category (40KB-320KB)
|
||||||
|
|
||||||
|
Revision 1.3 2008/10/14 10:27:30 kondo_masahiro
|
||||||
|
Added #define _DEBUG_BREAK_POINT
|
||||||
|
|
||||||
|
Revision 1.2 2008/07/09 01:29:34 paul
|
||||||
|
Added some macros to convert C definition __DATE__ (object file compilation date) to an integer.
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:07 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/19 05:49:31 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2007/12/27 11:36:55 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
Revision 1.1 2007/11/05 19:03:13 paul
|
||||||
|
first checkin
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Defs_h
|
||||||
|
#define wfskrn_Defs_h
|
||||||
|
|
||||||
|
|
||||||
|
#define _WIN32_WINNT 0x500
|
||||||
|
|
||||||
|
#include "revolution/wfs.h"
|
||||||
|
#include "wfskrn_Platform.h"
|
||||||
|
#include "wfskrn_Config.h"
|
||||||
|
#include "wfskrn_Errors.h"
|
||||||
|
#include "wfskrn_Types.h"
|
||||||
|
|
||||||
|
#if !_IOP
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef true
|
||||||
|
#define true 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef false
|
||||||
|
#define false 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WFS_ROUND_UP(v,x) (((v)+(x)-1)&-((signed)x))
|
||||||
|
#define WFS_ROUND_DOWN(v,x) ((v)&-((signed)x))
|
||||||
|
|
||||||
|
#define WFS_NUM_BITS_REQUIRED(x) \
|
||||||
|
(((x)<3)?1:((x)<5)?2:((x)<9)?3:\
|
||||||
|
((x)<0x11)?4:((x)<0x21)?5:((x)<0x41)?6:((x)<0x81)?7:\
|
||||||
|
((x)<0x101)?8:((x)<0x201)?9:((x)<0x401)?10:((x)<0x801)?11:\
|
||||||
|
((x)<0x1001)?12:((x)<0x2001)?13:((x)<0x4001)?14:((x)<0x8001)?15:\
|
||||||
|
((x)<0x10001)?16:((x)<0x20001)?17:((x)<0x40001)?18:((x)<0x80001)?19:\
|
||||||
|
((x)<0x100001)?20:((x)<0x200001)?21:((x)<0x400001)?22:((x)<0x800001)?23:\
|
||||||
|
((x)<0x1000001)?24:((x)<0x2000001)?25:((x)<0x4000001)?26:((x)<0x8000001)?27:\
|
||||||
|
((x)<0x10000001)?28:((x)<0x20000001)?29:((x)<0x40000001)?30:((x)<0x80000001)?31:32)
|
||||||
|
|
||||||
|
#define BYTES2BITS(b) ((b)<<3)
|
||||||
|
|
||||||
|
#define BUILD_YEAR ((((__DATE__[7]-'0')*10+(__DATE__[8]-'0'))*10+(__DATE__[9]-'0'))*10+(__DATE__[10]-'0'))
|
||||||
|
#define BUILD_MONTH (__DATE__[2]=='n'?0:__DATE__[2]=='b'?1:__DATE__[2]=='r'?(__DATE__[0]=='M'?2:3):__DATE__[2]=='y'?4:__DATE__[2]=='n'?5:__DATE__[2]=='l'?6:__DATE__[2]=='g'?7:__DATE__[2]=='p'?8:__DATE__[2]=='t'?9:__DATE__[2]=='v'?10:11)
|
||||||
|
#define BUILD_DAY ((__DATE__[4]==' '?0:__DATE__[4]-'0')*10+(__DATE__[5]-'0'))
|
||||||
|
#define BUILD_DATE (((BUILD_YEAR-2000)*12+BUILD_MONTH)*31+BUILD_DAY)
|
||||||
|
|
||||||
|
#ifndef swap_typ
|
||||||
|
#define swap_typ(Typ,a,b) { Typ t=a; a=b; b=t; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#ifndef _ASSERT
|
||||||
|
#define _ASSERT(x) ASSERT(x)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#ifndef _ASSERT
|
||||||
|
#define _ASSERT(x)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_BREAK_POINT 1
|
||||||
|
#else
|
||||||
|
#define _DEBUG_BREAK_POINT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // wfskrn_Defs_h
|
||||||
@ -0,0 +1,232 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Device.h - Storage device abstraction.
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Device.h,v $
|
||||||
|
Revision 1.14 2008/12/10 06:54:02 kondo_masahiro
|
||||||
|
Added a argument WFSDevType nDevType in DeviceAttachDetachCallback.
|
||||||
|
|
||||||
|
Revision 1.13 2008/11/26 02:43:58 kondo_masahiro
|
||||||
|
Added comments of DeviceRead/Write.
|
||||||
|
|
||||||
|
Revision 1.12 2008/11/26 01:46:01 kondo_masahiro
|
||||||
|
Fixed arguments of several functions in order to improve access speed.
|
||||||
|
Fixed source code for Win32 version to enable easier debug.
|
||||||
|
|
||||||
|
Revision 1.11 2008/10/09 01:40:14 kondo_masahiro
|
||||||
|
Fixed name of the function DeviceRead/WriteSingleBlk
|
||||||
|
|
||||||
|
Revision 1.10 2008/10/08 23:20:09 kondo_masahiro
|
||||||
|
Added codes to access large size file data
|
||||||
|
|
||||||
|
Revision 1.9 2008/10/03 08:37:18 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP
|
||||||
|
|
||||||
|
Revision 1.8 2008/09/30 02:02:27 ueno
|
||||||
|
Removed an obsolete define, WFSKRN_SIMULATED_DISK_SIZE.
|
||||||
|
|
||||||
|
Revision 1.7 2008/09/28 23:30:24 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.6 2008/08/29 00:12:36 kondo_masahiro
|
||||||
|
Added DeviceGetVolumeId.
|
||||||
|
|
||||||
|
Revision 1.5 2008/08/14 08:20:14 kondo_masahiro
|
||||||
|
Changed WFSKRN_SIMULATED_DISK_PATH
|
||||||
|
|
||||||
|
Revision 1.4 2008/08/14 08:07:27 kondo_masahiro
|
||||||
|
Changed several APIs in order to access the large size file.
|
||||||
|
|
||||||
|
Revision 1.3 2008/08/05 04:17:29 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.2 2008/07/17 05:07:43 kondo_masahiro
|
||||||
|
Added codes for IOP
|
||||||
|
|
||||||
|
Revision 1.1 2008/07/09 01:39:12 paul
|
||||||
|
Merged device definitions from wfskrn_PMem.h and wfskrn_Api.h.
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _WFSKRN_DEVICE_H_
|
||||||
|
#define _WFSKRN_DEVICE_H_
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "revolution/wfs.h"
|
||||||
|
#include "wfs_Names.h"
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
#include "wfskrn_Config.h"
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#include "msc_error.h"
|
||||||
|
#elif _TWL
|
||||||
|
#include "msc_error.h"
|
||||||
|
#elif _IOP
|
||||||
|
#include "msc_includes.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEVICE_EMBEDDED_HASH_DATA 1 // If it is on, the hash data is embedded to the written data.
|
||||||
|
#define DEVICE_VERIFY_HASH_DATA 1 // If it is on, DeviceRead can outputs error when two hash data discord.
|
||||||
|
#define DEVICE_DEBUG_PSEUDO_DEVICE_ERROR 1
|
||||||
|
|
||||||
|
#define DEVICE_IOP_MAX_ASYNC_NUM 2
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#define IOSError s32
|
||||||
|
#define WFSKRN_SIMULATED_DISK_PATH "Y:\\TEMP\\shirait\\WFS_VOL_S\\"
|
||||||
|
typedef HANDLE DeviceHandle; // Windows handle
|
||||||
|
#elif _TWL
|
||||||
|
#define IOSError s32
|
||||||
|
typedef u32 DeviceHandle;
|
||||||
|
#elif _RVL
|
||||||
|
typedef u32 DeviceHandle;
|
||||||
|
#elif _IOP
|
||||||
|
#define DEVICE_IOP_MSC_CHECK(mscfunc) if(mscfunc < IOS_ERROR_OK){ return WFSKRN_RESULT_DEVICE_ERROR; }
|
||||||
|
typedef HardDisc* DeviceHandle;
|
||||||
|
#else
|
||||||
|
#endif //_WIN32
|
||||||
|
|
||||||
|
|
||||||
|
//#define _DEBUG_WFSKRN_DEVICE_
|
||||||
|
|
||||||
|
#ifdef _DEBUG_WFSKRN_DEVICE_
|
||||||
|
#define dbgd(_s) (_s)
|
||||||
|
#else
|
||||||
|
#define dbgd(_s)
|
||||||
|
#endif // _DEBUG_WFSKRN_DEVICE_
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct DeviceHdr_ {
|
||||||
|
u32 nLog2SectorSize; // 1st field: Base 2 logarithm of the sector size (default = 9 corresponding to 512 byte sectors)
|
||||||
|
u32 nNumSectors; // 2nd field; capacity of device
|
||||||
|
} DeviceHdr;
|
||||||
|
|
||||||
|
typedef struct DeviceInfo_ {
|
||||||
|
DeviceHdr dh;
|
||||||
|
#if _WIN32
|
||||||
|
HANDLE hSimulatedDeviceFile;
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
bool bInUse;
|
||||||
|
u32 nSectorSize;
|
||||||
|
u64 nTotalCapacity;
|
||||||
|
DeviceHandle nDeviceDevHandle;
|
||||||
|
struct VolumeInfo_ *pVolInfo;
|
||||||
|
WFSDeviceName devName;
|
||||||
|
WFSDevType nDevType;
|
||||||
|
u8 nFlags;
|
||||||
|
} DeviceInfo;
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize Device library
|
||||||
|
void DeviceInitLib();
|
||||||
|
|
||||||
|
#if _IOP
|
||||||
|
// Regist callback function for attach/detach device
|
||||||
|
typedef void (*DeviceAttachDetachCallback)(u32 bAttach, u32 nDevIdx, u32 nLog2SectorSize, u32 nTotalSize, WFSDevType nDevType, void *pUserData);
|
||||||
|
void DeviceAttachDetachRegistCallback(DeviceAttachDetachCallback cbAttach, void *pUserData);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WFSKrnResult DeviceRead(DeviceInfo *pDevInfo, u32 nSectorAdr, u8 *pBuffer, u32 nSectors, WFSHashCode *pHash, u32 nLog2HashSectors, u32 nOffsetHashBlks, s32 nHashStride, s32 nHashStridePerMaxLBlks);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pDevInfo [IN] .. A pointer of DeviceInfo.
|
||||||
|
// nSecrorAdr [IN] .. A head sector address of HDD to read.
|
||||||
|
// pBuffer [OUT] .. A pointer of read buffer.
|
||||||
|
// nSectors [IN] .. A read sector size of HDD.
|
||||||
|
// pHash [IN] .. A pointer to compare the hash value.
|
||||||
|
// nLog2HashSectors [IN] .. A sector size unit for hash value. The hash value is calculated for each the unit.
|
||||||
|
// nOffsetHashBlks [IN] .. A offset block size for nHashStridePerMaxLBlks.
|
||||||
|
// nHashStride [IN] .. A stride of hash address for each hash size unit.
|
||||||
|
// nHashStridePerMaxLBlks [IN] .. A stride of hash address for each 512KB unit.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// Read nSector from device pDevInfo starting at LBA nSectorAdr into buffer pBuffer.
|
||||||
|
// nLog2HashSector is the hash size unit. The argument nLog2HashSector must be indicate up to 64KB (~16).
|
||||||
|
// The hash value is calculated and compared with pHash for each buffer size nLog2HashSector.
|
||||||
|
// The hash address pHash is added by nHashStride for each buffer size nLog2HashSector.
|
||||||
|
// After total hash calculation size is reached to the multiples of 512KB,
|
||||||
|
// The hash address pHash is added by nHashStride and nHashStridePerMaxLBlks for "SIZE_CATEGORY_LARGE".
|
||||||
|
// For example, When nLog2HashSectors is 16(64KB) and nOffsetHashBlks is 3,
|
||||||
|
// The hash address up to 5th block are added by nHashStride. (512 / 64 - 3 = 5)
|
||||||
|
// The hash address of 6th block is added by nHashStride and nHashStridePerMaxLBlks.
|
||||||
|
|
||||||
|
static inline WFSKrnResult DeviceReadSingleBlk(DeviceInfo *pDevInfo, u32 nSectorAdr, u8 *pBuffer, u32 nSectors, WFSHashCode *pHash, u32 nLog2HashSectors){
|
||||||
|
dbgd(printf("DeviceRead()\n"));
|
||||||
|
ASSERT(nSectors <= 1<<(WFS_LOG2_MAX_HASHABLE_BLK_SIZE-pDevInfo->dh.nLog2SectorSize) ); // ~64KB
|
||||||
|
return DeviceRead(pDevInfo, nSectorAdr, pBuffer, nSectors, pHash, nLog2HashSectors, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult DeviceWrite(DeviceInfo *pDevInfo, u32 nSectorAdr, u8 *pBuffer, u32 nSectors, WFSHashCode *pHash, u32 nLog2HashSectors, u32 nOffsetHashBlks, s32 nHashStride, s32 nHashStridePerMaxLBlks, bool bDecryption);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pDevInfo [IN] .. A pointer of DeviceInfo.
|
||||||
|
// nSecrorAdr [IN] .. A head sector address of HDD to read.
|
||||||
|
// pBuffer [IN] .. A pointer of read buffer.
|
||||||
|
// nSectors [IN] .. A read sector size of HDD.
|
||||||
|
// pHash [OUT] .. A pointer to store the hash value.
|
||||||
|
// nLog2HashSectors [IN] .. A sector size unit for hash value. The hash value is calculated for each the unit.
|
||||||
|
// nOffsetHashBlks [IN] .. A offset block size for nHashStridePerMaxLBlks.
|
||||||
|
// nHashStride [IN] .. A stride of hash address for each hash size unit.
|
||||||
|
// nHashStridePerMaxLBlks [IN] .. A stride of hash address for each 512KB unit.
|
||||||
|
// bDecryption [IN] .. A flag to indicate whether buffer is decrypted after write access or not.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// Write nSector from device pDevInfo starting at LBA nSectorAdr into buffer pBuffer.
|
||||||
|
// nLog2HashSector is the hash size unit. The argument nLog2HashSector must be indicate up to 64KB (~16).
|
||||||
|
// The hash value is calculated and stored to pHash for each buffer size nLog2HashSector.
|
||||||
|
// The hash address pHash is added by nHashStride for each buffer size nLog2HashSector.
|
||||||
|
// After total hash calculation size is reached to the multiples of 512KB,
|
||||||
|
// The hash address pHash is added by nHashStride and nHashStridePerMaxLBlks for "SIZE_CATEGORY_LARGE".
|
||||||
|
// For example, When nLog2HashSectors is 16(64KB) and nOffsetHashBlks is 3,
|
||||||
|
// The hash address up to 5th block are added by nHashStride. (512 / 64 - 3 = 5)
|
||||||
|
// The hash address of 6th block is added by nHashStride and nHashStridePerMaxLBlks.
|
||||||
|
|
||||||
|
static inline WFSKrnResult DeviceWriteSingleBlk(DeviceInfo *pDevInfo, u32 nSectorAdr, u8 *pBuffer, u32 nSectors, WFSHashCode *pHash, u32 nLog2HashSectors, bool bDecryption){
|
||||||
|
dbgd(printf("DeviceWrite()\n"));
|
||||||
|
ASSERT(nSectors <= 1<<(WFS_LOG2_MAX_HASHABLE_BLK_SIZE-pDevInfo->dh.nLog2SectorSize) ); // ~64KB
|
||||||
|
return DeviceWrite(pDevInfo, nSectorAdr, pBuffer, nSectors, pHash, nLog2HashSectors, 0, 0, 0, bDecryption);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the device info from the device name (from the path cache)
|
||||||
|
DeviceInfo *DeviceGetDeviceInfo(const WFSDeviceName *pDevName);
|
||||||
|
|
||||||
|
// Get a volume id from the device name even if the device is not mounted.
|
||||||
|
WFSKrnResult DeviceGetVolumeId(const WFSDeviceName *pDevName, WFSVolumeId *pVolId);
|
||||||
|
|
||||||
|
// Mount a volume
|
||||||
|
WFSKrnResult DeviceMountVolume(DeviceInfo *pDevInfo);
|
||||||
|
|
||||||
|
// Attach a device - called when user physically attaches a drive
|
||||||
|
WFSKrnResult DeviceAttach(DeviceInfo *pDevInfo, WFSDevType nDevType, u32 nDevIdx, u32 Log2SectorSize, u32 nNumSectors);
|
||||||
|
|
||||||
|
// Detach a device - called when user physically detaches a drive
|
||||||
|
WFSKrnResult DeviceDetach(DeviceInfo *pDevInfo);
|
||||||
|
|
||||||
|
//// Debug functions
|
||||||
|
void DeviceDebugSetPseudoDetachDevice(s32 cnt);
|
||||||
|
void DeviceDebugSetPseudoHashInconsistent(s32 cnt);
|
||||||
|
s32 DeviceDebugGetPseudoDetachDevice();
|
||||||
|
s32 DeviceDebugGetPseudoHashInconsistent();
|
||||||
|
|
||||||
|
#if _WIN32 // * Windows version *
|
||||||
|
#define DeviceOverhead() (2*sizeof(u32)) // overhead for simulating a device
|
||||||
|
#else
|
||||||
|
#define DeviceOverhead() 0
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#endif // _WFSKRN_DEVICE_H_
|
||||||
800
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Dir.h
Normal file
800
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Dir.h
Normal file
@ -0,0 +1,800 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Dir.h - Directory Module
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Dir.h,v $
|
||||||
|
Revision 1.28 2008/12/04 00:42:37 ooizumi
|
||||||
|
Changed definition name to enable permission.
|
||||||
|
|
||||||
|
Revision 1.27 2008/11/19 05:02:53 ooizumi
|
||||||
|
Fixed typo.
|
||||||
|
|
||||||
|
Revision 1.26 2008/11/18 04:57:11 saito_tomoya
|
||||||
|
Modified SetBit() and added SetBitArray().
|
||||||
|
|
||||||
|
Revision 1.25 2008/11/07 08:55:16 kondo_masahiro
|
||||||
|
Added DirCalculateAttrSubBlkLog2SizeUpdateAllocSize()
|
||||||
|
|
||||||
|
Revision 1.24 2008/11/04 00:25:07 kondo_masahiro
|
||||||
|
Added DirSbaAllocAndRegistSubBlk()
|
||||||
|
|
||||||
|
Revision 1.23 2008/10/31 09:51:42 ueno
|
||||||
|
Modified WFSSrvAPIs to return WFSKRN_RESULT_RESOURCE_LIMIT_EXCEEDED when path cache is short of memory.
|
||||||
|
|
||||||
|
Revision 1.22 2008/10/30 05:09:05 kondo_masahiro
|
||||||
|
Added DirCheckDisk
|
||||||
|
|
||||||
|
Revision 1.21 2008/10/24 09:02:25 kondo_masahiro
|
||||||
|
Added decrease block process of DirResize.
|
||||||
|
|
||||||
|
Revision 1.20 2008/10/17 08:51:27 kondo_masahiro
|
||||||
|
Added the new MEDIUM size category (40KB-320KB)
|
||||||
|
|
||||||
|
Revision 1.19 2008/10/16 09:25:53 ooizumi
|
||||||
|
Fixed definitions for debug build.
|
||||||
|
|
||||||
|
Revision 1.18 2008/10/14 10:27:44 kondo_masahiro
|
||||||
|
Added codes to access very large size file data
|
||||||
|
|
||||||
|
Revision 1.17 2008/10/10 02:11:31 kondo_masahiro
|
||||||
|
Fixed a bug to access large files
|
||||||
|
|
||||||
|
Revision 1.16 2008/10/09 04:15:46 kondo_masahiro
|
||||||
|
Fixed member of AreaHdr and AreaInfo
|
||||||
|
|
||||||
|
Revision 1.15 2008/10/08 23:20:09 kondo_masahiro
|
||||||
|
Added codes to access large size file data
|
||||||
|
|
||||||
|
Revision 1.14 2008/10/07 10:30:34 ooizumi
|
||||||
|
Added nObjCreator to DirEntryAttrHdr.
|
||||||
|
|
||||||
|
Revision 1.13 2008/09/28 23:30:31 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.12 2008/08/27 09:49:46 paul
|
||||||
|
Started coding for different size categories
|
||||||
|
|
||||||
|
Revision 1.11 2008/08/05 04:17:43 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.10 2008/07/28 22:26:54 paul
|
||||||
|
Improved updateMap processing. Added DirGetBlk().
|
||||||
|
|
||||||
|
Revision 1.9 2008/07/25 02:56:12 paul
|
||||||
|
Changed nTransIdx to *pTransInfo. Changed WFSTransBlkAdr to TransBlkAdr
|
||||||
|
|
||||||
|
Revision 1.8 2008/07/21 22:50:42 paul
|
||||||
|
Changed name from DirItrPinBlkAndUpdatePtrs() -> DirItrPinBlkAndFixPtrs()
|
||||||
|
|
||||||
|
Revision 1.7 2008/07/17 22:23:52 paul
|
||||||
|
Changes for update counters
|
||||||
|
|
||||||
|
Revision 1.6 2008/07/09 01:33:13 paul
|
||||||
|
Added DirItrCloseNoUnpin alternative to DirItrClose to give the option of unpinning the cache block while closing an interator. Made other minor changes.
|
||||||
|
|
||||||
|
Revision 1.5 2008/06/09 18:15:30 paul
|
||||||
|
No longer storing the non-persistent state: number of open read/write handles per file, within file attributes - moved this info to path cache which is non-persistent.
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/12 19:20:28 paul
|
||||||
|
Added a list of open directory iterators.
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 17:28:21 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.14 2008/04/23 01:30:14 paul
|
||||||
|
Continued updating and documenting Dir API
|
||||||
|
|
||||||
|
Revision 1.13 2008/04/19 05:49:25 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.12 2008/04/18 00:09:02 paul
|
||||||
|
Changed interface to Dir functions
|
||||||
|
|
||||||
|
Revision 1.11 2008/04/15 18:35:38 paul
|
||||||
|
Changed definition of DirFind to take separate nMaxBlkDepth and nFlags parameters.
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/05 03:10:40 paul
|
||||||
|
Many changes for Delete and associated testing.
|
||||||
|
|
||||||
|
Revision 1.9 2008/03/07 01:38:35 paul
|
||||||
|
added DIR_PREFIX_SEARCH
|
||||||
|
|
||||||
|
Revision 1.8 2008/02/29 02:29:46 paul
|
||||||
|
Added Delete functions, fixed DirCreateAndInitNewBlk4 parameters
|
||||||
|
|
||||||
|
Revision 1.7 2008/02/28 06:32:42 kondo_masahiro
|
||||||
|
Fixed code to accept PPC compiler
|
||||||
|
|
||||||
|
Revision 1.5 2008/02/21 04:30:54 paul
|
||||||
|
reorganization
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/21 01:36:56 paul
|
||||||
|
moved DIR_MAX_BLK_DEPTH to header file
|
||||||
|
updated definition for DirFind
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/21 00:11:34 paul
|
||||||
|
Moved SubBlk allocation out of the dir module making it more generic. Now DirBlkHdr pseudo-inherits from WFSSubBlkAllocHdr, which in turn inherits from WFSMetaDataHdr
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/20 07:46:21 paul
|
||||||
|
Numerous changes
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/27 11:36:29 paul
|
||||||
|
still at an early stage of development
|
||||||
|
|
||||||
|
Revision 1.2 2007/11/08 05:29:16 paul
|
||||||
|
continued with block layout initialization code
|
||||||
|
|
||||||
|
Revision 1.1 2007/11/05 19:03:13 paul
|
||||||
|
first checkin
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Dir_h
|
||||||
|
#define wfskrn_Dir_h
|
||||||
|
|
||||||
|
#include "wfskrn_Config.h"
|
||||||
|
#include "wfskrn_SubBlkAlloc.h"
|
||||||
|
#include "wfskrn_Trans.h"
|
||||||
|
#include "wfskrn_PTree.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_DIR 1 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_DIR 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DIR_MAX_BLK_DEPTH 5
|
||||||
|
#define DIR_PREFIX_SEARCH ((u32)-2)
|
||||||
|
#define DIR_PREFIX_SUPPRESSION 0
|
||||||
|
|
||||||
|
#define DIR_SUB_BLK_TYPE_RADIX_NODE 0x00
|
||||||
|
#define DIR_SUB_BLK_TYPE_BLK_PTR 0x01
|
||||||
|
|
||||||
|
#define DIR_SPLIT_BLK_ADR 0
|
||||||
|
|
||||||
|
// Flags which are store in the same variable as: WFS_FLAG_IS_A_DIRECTORY, WFS_FLAG_CONTIGUOUS_AREA
|
||||||
|
#define FILE_SIZE_CATEGORY_VERY_SMALL 0 // Files which fit in the directory leaf block. (up to about 960 bytes - also depends on file name length)
|
||||||
|
#define FILE_SIZE_CATEGORY_SMALL 1 // Files where the attr block points to between 1 and 5 small blocks.
|
||||||
|
#define FILE_SIZE_CATEGORY_MEDIUM 2 // Files where the attr block points to between 1 and 5 medium blocks.
|
||||||
|
#define FILE_SIZE_CATEGORY_LARGE 3 // Files where the attr block points to between 1 and 12 large blocks.
|
||||||
|
#define FILE_SIZE_CATEGORY_VERY_LARGE 4 // Files where the attr block points to indirect blocks which point to large blocks.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
extern bool bCheckDirBlks;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
extern u32 nDirTest;
|
||||||
|
extern u32 nDirTestBreakPoint;
|
||||||
|
extern u32 nDirTotalTests;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSSubBlkAllocHdr sbah;
|
||||||
|
u16 nRootOfs;
|
||||||
|
u16 nNumRecs; // Number of records in the block, not the whole directory
|
||||||
|
} DirBlkHdr;
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
#define SIZE_OF_DIRSUBBLKHDR 3
|
||||||
|
typedef struct {
|
||||||
|
u8 nStrLen;
|
||||||
|
u8 nNumEntries;
|
||||||
|
utf8 aFirstChar[1];
|
||||||
|
} _ATTRIBUTE_PACKED DirSubBlkHdr;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
typedef struct DirNodeStack_ DirNodeStack;
|
||||||
|
struct DirNodeStack_ {
|
||||||
|
DirNodeStack *pParent;
|
||||||
|
WFSBlkAdr nBlkAdr;
|
||||||
|
u32 nUpdateCtr; // Compared against counter stored in dir blocks to determine whether the block has been changed since this iterator was last used.
|
||||||
|
u16 nSubBlkOfs;
|
||||||
|
u8 nEntryIdx;
|
||||||
|
u8 nStrIdx;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u16 *pOfs; // A pointer to the offset pointer to the node. This would need to be updated if the sub block is relocated.
|
||||||
|
DirSubBlkHdr *pSubBlkHdr; // A pointer to the sub block containing the node.
|
||||||
|
u32 nLog2Size; // The base 2 logarithm of the size of the sub block containing the node.
|
||||||
|
utf8 *pStrPtr; // A string pointer to the current cursor position within the search name. After DirFind(), it points to the first mismatch.
|
||||||
|
utf8 *pNodeStrPtr; // A string pointer to the current cursor position within the node string. After DirFind(), it points to the first mismatch.
|
||||||
|
u32 nEntryIdx; // The entry index of the choice within the current node which is closest but <= search name during DirFind().
|
||||||
|
DirNodeStack *pDns; // A stack of locators within dir node sub blks recording the path taken through the name radix tree
|
||||||
|
u32 nDnsDepth; // Number of entries in the DirNodeStack
|
||||||
|
} DirNodeItr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 nSize;
|
||||||
|
u16 nContentIdx;
|
||||||
|
u16 nVersion;
|
||||||
|
} DirFileAttr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSBlkAdr nQuota; // Quota in multiples of blocks
|
||||||
|
WFSBlkAdr nSubDirBlkAdr;
|
||||||
|
} DirDirAttr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 nAccessListIdx;
|
||||||
|
u32 nAllocSize;
|
||||||
|
WFSFileTime timeCreated;
|
||||||
|
WFSFileTime timeUpdated;
|
||||||
|
#ifdef PERMISSION_ENABLED
|
||||||
|
WFSTitleId nObjCreator;
|
||||||
|
#endif
|
||||||
|
union {
|
||||||
|
DirFileAttr file;
|
||||||
|
DirDirAttr dir;
|
||||||
|
};
|
||||||
|
u8 nAttrLog2Size; // Log to the base 2 of the file attributes sub-block
|
||||||
|
u8 nSizeCategory; // Size category of the file
|
||||||
|
u8 nNameLen; // Length of the file name
|
||||||
|
u8 aCaseBitArray[1]; // (variable size) A bit per character of the file name to indicate whether each character is upper or lower case
|
||||||
|
} DirEntryAttrHdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct DirItr_ *pNext;
|
||||||
|
struct DirItr_ *pPrev;
|
||||||
|
} DirItrLink;
|
||||||
|
|
||||||
|
typedef struct DirItr_ {
|
||||||
|
DirItrLink link;
|
||||||
|
u32 nBlkDepth; // The depth of the block currently pointed to by the iterator. Normally, set to 0 before calling DirFind* functions.
|
||||||
|
TransBlkAdr tba; // The block currently pointed to by the iterator. Normally, set to the root block of the directory before calling DirFind* functions.
|
||||||
|
DirEntryAttrHdr *pAttrHdr; // Pointer to the file/dir attributes of the current file.
|
||||||
|
DirBlkHdr *pBlkHdr; // Pointer to start of block tba.nBlkAdr in memory. (Start of the block is the block header).
|
||||||
|
u32 nUpdateCtr; // Update counter of the block referenced by tba.nBlkAdr
|
||||||
|
DirNodeItr dni;
|
||||||
|
DirNodeStack **ppDnsRootParent; // Pointer to the parent link within the root dir node stack entry - to allow for easy freeing of the whole dir node stack.
|
||||||
|
WFSFileName name; // Name of the current entry pointed to by the iterator.
|
||||||
|
} DirItr; // Directory Iterator
|
||||||
|
|
||||||
|
#define MAX_INDIRECT_FILE_DEPTH 3
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
//TransBlkAdr tba;
|
||||||
|
//u32 nPos;
|
||||||
|
u8 *pDataPtr;
|
||||||
|
u32 nRemainingBlkSize;
|
||||||
|
} DirFilePos;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
//TransBlkAdr tba;
|
||||||
|
//u32 nPos;
|
||||||
|
WFSFileBlkPtr *pFileBlkPtr;
|
||||||
|
u32 nRemainingBlkSize;
|
||||||
|
} DirFilePosMedium;
|
||||||
|
|
||||||
|
WFSKrnResult DirFindFilePos(DirItr *pDi, WFSFileSize nPos, DirFilePos *pFpos, u32 nTransFlags);
|
||||||
|
WFSKrnResult DirResizeFile(DirItr *pDi, WFSFileSize nNewSize);
|
||||||
|
|
||||||
|
// ToDo: Now that a WFSFileName member has been added to DirItr, I should check for performance problems
|
||||||
|
// introduced by indiscriminate copies of DirItr structs. Some Dir functions which define a local WFSFileName
|
||||||
|
// could possibly use the storage space within the DirItr instead (eDirLeafBlkSplit, DirNodeBlkSplit).
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
utf8 aToLower[256];
|
||||||
|
utf8 aToUpper[256];
|
||||||
|
DirItrLink openDirItrListAnchor;
|
||||||
|
DirItr *pOpenDirItrListAnchor;
|
||||||
|
PTreeHdr updateMap; // Maps from nBlkAdr to nUpdateCtr for directory blocks which are referenced by currently open directory iterators
|
||||||
|
PTreeAllocator updateMapAllocator;
|
||||||
|
} DirGlobals;
|
||||||
|
|
||||||
|
extern DirGlobals dirGlobals;
|
||||||
|
|
||||||
|
u32 DirLeafGetSubBlkLog2Size_2(u32 nStrLen, u32 nNumEntries);
|
||||||
|
u32 DirNodeGetSubBlkLog2Size_3(u32 nStrLen, u32 nNumEntries, utf8 cFirstChoice);
|
||||||
|
u32 DirCalculateAttrSubBlkLog2Size(AreaInfo *pAreaInfo, u32 nAllocSize, u32 nNameLen, u8 *pSizeCategory);
|
||||||
|
u32 DirCalculateAttrSubBlkLog2SizeDecrease(AreaInfo *pAreaInfo, u32 nAllocSize, u32 nNameLen, u8 *pSizeCategory);
|
||||||
|
u32 DirCalculateAttrSubBlkLog2SizeUpdateAllocSize(AreaInfo *pAreaInfo, u32 *pAllocSize, u32 nNameLen, u8 *pSizeCategory);
|
||||||
|
u32 DirCalculateAttrSubBlkLog2SizeDecreaseUpdateAllocSize(AreaInfo *pAreaInfo, u32 *pAllocSize, u32 nNameLen, u8 *pSizeCategory);
|
||||||
|
|
||||||
|
void DirModuleInit();
|
||||||
|
|
||||||
|
void DirLeafCheckBlk(DirItr *pDi);
|
||||||
|
void DirNodeCheckBlk(DirItr *pDi);
|
||||||
|
void DirCheckBlk(DirItr *pDi);
|
||||||
|
|
||||||
|
#define DIR_CHECK_DISK_FOR_DIR_TREE 0
|
||||||
|
#define DIR_CHECK_DISK_FOR_ACL_TREE 1
|
||||||
|
WFSKrnResult DirCheckDisk(WFSBlkAdr rootBlkAdr, DirItr *pDi, WFSSrvFileHandle fh, u8* pBuffer, u32 bufferSize, u32 nFlag);
|
||||||
|
|
||||||
|
WFSKrnResult DirGetBlk(DirItr *pDi, u32 nTransFlags, DirBlkHdr **ppBlkHdr);
|
||||||
|
|
||||||
|
WFSKrnResult DirCreateAndInitNewBlk4(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, WFSMetaDataFlags nFlags, TransInfo *pTransInfo, DirBlkHdr **ppBlkHdr);
|
||||||
|
//WFSKrnResult DirCreateAndInitNewBlk(TransBlkAdr *pTba, WFSMetaDataFlags nFlags, DirBlkHdr **ppBlkHdr);
|
||||||
|
void DirBlkCreateRootNode(DirBlkHdr *pBlkHdr);
|
||||||
|
|
||||||
|
WFSKrnResult DirReGetHashAdr(AreaInfo *pAreaInfo, DirEntryAttrHdr *pAttrHdr, WFSBlkAdr nNewBlkAdr, DirBlkHdr* pNewBlkHdr);
|
||||||
|
|
||||||
|
WFSKrnResult DirSbaAllocAndRegistSubBlk(WFSFileName *pName, DirItr *pDi, u32 nLog2Size, DirEntryAttrHdr **ppNewAttrHdr);
|
||||||
|
|
||||||
|
WFSKrnResult DirFindNameWithoutCaseConversion(DirItr *pDi);
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirFindName(WFSFileName *pName, DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pName [IN/OUT] .. A pointer to a WFSFileName struct containing the utf8 name to search for.
|
||||||
|
// pDi [OUT] .. A pointer to a DirItr struct which will be updated with the search location.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The name was found. *pDi is overwritten with the contents of the directory iterator.
|
||||||
|
// WFSKRN_RESULT_NOT_FOUND .. The specified name was not found.
|
||||||
|
// Other error codes are possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function searches for a specific name in the directory, and if a match is found, returns the location of the
|
||||||
|
// file or sub-directory attributes for the associated entry.
|
||||||
|
// NOTE: Some parts of the directory iterator structure are allocated dynamically, and must be freed
|
||||||
|
// by calling DirItrClose() when pDi is no longer needed.
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirFindRaw(DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pDi [IN/OUT] .. A pointer to DirItr struct which will be updated with the details of the location.
|
||||||
|
// pDi->name contains a raw input name to search for (will not be case-converted)
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The name was found. *ppAttr is overwritten with the contents of the associated attributes block.
|
||||||
|
// WFSKRN_RESULT_NOT_FOUND .. The specified name was not found.
|
||||||
|
// Other error codes are possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function searches for a specific raw name in the directory, and if a match is found, returns the location of the
|
||||||
|
// attributes for the associated entry.
|
||||||
|
// NOTE: This function is provided to support Access-lists, and should not be used for normal directories.
|
||||||
|
// Some parts of the directory iterator structure are allocated dynamically, and must be freed
|
||||||
|
// by calling DirItrClose() when pDi is no longer needed.
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirFindFirstNamePrefixMatch(WFSFileName *pName, DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pName [IN/OUT] .. A pointer to a WFSFileName struct containing the prefix of the utf8 name to search for.
|
||||||
|
// pDi [OUT] .. A pointer to a directory iterator struct which stores information about the file location.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The first name which starts with the prefix was found. *pDi contains the location of the file/dir attributes block.
|
||||||
|
// WFSKRN_RESULT_NOT_FOUND .. No name was found which starts with the specified prefix.
|
||||||
|
// Other error codes are possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function searches the directory for a name which starts with a specified prefix. If one or more matching names exsit,
|
||||||
|
// this function returns the location of the first match, and the corresponding entry attributes data in *pDi.
|
||||||
|
// pDi can be passed to DirFindNext() to find the next entry in the directory.
|
||||||
|
// NOTE: Some parts of the directory iterator structure are allocated dynamically, and must be freed
|
||||||
|
// by calling DirItrClose() when pDi is no longer needed.
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirNextName(WFSFileName *pName, DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pName [OUT] .. A pointer to a WFSFileName struct containing the file name to search for.
|
||||||
|
// pDi [IN/OUT] .. A pointer to a directory iterator struct which stores information about the file location.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. A next entry was found. *pName and *pDi were updated.
|
||||||
|
// WFSKRN_RESULT_NOT_FOUND .. No further entries were found.
|
||||||
|
// Other error codes are possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function increments the directory iterator to the next entry (in lexicographical order)
|
||||||
|
// The name of the next entry is returned in *pName. The directory location including file attributes is returned in *pDi.
|
||||||
|
// NOTE: Some parts of the directory iterator structure are allocated dynamically, and must be freed
|
||||||
|
// by calling DirItrClose() when pDi is no longer needed.
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirNextRaw(WFSFileName *pName, DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pName [OUT] .. A pointer to a WFSFileName struct containing the file name to search for.
|
||||||
|
// pDi [IN/OUT] .. A pointer to a directory iterator struct which stores information about the file location.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. A next entry was found. *pName and *pDi were updated.
|
||||||
|
// WFSKRN_RESULT_NOT_FOUND .. No further entries were found.
|
||||||
|
// Other error codes are possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function increments the directory iterator to the next entry (in lexicographical order)
|
||||||
|
// The name of the next entry is returned in *pName. The directory location including file attributes is returned in *pDi.
|
||||||
|
// NOTE: Some parts of the directory iterator structure are allocated dynamically, and must be freed
|
||||||
|
// by calling DirItrClose() when pDi is no longer needed.
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirItrClose(DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pDi [IN] .. A pointer to a directory iterator struct.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The directory iterator was successfully closed.
|
||||||
|
// Other error codes may be possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function closes the directory iterator and frees up dynamically allocated resources.
|
||||||
|
// Includes unpinning the currently referenced block
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirItrCloseNoUnpin(DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pDi [IN] .. A pointer to a directory iterator struct.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The directory iterator was successfully closed.
|
||||||
|
// Other error codes may be possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function closes the directory iterator and frees up dynamically allocated resources.
|
||||||
|
// Does not include unpinning the currently referenced block
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirInsertName(WFSFileName *pName, DirItr *pDi, u32 nAllocSize);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pName [IN] .. A pointer to a WFSFileName struct containing a utf-8 name string to insert.
|
||||||
|
// pDi [OUT] .. A pointer to a directory iterator struct which represents the location within the directory.
|
||||||
|
// nAllocSize [IN] .. The initial size of the file. When creating sub-directories, use nAllocSize = 0.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The name was inserted successfully.
|
||||||
|
// WFSKRN_RESULT_ALREADY_EXISTS .. A conflicting name already exists in the directory.
|
||||||
|
// Other error codes may be possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function inserts a utf-8 name into the directory. The case information for each character is stored, but is ingored
|
||||||
|
// when comparing with existing names, so the name will conflict with an existing name which differs only in capitalization.
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirInsertRaw(WFSFileName *pName, DirItr *pDi, u32 nAllocSize);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pName [IN] .. A pointer to a WFSFileName struct containing a raw name to insert. (The name can use any 8-bit characters but must be 0 terminated).
|
||||||
|
// pDi [OUT] .. A pointer to a directory iterator struct.
|
||||||
|
// nAllocSize [IN] .. The initial size of the file.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The name was inserted successfully.
|
||||||
|
// WFSKRN_RESULT_ALREADY_EXISTS .. The same name already exists in the directory.
|
||||||
|
// Other error codes may be possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function inserts a raw string into the directory. No case manipulations are performed,
|
||||||
|
// so the comparison with existing names is case-sensitive.
|
||||||
|
// NOTE: This function is provided to support Access-lists, and should not be used for normal directories.
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirDeleteEntry(DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pDi [OUT] .. A pointer to a directory iterator struct which is pointing to a particular entry.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The entry name and its associated attribute data was deleted successfully from the directory.
|
||||||
|
// Other error codes may be possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function deletes an entry from a directory. This includes deleting the attribute data for the file or sub-directory,
|
||||||
|
// but does not include deleting separate data blocks or meta-data blocks associated with the file or sub-directory.
|
||||||
|
// One of the DirFind* functions should be used to
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirDeleteFile(DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pDi [IN] .. A pointer to a directory iterator struct which is pointing to a particular entry.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The file was deleted successfully.
|
||||||
|
// Other error codes may be possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function deletes the data blocks and meta-data blocks associated with a file entry, but does not delete
|
||||||
|
// the entry itself from its parent directory.
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirDeleteSubDir(DirItr *pDi);
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pDi [IN] .. A pointer to a directory iterator struct which is pointing to a particular entry.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. The sub directory was deleted successfully.
|
||||||
|
// WFSKRN_RESULT_NOT_EMPTY .. The sub directory is not empty, and was not deleted.
|
||||||
|
// Other error codes may be possible - passed back from lower level functions
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function deletes the root block associated with a sub-directory entry, but does not delete
|
||||||
|
// the entry itself from its parent directory.
|
||||||
|
|
||||||
|
|
||||||
|
void DirInitDirEntryAttrHdr(DirEntryAttrHdr *pAttrHdr);
|
||||||
|
void DirInitFileEntryAttrHdr(DirEntryAttrHdr *pAttrHdr);
|
||||||
|
WFSKrnResult DirItrPinBlkAndFixPtrs(DirItr *pDi, u32 nTransFlags);
|
||||||
|
WFSKrnResult DirItrMapBlks(DirItr *pDi);
|
||||||
|
void DirItrUnmapBlks(DirItr *pDi);
|
||||||
|
WFSKrnResult DirItrCheckMapBlks(DirItr *pDi);
|
||||||
|
WFSKrnResult DirItrCheckAndUnmapBlks(DirItr *pDi);
|
||||||
|
|
||||||
|
void WFSKrnCopyFileName(WFSFileName *pDst, WFSFileName *pSrc);
|
||||||
|
void WFSKrnCopyStrAndConvertToLowerCase(utf8 *pDstStr, const utf8 *pSrcStr, u32 nLen);
|
||||||
|
void WFSKrnCopyFileNameAndConvertToLowerCase(WFSFileName *pDst, WFSFileName *pSrc);
|
||||||
|
void WFSKrnCopyFileNameAndRestoreCase(utf8 *pDst, WFSFileName *pSrc, u8 *pCaseBitArray);
|
||||||
|
WFSKrnResult WFSKrnValidateCopyStrAndConvertToLowerCase(utf8 *pDstStr, const utf8 *pSrcStr, u32 nLen, u32 nMaxLen);
|
||||||
|
|
||||||
|
void WFSKrnStoreCaseInformationStr(u8 *pCaseBitArray, const utf8 *pStr, u32 nLen);
|
||||||
|
|
||||||
|
static inline WFSKrnResult DirCreateAndInitNewBlk(TransBlkAdr *pTba, WFSMetaDataFlags nFlags, DirBlkHdr **ppBlkHdr) {
|
||||||
|
return DirCreateAndInitNewBlk4(pTba->pAreaInfo, pTba->nBlkAdr, nFlags, pTba->pTransInfo, ppBlkHdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void WFSKrnStoreCaseInformation(u8 *pCaseBitArray, WFSFileName *pName) {
|
||||||
|
WFSKrnStoreCaseInformationStr(pCaseBitArray, pName->sStr, pName->nLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inline Functions for FILE_SIZE_CATEGORY_SMALL // 1 block = 8KB (small block size)
|
||||||
|
static inline WFSFileBlkPtr *WFSKrnGetFileBlkPtrForCategorySmall(DirEntryAttrHdr *pAttrHdr, u32 nAttrLog2Size, u32 nBlkIdx){
|
||||||
|
return (WFSFileBlkPtr *)((size_t)pAttrHdr + (1<<nAttrLog2Size) - ((1 + nBlkIdx) * sizeof(WFSFileBlkPtr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSFileBlkInfo WFSKrnGetFileBlkInfoForCategorySmall(AreaInfo *pAreaInfo, DirEntryAttrHdr *pAttrHdr, u32 nAttrLog2Size, u32 nBlkIdx){
|
||||||
|
WFSFileBlkPtr *pFileBlkPtr = WFSKrnGetFileBlkPtrForCategorySmall(pAttrHdr, nAttrLog2Size, nBlkIdx);
|
||||||
|
WFSFileBlkInfo fileBlkInfo;
|
||||||
|
fileBlkInfo.nBlkAdr = pFileBlkPtr->nBlkAdr;
|
||||||
|
fileBlkInfo.pHash = &pFileBlkPtr->hash;
|
||||||
|
return fileBlkInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSFileBlkInfo WFSKrnGetFileBlkInfoForCategorySmallCast(AreaInfo *pAreaInfo, void *pMetaData, u32 nLog2MetaSize, u32 nBlkIdx){
|
||||||
|
return WFSKrnGetFileBlkInfoForCategorySmall(pAreaInfo, (DirEntryAttrHdr*)pMetaData, nLog2MetaSize, nBlkIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inline Functions for FILE_SIZE_CATEGORY_MEDIUM // 1 block = 64KB (small block size)
|
||||||
|
#define WFSKrnGetFileBlkPtrForCategoryMedium WFSKrnGetFileBlkPtrForCategorySmall
|
||||||
|
#define WFSKrnGetFileBlkInfoForCategoryMedium WFSKrnGetFileBlkInfoForCategorySmall
|
||||||
|
#define WFSKrnGetFileBlkInfoForCategoryMediumCast WFSKrnGetFileBlkInfoForCategorySmallCast
|
||||||
|
|
||||||
|
// Inline Functions for FILE_SIZE_CATEGORY_LARGE // Meddium Block Size = 64KB (Max hash size)
|
||||||
|
static inline WFSFileLargeBlkPtr *WFSKrnGetFileLargeBlkPtrForCategoryLarge(DirEntryAttrHdr *pAttrHdr, u32 nAttrLog2Size, u32 nLargeBlkIdx){
|
||||||
|
return (WFSFileLargeBlkPtr *)( (size_t)pAttrHdr + (1<<nAttrLog2Size) - ((1 + nLargeBlkIdx) * sizeof(WFSFileLargeBlkPtr)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSFileBlkInfo WFSKrnGetFileBlkInfoForCategoryLarge(AreaInfo *pAreaInfo, WFSFileLargeBlkPtr *pFileLargeBlkPtr, u32 nMedBlkIdx){
|
||||||
|
WFSFileBlkInfo fileBlkInfo;
|
||||||
|
fileBlkInfo.nBlkAdr = pFileLargeBlkPtr->nBlkAdr+(nMedBlkIdx<<pAreaInfo->nLog2BlksPerMediumBlk);
|
||||||
|
fileBlkInfo.pHash = &pFileLargeBlkPtr->aHash[nMedBlkIdx];
|
||||||
|
return fileBlkInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSFileBlkInfo WFSKrnGetFileBlkInfoForCategoryLarge4(AreaInfo *pAreaInfo, DirEntryAttrHdr *pAttrHdr, u32 nAttrLog2Size, u32 nMedBlkIdx){
|
||||||
|
return WFSKrnGetFileBlkInfoForCategoryLarge(pAreaInfo,
|
||||||
|
WFSKrnGetFileLargeBlkPtrForCategoryLarge(pAttrHdr,
|
||||||
|
nAttrLog2Size,
|
||||||
|
nMedBlkIdx>>pAreaInfo->nLog2MediumBlkPerLargeBlk),
|
||||||
|
nMedBlkIdx%(1<<pAreaInfo->nLog2MediumBlkPerLargeBlk));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSFileBlkInfo WFSKrnGetFileBlkInfoForCategoryLargeCast(AreaInfo *pAreaInfo, void *pMetaData, u32 nLog2MetaSize, u32 nMedBlkIdx){
|
||||||
|
return WFSKrnGetFileBlkInfoForCategoryLarge4(pAreaInfo, (DirEntryAttrHdr*)pMetaData, nLog2MetaSize, nMedBlkIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inline Functions for FILE_SIZE_CATEGORY_VERY_LARGE // Meddium Block Size = 64KB (Max hash size)
|
||||||
|
static inline WFSBlkAdr *WFSKrnGetBlkAdrPtrFromAttrHdrAndIndirectBlkIdxForCategoryVeryLarge(AreaInfo *pAreaInfo, DirEntryAttrHdr *pAttrHdr, u32 nAttrLog2Size, u32 nIndirectBlkIdx){
|
||||||
|
return (WFSBlkAdr*)( (size_t)pAttrHdr + (1<<nAttrLog2Size) - ((1 + nIndirectBlkIdx) * sizeof(WFSBlkAdr)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSBlkAdr *WFSKrnGetBlkAdrPtrFromAttrHdrAndLargeBlkIdxForCategoryVeryLarge(AreaInfo *pAreaInfo, DirEntryAttrHdr *pAttrHdr, u32 nAttrLog2Size, u32 nLargeBlkIdx){
|
||||||
|
u32 nIndirectBlkIdx = (nLargeBlkIdx)/pAreaInfo->nNumLargeBlkPtrsPerBlk;
|
||||||
|
return WFSKrnGetBlkAdrPtrFromAttrHdrAndIndirectBlkIdxForCategoryVeryLarge(pAreaInfo, pAttrHdr, nAttrLog2Size, nIndirectBlkIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSBlkAdr *WFSKrnGetBlkAdrPtrFromAttrHdrAndMedBlkIdxForCategoryVeryLarge(AreaInfo *pAreaInfo, DirEntryAttrHdr *pAttrHdr, u32 nAttrLog2Size, u32 nMedBlkIdx){
|
||||||
|
return WFSKrnGetBlkAdrPtrFromAttrHdrAndLargeBlkIdxForCategoryVeryLarge(pAreaInfo, pAttrHdr, nAttrLog2Size, nMedBlkIdx>>pAreaInfo->nLog2MediumBlkPerLargeBlk);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSFileLargeBlkPtr *WFSKrnGetFileLargeBlkPtrFromIndirectBlkForCategoryVeryLarge(u8 *pBlkPtr, u32 nLargeBlkIdx){
|
||||||
|
return (WFSFileLargeBlkPtr *)( (size_t)pBlkPtr + sizeof(WFSMetaDataHdr) + (nLargeBlkIdx * sizeof(WFSFileLargeBlkPtr)) );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSFileBlkInfo WFSKrnGetFileBlkInfoFromIndirectBlkForCategoryVeryLarge(AreaInfo *pAreaInfo, u8 *pBlkPtr, u32 nMedBlkIdx){
|
||||||
|
return WFSKrnGetFileBlkInfoForCategoryLarge(pAreaInfo,
|
||||||
|
WFSKrnGetFileLargeBlkPtrFromIndirectBlkForCategoryVeryLarge(pBlkPtr,
|
||||||
|
nMedBlkIdx>>pAreaInfo->nLog2MediumBlkPerLargeBlk),
|
||||||
|
nMedBlkIdx%(1<<pAreaInfo->nLog2MediumBlkPerLargeBlk));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSFileBlkInfo WFSKrnGetFileBlkInfoFromIndirectBlkForCategoryVeryLargeCast(AreaInfo *pAreaInfo, void *pMetaData, u32 nLog2MetaSize, u32 nMedBlkIdx){
|
||||||
|
return WFSKrnGetFileBlkInfoFromIndirectBlkForCategoryVeryLarge(pAreaInfo, (u8*)pMetaData, nMedBlkIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inline Functions for Dir Module
|
||||||
|
static inline u32 DirLeafGetSubBlkLog2Size(DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
return DirLeafGetSubBlkLog2Size_2(pSubBlkHdr->nStrLen, pSubBlkHdr->nNumEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 DirNodeGetSubBlkLog2Size(DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
return DirNodeGetSubBlkLog2Size_3(pSubBlkHdr->nStrLen, pSubBlkHdr->nNumEntries, pSubBlkHdr->aFirstChar[pSubBlkHdr->nStrLen]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16* DirNodeGetOfsTblStartPtr_ote(DirSubBlkHdr *pSubBlkHdr, u16 *pOfsTblEnd) {
|
||||||
|
if (pSubBlkHdr->aFirstChar[pSubBlkHdr->nStrLen] == 0) {
|
||||||
|
return &pOfsTblEnd[-(s32)pSubBlkHdr->nNumEntries-1];
|
||||||
|
} else {
|
||||||
|
return &pOfsTblEnd[-(s32)pSubBlkHdr->nNumEntries];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static inline u16* DirNodeGetOfsTblStartPtr_l2s(DirSubBlkHdr *pSubBlkHdr, u32 nLog2Size) {
|
||||||
|
u16 *pOfsTblEnd = (u16*)((u8*)pSubBlkHdr + (1<<nLog2Size));
|
||||||
|
return DirNodeGetOfsTblStartPtr_ote(pSubBlkHdr, pOfsTblEnd);
|
||||||
|
}
|
||||||
|
static inline u16* DirNodeGetOfsTblStartPtr(DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
u32 nLog2Size = DirNodeGetSubBlkLog2Size(pSubBlkHdr);
|
||||||
|
return DirNodeGetOfsTblStartPtr_l2s(pSubBlkHdr, nLog2Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16* DirNodeGetIntraBlkOfsPtr_ote(s32 nIdx, DirSubBlkHdr *pSubBlkHdr, u16 *pOfsTblEnd) {
|
||||||
|
#if DIR_SPLIT_BLK_ADR
|
||||||
|
return &pOfsTblEnd[-nIdx];
|
||||||
|
#else
|
||||||
|
if (pSubBlkHdr->aFirstChar[pSubBlkHdr->nStrLen] == 0) {
|
||||||
|
return &pOfsTblEnd[-nIdx-1];
|
||||||
|
} else {
|
||||||
|
return &pOfsTblEnd[-nIdx];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16* DirNodeGetIntraBlkOfsPtr_l2s(s32 nIdx, DirSubBlkHdr *pSubBlkHdr, u32 nLog2Size) {
|
||||||
|
u16 *pOfsTblEnd = (u16*)((u8*)pSubBlkHdr + (1<<nLog2Size));
|
||||||
|
return DirNodeGetIntraBlkOfsPtr_ote(nIdx, pSubBlkHdr, pOfsTblEnd);
|
||||||
|
}
|
||||||
|
static inline u16* DirNodeGetIntraBlkOfsPtr(s32 nIdx, DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
u32 nLog2Size = DirNodeGetSubBlkLog2Size(pSubBlkHdr);
|
||||||
|
return DirNodeGetIntraBlkOfsPtr_l2s(nIdx, pSubBlkHdr, nLog2Size);
|
||||||
|
}
|
||||||
|
static inline u16 DirNodeGetIntraBlkOfs_ote(s32 nIdx, DirSubBlkHdr *pSubBlkHdr, u16 *pOfsTblEnd) {
|
||||||
|
return *DirNodeGetIntraBlkOfsPtr_ote(nIdx, pSubBlkHdr, pOfsTblEnd);
|
||||||
|
}
|
||||||
|
static inline u16 DirNodeGetIntraBlkOfs_l2s(s32 nIdx, DirSubBlkHdr *pSubBlkHdr, u32 nLog2Size) {
|
||||||
|
return *DirNodeGetIntraBlkOfsPtr_l2s(nIdx, pSubBlkHdr, nLog2Size);
|
||||||
|
}
|
||||||
|
static inline u16 DirNodeGetIntraBlkOfs(s32 nIdx, DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
return *DirNodeGetIntraBlkOfsPtr(nIdx, pSubBlkHdr);
|
||||||
|
}
|
||||||
|
static inline void DirNodeSetIntraBlkOfs_ote(s32 nIdx, u16 nOfs, DirSubBlkHdr *pSubBlkHdr, u16 *pOfsTblEnd) {
|
||||||
|
*DirNodeGetIntraBlkOfsPtr_ote(nIdx, pSubBlkHdr, pOfsTblEnd) = nOfs;
|
||||||
|
}
|
||||||
|
static inline void DirNodeSetIntraBlkOfs_l2s(s32 nIdx, u16 nOfs, DirSubBlkHdr *pSubBlkHdr, u32 nLog2Size) {
|
||||||
|
*DirNodeGetIntraBlkOfsPtr_l2s(nIdx, pSubBlkHdr, nLog2Size) = nOfs;
|
||||||
|
}
|
||||||
|
static inline void DirNodeSetIntraBlkOfs(s32 nIdx, u16 nOfs, DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
*DirNodeGetIntraBlkOfsPtr(nIdx, pSubBlkHdr) = nOfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*inline WFSBlkAdr DirNodeGetBlkAdr_ote(DirSubBlkHdr *pSubBlkHdr, u16 *pOfsTblEnd) {
|
||||||
|
#if DIR_SPLIT_BLK_ADR
|
||||||
|
return (WFSBlkAdr)(pOfsTblEnd[-1] + (pOfsTblEnd[-(s32)pSubBlkHdr->nNumEntries-1]<<16));
|
||||||
|
#else
|
||||||
|
DirSubBlkHdr *psbh = pSubBlkHdr; // for warning
|
||||||
|
return ((WFSBlkAdr*)pOfsTblEnd)[-1];
|
||||||
|
#endif
|
||||||
|
}*/
|
||||||
|
#if DIR_SPLIT_BLK_ADR
|
||||||
|
#define DirNodeGetBlkAdr_ote(pSubBlkHdr, pOfsTblEnd) ((WFSBlkAdr)(pOfsTblEnd[-1] + (pOfsTblEnd[-(s32)pSubBlkHdr->nNumEntries-1]<<16)));
|
||||||
|
#else
|
||||||
|
#define DirNodeGetBlkAdr_ote(pSubBlkHdr, pOfsTblEnd) ((WFSBlkAdr*)pOfsTblEnd)[-1];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static inline WFSBlkAdr DirNodeGetBlkAdr_l2s(DirSubBlkHdr *pSubBlkHdr, u32 nLog2Size) {
|
||||||
|
u16 *pOfsTblEnd = (u16*)((u8*)pSubBlkHdr + (1<<nLog2Size));
|
||||||
|
return DirNodeGetBlkAdr_ote(pSubBlkHdr, pOfsTblEnd);
|
||||||
|
}
|
||||||
|
static inline WFSBlkAdr DirNodeGetBlkAdr(DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
u32 nLog2Size = DirNodeGetSubBlkLog2Size(pSubBlkHdr);
|
||||||
|
return DirNodeGetBlkAdr_l2s(pSubBlkHdr, nLog2Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*static inline void DirNodeSetBlkAdr_ote(WFSBlkAdr nBlkAdr, DirSubBlkHdr *pSubBlkHdr, u16 *pOfsTblEnd) {
|
||||||
|
#if DIR_SPLIT_BLK_ADR
|
||||||
|
pOfsTblEnd[-1] = (u16)nBlkAdr;
|
||||||
|
pOfsTblEnd[-(s32)pSubBlkHdr->nNumEntries-1] = (u16)(nBlkAdr>>16);
|
||||||
|
#else
|
||||||
|
DirSubBlkHdr *psbh = pSubBlkHdr; // for warning
|
||||||
|
((u32*)pOfsTblEnd)[-1] = nBlkAdr;
|
||||||
|
#endif
|
||||||
|
}*/
|
||||||
|
#if DIR_SPLIT_BLK_ADR
|
||||||
|
#define DirNodeSetBlkAdr_ote(nBlkAdr, pSubBlkHdr, pOfsTblEnd) { pOfsTblEnd[-1] = (u16)nBlkAdr; pOfsTblEnd[-(s32)pSubBlkHdr->nNumEntries-1] = (u16)(nBlkAdr>>16); }
|
||||||
|
#else
|
||||||
|
#define DirNodeSetBlkAdr_ote(nBlkAdr, pSubBlkHdr, pOfsTblEnd) ((u32*)pOfsTblEnd)[-1] = nBlkAdr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static inline void DirNodeSetBlkAdr_l2s(WFSBlkAdr nBlkAdr, DirSubBlkHdr *pSubBlkHdr, u32 nLog2Size) {
|
||||||
|
u16 *pOfsTblEnd = (u16*)((u8*)pSubBlkHdr + (1<<nLog2Size));
|
||||||
|
DirNodeSetBlkAdr_ote(nBlkAdr, pSubBlkHdr, pOfsTblEnd);
|
||||||
|
}
|
||||||
|
static inline void DirNodeSetBlkAdr(WFSBlkAdr nBlkAdr, DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
u32 nLog2Size = DirNodeGetSubBlkLog2Size(pSubBlkHdr);
|
||||||
|
DirNodeSetBlkAdr_l2s(nBlkAdr, pSubBlkHdr, nLog2Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16 *DirLeafGetIntraBlkOfsPtr_ote(s32 nIdx, u16 *pOfsTblEnd) {
|
||||||
|
return &pOfsTblEnd[-nIdx];
|
||||||
|
}
|
||||||
|
static inline u16* DirLeafGetIntraBlkOfsPtr_l2s(s32 nIdx, DirSubBlkHdr *pSubBlkHdr, u32 nLog2Size) {
|
||||||
|
u16 *pOfsTblEnd = (u16*)((u8*)pSubBlkHdr + (1<<nLog2Size));
|
||||||
|
return DirLeafGetIntraBlkOfsPtr_ote(nIdx, pOfsTblEnd);
|
||||||
|
}
|
||||||
|
static inline u16* DirLeafGetIntraBlkOfsPtr(s32 nIdx, DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
u32 nLog2Size = DirLeafGetSubBlkLog2Size(pSubBlkHdr);
|
||||||
|
return DirLeafGetIntraBlkOfsPtr_l2s(nIdx, pSubBlkHdr, nLog2Size);
|
||||||
|
}
|
||||||
|
static inline u16 DirLeafGetIntraBlkOfs_ote(s32 nIdx, u16 *pOfsTblEnd) {
|
||||||
|
return *DirLeafGetIntraBlkOfsPtr_ote(nIdx, pOfsTblEnd);
|
||||||
|
}
|
||||||
|
static inline u16 DirLeafGetIntraBlkOfs_l2s(s32 nIdx, DirSubBlkHdr *pSubBlkHdr, u32 nLog2Size) {
|
||||||
|
return *DirLeafGetIntraBlkOfsPtr_l2s(nIdx, pSubBlkHdr, nLog2Size);
|
||||||
|
}
|
||||||
|
static inline u16 DirLeafGetIntraBlkOfs(s32 nIdx, DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
return *DirLeafGetIntraBlkOfsPtr(nIdx, pSubBlkHdr);
|
||||||
|
}
|
||||||
|
static inline void DirLeafSetIntraBlkOfs_ote(s32 nIdx, u16 nOfs, u16 *pOfsTblEnd) {
|
||||||
|
*DirLeafGetIntraBlkOfsPtr_ote(nIdx, pOfsTblEnd) = nOfs;
|
||||||
|
}
|
||||||
|
static inline void DirLeafSetIntraBlkOfs_l2s(s32 nIdx, u16 nOfs, DirSubBlkHdr *pSubBlkHdr, u32 nLog2Size) {
|
||||||
|
*DirLeafGetIntraBlkOfsPtr_l2s(nIdx, pSubBlkHdr, nLog2Size) = nOfs;
|
||||||
|
}
|
||||||
|
static inline void DirLeafSetIntraBlkOfs(s32 nIdx, u16 nOfs, DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
*DirLeafGetIntraBlkOfsPtr(nIdx, pSubBlkHdr) = nOfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //define wfskrn_Dir_h
|
||||||
@ -0,0 +1,39 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_DirFind.h - Find functions for the Directory Module
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_DirFind.h,v $
|
||||||
|
Revision 1.3 2008/05/16 18:54:09 paul
|
||||||
|
Added DirFindNext()
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/24 23:21:18 kondo_masahiro
|
||||||
|
Initial check-in
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/23 00:34:38 paul
|
||||||
|
Split off from wfskrn_Dir.cpp
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_DirFind_h
|
||||||
|
#define wfskrn_DirFind_h
|
||||||
|
|
||||||
|
#define DIR_FIND_MODE_NORMAL 0
|
||||||
|
#define DIR_FIND_MODE_PREFIX_SEARCH 1
|
||||||
|
#define DIR_FIND_MODE_NODE_SEARCH 2
|
||||||
|
|
||||||
|
WFSKrnResult DirFind(WFSFileName *pName, DirItr *pDi, u32 nMaxBlkDepth, u32 nMode);
|
||||||
|
WFSKrnResult DirFindNext(WFSFileName *pName, DirItr *pDi);
|
||||||
|
|
||||||
|
#endif //define wfskrn_DirFind_h
|
||||||
@ -0,0 +1,77 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_DirNodeStack.h - Directory Module
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_DirNodeStack.h,v $
|
||||||
|
Revision 1.3 2008/10/16 09:25:53 ooizumi
|
||||||
|
Fixed definitions for debug build.
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/17 17:34:24 paul
|
||||||
|
Added some more debug functions
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/05 03:20:57 paul
|
||||||
|
_DEBUG -> _DEBUG_DIR
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/27 09:48:02 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_DirNodeStack_h
|
||||||
|
#define wfskrn_DirNodeStack_h
|
||||||
|
|
||||||
|
#include "wfskrn_Dir.h"
|
||||||
|
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
#define _DEBUG_DIR_NODE_STACK 1 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_DIR_NODE_STACK 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
void DebugCheckNumFreeDnsPoolEntries(char *str);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
extern bool bCheckDirNodeStack;
|
||||||
|
void DirNodeStackCheckFreeList();
|
||||||
|
WFSKrnResult _DirNodeStackGetEntry (char *sFile, u32 nLine, DirNodeItr *pDni);
|
||||||
|
WFSKrnResult _DirPushNodeStackEntry(char *sFile, u32 nLine, DirNodeItr *pDni, WFSBlkAdr nBlkAdr);
|
||||||
|
void _DirNodeStackFree (char *sFile, u32 nLine, DirNodeItr *pDni, DirNodeStack **ppParent);
|
||||||
|
void _DirPopNodeStackEntry (char *sFile, u32 nLine, DirNodeItr *pDni);
|
||||||
|
void _DirNodeStackCheckEmpty();
|
||||||
|
|
||||||
|
#define DirNodeStackGetEntry(pDni) _DirNodeStackGetEntry (_KRN_FILE_, __LINE__, pDni)
|
||||||
|
#define DirPushNodeStackEntry(pDni,nBlkAdr) _DirPushNodeStackEntry(_KRN_FILE_, __LINE__, pDni, nBlkAdr)
|
||||||
|
#define DirNodeStackFree(pDni,ppParent) _DirNodeStackFree (_KRN_FILE_, __LINE__, pDni, ppParent)
|
||||||
|
#define DirPopNodeStackEntry(pDni) _DirPopNodeStackEntry (_KRN_FILE_, __LINE__, pDni)
|
||||||
|
#define DirNodeStackCheckEmpty _DirNodeStackCheckEmpty();
|
||||||
|
#else
|
||||||
|
WFSKrnResult DirNodeStackGetEntry (DirNodeItr *pDni);
|
||||||
|
WFSKrnResult DirPushNodeStackEntry(DirNodeItr *pDni, WFSBlkAdr nBlkAdr);
|
||||||
|
void DirNodeStackFree(DirNodeItr *pDni, DirNodeStack **ppParent);
|
||||||
|
void DirPopNodeStackEntry(DirNodeItr *pDni);
|
||||||
|
#define DirNodeStackCheckEmpty
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WFSKrnResult DirAllocateMoreNodeStackEntries();
|
||||||
|
|
||||||
|
void DirConstructEntryNameFromNodeStack(WFSFileName *pKey, DirItr *pDi);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //wfskrn_DirNodeStack_h
|
||||||
@ -0,0 +1,145 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_DirRxTree.h - Find functions for the Directory Module
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_DirRxTree.h,v $
|
||||||
|
Revision 1.4 2008/07/30 21:21:08 paul
|
||||||
|
Changed the default value of _CHECK_RXT to 0 to improve the speed of the stress test
|
||||||
|
|
||||||
|
Revision 1.3 2008/07/21 22:49:55 paul
|
||||||
|
Added callback to RxtCheck()
|
||||||
|
|
||||||
|
Revision 1.2 2008/06/09 18:06:12 paul
|
||||||
|
Rewrote DirRxTree to support PathCache. New version includes parent pointers in each node.
|
||||||
|
|
||||||
|
Revision 1.1 2008/05/10 04:00:23 kondo_masahiro
|
||||||
|
Initial check-in
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_DirRxTree_h
|
||||||
|
#define wfskrn_DirRxTree_h
|
||||||
|
|
||||||
|
#include "wfskrn_Bitfield.h"
|
||||||
|
#include "wfskrn_Dir.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define RXT_LOG2_RESERVE_SIZE 9
|
||||||
|
#define RXT_MIN_LOG2_NODE_SIZE 4
|
||||||
|
#define RXT_MAX_LOG2_SIZE 16
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
#define _CHECK_RXT 0 // Set to 1 to enable radix tree and path cache check. However, it makes the test program run a lot slower
|
||||||
|
#else
|
||||||
|
#define _CHECK_RXT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct {
|
||||||
|
u8 nLog2Size; // The value n such that 2^n is the size of the node
|
||||||
|
u8 nEntryIdx; // The index of the entry in the parent block which points to this node
|
||||||
|
u16 nParentOfs; // The offset to the parent of this node
|
||||||
|
u16 nStrLen; // The length of the prefix string of this node
|
||||||
|
u8 nNumEntries; // The number of entries in this node
|
||||||
|
utf8 aFirstChar[1]; // The first character of the variable-size part of the node: format is prefix string followed by choice characters
|
||||||
|
// The table of u16 offsets to child nodes are stored in reverse order starting from the end of the node
|
||||||
|
} RxtNodeHdr;
|
||||||
|
//} _ATTRIBUTE_PACKED RxtNodeHdr;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u16 *pOfs; // A pointer to the offset pointer to the node. This would need to be updated if the sub block is relocated.
|
||||||
|
RxtNodeHdr *pNodeHdr; // A pointer to the sub block containing the node.
|
||||||
|
utf8 *pStrPtr; // A string pointer to the current cursor position within the search name. After RxtFind(), it points to the first mismatch.
|
||||||
|
utf8 *pNodeStrPtr; // A string pointer to the current cursor position within the node string. After RxtFind(), it points to the first mismatch.
|
||||||
|
s32 nEntryIdx; // The entry index of the choice within the current node which is closest but <= search name after RxtFind().
|
||||||
|
u32 nDepth; // Current depth of iterator
|
||||||
|
} RxtItr;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSSubBlkAllocHdr sbah;
|
||||||
|
u16 nRootOfs;
|
||||||
|
u16 nReserveOfs; // Offset to a sub-block which can be used to guarantee Delete will always succeed
|
||||||
|
u16 nNumRecs; // Number of records in the block, not the whole directory
|
||||||
|
} RxtHdr;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 nLog2Size;
|
||||||
|
u8 nEntryIdx;
|
||||||
|
u16 nParentOfs;
|
||||||
|
} RxtAttrHdr;
|
||||||
|
|
||||||
|
WFSBool DirBinarySplitSearchChoices(utf8 *aSortedArray, u32 nNumEntries, utf8 cSearchChar, u32 *pEntryIdx);
|
||||||
|
|
||||||
|
void RxtInit (RxtHdr *pRxtHdr, u32 nLog2Size);
|
||||||
|
WFSKrnResult RxtFind (RxtHdr *pRxtHdr, RxtItr *pRxi, u32 nStrLen);
|
||||||
|
WFSKrnResult RxtFindNext(RxtHdr *pRxtHdr, RxtItr *pRxi, utf8 cSeparator);
|
||||||
|
WFSKrnResult RxtInsert (RxtHdr *pRxtHdr, RxtItr *pRxi, u32 nSuffixLen, RxtAttrHdr *pAttrHdr);
|
||||||
|
WFSKrnResult RxtDeleteNode(RxtHdr *pRxtHdr, RxtItr *pRxi, u32 nEntryIdx, u32 nNodeOfs, RxtNodeHdr *pNodeHdr);
|
||||||
|
WFSKrnResult RxtDelete (RxtHdr *pRxtHdr, RxtItr *pRxi);
|
||||||
|
WFSKrnResult RxtNext (RxtHdr *pRxtHdr, RxtItr *pRxi);
|
||||||
|
WFSKrnResult RxtNextUntilSeparator(RxtHdr *pRxtHdr, RxtItr *pRxi, utf8 cSeparator);
|
||||||
|
|
||||||
|
void RxtGetString(RxtHdr *pRxtHdr, RxtNodeHdr *pNodeHdr, utf8 *sStr, u32 nStrLen);
|
||||||
|
|
||||||
|
|
||||||
|
#if _CHECK_RXT
|
||||||
|
typedef void (*RxtCheckEntry)(u32 nRecIdx, u32 nDepth, utf8 *sPath, void *pPtr);
|
||||||
|
void RxtCheck(RxtHdr *pRxtHdr, u32 nTotalSize, RxtCheckEntry cbCheckEntry);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void RxtTest();
|
||||||
|
|
||||||
|
// Inline Function Definitions
|
||||||
|
static inline u32 RxtGetNodeLog2Size_2(u32 nStrLen, u32 nNumEntries) {
|
||||||
|
//u32 nNumBytesRequired = (u32)&((RxtNodeHdr*)0)->aFirstChar + nStrLen + (nNumEntries*3);
|
||||||
|
u32 nNumBytesRequired = sizeof(RxtNodeHdr)-1 + nStrLen + (nNumEntries*3);
|
||||||
|
u32 nLog2Size = WfsCalculateFieldSizeInBits(nNumBytesRequired-1);
|
||||||
|
if (nLog2Size < SBA_MIN_LOG2_SUB_BLK_SIZE) {
|
||||||
|
nLog2Size = SBA_MIN_LOG2_SUB_BLK_SIZE;
|
||||||
|
}
|
||||||
|
return nLog2Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u32 RxtGetNodeLog2Size(RxtNodeHdr *pNodeHdr) {
|
||||||
|
return RxtGetNodeLog2Size_2(pNodeHdr->nStrLen, pNodeHdr->nNumEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16 *RxtGetChildOfsPtr_ote(s32 nIdx, u16 *pOfsTblEnd) {
|
||||||
|
return &pOfsTblEnd[-nIdx];
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16* RxtGetChildOfsPtr(s32 nIdx, RxtNodeHdr *pNodeHdr) {
|
||||||
|
u16 *pOfsTblEnd = (u16*)((u8*)pNodeHdr + (1<<pNodeHdr->nLog2Size));
|
||||||
|
return RxtGetChildOfsPtr_ote(nIdx, pOfsTblEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16 RxtGetChildOfs_ote(s32 nIdx, u16 *pOfsTblEnd) {
|
||||||
|
return *RxtGetChildOfsPtr_ote(nIdx, pOfsTblEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline u16 RxtGetChildOfs(s32 nIdx, RxtNodeHdr *pNodeHdr) {
|
||||||
|
return *RxtGetChildOfsPtr(nIdx, pNodeHdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void RxtSetChildOfs_ote(s32 nIdx, u16 nOfs, u16 *pOfsTblEnd) {
|
||||||
|
*RxtGetChildOfsPtr_ote(nIdx, pOfsTblEnd) = nOfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void RxtSetChildOfs(s32 nIdx, u16 nOfs, RxtNodeHdr *pNodeHdr) {
|
||||||
|
*RxtGetChildOfsPtr(nIdx, pNodeHdr) = nOfs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //define wfskrn_DirRxTree_h
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_EPTree.h
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_EPTree.h,v $
|
||||||
|
Revision 1.4 2008/12/17 05:08:17 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.3 2008/12/15 02:40:27 ueno
|
||||||
|
Added support for multi p-tree.
|
||||||
|
|
||||||
|
Revision 1.1 2008/12/02 04:55:39 ueno
|
||||||
|
Added EPTree to support multi-PTree.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFSKRN_EPTREE_H__
|
||||||
|
#define __WFSKRN_EPTREE_H__
|
||||||
|
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_FTree.h"
|
||||||
|
|
||||||
|
#define EPTREEHDR_OFFSET (BLOCK_SIZE - sizeof(EPTreeHdr))
|
||||||
|
#define GET_EPTREEHDR(pBlock) ((EPTreeHdr*) ((u8*) (pBlock) + EPTREEHDR_OFFSET))
|
||||||
|
#define GET_BLOCK_FROM_EPTREEHDR(eptreeHdr) ((u8*) (eptreeHdr) - EPTREEHDR_OFFSET)
|
||||||
|
|
||||||
|
#define EPTREE_GET_KEY(epti) ((epti)->nKey)
|
||||||
|
#define EPTREE_GET_DATA(epti) ((epti)->nData)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PTreeHdr ptreeHdr; // 8 bytes.
|
||||||
|
WFSBlkAdr addr;
|
||||||
|
u8 height; // height = 1, 2 ...
|
||||||
|
u8 padding[11];
|
||||||
|
SubBlockAllocatorHeader sbaHdr; // 8 bytes.
|
||||||
|
} EPTreeHdr; // sizeof(EPTreeHdr) must be 32 bytes. ( == sizeof(FTreeBlock));
|
||||||
|
|
||||||
|
typedef PTreeItr EPTreeItr;
|
||||||
|
|
||||||
|
#define EPTREE_MAX_HEIGHT 2
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
EPTreeHdr* eptreeHdr[EPTREE_MAX_HEIGHT]; // inherited FBATreeItr
|
||||||
|
EPTreeItr epti[EPTREE_MAX_HEIGHT]; // inherited FBATreeItr.
|
||||||
|
} MEPTreeItr;
|
||||||
|
|
||||||
|
EPTreeHdr* EPTreeBlockInit(AreaInfo* area, void* block, WFSBlkAdr addr, u32 offset, u8 height);
|
||||||
|
EPTreeItr* EPTreeGetLastIter(MEPTreeItr* iter);
|
||||||
|
WFSKrnResult EPTreeFind(AreaInfo* area, MEPTreeItr* iter, u32 nKey);
|
||||||
|
WFSKrnResult EPTreePrev(AreaInfo* area, MEPTreeItr* iter);
|
||||||
|
WFSKrnResult EPTreeNext(AreaInfo* area, MEPTreeItr* iter);
|
||||||
|
WFSKrnResult EPTreeFirst(AreaInfo* area, MEPTreeItr* iter);
|
||||||
|
WFSKrnResult EPTreeLast(AreaInfo* area, MEPTreeItr* iter);
|
||||||
|
WFSKrnResult EPTreeInsert(AreaInfo* area, MEPTreeItr* iter, u32 key, u32 data); // [check] can remove area?
|
||||||
|
WFSKrnResult EPTreeDelete(AreaInfo* area, MEPTreeItr* iter, u32 key, WFSBlkAdr* freeBlks);
|
||||||
|
WFSKrnResult EPTreeInit(AreaInfo* area, u32 offset);
|
||||||
|
|
||||||
|
#endif // __WFSKRN_EPTREE_H__
|
||||||
|
|
||||||
@ -0,0 +1,309 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Errors_h
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Errors.h,v $
|
||||||
|
Revision 1.19 2008/12/15 02:40:27 ueno
|
||||||
|
Added support for multi p-tree.
|
||||||
|
|
||||||
|
Revision 1.18 2008/11/07 08:54:35 kondo_masahiro
|
||||||
|
Added WFSKrnExit4/5OnError()
|
||||||
|
|
||||||
|
Revision 1.17 2008/10/30 05:08:19 kondo_masahiro
|
||||||
|
Added error for DirCheckDisk
|
||||||
|
|
||||||
|
Revision 1.16 2008/09/28 23:30:40 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.15 2008/08/27 10:03:58 paul
|
||||||
|
added WFSKRN_RESULT_BLK_CACHE_ALLOC_FAILED
|
||||||
|
|
||||||
|
Revision 1.14 2008/08/05 04:17:52 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.13 2008/07/17 22:25:49 paul
|
||||||
|
Added WFSKRN_RESULT_DIR_ITR_INVALID
|
||||||
|
Fixed value for WFSKRN_RESULT_FILE_OPEN
|
||||||
|
|
||||||
|
Revision 1.12 2008/07/17 05:11:44 kondo_masahiro
|
||||||
|
Added WFSKRN_RESULT_DEVICE_HASH_INCONSISTENT
|
||||||
|
|
||||||
|
Revision 1.11 2008/07/17 04:18:24 ueno
|
||||||
|
Added errors for freeblock allocator.
|
||||||
|
|
||||||
|
Revision 1.10 2008/07/11 18:05:17 paul
|
||||||
|
Updated to match latest wfsError.h
|
||||||
|
|
||||||
|
Revision 1.9 2008/07/09 01:35:43 paul
|
||||||
|
Changed some result code names, and added new result codes for PTree.
|
||||||
|
|
||||||
|
Revision 1.8 2008/06/10 20:13:04 kondo_masahiro
|
||||||
|
Added WFSKrnCommandCountBreak.
|
||||||
|
|
||||||
|
Revision 1.7 2008/06/09 18:05:48 paul
|
||||||
|
Added support for logging calls to WFSSrv functions.
|
||||||
|
Added new result codes.
|
||||||
|
|
||||||
|
Revision 1.6 2008/06/05 08:09:18 ueno
|
||||||
|
Revised permission APIs.
|
||||||
|
|
||||||
|
Revision 1.5 2008/05/28 01:06:13 ueno
|
||||||
|
Added error codes for AclCheckDisk().
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/12 19:21:31 paul
|
||||||
|
Added an error code.
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 12:07:44 nakanose_jin
|
||||||
|
add new errors
|
||||||
|
|
||||||
|
Revision 1.13 2008/04/26 01:13:53 wayne.wong
|
||||||
|
Moved area allocation functionality from Volume to Area module.
|
||||||
|
Changed error codes appropriately.
|
||||||
|
|
||||||
|
Revision 1.12 2008/04/25 04:35:29 nakanose_jin
|
||||||
|
add new errors
|
||||||
|
|
||||||
|
Revision 1.11 2008/04/22 23:01:43 paul
|
||||||
|
Added WFSKRN_RESULT_DEV_IN_USE to match wfsError.h. Added WFSKrnExitOnError
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/18 01:42:46 wayne.wong
|
||||||
|
Added some area-specific error codes.
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/15 07:40:11 ueno
|
||||||
|
Added error codes to WFSKrnResult for accesslist.
|
||||||
|
|
||||||
|
Revision 1.8 2008/03/19 07:35:48 wayne.wong
|
||||||
|
Added and fixed error codes.
|
||||||
|
|
||||||
|
Revision 1.7 2008/03/11 03:09:34 wayne.wong
|
||||||
|
Added some more BCache and Volume errors.
|
||||||
|
|
||||||
|
Revision 1.6 2008/02/28 06:32:36 kondo_masahiro
|
||||||
|
Fixed code to accept PPC compiler
|
||||||
|
|
||||||
|
Revision 1.5 2008/02/27 00:46:26 paul
|
||||||
|
Differentiated names of error functions
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/21 22:25:26 wayne.wong
|
||||||
|
Added errors for the modules BCache, PMem, Volume, and Transaction.
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/21 01:37:43 paul
|
||||||
|
split into wfskrn_Errors.h and wfskrn_Errors.cpp
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/20 07:47:52 paul
|
||||||
|
Updated error codes and added WFSKrnOutputError macro to output error code as a string
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/27 11:35:52 paul
|
||||||
|
internal error definitions
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Errors_h
|
||||||
|
#define wfskrn_Errors_h
|
||||||
|
|
||||||
|
#define WFSKrnReturnOnError(x) { WFSKrnResult nResult = x; if (nResult < WFSKRN_RESULT_OK) return nResult; }
|
||||||
|
#define WFSKrnExitOnError(x) { nResult = x; if (nResult < WFSKRN_RESULT_OK) goto Exit; }
|
||||||
|
#define WFSKrnExit1OnError(x) { nResult = x; if (nResult < WFSKRN_RESULT_OK) goto Exit1; }
|
||||||
|
#define WFSKrnExit2OnError(x) { nResult = x; if (nResult < WFSKRN_RESULT_OK) goto Exit2; }
|
||||||
|
#define WFSKrnExit3OnError(x) { nResult = x; if (nResult < WFSKRN_RESULT_OK) goto Exit3; }
|
||||||
|
#define WFSKrnExit4OnError(x) { nResult = x; if (nResult < WFSKRN_RESULT_OK) goto Exit4; }
|
||||||
|
#define WFSKrnExit5OnError(x) { nResult = x; if (nResult < WFSKRN_RESULT_OK) goto Exit5; }
|
||||||
|
|
||||||
|
#define WFSKrnReturnOnNullParameter(p) { if (p == NULL) return WFSKRN_RESULT_INVALID; }
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WFSKRN_RESULT_OK = 0, // Success
|
||||||
|
|
||||||
|
// Errors that can usually be detected early, and if detected, would result in the Async callback not being called:
|
||||||
|
WFSKRN_RESULT_BUSY = -1, // Too many requests, try waiting then calling again.
|
||||||
|
WFSKRN_RESULT_OUT_OF_MEMORY = -2, // The library does not have enough memory to complete the requested operation. (May be due to too many outstanding aysnc calls).
|
||||||
|
WFSKRN_RESULT_INVALID = -3, // The function parameters were invalid, e.g. File name is too long, Path is too long or too deep.
|
||||||
|
WFSKRN_RESULT_ACCESS = -4, // Trying to write to a file which was opened for read-only access, or vice versa.
|
||||||
|
WFSKRN_RESULT_LIB_NOT_INITIALIZED = -5, // The WFS library has not been initialized. Please call WFSInit() (This error is checked in functions that require the library to be initialized, but only in the debug versions).
|
||||||
|
WFSKRN_RESULT_LIB_ALREADY_INITIALIZED = -6, // The WFS library has already been initialized.
|
||||||
|
WFSKRN_RESULT_FILE_TOO_BIG = -7, // The current write/append request would push the file over the size limit.
|
||||||
|
WFSKRN_RESULT_NO_CHANGE_SIZE = -8, // The requested operation would cause the file size to change, but this file has WFS_PERM_NO_CHANGE_SIZE flag set.
|
||||||
|
|
||||||
|
// Errors that cannot usually be detected early, and would be passed via nResult to the Async callbacks:
|
||||||
|
WFSKRN_RESULT_MEDIA_ERROR = -9, // The device or media is not attached, or was removed before the requested operation could be completed.
|
||||||
|
WFSKRN_RESULT_DEV_UNUSABLE = -10, // Attached device is not accessible, e.g. because it is an unsupported device, or has an unknown format.
|
||||||
|
WFSKRN_RESULT_DEV_NOT_INITIALIZED = -11, // Device not formatted, or does not yet contain a WFS volume
|
||||||
|
WFSKRN_RESULT_DEV_IN_USE = -12, // Trying to initialize a device which is in use (mounted) by one or more clients.
|
||||||
|
WFSKRN_RESULT_VOL_ID_ERROR = -13, // Attempted to mount a volume with the same unique Id as an already mounted volume (This could happen if the User backs up an entire WFS volume using a PC)
|
||||||
|
WFSKRN_RESULT_WRITE_PROTECTED = -14, // Device is physically write protected (e.g. USB Flash memory, SD Card)
|
||||||
|
WFSKRN_RESULT_ALREADY_MOUNTED = -15, // The device is already mounted
|
||||||
|
|
||||||
|
WFSKRN_RESULT_PERMISSION = -16, // Permission flags do not permit the requested access from this application.
|
||||||
|
WFSKRN_RESULT_PERMISSION_CL = -17, // Permission error caused by control level problems.
|
||||||
|
WFSKRN_RESULT_ACL_FULL = -18, // The access list is full.
|
||||||
|
WFSKRN_RESULT_ACL_ENTRY_NOT_FOUND = -19, // The specified entry does not exist in the access list.
|
||||||
|
WFSKRN_RESULT_AUTHENTICATION = -20, // Trying to access content on a different Wii, which does not have the required access rights.
|
||||||
|
WFSKRN_RESULT_CORRUPTION = -21, // A corrupted block was encountered which prevented the operation from being completed.
|
||||||
|
|
||||||
|
WFSKRN_RESULT_DIRECTORY_QUOTA = -22, // One of the ancestor directories would exceed its quota.
|
||||||
|
|
||||||
|
WFSKRN_RESULT_MAX_HANDLES = -23, // The maximum number of concurrent file handles / search handles are already in use.
|
||||||
|
WFSKRN_RESULT_ALREADY_EXISTS = -24, // The file or directory being created already exists.
|
||||||
|
WFSKRN_RESULT_NOT_FOUND = -25, // The specified file or directory or device does not exist.
|
||||||
|
WFSKRN_RESULT_NOT_EMPTY = -26, // The specified directory cannot be deleted because it is not empty.
|
||||||
|
WFSKRN_RESULT_NOT_FILE = -27, // The specified path is directory instead of a file.
|
||||||
|
WFSKRN_RESULT_NOT_DIRECTORY = -28, // The specified path is a file instead of a directory
|
||||||
|
WFSKRN_RESULT_FILE_OPEN = -29, // The file is open. Cannot delete, move, rename, change permissions of an open file. Cannot open a file more than once unless all opens are WFS_ACCESS_READ.
|
||||||
|
WFSKRN_RESULT_LOCKED = -30, // Cannot perform the requested operation since the file or directory is locked by an existing operation.
|
||||||
|
WFSKRN_RESULT_RESOURCE_LIMIT_EXCEEDED = -31, // A resource limit prevents this function call. Try smaller values.
|
||||||
|
|
||||||
|
// Directory find results - these can be errors or expected depending on whether we are trying to access an existing file or trying to create a new one:
|
||||||
|
WFSKRN_RESULT_DIR_ENTRY_FOUND = -40, // The search string was matched and pointed to an entry
|
||||||
|
WFSKRN_RESULT_DIR_NODE_STRING_PREFIX = -41, // The search string ended early during comparison with a node sub string. (So this name is a prefix of existing names)
|
||||||
|
WFSKRN_RESULT_DIR_CHOICE_PREFIX = -42, // The search string ended at the end of a node sub string, but the node did not have a termination choice. (This name is a prefix of existing names)
|
||||||
|
WFSKRN_RESULT_DIR_NODE_STRING_MISMATCH = -43, // A mismatch was encountered while comparing the search string to a sub node prefix string.
|
||||||
|
WFSKRN_RESULT_DIR_NODE_CHOICE_NOT_FOUND = -44, // A mismatch was encountered while comparing a character of the search string with a set of choices for that character.
|
||||||
|
WFSKRN_RESULT_DIR_BLK_FULL = -45, // Unable to insert the specified string to the radix tree, due to lack of space in the block.
|
||||||
|
WFSKRN_RESULT_DIR_ITR_INVALID = -46, // One or more blocks referenced by the directory iterator and its node stack have been updated since the iterator was last used. DirFind must be called again.
|
||||||
|
|
||||||
|
// These result codes are not errors, but normal return values for the path cache functions
|
||||||
|
WFSKRN_RESULT_SRV_END_OF_PATH = -60, // Last part of path name parsed
|
||||||
|
WFSKRN_RESULT_SRV_PATH_DEPTH_1 = -61, // Path was of depth 1, such as "/something"
|
||||||
|
WFSKRN_RESULT_SRV_PATH_DEV = -62, // Path was "/dev"
|
||||||
|
WFSKRN_RESULT_SRV_PATH_VOL = -63, // Path was "/vol"
|
||||||
|
WFSKRN_RESULT_SRV_PATH_VOL_ROOT = -64, // Path was a volume root path, such as "/vol/xxxxxxx/"
|
||||||
|
|
||||||
|
WFSKRN_RESULT_PTREE_ENTRY_FOUND = -70,
|
||||||
|
WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND = -71,
|
||||||
|
WFSKRN_RESULT_PTREE_FULL = -72,
|
||||||
|
WFSKRN_RESULT_PTREE_EMPTY = -73,
|
||||||
|
|
||||||
|
WFSKRN_RESULT_DEVICE_ERROR = -80,
|
||||||
|
WFSKRN_RESULT_DEVICE_INVALID_PARAMETER = -81,
|
||||||
|
WFSKRN_RESULT_DEVICE_NOT_FOUND = -82,
|
||||||
|
WFSKRN_RESULT_DEVICE_HASH_INCONSISTENT = -83,
|
||||||
|
|
||||||
|
WFSKRN_RESULT_BLK_CACHE_ALLOC_FAILED = -90,
|
||||||
|
|
||||||
|
WFSKRN_RESULT_BCACHE_ERROR = -300, // unspecified error
|
||||||
|
WFSKRN_RESULT_BCACHE_RESOURCE_LIMIT = -301, // exhausted resources
|
||||||
|
WFSKRN_RESULT_BCACHE_INVALID_PARAMETER = -302, // at least one argument is invalid
|
||||||
|
WFSKRN_RESULT_BCACHE_NO_MEMORY = -303, // could not malloc
|
||||||
|
WFSKRN_RESULT_BCACHE_NOT_FOUND = -304, // sector is not cached
|
||||||
|
WFSKRN_RESULT_BCACHE_MAX_DEVICES = -305, // max devices alreay allocated
|
||||||
|
WFSKRN_RESULT_BCACHE_INVALID_DEVICE = -306, // device not found/open
|
||||||
|
WFSKRN_RESULT_BCACHE_INVALID_HANDLE = -307, // invalid device handle
|
||||||
|
WFSKRN_RESULT_BCACHE_INVALID_VOLUME = -308, // invalid volume ID (not mapped)
|
||||||
|
WFSKRN_RESULT_BCACHE_ALREADY_MAPPED = -309, // vol or devH already mapped
|
||||||
|
WFSKRN_RESULT_BCACHE_ALLOC = -310, // cannot alloc (no mem, or pmem error)
|
||||||
|
WFSKRN_RESULT_BCACHE_HASH_BLK_NOT_MAPPED = -311, // hash block isn't mapped on cache
|
||||||
|
|
||||||
|
WFSKRN_RESULT_VOLUME_ERROR = -400, // unspecified volume error
|
||||||
|
WFSKRN_RESULT_VOLUME_INVALID_PARAMETER = -401, // at least one argument is invalid
|
||||||
|
WFSKRN_RESULT_VOLUME_BCACHE_ALLOC = -402, // cannot allocate a page/block in memory
|
||||||
|
WFSKRN_RESULT_VOLUME_BCACHE_CONFIG = -403, // block cache not configured correctly
|
||||||
|
WFSKRN_RESULT_VOLUME_ID = -404, // bad volume ID or not initialized
|
||||||
|
WFSKRN_RESULT_VOLUME_CORRUPT_MR = -405, // the MR (or its free lists) are corrupted
|
||||||
|
WFSKRN_RESULT_VOLUME_AREA_ALLOC = -406, // area allocation cannot be satisfied
|
||||||
|
WFSKRN_RESULT_VOLUME_DEVICE_PARAMETER = -407, // parameters incompatible with device
|
||||||
|
WFSKRN_RESULT_VOLUME_NOT_MAPPED = -408, // volume is not mapped; invalid volume ID
|
||||||
|
|
||||||
|
WFSKRN_RESULT_TRANSACTION_ERROR = -500, // unspecified transaction error
|
||||||
|
WFSKRN_RESULT_TRANSACTION_INVALID_PARAMETER= -501,
|
||||||
|
|
||||||
|
WFSKRN_RESULT_ACL_ERROR = -600, // unspecified error
|
||||||
|
WFSKRN_RESULT_ACL_INVALID_PARAMETER = -601, // at least one argument is invalid
|
||||||
|
WFSKRN_RESULT_ACL_MAX_ENTRIES = -602, // max entries alreay in the accesslist.
|
||||||
|
WFSKRN_RESULT_ACL_BUFFER_TOO_SMALL = -603, // buffer is too small to store an accesslist.
|
||||||
|
WFSKRN_RESULT_ACL_CACHE = -610, // cannot allocate a cache.
|
||||||
|
WFSKRN_RESULT_ACL_FILE = -620, // cannot create, modify or delete the accesslist file.
|
||||||
|
WFSKRN_RESULT_ACL_ACLDIR_INCONSISTENT = -621, // accesslist files and indexlist are inconsistent.
|
||||||
|
WFSKRN_RESULT_ACL_FILENAME = -630, // cannot convert acl filename <=> acl content.
|
||||||
|
WFSKRN_RESULT_ACL_NAMEDIR_INCONSISTENT = -631, // access name files and indexlist are inconsistent.
|
||||||
|
WFSKRN_RESULT_ACL_HANDLE = -640, // cannot allocate an accesslist handle.
|
||||||
|
|
||||||
|
WFSKRN_RESULT_AREA_ERROR = -700, // unspecified area error
|
||||||
|
WFSKRN_RESULT_AREA_INVALID_PARAMETER = -701,
|
||||||
|
WFSKRN_RESULT_AREA_BCACHE_ALLOC = -702, // cannot allocate a page/block in memory
|
||||||
|
WFSKRN_RESULT_AREA_CORRUPT_HDR = -703, // the area header is corrupted
|
||||||
|
WFSKRN_RESULT_AREA_VOLUME_NOT_MAPPED = -704, // volume is not mapped; invalid volume ID
|
||||||
|
WFSKRN_RESULT_AREA_ALLOC = -705, // area allocation cannot be satisfied
|
||||||
|
|
||||||
|
WFSKRN_RESULT_FTREE_RETRY = -801, // retry insert.
|
||||||
|
WFSKRN_RESULT_FTREE_SPLIT = -802, // cannot split tree.
|
||||||
|
WFSKRN_RESULT_FTREE_EMPTY = -803, // no entry in the F-tree.
|
||||||
|
|
||||||
|
WFSKRN_RESULT_CHECKDISK_INCONSISTENT = -901, // bit arrays does not consistent between free block allocator and dir module.
|
||||||
|
WFSKRN_RESULT_CHECKDISK_INTERNAL_ERROR = -902, // bit arrays can not construct.
|
||||||
|
|
||||||
|
WFSKRN_RESULT_NOT_IMPLEMENTED = -1026, // The requested function has not yet been implemented //ToDo: This error should be removed from the final API
|
||||||
|
WFSKRN_RESULT_UNKNOWN = -1027, // Unexpected error - could be caused by a bug in the file system.
|
||||||
|
WFSKRN_RESULT_FATAL_ERROR = -1028 // May be caused by critical metadata corruption.
|
||||||
|
} WFSKrnResult;
|
||||||
|
|
||||||
|
#define WFSSetLastError(nErr) (wkg.nLastErr = (nErr))
|
||||||
|
|
||||||
|
const char *WFSKrnGetErrorString( WFSKrnResult nResult );
|
||||||
|
WFSKrnResult WFSKrnOutputErrorCode(WFSKrnResult nResult);
|
||||||
|
WFSKrnResult WFSKrnOutputErrorStr(const char *pStr);
|
||||||
|
void WFSKrnCommandCountBreak();
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
#define DBG_OUTPUT_TO_LOG_FILE 0
|
||||||
|
#define DBG_OUTPUT_TO_SCREEN 0
|
||||||
|
#define DBG_OUTPUT_PREFIX "%5d. "
|
||||||
|
extern u32 nDbgCommandCount;
|
||||||
|
extern u32 nDbgCommandOutputStart;
|
||||||
|
extern u32 nDbgCommandOutputEnd;
|
||||||
|
extern u32 nDbgCommandCountBreak;
|
||||||
|
#define WFSKrnDbgOutputTest(x) if ((nDbgCommandCount>=nDbgCommandOutputStart)&&(nDbgCommandCount<nDbgCommandOutputEnd)) { x; WFSKrnCommandCountBreak(); }
|
||||||
|
#else
|
||||||
|
#define WFSKrnDbgOutputTest(x)
|
||||||
|
#endif //_DEBUG
|
||||||
|
|
||||||
|
#if (DBG_OUTPUT_TO_LOG_FILE && _WIN32)
|
||||||
|
extern FILE *fpLog;
|
||||||
|
#define WFSKrnDbgOutputInit(fileName) fpLog = fopen(fileName, "w");
|
||||||
|
#define WFSKrnDbgOutputClose() fclose(fpLog);
|
||||||
|
#if DBG_OUTPUT_TO_SCREEN
|
||||||
|
#define WFSKrnDbgOutputCmdNum { fprintf(fpLog, DBG_OUTPUT_PREFIX"WFSSrv", nDbgCommandCount); MyOSReport(DBG_OUTPUT_PREFIX, nDbgCommandCount); }
|
||||||
|
#define WFSKrnDbgOutput1(fmt) { fprintf(fpLog, fmt); MyOSReport(fmt); }
|
||||||
|
#define WFSKrnDbgOutput2(fmt,a) { fprintf(fpLog, fmt, a); MyOSReport(fmt, a); }
|
||||||
|
#define WFSKrnDbgOutput3(fmt,a,b) { fprintf(fpLog, fmt, a,b); MyOSReport(fmt, a,b); }
|
||||||
|
#define WFSKrnDbgOutput4(fmt,a,b,c) { fprintf(fpLog, fmt, a,b,c); MyOSReport(fmt, a,b,c); }
|
||||||
|
#define WFSKrnDbgOutput5(fmt,a,b,c,d) { fprintf(fpLog, fmt, a,b,c,d); MyOSReport(fmt, a,b,c,d); }
|
||||||
|
#else //DBG_OUTPUT_TO_SCREEN
|
||||||
|
#define WFSKrnDbgOutputCmdNum fprintf(fpLog, DBG_OUTPUT_PREFIX"WFSSrv", nDbgCommandCount)
|
||||||
|
#define WFSKrnDbgOutput1(fmt) fprintf(fpLog, fmt);
|
||||||
|
#define WFSKrnDbgOutput2(fmt,a) fprintf(fpLog, fmt, a);
|
||||||
|
#define WFSKrnDbgOutput3(fmt,a,b) fprintf(fpLog, fmt, a,b);
|
||||||
|
#define WFSKrnDbgOutput4(fmt,a,b,c) fprintf(fpLog, fmt, a,b,c);
|
||||||
|
#define WFSKrnDbgOutput5(fmt,a,b,c,d) fprintf(fpLog, fmt, a,b,c,d);
|
||||||
|
#endif //DBG_OUTPUT_TO_SCREEN
|
||||||
|
#else //(DBG_OUTPUT_TO_LOG_FILE && _WIN32)
|
||||||
|
#define WFSKrnDbgOutputInit(fileName)
|
||||||
|
#define WFSKrnDbgOutputClose()
|
||||||
|
#if DBG_OUTPUT_TO_SCREEN
|
||||||
|
#define WFSKrnDbgOutputCmdNum MyOSReport(DBG_OUTPUT_PREFIX, nDbgCommandCount)
|
||||||
|
#define WFSKrnDbgOutput1(fmt) MyOSReport(fmt);
|
||||||
|
#define WFSKrnDbgOutput2(fmt,a) MyOSReport(fmt, a);
|
||||||
|
#define WFSKrnDbgOutput3(fmt,a,b) MyOSReport(fmt, a,b);
|
||||||
|
#define WFSKrnDbgOutput4(fmt,a,b,c) MyOSReport(fmt, a,b,c);
|
||||||
|
#define WFSKrnDbgOutput5(fmt,a,b,c,d) MyOSReport(fmt, a,b,c,d);
|
||||||
|
#else //DBG_OUTPUT_TO_SCREEN
|
||||||
|
#define WFSKrnDbgOutputCmdNum
|
||||||
|
#define WFSKrnDbgOutput1(fmt)
|
||||||
|
#define WFSKrnDbgOutput2(fmt,a)
|
||||||
|
#define WFSKrnDbgOutput3(fmt,a,b)
|
||||||
|
#define WFSKrnDbgOutput4(fmt,a,b,c)
|
||||||
|
#define WFSKrnDbgOutput5(fmt,a,b,c,d)
|
||||||
|
#endif //DBG_OUTPUT_TO_SCREEN
|
||||||
|
#endif //(DBG_OUTPUT_TO_LOG_FILE && _WIN32)
|
||||||
|
|
||||||
|
#endif //wfskrn_Errors_h
|
||||||
285
trunk/firmware/build/libraries/nfs/common/include/wfskrn_FTree.h
Normal file
285
trunk/firmware/build/libraries/nfs/common/include/wfskrn_FTree.h
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_FTree.h
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_FTree.h,v $
|
||||||
|
Revision 1.15 2008/12/18 05:09:43 ueno
|
||||||
|
Added "extern" for VC++.
|
||||||
|
|
||||||
|
Revision 1.14 2008/12/18 00:31:45 ueno
|
||||||
|
Moved FTreeBlkLog2Ofs{} for IOP.
|
||||||
|
|
||||||
|
Revision 1.13 2008/12/17 05:08:17 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.12 2008/12/02 00:32:23 ueno
|
||||||
|
Started implementing EPTree.
|
||||||
|
|
||||||
|
Revision 1.11 2008/10/30 04:33:12 ueno
|
||||||
|
Modified for release build.
|
||||||
|
|
||||||
|
Revision 1.10 2008/10/17 08:51:27 kondo_masahiro
|
||||||
|
Added the new MEDIUM size category (40KB-320KB)
|
||||||
|
|
||||||
|
Revision 1.9 2008/10/14 11:25:13 ueno
|
||||||
|
Disabled runtime check.
|
||||||
|
|
||||||
|
Revision 1.8 2008/09/29 10:19:25 ueno
|
||||||
|
Revised to support multi-B-tree-based allocator.
|
||||||
|
|
||||||
|
Revision 1.7 2008/09/02 07:01:05 kondo_masahiro
|
||||||
|
Fixed VerifyMemoryBlock -> VerifyMemoryBlockFTree
|
||||||
|
|
||||||
|
Revision 1.6 2008/08/09 03:34:29 ueno
|
||||||
|
Disabled runtime check.
|
||||||
|
|
||||||
|
Revision 1.5 2008/08/09 02:02:02 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.4 2008/08/08 13:27:22 ueno
|
||||||
|
Fixed BLOCK_SIZE.
|
||||||
|
|
||||||
|
Revision 1.3 2008/08/07 10:46:50 ueno
|
||||||
|
Modified for BTREE_BASED_ALLOCATOR (now debugging).
|
||||||
|
|
||||||
|
Revision 1.2 2008/08/02 11:52:10 ueno
|
||||||
|
Revised the positions of FTreeHdr{} and FBAPTreeHdr{} in 8KB-blocks to protect hash code.
|
||||||
|
|
||||||
|
Revision 1.1 2008/08/01 06:57:39 ueno
|
||||||
|
Initial Check-in.
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFSKRN_FTREE_H__
|
||||||
|
#define __WFSKRN_FTREE_H__
|
||||||
|
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#if BTREE_BASED_ALLOCATOR
|
||||||
|
|
||||||
|
#define MAX_SUB_TREE 7
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
#include "wfskrn_Api.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_Errors.h"
|
||||||
|
#include "wfskrn_PTree.h"
|
||||||
|
|
||||||
|
#define FTREE_LEAF_FAN_OUT 7
|
||||||
|
|
||||||
|
#define FTREE_LEAF_APPROPRIATE_NUM 5 // 70% of FTREE_LEAF_FAN_OUT
|
||||||
|
#define FTREE_NODE_APPROPRIATE_NUM 4 // 70% of PTREE_NODE_FAN_OUT
|
||||||
|
|
||||||
|
enum // treeType
|
||||||
|
{
|
||||||
|
FTREE_TYPE_A = 0,
|
||||||
|
FTREE_TYPE_B,
|
||||||
|
FTREE_TYPE_C,
|
||||||
|
FTREE_TYPE_D,
|
||||||
|
FTREE_TYPE_E,
|
||||||
|
FTREE_TYPE_F,
|
||||||
|
FTREE_TYPE_G,
|
||||||
|
FTREE_TYPE_END // this is not used.
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GET_SUBTREE(header, treeType) (&(header)->tree[(treeType)])
|
||||||
|
#define GET_SUBTREE_TYPE(header, fti) ((fti)->subTree - &(header)->tree[0])
|
||||||
|
|
||||||
|
typedef PTreeNode FTreeNode;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
[check] should save the number of data.
|
||||||
|
4 bits * 7 (remainder 4 bits)
|
||||||
|
<----------------------------------->
|
||||||
|
+---+---+---+---+---+---+---+---+---+
|
||||||
|
| x | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
||||||
|
+---+---+---+---+---+---+---+---+---+
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 aKey[FTREE_LEAF_FAN_OUT];
|
||||||
|
u32 data; // 4 bits * 7 (remainder 4 bits)
|
||||||
|
} FTreeLeaf;
|
||||||
|
|
||||||
|
#define LEAF_GET_LEN(leaf, index) ((((leaf)->data) >> (4 * (index))) & 0x0f)
|
||||||
|
#define FTREE_SBA_OFFSET 24
|
||||||
|
|
||||||
|
/*
|
||||||
|
an 8kb-block.
|
||||||
|
+-------------------------+ A
|
||||||
|
| | |
|
||||||
|
| hash code, areaInfo, | | offset
|
||||||
|
| volumeInfo, etc... | |
|
||||||
|
| | |
|
||||||
|
+-------------------------+ V
|
||||||
|
| | A
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| Sub-blocks | |
|
||||||
|
| | | size
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
| | V
|
||||||
|
+-------------------------+ A
|
||||||
|
| | |
|
||||||
|
+-------------------------+ | FTreeHdr (footer?)
|
||||||
|
| SubBlockAllocatorHeader | |
|
||||||
|
+-------------------------+ V
|
||||||
|
*/
|
||||||
|
typedef struct _SubBlockAllocatorHeader
|
||||||
|
{
|
||||||
|
u16 freeBlock; // start address of free blocks.
|
||||||
|
u16 numBlock; // the number of blocks in this 8kB block.
|
||||||
|
|
||||||
|
u16 offset;
|
||||||
|
u16 size;
|
||||||
|
} SubBlockAllocatorHeader;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PTreeHdr tree[MAX_SUB_TREE]; // 8 bytes * 7
|
||||||
|
SubBlockAllocatorHeader sbaHdr; // 8 bytes
|
||||||
|
} FTreeHdr; // sizeof(FTreeHdr) == sizeof(FTreeBlock) * NUM_HEADER_BLOCK.
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 prev;
|
||||||
|
u32 next;
|
||||||
|
u16 num;
|
||||||
|
} FTreeFreeBlock;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
u32 prev;
|
||||||
|
u32 next;
|
||||||
|
u16 num;
|
||||||
|
u8 padding[22]; // sizeof(FTreeBlock) must be 32.
|
||||||
|
} FTreeBlock;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
PTreeItr ptree; // inherit PTreeItr.
|
||||||
|
FTreeLeaf* pLeaf;
|
||||||
|
PTreeHdr* subTree;
|
||||||
|
WFSBlkAdr splitKey; // [ToDo] should separete FTreeItr.
|
||||||
|
WFSBlkAdr newChild; // [ToDo] should separete FTreeItr.
|
||||||
|
WFSBlkAdr newChildSubTreeType; // [ToDo] should separete FTreeItr.
|
||||||
|
} FTreeItr;
|
||||||
|
|
||||||
|
#define FTREE_GET_KEY(pFti) ((pFti)->ptree.nKey)
|
||||||
|
#define FTREE_GET_DATA(pFti) ((pFti)->ptree.nData)
|
||||||
|
|
||||||
|
#define PTREE_GET_KEY(pPti) ((pPti)->nKey)
|
||||||
|
#define PTREE_GET_DATA(pPti) ((pPti)->nData)
|
||||||
|
|
||||||
|
#define FTREE_MASK_LENGTH 0x07FF
|
||||||
|
#define FTREE_FLAG_BTREE 0x8000
|
||||||
|
#define FTREE_BLOCK_SIZE (32)
|
||||||
|
|
||||||
|
#define BLOCK_SIZE (1<<WFS_LOG2_SMALL_BLK_SIZE) // [check] should use area->nBlkSize as a block size.
|
||||||
|
|
||||||
|
#define FTREE_LOG2_OFS_A 0
|
||||||
|
#define FTREE_LOG2_OFS_B 3
|
||||||
|
#define FTREE_LOG2_OFS_C 6
|
||||||
|
#define FTREE_LOG2_OFS_D 10
|
||||||
|
#define FTREE_LOG2_OFS_E 14
|
||||||
|
#define FTREE_LOG2_OFS_F 18
|
||||||
|
#define FTREE_LOG2_OFS_G 22
|
||||||
|
#define FTREE_LOG2_OFS_END 26
|
||||||
|
|
||||||
|
extern const u32 FTreeBlkLog2Ofs[MAX_SUB_TREE+1];
|
||||||
|
|
||||||
|
#define SBAHDR_OFFSET (BLOCK_SIZE - sizeof(SubBlockAllocatorHeader))
|
||||||
|
#define GET_SBAHDR(pBlock) ((SubBlockAllocatorHeader*) ((u8*) pBlock + SBAHDR_OFFSET))
|
||||||
|
#define SET_FREEBLOCK(sbaHdr, pBlock) (sbaHdr->freeBlock = ((FTreeBlock*) (pBlock) - CACHE(sbaHdr)))
|
||||||
|
#define FREEBLOCK_NUMBER(sbaHdr) (sbaHdr->freeBlock)
|
||||||
|
#define CACHE(sbaHdr) ((FTreeBlock*) ((u8*) (sbaHdr) - (SBAHDR_OFFSET - (sbaHdr)->offset)))
|
||||||
|
#define END_OF_CACHE(sbaHdr) ((FTreeBlock*) ((u8*) CACHE(sbaHdr) + (sbaHdr)->size))
|
||||||
|
#define GET_FREEBLOCK(sbaHdr) (CACHE(sbaHdr) + (sbaHdr)->freeBlock)
|
||||||
|
#define MAX_FREEBLOCK(sbaHdr) ((sbaHdr)->size / sizeof(FTreeBlock))
|
||||||
|
#define GET_BLOCK_HEAD(treeHdr /* EPTreeHdr or FTreeHdr */) ((FTreeBlock*) ((u8*) &((treeHdr)->sbaHdr) - SBAHDR_OFFSET))
|
||||||
|
|
||||||
|
#define FTREEHDR_OFFSET (BLOCK_SIZE - sizeof(FTreeHdr))
|
||||||
|
#define GET_FTREEHDR(pBlock) ((FTreeHdr*) ((u8*) (pBlock) + FTREEHDR_OFFSET))
|
||||||
|
#define GET_SUBBLOCK(ftreeHdr, offset) ((FTreeBlock*) ((u8*) GET_BLOCK_HEAD(ftreeHdr) + (offset)))
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
// #define FTREE_RUNTIME_CHECK // for debug.
|
||||||
|
#endif // _DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef FTREE_RUNTIME_CHECK
|
||||||
|
#define WFSKRN_FTREE_RUNTIME_CHECK(x) { \
|
||||||
|
if (FBADebugVerbose) \
|
||||||
|
{ \
|
||||||
|
WFSKRN_FTREE_ASSERT(x); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define WFSKRN_FTREE_RUNTIME_CHECK(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#ifdef WIN32
|
||||||
|
#define WFSKRN_FTREE_ASSERT(x) assert(x)
|
||||||
|
#else // Win32
|
||||||
|
#define WFSKRN_FTREE_ASSERT(x) ASSERT(x)
|
||||||
|
#endif // WIN32
|
||||||
|
#else
|
||||||
|
#define WFSKRN_FTREE_ASSERT(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct _FTreeExtent
|
||||||
|
{
|
||||||
|
u32 start;
|
||||||
|
u32 len; // the unit is 8kB.
|
||||||
|
} FTreeExtent;
|
||||||
|
|
||||||
|
FTreeHdr* FTreeBlockInit(AreaInfo* area, void* block /* 8kB block */);
|
||||||
|
|
||||||
|
WFSKrnResult FTreeFind(FTreeHdr* header, FTreeItr* iter, u32 nKey, WFSBool strictSearch);
|
||||||
|
|
||||||
|
WFSKrnResult FTreeInsert(AreaInfo* area, FTreeHdr* header, FTreeItr* iter, u32 nKey, u32 nData);
|
||||||
|
WFSKrnResult FTreeDelete(FTreeHdr* header, FTreeItr* iter, u32 nKey);
|
||||||
|
WFSKrnResult FTreeModify(FTreeHdr* header, FTreeItr* iter, u32 originalKey, u32 modKey, u32 modData);
|
||||||
|
|
||||||
|
WFSKrnResult FTreeFirst(FTreeHdr* header, FTreeItr* iter);
|
||||||
|
WFSKrnResult FTreeNext(FTreeHdr* header, FTreeItr* iter);
|
||||||
|
WFSKrnResult FTreeLast(FTreeHdr* header, FTreeItr* iter);
|
||||||
|
WFSKrnResult FTreePrev(FTreeHdr* header, FTreeItr* iter);
|
||||||
|
WFSKrnResult PTreeLast(PTreeHdr *pPTreeHdr, PTreeItr *pPti, PTreeAllocator *pAllocator);
|
||||||
|
WFSKrnResult PTreePrev(PTreeHdr *pPTreeHdr, PTreeItr *pPti, PTreeAllocator *pAllocator);
|
||||||
|
PTreeHdr* FTreeSelectSubTree(FTreeHdr* header, WFSBlkAdr unitLen);
|
||||||
|
|
||||||
|
u16 FTreeAllocEntry(void *pBase);
|
||||||
|
WFSKrnResult FTreeAllocEntries(void *pBase, u16 *pNodeOfs, u32 nNumNodes);
|
||||||
|
void FTreeFreeEntry(void *pBase, u16 nOfs);
|
||||||
|
|
||||||
|
FTreeBlock* MemoryBlockAlloc(SubBlockAllocatorHeader* header, int numBlocks);
|
||||||
|
int MemoryBlockFree(SubBlockAllocatorHeader* header, FTreeBlock* block, u32 numBlocks);
|
||||||
|
|
||||||
|
void FTreeSbaInit(AreaInfo* area, void* block, u32 footerSize, u32 offset);
|
||||||
|
|
||||||
|
WFSBool VerifyMemoryBlockFTree(SubBlockAllocatorHeader* header); // [check] debug API.
|
||||||
|
WFSBool FTreeVerifyTree(FTreeHdr* header);
|
||||||
|
|
||||||
|
#endif // BTREE_BASED_ALLOCATOR
|
||||||
|
#endif // __WFSKRN_FTREE_H__
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,184 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_FreeBlkAlloc.h
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_FreeBlkAlloc.h,v $
|
||||||
|
Revision 1.16 2008/12/18 00:32:11 ueno
|
||||||
|
Removed FBADirtyFtreeBlock().
|
||||||
|
|
||||||
|
Revision 1.15 2008/12/17 05:08:17 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.14 2008/12/15 02:40:27 ueno
|
||||||
|
Added support for multi p-tree.
|
||||||
|
|
||||||
|
Revision 1.13 2008/12/02 04:55:39 ueno
|
||||||
|
Added EPTree to support multi-PTree.
|
||||||
|
|
||||||
|
Revision 1.11 2008/11/18 04:57:11 saito_tomoya
|
||||||
|
Modified SetBit() and added SetBitArray().
|
||||||
|
|
||||||
|
Revision 1.10 2008/11/07 03:01:42 ueno
|
||||||
|
Fixed FTreeExtentInfo{} for IOP.
|
||||||
|
|
||||||
|
Revision 1.9 2008/10/14 11:25:13 ueno
|
||||||
|
Disabled runtime check.
|
||||||
|
|
||||||
|
Revision 1.8 2008/09/29 10:19:25 ueno
|
||||||
|
Revised to support multi-B-tree-based allocator.
|
||||||
|
|
||||||
|
Revision 1.7 2008/08/13 04:14:00 ueno
|
||||||
|
Modified FreeBlkAlloc() to allocate blocks near nRefBlkAdr.
|
||||||
|
|
||||||
|
Revision 1.6 2008/08/13 00:14:09 paul
|
||||||
|
Changed type of nStride from u32 to s32
|
||||||
|
|
||||||
|
Revision 1.5 2008/08/09 03:34:29 ueno
|
||||||
|
Disabled runtime check.
|
||||||
|
|
||||||
|
Revision 1.4 2008/08/08 13:27:42 ueno
|
||||||
|
Added UnpinFTreeBlk().
|
||||||
|
|
||||||
|
Revision 1.3 2008/08/07 10:46:50 ueno
|
||||||
|
Modified for BTREE_BASED_ALLOCATOR (now debugging).
|
||||||
|
|
||||||
|
Revision 1.2 2008/08/02 11:52:10 ueno
|
||||||
|
Revised the positions of FTreeHdr{} and FBAPTreeHdr{} in 8KB-blocks to protect hash code.
|
||||||
|
|
||||||
|
Revision 1.1 2008/08/01 06:57:39 ueno
|
||||||
|
Initial Check-in.
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFSKRN_FREEBLKALLOC_H__
|
||||||
|
#define __WFSKRN_FREEBLKALLOC_H__
|
||||||
|
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#if BTREE_BASED_ALLOCATOR
|
||||||
|
|
||||||
|
#include "wfskrn_FreeBlkAlloc_Type.h"
|
||||||
|
#include "wfskrn_FTree.h"
|
||||||
|
#include "wfskrn_EPTree.h"
|
||||||
|
|
||||||
|
#define FBA_ROOT_BLK 0 // default block for p-tree.
|
||||||
|
#define FBA_INITIAL_FTREE_BLK 1 // default block for f-tree.
|
||||||
|
|
||||||
|
#define GET_FBATREE_HDR(area) (&((area)->ah.freeBlkAllocHdr)) // [check]
|
||||||
|
#define FBA_SBA_OFFSET (sizeof(AreaHdr) + sizeof(VolumeHdr))
|
||||||
|
#define FBA_GET_FTREE_BLK(pIter) ((pIter)->epti[(pIter)->height - 1].nData)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
EPTreeHdr* eptreeHdr[EPTREE_MAX_HEIGHT]; // inherit MEPTreeItr.
|
||||||
|
EPTreeItr epti[EPTREE_MAX_HEIGHT]; // inherit MEPTreeItr.
|
||||||
|
FTreeItr fti;
|
||||||
|
FTreeHdr* ftreeHdr;
|
||||||
|
WFSBlkAdr ftreeAddr;
|
||||||
|
|
||||||
|
WFSBool isInserted;
|
||||||
|
u8 height;
|
||||||
|
} FBATreeItr;
|
||||||
|
|
||||||
|
typedef struct _ExtentStorageHeader
|
||||||
|
{
|
||||||
|
u32 prio; // priority
|
||||||
|
u32 numPrev;
|
||||||
|
u32 numNext;
|
||||||
|
} ExtentStorageHeader;
|
||||||
|
|
||||||
|
typedef struct _ExtentStorageEntry
|
||||||
|
{
|
||||||
|
WFSBlkAdr start;
|
||||||
|
WFSBlkAdr len; // block len.
|
||||||
|
u16 treeType;
|
||||||
|
u16 nNumBlk;
|
||||||
|
} ExtentStorageEntry;
|
||||||
|
|
||||||
|
typedef struct _FBASingleEntry
|
||||||
|
{
|
||||||
|
ExtentStorageHeader header;
|
||||||
|
ExtentStorageEntry entry;
|
||||||
|
} FBASingleEntry;
|
||||||
|
|
||||||
|
typedef struct _RemainderExtents
|
||||||
|
{
|
||||||
|
FTreeExtent head;
|
||||||
|
FTreeExtent fractionHead;
|
||||||
|
FTreeExtent tail;
|
||||||
|
FTreeExtent fractionTail;
|
||||||
|
} RemainderExtents;
|
||||||
|
|
||||||
|
typedef struct _FTreeExtentInfo
|
||||||
|
{
|
||||||
|
WFSBlkAdr start;
|
||||||
|
WFSBlkAdr len; // the unit is 8kB.
|
||||||
|
FBATreeItr iter;
|
||||||
|
WFSBool alignment;
|
||||||
|
} FTreeExtentInfo;
|
||||||
|
|
||||||
|
#define FBA_RESULT_KEY(pIter) ((pIter)->fti.ptree.nKey)
|
||||||
|
#define FBA_RESULT_DATA(pIter) ((pIter)->fti.ptree.nData)
|
||||||
|
|
||||||
|
EPTreeHdr* EpTreeBlockInit(AreaInfo* area, void* block, u32 offset);
|
||||||
|
|
||||||
|
WFSKrnResult FreeBlkInsert(AreaInfo* area, FBATreeItr* iter, WFSBlkAdr nBlkAdr, WFSBlkAdr nNumBlks);
|
||||||
|
WFSKrnResult FreeBlkDelete(AreaInfo* area, FBATreeItr* iter, WFSBlkAdr nBlkAdr, WFSBlkAdr nNumBlks, u32 nBlkLog2Size);
|
||||||
|
|
||||||
|
WFSKrnResult FreeBlkInit(AreaInfo *pAreaInfo, u32 offset);
|
||||||
|
WFSKrnResult FreeBlkAlloc(AreaInfo *pAreaInfo, WFSBlkAdr nRefBlkAdr, WFSBlkAdr nNumBlks, WFSBlkAdr *aBlkAdr, s32 nStride, u32 nBlkLog2Size);
|
||||||
|
WFSKrnResult FreeBlkFree(AreaInfo *pAreaInfo, WFSBlkAdr nNumBlks, WFSBlkAdr *aBlkAdr, s32 nStride, u32 nBlkLog2Size);
|
||||||
|
|
||||||
|
WFSKrnResult FreeBlkFirst(AreaInfo* area, FBATreeItr* iter, u32 nSubTreeBlkLog2Size);
|
||||||
|
WFSKrnResult FreeBlkLast(AreaInfo* area, FBATreeItr* iter, u32 nSubTreeBlkLog2Size);
|
||||||
|
WFSKrnResult FreeBlkNext(AreaInfo* area, FBATreeItr* iter);
|
||||||
|
WFSKrnResult FreeBlkPrev(AreaInfo* area, FBATreeItr* iter);
|
||||||
|
|
||||||
|
WFSKrnResult FreeBlkFind(AreaInfo* area, FBATreeItr* iter, u32 key, u32 nBlkLog2Size);
|
||||||
|
WFSKrnResult FreeBlkFindStrict(AreaInfo* area, FBATreeItr* iter, u32 nBlkAdr, u32 nBlkLog2Size);
|
||||||
|
|
||||||
|
WFSBlkAdr FreeBlkGetFreeSize(AreaInfo *pAreaInfo);
|
||||||
|
|
||||||
|
WFSBool FreeBlkVerify(AreaInfo* area);
|
||||||
|
WFSKrnResult FreeBlkCheckDisk(AreaInfo* area, WFSSrvFileHandle fh, u8* pBuffer, u32 bufferSize, u32 size);
|
||||||
|
u32 FreeBlkGetFreeBlkLen(AreaInfo* area, u32 nBlkLog2SizeOfs);
|
||||||
|
WFSKrnResult FreeBlkDumpFreeblock(AreaInfo* area);
|
||||||
|
|
||||||
|
void FBAItrOpen(AreaInfo* area, FBATreeItr* iter);
|
||||||
|
void FBAItrClose(AreaInfo* area, FBATreeItr* iter);
|
||||||
|
|
||||||
|
PTreeHdr* FTreeSelectSubTree(FTreeHdr* header, WFSBlkAdr unitLen);
|
||||||
|
|
||||||
|
void FBAUnpinCache(AreaInfo* area, u32 diskAddr);
|
||||||
|
void FBAUnpinFTreeBlk(AreaInfo* area, FBATreeItr* iter);
|
||||||
|
void FBAFreeCache(AreaInfo* area, u32 diskAddr);
|
||||||
|
WFSKrnResult FBAGetCache(AreaInfo* area, u32 diskAddr, u32 flags, void** cache);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
// #define FBA_DEBUG_VERBOSE
|
||||||
|
// #define WFSKRN_FBA_RUNTIME_CHECK
|
||||||
|
#endif // _DEBUG
|
||||||
|
|
||||||
|
#ifdef WFSKRN_FBA_RUNTIME_CHECK
|
||||||
|
#define FBA_STRICT_ASSERT(x) { \
|
||||||
|
if (FBADebugVerbose) \
|
||||||
|
{ \
|
||||||
|
WFSKRN_FTREE_ASSERT(x); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define FBA_STRICT_ASSERT(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // BTREE_BASED_ALLOCATOR
|
||||||
|
|
||||||
|
#endif // __WFSKRN_FREEBLKALLOC_H__
|
||||||
|
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_FreeBlkAlloc.h
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_FreeBlkAlloc_Type.h,v $
|
||||||
|
Revision 1.4 2008/12/02 04:55:39 ueno
|
||||||
|
Added EPTree to support multi-PTree.
|
||||||
|
|
||||||
|
Revision 1.2 2008/08/09 03:34:29 ueno
|
||||||
|
Disabled runtime check.
|
||||||
|
|
||||||
|
Revision 1.1 2008/08/07 10:47:29 ueno
|
||||||
|
Added for BTREE_BASED_ALLOCATOR (now debugging).
|
||||||
|
|
||||||
|
Revision 1.2 2008/08/02 11:52:10 ueno
|
||||||
|
Revised the positions of FTreeHdr{} and FBAPTreeHdr{} in 8KB-blocks to protect hash code.
|
||||||
|
|
||||||
|
Revision 1.1 2008/08/01 06:57:39 ueno
|
||||||
|
Initial Check-in.
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFSKRN_FREEBLKALLOC_TYPE_H__
|
||||||
|
#define __WFSKRN_FREEBLKALLOC_TYPE_H__
|
||||||
|
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#if BTREE_BASED_ALLOCATOR
|
||||||
|
|
||||||
|
#define GET_FBATREE_HDR(area) (&((area)->ah.freeBlkAllocHdr))
|
||||||
|
|
||||||
|
#define GET_EPTREEHDR_FROM_AREAINFO(area) ((EPTreeHdr*) ((u8*) ((area)->pAflh) + GET_FBATREE_HDR(area)->ofsEPtreeHdr))
|
||||||
|
// ~
|
||||||
|
|
||||||
|
/*
|
||||||
|
root disk block in the area.
|
||||||
|
+-----------------+ <-- pVolInfo - - - - - - - - -A
|
||||||
|
| | |
|
||||||
|
+-----------------+ <-- pAreaHdr (pAreaInfo->ah) |
|
||||||
|
| | |
|
||||||
|
A +-----------------+ <-- pAreaInfo->pAflh |
|
||||||
|
| | | A |
|
||||||
|
| | | | |
|
||||||
|
| | | | | pAreaInfo->nBlkSize (4kB or 8kB?)
|
||||||
|
ofsEPtreeHdr | | | | |
|
||||||
|
| | | | nSizeRemaining |
|
||||||
|
| | | | |
|
||||||
|
V +-----------------+ | |
|
||||||
|
| EPTreeHdr | | |
|
||||||
|
+-----------------+ V - - - - - - - - - - - - - - V
|
||||||
|
*/
|
||||||
|
|
||||||
|
// FBATreeHdr is stored in a disk.
|
||||||
|
typedef struct _FBATreeHdr
|
||||||
|
{
|
||||||
|
unsigned totalBlks; // freeblocks and metadata blocks in the Freeblock allocator.
|
||||||
|
unsigned ofsEPtreeHdr; // offset of FBAPTreeHdr from pAreaInfo->pAflh.
|
||||||
|
unsigned ptreeHeight; // height of ptree blocks. the min is FBA_PTREE_MIN_HEIGHT.
|
||||||
|
} FBATreeHdr;
|
||||||
|
|
||||||
|
#endif // BTREE_BASED_ALLOCATOR
|
||||||
|
#endif // __WFSKRN_FREEBLKALLOC_TYPE_H__
|
||||||
|
|
||||||
@ -0,0 +1,136 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Handles.h - Module for file handles and search directory handles
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Handles.h,v $
|
||||||
|
Revision 1.6 2008/10/07 06:01:16 ueno
|
||||||
|
Modified WFSKrnFileInfoAlloc() to set WFSKRN_HANDLE_ALLOCATED in order to indicate the handle is allocated.
|
||||||
|
|
||||||
|
Revision 1.5 2008/07/17 22:27:36 paul
|
||||||
|
Removed nRootBlkAdr from WFSKrnSearchDirInfo. (Now in PathCacheItr)
|
||||||
|
|
||||||
|
Revision 1.4 2008/06/09 18:12:18 paul
|
||||||
|
Made changes to support PathCache. Handles now contain a path cache iterator.
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/16 18:53:34 paul
|
||||||
|
Added nRootBlkAdr to WFSKrnSearchDirInfo
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/24 23:21:13 kondo_masahiro
|
||||||
|
Initial check-in
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/23 00:27:45 paul
|
||||||
|
Copied and modified from wfscli_Handles.h
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Handles_h
|
||||||
|
#define wfskrn_Handles_h
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_WFSKRN_HANDLES 1
|
||||||
|
#else
|
||||||
|
#define _DEBUG_WFSKRN_HANDLES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
#include "wfskrn_Mutex.h"
|
||||||
|
#include "wfskrn_PathCache.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define WFSKRN_MAX_FILE_HANDLES (1<<WFSKRN_FILE_HANDLE_IDX_BITS)
|
||||||
|
#define WFSKRN_MAX_SEARCH_DIR_HANDLES (1<<WFSKRN_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
#define WFSKRN_LOG2_MAX_NUM_HANDLES WFS_NUM_BITS_REQUIRED(WFSKRN_MAX_FILE_HANDLES + WFSKRN_MAX_SEARCH_DIR_HANDLES)
|
||||||
|
|
||||||
|
#define WFSKRN_FILE_HANDLE_INC (1<<WFSKRN_FILE_HANDLE_IDX_BITS)
|
||||||
|
#define WFSKRN_SEARCH_DIR_HANDLE_INC (1<<WFSKRN_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
|
||||||
|
|
||||||
|
#define WFSKRN_HANDLE_MASK 0xFFFF
|
||||||
|
#define WFSKRN_HANDLE_COUNTER_MASK 0xFFFF
|
||||||
|
#define WFSKRN_HANDLE_ALLOCATED 0xFFFF
|
||||||
|
|
||||||
|
// Internal binary format of WFSFileHandle (u32)
|
||||||
|
//
|
||||||
|
// 0TTcccccccccCCCCssssssssssSSSSSS
|
||||||
|
//
|
||||||
|
// 0 = always 0 (Number of bits = 1 )
|
||||||
|
// T = type of handle: 00 for FileHandle (Number of bits = 2 )
|
||||||
|
// c = incrementally assigned by client (Number of bits = 13 - WFSCLI_FILE_HANDLE_IDX_BITS)
|
||||||
|
// C = idx of aCliFileInfo array (Number of bits = WFSCLI_FILE_HANDLE_IDX_BITS)
|
||||||
|
// s = incrementally assigned by server (Number of bits = 16 - WFSKRN_FILE_HANDLE_IDX_BITS)
|
||||||
|
// S = idx of aSrvFileInfo array (Number of bits = WFSKRN_FILE_HANDLE_IDX_BITS)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 nNext;
|
||||||
|
WFSKrnMutex mxAccessCliFileInfo;
|
||||||
|
WFSSrvFileHandle nHandle;
|
||||||
|
DirEntryAttrHdr attr;
|
||||||
|
u8 nAccess;
|
||||||
|
PathCacheItr pci;
|
||||||
|
DirFilePos fpos;
|
||||||
|
#if _DEBUG
|
||||||
|
WFSPathName pathDebug;
|
||||||
|
#endif
|
||||||
|
} WFSKrnFileInfo;
|
||||||
|
|
||||||
|
|
||||||
|
// Internal binary format of WFSSearcDirHandle (u32)
|
||||||
|
//
|
||||||
|
// 0TTcccccccccccCCssssssssssssSSSS
|
||||||
|
//
|
||||||
|
// 0 = always 0 (Number of bits = 1 )
|
||||||
|
// T = type of handle: 01 for SearchDirHandle (Number of bits = 2 )
|
||||||
|
// c = incrementally assigned by client (Number of bits = 13 - WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
// C = idx of aCliSearchDirInfo array (Number of bits = WFSCLI_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
// s = incrementally assigned by server (Number of bits = 16 - WFSKRN_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
// S = idx of aSrvSearchDirInfo array (Number of bits = WFSKRN_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 nNext;
|
||||||
|
WFSSrvSearchDirectoryHandle nHandle;
|
||||||
|
WFSFileName pattern;
|
||||||
|
PathCacheItr pci;
|
||||||
|
#if _DEBUG
|
||||||
|
WFSPathName pathDebug;
|
||||||
|
#endif
|
||||||
|
} WFSKrnSearchDirInfo;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSSrvFileHandle nFileHandleCounter; // Counter for ssss field of file handle.
|
||||||
|
WFSSrvSearchDirectoryHandle nSearchDirHandleCounter; // Counter for ssss field of search directory handle.
|
||||||
|
u32 nFirstFreeFileHandle; // Index of the first free element of aClientFileInfo
|
||||||
|
u32 nFirstFreeSearchDirHandle; // Index of the first free element of aClientSearchDirInfo
|
||||||
|
u32 nNumUsedFileHandles;
|
||||||
|
u32 nNumUsedSearchDirHandles;
|
||||||
|
WFSKrnMutex mxAccessTheFileInfo;
|
||||||
|
WFSKrnMutex mxAccessTheSearchDirInfo;
|
||||||
|
WFSKrnFileInfo aFileInfo[WFSKRN_MAX_FILE_HANDLES];
|
||||||
|
WFSKrnSearchDirInfo aSearchDirInfo[WFSKRN_MAX_SEARCH_DIR_HANDLES];
|
||||||
|
} WFSKrnHandles;
|
||||||
|
|
||||||
|
|
||||||
|
void WFSKrnInitHandles();
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnGetFileInfo(WFSKrnFileInfo **ppFi, WFSSrvFileHandle fh);
|
||||||
|
WFSKrnResult WFSKrnGetSearchDirInfo(WFSKrnSearchDirInfo **ppSdi, WFSSrvSearchDirectoryHandle ssdh);
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnFileInfoAlloc(WFSKrnFileInfo **ppFi);
|
||||||
|
WFSKrnResult WFSKrnSearchDirInfoAlloc(WFSKrnSearchDirInfo **ppSdi);
|
||||||
|
|
||||||
|
void WFSKrnFileInfoFree(WFSKrnFileInfo *pFi);
|
||||||
|
void WFSKrnSearchDirInfoFree(WFSKrnSearchDirInfo *pSdi);
|
||||||
|
|
||||||
|
#endif //define wfskrn_Handles_h
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Heap.h - memory allocation functions
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Heap.h,v $
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/27 11:35:11 paul
|
||||||
|
similar to wfs_Heap, but will eventually support IOP
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Heap_h
|
||||||
|
#define wfskrn_Heap_h
|
||||||
|
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_WFSKRN_ALLOC 0 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_WFSKRN_ALLOC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
typedef HANDLE WFSKrnHeap;
|
||||||
|
|
||||||
|
//-- twl modified
|
||||||
|
#elif _TWL
|
||||||
|
|
||||||
|
typedef OSHeapHandle WFSKrnHeap;
|
||||||
|
|
||||||
|
//-- twl modified
|
||||||
|
|
||||||
|
#elif _RVL
|
||||||
|
|
||||||
|
#include <revolution/mem.h>
|
||||||
|
#define WFS_HEAP_DEFAULT_ALIGNMENT 32
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
MEMAllocator allocator;
|
||||||
|
MEMHeapHandle handle;
|
||||||
|
} WFSKrnHeap;
|
||||||
|
|
||||||
|
#elif _IOP
|
||||||
|
|
||||||
|
#define WFSKrnHeap IOSHeapId
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void WFSKrnCreateHeap(WFSKrnHeap *pHeap, void *pBase, size_t nSize);
|
||||||
|
void *WFSKrnHeapAlloc(WFSKrnHeap *pHeap, size_t nSize);
|
||||||
|
void WFSKrnHeapFree(WFSKrnHeap *pHeap, void *pAddr);
|
||||||
|
void WFSKrnHeapDestroy(WFSKrnHeap *pHeap);
|
||||||
|
|
||||||
|
#endif //define wfskrn_Heap_h
|
||||||
190
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Mutex.h
Normal file
190
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Mutex.h
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Mutex.h - mutual exclusion for multi-thread case
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Mutex.h,v $
|
||||||
|
Revision 1.2 2008/08/05 04:17:58 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/19 05:48:44 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/28 06:32:23 kondo_masahiro
|
||||||
|
Fixed code to accept PPC compiler
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/27 11:34:29 paul
|
||||||
|
similar to wfs_Mutex.h, but will eventually have to support IOP
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Mutex_h
|
||||||
|
#define wfskrn_Mutex_h
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
#define _TWL 1 //twl modified
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_WFSKRN_MUTEX 0 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_WFSKRN_MUTEX 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HANDLE hHandle;
|
||||||
|
} WFSKrnMutex;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HANDLE hAutoResetEvent;
|
||||||
|
//HANDLE hManualResetEvent;
|
||||||
|
} WFSKrnCond;
|
||||||
|
|
||||||
|
#define WFSKrnSemaphore HANDLE
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HANDLE hThread;
|
||||||
|
} WFSKrnThread;
|
||||||
|
|
||||||
|
void WFSKrnInitMutex(WFSKrnMutex *mutex);
|
||||||
|
void WFSKrnLockMutex(WFSKrnMutex *mutex);
|
||||||
|
bool WFSKrnTryLockMutex(WFSKrnMutex *mutex);
|
||||||
|
void WFSKrnUnlockMutex(WFSKrnMutex *mutex);
|
||||||
|
|
||||||
|
void WFSKrnInitCond(WFSKrnCond *pCond);
|
||||||
|
void WFSKrnSignalCond(WFSKrnCond *pCond);
|
||||||
|
void WFSKrnWaitCond(WFSKrnCond *pCond, WFSKrnMutex* pMx);
|
||||||
|
void WFSKrnResetCond(WFSKrnCond *pCond);
|
||||||
|
|
||||||
|
#define WFSKrnInitSemaphore(pSem, initNum) *pSem = CreateSemaphore(NULL,initNum,1,NULL);
|
||||||
|
#define WFSKrnSignalSemaphore(pSem) ReleaseSemaphore(*pSem, 1, NULL);
|
||||||
|
#define WFSKrnWaitSemaphore(pSem) WaitForSingleObject(*pSem, INFINITE);
|
||||||
|
|
||||||
|
s32 WFSKrnResumeThread(WFSKrnThread *pThread);
|
||||||
|
void WFSKrnCancelThread(WFSKrnThread *pThread);
|
||||||
|
void WFSKrnExitThread(void *pVal);
|
||||||
|
s32 WFSKrnSuspendThread(WFSKrnThread *pThread);
|
||||||
|
bool WFSKrnIsThreadTerminated(WFSKrnThread *thread);
|
||||||
|
bool WFSKrnJoinThread(WFSKrnThread *thread, void** val);
|
||||||
|
|
||||||
|
//-- twl modified
|
||||||
|
#elif _TWL
|
||||||
|
typedef u32 OSPriority;
|
||||||
|
#define WFSKrnMutex OSMutex
|
||||||
|
#define WFSKrnCond OSEvent
|
||||||
|
#define WFSKrnSemaphore OSSemaphore
|
||||||
|
#define WFSKrnThread OSThread
|
||||||
|
|
||||||
|
#define WFSKrnInitMutex osInitMutex
|
||||||
|
#define WFSKrnLockMutex osLockMutex
|
||||||
|
#define WFSKrnTryLockMutex osTryLockMutex
|
||||||
|
#define WFSKrnUnlockMutex osUnlockMutex
|
||||||
|
|
||||||
|
//#define WFSKrnInitCond osInitCond
|
||||||
|
//#define WFSKrnSignalCond osSignalCond
|
||||||
|
//#define WFSKrnWaitCond osWaitCond
|
||||||
|
//#define WFSKrnResetCond(x) // This function does nothing on RVL, only needed for Windows
|
||||||
|
void WFSKrnInitCond(WFSCond *pCond);
|
||||||
|
void WFSKrnSignalCond(WFSCond *pCond);
|
||||||
|
void WFSKrnWaitCond(WFSCond *pCond, WFSMutex* pMx);
|
||||||
|
void WFSKrnResetCond(WFSCond *pCond);
|
||||||
|
|
||||||
|
#define WFSKrnInitSemaphore osInitSemaphore
|
||||||
|
#define WFSKrnSignalSemaphore osSignalSemaphore
|
||||||
|
#define WFSKrnWaitSemaphore osWaitSemaphore
|
||||||
|
|
||||||
|
#define WFSKrnResumeThread OSResumeThread
|
||||||
|
#define WFSKrnCancelThread OSCancelThread
|
||||||
|
#define WFSKrnExitThread OSExitThread
|
||||||
|
#define WFSKrnSuspendThread OSSuspendThread
|
||||||
|
#define WFSKrnIsThreadTerminated OSIsThreadTerminated
|
||||||
|
#define WFSKrnJoinThread OSJoinThread
|
||||||
|
//-- twl modified
|
||||||
|
|
||||||
|
#elif _RVL
|
||||||
|
|
||||||
|
#define WFSKrnMutex OSMutex
|
||||||
|
#define WFSKrnCond OSCond
|
||||||
|
#define WFSKrnSemaphore OSSemaphore
|
||||||
|
#define WFSKrnThread OSThread
|
||||||
|
|
||||||
|
#define WFSKrnInitMutex OSInitMutex
|
||||||
|
#define WFSKrnLockMutex OSLockMutex
|
||||||
|
#define WFSKrnTryLockMutex OSTryLockMutex
|
||||||
|
#define WFSKrnUnlockMutex OSUnlockMutex
|
||||||
|
|
||||||
|
#define WFSKrnInitCond OSInitCond
|
||||||
|
#define WFSKrnSignalCond OSSignalCond
|
||||||
|
#define WFSKrnWaitCond OSWaitCond
|
||||||
|
#define WFSKrnResetCond(x) // This function does nothing on RVL, only needed for Windows
|
||||||
|
|
||||||
|
#define WFSKrnInitSemaphore OSInitSemaphore
|
||||||
|
#define WFSKrnSignalSemaphore OSSignalSemaphore
|
||||||
|
#define WFSKrnWaitSemaphore OSWaitSemaphore
|
||||||
|
|
||||||
|
#define WFSKrnResumeThread OSResumeThread
|
||||||
|
#define WFSKrnCancelThread OSCancelThread
|
||||||
|
#define WFSKrnExitThread OSExitThread
|
||||||
|
#define WFSKrnSuspendThread OSSuspendThread
|
||||||
|
#define WFSKrnIsThreadTerminated OSIsThreadTerminated
|
||||||
|
#define WFSKrnJoinThread OSJoinThread
|
||||||
|
|
||||||
|
#elif _IOP
|
||||||
|
|
||||||
|
#define WFSKRN_MUTEX_Q_SIZE 1
|
||||||
|
typedef s32 OSPriority;
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
IOSMessageQueueId mqid; // Message queue
|
||||||
|
IOSMessage mq[WFSKRN_MUTEX_Q_SIZE];
|
||||||
|
s32 count; // lock count
|
||||||
|
IOSThreadId owner;
|
||||||
|
} WFSKrnMutex;
|
||||||
|
|
||||||
|
//#define WFSKrnCond
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
IOSThreadId tid;
|
||||||
|
s32 count;
|
||||||
|
} WFSKrnThread;
|
||||||
|
|
||||||
|
void WFSKrnInitMutex(WFSKrnMutex *mutex);
|
||||||
|
void WFSKrnLockMutex(WFSKrnMutex *mutex);
|
||||||
|
bool WFSKrnTryLockMutex(WFSKrnMutex *mutex);
|
||||||
|
void WFSKrnUnlockMutex(WFSKrnMutex *mutex);
|
||||||
|
|
||||||
|
//#define WFSKrnInitCond
|
||||||
|
//#define WFSKrnSignalCond
|
||||||
|
//#define WFSKrnWaitCond
|
||||||
|
//#define WFSKrnResetCond
|
||||||
|
|
||||||
|
s32 WFSKrnResumeThread(WFSKrnThread *pThread);
|
||||||
|
void WFSKrnCancelThread(WFSKrnThread *pThread);
|
||||||
|
void WFSKrnExitThread(void *pVal);
|
||||||
|
s32 WFSKrnSuspendThread(WFSKrnThread *pThread);
|
||||||
|
bool WFSKrnIsThreadTerminated(WFSKrnThread *pThread);
|
||||||
|
bool WFSKrnJoinThread(WFSKrnThread *pThread, void** val);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef void *(*WFSKrnThreadFunc)(void *);
|
||||||
|
|
||||||
|
bool WFSKrnCreateThread(WFSKrnThread *thread,
|
||||||
|
WFSKrnThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority);
|
||||||
|
|
||||||
|
#endif //define wfskrn_Mutex_h
|
||||||
106
trunk/firmware/build/libraries/nfs/common/include/wfskrn_PTree.h
Normal file
106
trunk/firmware/build/libraries/nfs/common/include/wfskrn_PTree.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_PTree.h
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_PTree.h,v $
|
||||||
|
Revision 1.2 2008/07/17 22:33:39 paul
|
||||||
|
Added adapter functions to the Sba allocators for updateMap
|
||||||
|
|
||||||
|
Revision 1.1 2008/07/09 01:42:35 paul
|
||||||
|
u32->u32 mapping optimized B-Tree. (for use by new block allocator, and transaction block re-mapper)
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_PTree_h
|
||||||
|
#define wfskrn_PTree_h
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_PTREE 0 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_PTREE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define PTREE_LOG2_NODE_SIZE 5
|
||||||
|
#define PTREE_NODE_FAN_OUT 6 // (6 * 2 Byte Offset) + (5 * 4 Byte Key) = 32 Bytes
|
||||||
|
#define PTREE_LEAF_FAN_OUT 4 // 4 * (4 Byte Key + 4 Byte Value) = 32 Bytes
|
||||||
|
#define PTREE_MAX_HEIGHT 5
|
||||||
|
|
||||||
|
|
||||||
|
// Node Sizes:
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 aKey[PTREE_NODE_FAN_OUT-1];
|
||||||
|
u16 aOfs[PTREE_NODE_FAN_OUT];
|
||||||
|
} PTreeNode;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 aKey[PTREE_LEAF_FAN_OUT];
|
||||||
|
u32 aData[PTREE_LEAF_FAN_OUT];
|
||||||
|
} PTreeLeaf;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u16 *pOfs; // A pointer to the offset pointer to the node. This would need to be updated if the sub block is relocated.
|
||||||
|
PTreeLeaf *pLeaf;
|
||||||
|
PTreeNode *apNode[PTREE_MAX_HEIGHT-1];
|
||||||
|
u32 aEntryIdx[PTREE_MAX_HEIGHT];
|
||||||
|
//u32 *apKey[PTREE_MAX_HEIGHT];
|
||||||
|
u32 nKey;
|
||||||
|
u32 nData;
|
||||||
|
} PTreeItr;
|
||||||
|
|
||||||
|
typedef u16 (*PTreeAllocNodeFunc) (void *pBase);
|
||||||
|
typedef WFSKrnResult (*PTreeAllocNodesFunc)(void *pBase, u16 *pNodeOfs, u32 nNumNodes);
|
||||||
|
typedef void (*PTreeFreeNodeFunc) (void *pBase, u16 nOfs);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void *pBase;
|
||||||
|
PTreeAllocNodeFunc fpAllocNode;
|
||||||
|
PTreeAllocNodesFunc fpAllocNodes;
|
||||||
|
PTreeFreeNodeFunc fpFreeNode;
|
||||||
|
} PTreeAllocator;
|
||||||
|
|
||||||
|
// Allocator functions which use SubBlkAlloc module
|
||||||
|
u16 PTreeAllocNodeFromSba(void *pBase);
|
||||||
|
WFSKrnResult PTreeAllocNodesFromSba(void *pBase, u16 aNodeOfs[], u32 nNumNodes);
|
||||||
|
void PTreeFreeNodeToSba(void *pBase, u16 nOfs);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 nRootHeight; // height of root node (opposite of depth).
|
||||||
|
u16 nRootOfs; // Offset to the root node of the tree.
|
||||||
|
u16 nNumRecs; // Number of records in the tree.
|
||||||
|
} PTreeHdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u16 nParentOfs; // The offset the to parent of this node
|
||||||
|
u8 nEntryIdx; // The index of the entry in the parent block which points to this node
|
||||||
|
u8 nNumEntries; // The number of entries in this node
|
||||||
|
u32 nLength;
|
||||||
|
} PTreeAttrHdr;
|
||||||
|
|
||||||
|
void PTreeInit (PTreeHdr *pPTreeHdr, PTreeAllocator *pAllocator);
|
||||||
|
WFSKrnResult PTreeFind (PTreeHdr *pPTreeHdr, PTreeItr *pPti, u32 nKey, PTreeAllocator *pAllocator);
|
||||||
|
WFSKrnResult PTreeInsert(PTreeHdr *pPTreeHdr, PTreeItr *pPti, u32 nKey, u32 nData, PTreeAllocator *pAllocator);
|
||||||
|
WFSKrnResult PTreeDelete(PTreeHdr *pPTreeHdr, PTreeItr *pPti, PTreeAllocator *pAllocator);
|
||||||
|
WFSKrnResult PTreeFirst (PTreeHdr *pPTreeHdr, PTreeItr *pPti, PTreeAllocator *pAllocator);
|
||||||
|
WFSKrnResult PTreeNext (PTreeHdr *pPTreeHdr, PTreeItr *pPti, PTreeAllocator *pAllocator);
|
||||||
|
|
||||||
|
WFSKrnResult PTreeInsertOrUpdateRec(PTreeHdr *pPTreeHdr, u32 nKey, u32 nData, PTreeAllocator *pAllocator);
|
||||||
|
|
||||||
|
void PTreeCheck(PTreeHdr *pPTreeHdr, u32 nLog2Size, PTreeAllocator *pAllocator);
|
||||||
|
void PTreeTest();
|
||||||
|
|
||||||
|
|
||||||
|
#endif //define wfskrn_PTree_h
|
||||||
@ -0,0 +1,202 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_PathCache.h - Caches recently used path names plus root path names "/dev", "/vol"
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_PathCache.h,v $
|
||||||
|
Revision 1.13 2008/12/04 00:42:37 ooizumi
|
||||||
|
Changed definition name to enable permission.
|
||||||
|
|
||||||
|
Revision 1.12 2008/10/31 09:51:42 ueno
|
||||||
|
Modified WFSSrvAPIs to return WFSKRN_RESULT_RESOURCE_LIMIT_EXCEEDED when path cache is short of memory.
|
||||||
|
|
||||||
|
Revision 1.11 2008/10/07 10:30:01 ooizumi
|
||||||
|
Defined PathCachePerm.
|
||||||
|
Added nObjCreator to PathCacheData.
|
||||||
|
|
||||||
|
Revision 1.10 2008/07/30 21:25:01 paul
|
||||||
|
Removed some unused definitions
|
||||||
|
|
||||||
|
Revision 1.9 2008/07/30 06:04:34 ooizumi
|
||||||
|
Added definitions for permission.
|
||||||
|
|
||||||
|
Revision 1.8 2008/07/21 22:48:35 paul
|
||||||
|
Added PathCacheCheck()
|
||||||
|
|
||||||
|
Revision 1.7 2008/07/17 22:31:12 paul
|
||||||
|
Added nRootBlkAdr to PathCacheItr.
|
||||||
|
|
||||||
|
Revision 1.6 2008/07/09 01:46:06 paul
|
||||||
|
Minor change.
|
||||||
|
|
||||||
|
Revision 1.5 2008/06/23 13:44:04 nakanose_jin
|
||||||
|
add cast for avoid warning
|
||||||
|
|
||||||
|
Revision 1.4 2008/06/09 18:06:42 paul
|
||||||
|
Rewrote PathCache to use a radix tree. Now actually provides PathCache functionality.
|
||||||
|
Also stores a list of open file / directory search paths so that invalid WFSSrv calls can be detected.
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/14 02:14:54 paul
|
||||||
|
Added some comments
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/12 19:22:12 paul
|
||||||
|
Made naming more consistent
|
||||||
|
|
||||||
|
Revision 1.1 2008/05/10 04:00:29 kondo_masahiro
|
||||||
|
Initial check-in
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_PathCache_h
|
||||||
|
#define wfskrn_PathCache_h
|
||||||
|
|
||||||
|
#include "wfskrn_Config.h"
|
||||||
|
#include "wfskrn_DirRxTree.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_PATH_CACHE 0 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_PATH_CACHE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _CHECK_RXT
|
||||||
|
#define _CHECK_PATH_CACHE 1
|
||||||
|
#else
|
||||||
|
#define _CHECK_PATH_CACHE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define WFS_DEVICE_DIRECTORY "/dev"
|
||||||
|
#define WFS_VOLUME_DIRECTORY "/vol"
|
||||||
|
|
||||||
|
|
||||||
|
#define PATH_CACHE_MAX_ENTRIES ((1<<WFSKRN_FILE_HANDLE_IDX_BITS) + (1<<WFSKRN_SEARCH_DIR_HANDLE_IDX_BITS) + 20 + WFSKRN_MAX_VOLUMES)
|
||||||
|
|
||||||
|
#define PATH_CACHE_ENABLED 1
|
||||||
|
|
||||||
|
#define PATH_CACHE_FLAG_OPEN_FOR_WRITE 0x8000
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct PathCacheEntry_ *pNext;
|
||||||
|
struct PathCacheEntry_ *pPrev;
|
||||||
|
} PathCacheLink;
|
||||||
|
|
||||||
|
#ifdef PERMISSION_ENABLED
|
||||||
|
#define PATH_CACHE_PERM_MAX 2
|
||||||
|
typedef struct {
|
||||||
|
WFSTitleId nTitleId;
|
||||||
|
WFSTitleId nEntryCreatorId;
|
||||||
|
u32 nFlags;
|
||||||
|
u32 nEntryCreatorCl;
|
||||||
|
} PathCachePerm;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
void *pData;
|
||||||
|
AreaInfo *pAreaInfo;
|
||||||
|
};
|
||||||
|
u32 nBlkAdr;
|
||||||
|
u16 nOpenHandleCount; // This is calculated as the sum of nPinCount for all sub-paths currently in the cache
|
||||||
|
u16 nPinCount;
|
||||||
|
u16 nFlags;
|
||||||
|
u16 nStrLen;
|
||||||
|
#ifdef PERMISSION_ENABLED
|
||||||
|
u32 nAccessListIdx;
|
||||||
|
WFSTitleId nObjCreator;
|
||||||
|
// PathCachePerm aPerm[PATH_CACHE_PERM_MAX];
|
||||||
|
#endif
|
||||||
|
} PathCacheData;
|
||||||
|
|
||||||
|
typedef struct PathCacheEntry_ {
|
||||||
|
RxtAttrHdr ah;
|
||||||
|
PathCacheLink ml;
|
||||||
|
PathCacheData pcd;
|
||||||
|
} PathCacheEntry;
|
||||||
|
|
||||||
|
#define PATH_CACHE_LOG2_NODE_SIZE WFS_NUM_BITS_REQUIRED(sizeof(PathCacheEntry))
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 aRxtBuf[1<<WFS_LOG2_PATH_CACHE_SIZE]; // WFS_LOG2_PATH_CACHE_SIZE <= RXT_MAX_LOG2_SIZE
|
||||||
|
RxtHdr *pRxtHdr;
|
||||||
|
PathCacheLink mruAnchor;
|
||||||
|
PathCacheEntry *pMruAnchor; // List from Most Recently Used to Least Recently Used
|
||||||
|
PathCacheLink pinAnchor;
|
||||||
|
PathCacheEntry *pPinAnchor; // List of directories that are pinned - do not get automatically deleted to make room for other
|
||||||
|
#if _DEBUG_PATH_CACHE
|
||||||
|
u32 nNumPinned;
|
||||||
|
#endif
|
||||||
|
} PathCache;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
RxtItr rxi;
|
||||||
|
DirItr di;
|
||||||
|
WFSBlkAdr nRootBlkAdr;
|
||||||
|
const utf8 *pNameEnd;
|
||||||
|
const utf8 *pRawNameStart;
|
||||||
|
PathCacheEntry *pEntry;
|
||||||
|
} PathCacheItr;
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
void PathCacheDebugOutput();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PathCacheEntry *PathCacheInsertAfterCursorEntry3(PathCacheEntry *pCursorEntry, utf8 *sStr, u32 nStrLen);
|
||||||
|
|
||||||
|
static inline PathCacheEntry *PathCacheInsertAfterCursorEntry2(PathCacheEntry *pCursorEntry, utf8 *sStr) {
|
||||||
|
u32 nStrLen = (u32)STRNLEN(sStr, WFS_MAX_PATH_NAME_SIZE);
|
||||||
|
return PathCacheInsertAfterCursorEntry3(pCursorEntry, sStr, nStrLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
PathCacheEntry *PathCacheFind3(RxtItr *pRxi, u32 nStrLen, void **ppData);
|
||||||
|
|
||||||
|
static inline PathCacheEntry *PathCacheFind2(RxtItr *pRxi, void **ppData) {
|
||||||
|
u32 nStrLen = (u32)STRNLEN(pRxi->pStrPtr, WFS_MAX_PATH_NAME_SIZE);
|
||||||
|
return PathCacheFind3(pRxi, nStrLen, ppData);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline PathCacheEntry *PathCacheFind1(RxtItr *pRxi) {
|
||||||
|
void *pData;
|
||||||
|
return PathCacheFind2(pRxi, &pData);
|
||||||
|
}
|
||||||
|
|
||||||
|
PathCacheEntry *PathCacheIncrementalFindEntry(RxtItr *pRxi, u32 nStrLen, void **ppData);
|
||||||
|
|
||||||
|
void PathCacheDeleteEntry(PathCacheEntry *pEntry);
|
||||||
|
WFSKrnResult PathCacheDeleteSubTree(PathCacheEntry *pEntry);
|
||||||
|
WFSKrnResult PathCacheDeleteLru();
|
||||||
|
|
||||||
|
PathCacheEntry *PathCacheIncrementalInsertAfterCursorEntry(PathCacheEntry *pCursorEntry, RxtItr *pRxi, u32 nPrefixLen, u32 nSuffixLen);
|
||||||
|
WFSKrnResult PathCacheIncrementalInsertPinnedEntry(PathCacheItr *pPci, u32 nStrLen);
|
||||||
|
#if _DEBUG_PATH_CACHE
|
||||||
|
WFSKrnResult PathCacheIncreaseEntryOpenHandleCount(PathCacheItr *pPci, WFSAccess nDesiredAccess, utf8 *sStr);
|
||||||
|
WFSKrnResult PathCacheDecreaseEntryOpenHandleCount(PathCacheItr *pPci, utf8 *sStr);
|
||||||
|
void PathCachePinEntry(PathCacheEntry *pEntry, utf8 *sStr);
|
||||||
|
#else
|
||||||
|
WFSKrnResult PathCacheIncreaseEntryOpenHandleCount(PathCacheItr *pPci, WFSAccess nDesiredAccess);
|
||||||
|
WFSKrnResult PathCacheDecreaseEntryOpenHandleCount(PathCacheItr *pPci);
|
||||||
|
void PathCachePinEntry(PathCacheEntry *pEntry);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _CHECK_PATH_CACHE
|
||||||
|
void PathCacheCheck();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void PathCacheInit();
|
||||||
|
void PathCacheTest();
|
||||||
|
|
||||||
|
WFSKrnResult PathCacheFindParentDir(const WFSPathName *pAbsPathName, utf8 *sLowerCaseStr, PathCacheItr *pPci);
|
||||||
|
WFSKrnResult PathCacheFindPath (const WFSPathName *pAbsPathName, utf8 *sLowerCaseStr, PathCacheItr *pPci);
|
||||||
|
|
||||||
|
#endif //define wfskrn_PathCache_h
|
||||||
@ -0,0 +1,79 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Permission.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Permission.h,v $
|
||||||
|
Revision 1.5 2008/12/18 10:28:33 ooizumi
|
||||||
|
Fixed macro.
|
||||||
|
|
||||||
|
Revision 1.4 2008/12/04 00:49:49 ooizumi
|
||||||
|
Removed old codes.
|
||||||
|
Fixed.
|
||||||
|
|
||||||
|
Revision 1.3 2008/07/31 23:59:09 ooizumi
|
||||||
|
Fixed permission of special directories..
|
||||||
|
|
||||||
|
Revision 1.2 2008/07/30 06:04:34 ooizumi
|
||||||
|
Added definitions for permission.
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.6 2008/02/28 04:36:47 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.5 2008/02/27 10:05:26 ueno
|
||||||
|
Revised to use WFSAreaHdr{} to specifiy WFS area.
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/27 04:33:36 ueno
|
||||||
|
Added root ID and alias permission flags.
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/26 14:12:06 ueno
|
||||||
|
Added WFSAccessListAddEntry() and WFSAccessListRemoveEntry() to edit accesslist.
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/25 09:44:08 ueno
|
||||||
|
Added support for accesslist cache.
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/22 05:15:55 ueno
|
||||||
|
Initial Check-in.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef __WFS_PERMISSION_H__
|
||||||
|
#define __WFS_PERMISSION_H__
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define WFSKRN_PERM_ASSERT(x) assert(x)
|
||||||
|
//#define WFSKRN_PERM_REPORT printf
|
||||||
|
#define WFSKRN_PERM_REPORT
|
||||||
|
#else // Win32
|
||||||
|
#define WFSKRN_PERM_ASSERT(x) SDK_ASSERT(x)
|
||||||
|
//#define WFSKRN_PERM_REPORT(...) printf(__VA_ARGS__)
|
||||||
|
#define WFSKRN_PERM_REPORT osTPrintf
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
#else // _DEBUG
|
||||||
|
|
||||||
|
#define WFSKRN_PERM_ASSERT(x) SDK_ASSERT(x)
|
||||||
|
#define WFSKRN_PERM_REPORT(...) osTPrintf(__VA_ARGS__)
|
||||||
|
//#define WFSKRN_PERM_ASSERT(x)
|
||||||
|
//#define WFSKRN_PERM_REPORT(...)
|
||||||
|
|
||||||
|
#endif // _DEBUG
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnGetInheritedPermissionForUserDi(PathCacheItr* pPci, u32* pFlags, WFSTitleId titleId);
|
||||||
|
WFSKrnResult WFSKrnGetInheritedPermissionForUserPci(PathCacheItr* pPci, u32* pFlags, WFSTitleId titleId);
|
||||||
|
WFSKrnResult WFSKrnGetParentInheritedPermissionForUserPci(PathCacheItr* pPci, u32* pFlags, WFSTitleId titleId);
|
||||||
|
WFSKrnResult WFSKrnSetInheritedPermissionForUser(PathCacheItr* pPci, u32 nFlags, u32 nMask, WFSTitleId entryCreatorId, WFSTitleId titleId);
|
||||||
|
|
||||||
|
#endif // __WFS_PERMISSION_H__
|
||||||
@ -0,0 +1,567 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Permission_AccessList.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Permission_AccessList.h,v $
|
||||||
|
Revision 1.23 2008/09/24 07:32:07 ueno
|
||||||
|
Added AclHdr{} to AreaHdr{} to save configuration of accesslists in a disk.
|
||||||
|
|
||||||
|
Revision 1.22 2008/08/14 08:02:57 kondo_masahiro
|
||||||
|
Fixed definition of ACL_GET_CL_RELATIVE() from inline to static inline.
|
||||||
|
|
||||||
|
Revision 1.21 2008/07/23 04:18:07 ueno
|
||||||
|
Reduced memory size required for accesslist.
|
||||||
|
|
||||||
|
Revision 1.20 2008/07/11 08:10:50 ueno
|
||||||
|
Fixed control level check.
|
||||||
|
|
||||||
|
Revision 1.19 2008/06/16 18:03:56 ueno
|
||||||
|
Fixed comment.
|
||||||
|
|
||||||
|
Revision 1.18 2008/06/05 14:04:11 ueno
|
||||||
|
Modified to reserve accesslist index 0 as the default (empty) accesslist.
|
||||||
|
|
||||||
|
Revision 1.17 2008/06/05 08:44:40 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.16 2008/06/05 08:09:18 ueno
|
||||||
|
Revised permission APIs.
|
||||||
|
|
||||||
|
Revision 1.15 2008/06/02 15:09:54 ueno
|
||||||
|
Revised WFSKrnAccessList{} to reduce the size.
|
||||||
|
|
||||||
|
Revision 1.14 2008/05/29 14:08:13 ueno
|
||||||
|
Modified _WFSAccessListControlBlock().
|
||||||
|
|
||||||
|
Revision 1.13 2008/05/28 02:12:57 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.12 2008/05/23 06:31:52 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.11 2008/05/19 05:31:53 ueno
|
||||||
|
Defined accesslist meta-data types.
|
||||||
|
|
||||||
|
Revision 1.10 2008/05/15 13:33:46 ueno
|
||||||
|
Implemented initialization using directory module.
|
||||||
|
|
||||||
|
Revision 1.9 2008/05/06 02:27:21 ueno
|
||||||
|
Fixed ifdef.
|
||||||
|
|
||||||
|
Revision 1.8 2008/04/29 06:25:14 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.7 2008/04/29 01:12:54 ueno
|
||||||
|
Defined WFS_ROOT_ID and WFS_EVERYONE_ID.
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/25 19:15:14 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/25 06:22:55 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/25 04:40:47 ueno
|
||||||
|
Added support for WFSDEV.
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.23 2008/04/23 08:59:55 ueno
|
||||||
|
Replaced WFSAreaHdr by AreaInfo.
|
||||||
|
Revised directory permission (change -> add).
|
||||||
|
|
||||||
|
Revision 1.22 2008/04/21 06:07:54 ueno
|
||||||
|
Fixed struct for C99.
|
||||||
|
|
||||||
|
Revision 1.21 2008/04/15 07:35:29 ueno
|
||||||
|
Fixed error codes.
|
||||||
|
|
||||||
|
Revision 1.20 2008/04/15 06:45:47 ueno
|
||||||
|
Changed return type to WFSKrnResult.
|
||||||
|
|
||||||
|
Revision 1.19 2008/04/14 13:50:17 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.18 2008/04/14 03:02:16 ueno
|
||||||
|
Modified WFSKrnCreateRootAccessList() to create an accesslist only for the root.
|
||||||
|
Added WFSKrnDebugCreateAccessList() for tests.
|
||||||
|
|
||||||
|
Revision 1.17 2008/04/11 13:20:13 ueno
|
||||||
|
Removed WFSKrnAccessListSetInstallerPermission().
|
||||||
|
|
||||||
|
Revision 1.16 2008/04/11 06:16:33 ueno
|
||||||
|
Defined WFSAclFileHandle.
|
||||||
|
Cleaned up headers.
|
||||||
|
|
||||||
|
Revision 1.15 2008/04/11 02:52:11 ueno
|
||||||
|
Renamed WFSKrnCreateAccessList() to make clear the purpose.
|
||||||
|
|
||||||
|
Revision 1.14 2008/04/09 11:31:25 ueno
|
||||||
|
Changed the maximum number of accesslist handles.
|
||||||
|
|
||||||
|
Revision 1.13 2008/04/07 12:47:17 ueno
|
||||||
|
Added support for group others.
|
||||||
|
|
||||||
|
Revision 1.12 2008/04/07 09:18:54 ueno
|
||||||
|
Modified WFSAccessListControlBlock() to keep permissions for the installer.
|
||||||
|
|
||||||
|
Revision 1.11 2008/04/03 09:59:30 ueno
|
||||||
|
Added manuals of WFS AccessList APIs.
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/03 06:40:35 ueno
|
||||||
|
Removed WFSKRN_ACCESSLIST_FLAG_CONTENT_DIRECTORY flag.
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/02 14:15:13 ueno
|
||||||
|
Revised permission inheritance.
|
||||||
|
|
||||||
|
Revision 1.8 2008/03/31 14:06:49 ueno
|
||||||
|
Removed WFSKrnAccessListAddUser() and RemoveUser().
|
||||||
|
Removed WFSKrnAccessListCan*().
|
||||||
|
|
||||||
|
Revision 1.7 2008/03/19 10:18:49 ueno
|
||||||
|
Revised WFSKrnAddUser() and RemoveUser() to specify operator title ID.
|
||||||
|
|
||||||
|
Revision 1.6 2008/03/18 13:42:28 ueno
|
||||||
|
Added WFSKrnAccessListSetControlLevel(), GetControlLevel() to set/get a control level.
|
||||||
|
|
||||||
|
Revision 1.5 2008/03/14 08:02:48 ueno
|
||||||
|
Revised API prefixes (WFS -> WFSKrn).
|
||||||
|
|
||||||
|
Revision 1.4 2008/03/12 06:37:34 ueno
|
||||||
|
Added WFSAccessListCanRead(), Write()...
|
||||||
|
|
||||||
|
Revision 1.3 2008/03/11 12:10:35 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.2 2008/03/11 11:38:58 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.1 2008/03/11 11:09:21 ueno
|
||||||
|
Renamed.
|
||||||
|
|
||||||
|
Revision 1.14 2008/03/11 09:51:51 ueno
|
||||||
|
Fixed EscapeAccessList() to make a filename from UTF-16 characters (0x3300-0x33ff).
|
||||||
|
|
||||||
|
Revision 1.13 2008/03/11 06:53:02 ueno
|
||||||
|
Added WFSAccessListSetPermission() and GetPermission().
|
||||||
|
|
||||||
|
Revision 1.12 2008/03/07 05:43:57 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.10 2008/03/06 12:26:04 ueno
|
||||||
|
Revised cache freelist (signgle -> double link list).
|
||||||
|
|
||||||
|
Revision 1.9 2008/03/06 10:46:19 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.8 2008/02/29 00:47:45 ueno
|
||||||
|
Changed the attribute of index to inout (WFSAccessListAddEntry() and RemoveEntry()).
|
||||||
|
|
||||||
|
Revision 1.7 2008/02/28 13:11:58 ueno
|
||||||
|
Revised to keep accesslist cache and indexlist handle in WFSAreaHdr{}.
|
||||||
|
|
||||||
|
Revision 1.6 2008/02/28 04:36:47 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.5 2008/02/27 10:05:26 ueno
|
||||||
|
Revised to use WFSAreaHdr{} to specifiy WFS area.
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/27 04:33:36 ueno
|
||||||
|
Added root ID and alias permission flags.
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/26 14:12:06 ueno
|
||||||
|
Added WFSAccessListAddEntry() and WFSAccessListRemoveEntry() to edit accesslist.
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/25 09:44:08 ueno
|
||||||
|
Added support for accesslist cache.
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/22 05:15:55 ueno
|
||||||
|
Initial Check-in.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef __WFSKRN_PERMISSION_ACCESSLIST_H__
|
||||||
|
#define __WFSKRN_PERMISSION_ACCESSLIST_H__
|
||||||
|
|
||||||
|
#include <revolution/wfs.h>
|
||||||
|
|
||||||
|
#if !_IOP
|
||||||
|
#include "wfs_Client.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_Mutex.h"
|
||||||
|
#include "wfskrn_Permission_Type.h"
|
||||||
|
|
||||||
|
#define WFSKRN_ACCESSLIST_MAX_CONTROL_LEVEL 3
|
||||||
|
|
||||||
|
#if !_IOP
|
||||||
|
namespace wfsdev_api{
|
||||||
|
struct tagSAreaInfo;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef ROUNDUP32BYTE
|
||||||
|
#define ROUNDUP32BYTE(val) (((size_t)val+31)&~31)
|
||||||
|
#endif // ROUNDUP32BYTE
|
||||||
|
|
||||||
|
//
|
||||||
|
// Accesslist Cache
|
||||||
|
//
|
||||||
|
|
||||||
|
#define ACL_MAX_MEMORY_BLOCK 254 // [check]
|
||||||
|
#define ACL_NO_ENTRY 255 // [check]
|
||||||
|
|
||||||
|
typedef struct WFSKrnAccessListEntry
|
||||||
|
{
|
||||||
|
u32 id; // title ID.
|
||||||
|
u32 ecId; // entry creator's Id.
|
||||||
|
u32 pm; // permissions and control levels.
|
||||||
|
} WFSKrnAccessListEntry;
|
||||||
|
|
||||||
|
typedef struct _WFSKrnAccessList WFSKrnAccessList;
|
||||||
|
|
||||||
|
struct _WFSKrnAccessList
|
||||||
|
{
|
||||||
|
u8 num; // number of blocks in this list.
|
||||||
|
u8 type; // WFSKRN_ACCESSLIST_FREEBLOCK or 0.
|
||||||
|
u16 ref; // reference count of this cache.
|
||||||
|
WFSKrnAclHandle handle; // access list handle and WFSKRN_ACCESSLIST_FLAG_* flags
|
||||||
|
u8 prevFreeCacheBlock; // previous free cache.
|
||||||
|
u8 nextFreeCacheBlock; // next free cache.
|
||||||
|
u8 prevBlock; // previous cache.
|
||||||
|
u8 nextBlock; // next cache.
|
||||||
|
};
|
||||||
|
|
||||||
|
// cache list, free cache list.
|
||||||
|
typedef struct WFSKrnAccessListLinkList
|
||||||
|
{
|
||||||
|
WFSKrnAccessList* head;
|
||||||
|
WFSKrnAccessList* tail;
|
||||||
|
} WFSKrnAccessListLinkList;
|
||||||
|
|
||||||
|
#define WFSKRN_ACCESSLIST_FREEBLOCK ((u8) 0x1) // Free memory block.
|
||||||
|
#define WFSKRN_BLOCKS_IN_LIST(x) (sizeof(WFSKrnAccessList)/sizeof(WFSKrnAccessListBlock) + \
|
||||||
|
WFSKrnAccessListGetNum(x) * (sizeof(WFSKrnAccessListEntry)/sizeof(WFSKrnAccessListBlock)))
|
||||||
|
|
||||||
|
typedef struct WFSKrnAccessListBlock
|
||||||
|
{
|
||||||
|
u8 num; // number of blocks in this chunk.
|
||||||
|
u8 type; // WFSKRN_ACCESSLIST_FREEBLOCK or 0.
|
||||||
|
u8 reserved;
|
||||||
|
u8 nextBlock; // the block number of the next chunk.
|
||||||
|
} WFSKrnAccessListBlock;
|
||||||
|
|
||||||
|
#define ACL_DEFAULT_CACHESIZE (128 * sizeof(WFSKrnAccessListBlock))
|
||||||
|
|
||||||
|
//
|
||||||
|
// Accesslist Index
|
||||||
|
//
|
||||||
|
|
||||||
|
#define ACL_RELATIVE_CL_FLAG 0x8000
|
||||||
|
#define ACL_CL_MASK 0x0003
|
||||||
|
#define WFS_PERM_RELATIVE_CL_FLAG 0x8000
|
||||||
|
|
||||||
|
static inline WFSKrnResult ACL_GET_CL_RELATIVE(u32 perm, int* cl)
|
||||||
|
{
|
||||||
|
WFSKrnResult result = WFSKRN_RESULT_INVALID;
|
||||||
|
if (perm & ACL_RELATIVE_CL_FLAG)
|
||||||
|
{
|
||||||
|
u32 val = ((~perm >> WFS_PERM_CL_SHIFT) & ACL_CL_MASK);
|
||||||
|
*cl = -((int) val);
|
||||||
|
result = WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ACL_ENTRY_NET_SIZE (sizeof(u32) + sizeof(u32) + sizeof(u16)) // smaller than sizeof(WFSKrnAccessListEntry).
|
||||||
|
#define ACL_MAX_ENTRIES (WFS_MAX_FILE_NAME_SIZE - sizeof(u32)*2)/(ACL_ENTRY_NET_SIZE*2)
|
||||||
|
// flags for accesslist handle
|
||||||
|
#define ACL_FLAG_DIRECTORY (1<<31) // accesslist for directory.
|
||||||
|
#define ACL_FLAG_RESERVED0 (1<<30)
|
||||||
|
#define ACL_FLAG_RESERVED1 (1<<29)
|
||||||
|
#define ACL_FLAG_RESERVED2 (1<<28)
|
||||||
|
#define ACL_TYPE_MASK (~0xf0000000)
|
||||||
|
#define ACL_TYPE(x) ((x)->handle & ~ACL_TYPE_MASK)
|
||||||
|
#define ACL_INDEX(x) ((x)->handle & ACL_TYPE_MASK)
|
||||||
|
|
||||||
|
#define WFSKRN_ACCESSLIST_GROUP 0x80000000
|
||||||
|
|
||||||
|
// escape sequence to convert a content of an accesslist to a filename.
|
||||||
|
#define ESCAPE 0x33
|
||||||
|
#define ESCAPED_NULL 0x58
|
||||||
|
|
||||||
|
//
|
||||||
|
// Index List
|
||||||
|
// which manages indices of free and used accesslists.
|
||||||
|
//
|
||||||
|
#define WFSKRN_ACCESSLIST_INDEXES_IN_PAGE 16
|
||||||
|
#define WFSKRN_ACCESSLIST_INDEXLIST_MAX_PAGE 6
|
||||||
|
#define WFSKRN_ACCESSLIST_FREEINDEX 0xffffffff
|
||||||
|
|
||||||
|
typedef struct IndexListHeader
|
||||||
|
{
|
||||||
|
u32 numEntry;
|
||||||
|
} IndexListHeader;
|
||||||
|
|
||||||
|
typedef struct IndexListEntry
|
||||||
|
{
|
||||||
|
u32 location;
|
||||||
|
} IndexListEntry;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Control Block of Accesslists.
|
||||||
|
//
|
||||||
|
|
||||||
|
#if WFSDEV
|
||||||
|
namespace wfsdev_api{
|
||||||
|
struct tagSAreaInfo;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _struct_WFSAccessListControlBlock_
|
||||||
|
#define _struct_WFSAccessListControlBlock_
|
||||||
|
typedef struct _WFSAccessListControlBlock WFSAccessListControlBlock;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct _WFSAccessListControlBlock
|
||||||
|
{
|
||||||
|
WFSKrnAccessListBlock* freeBlock;
|
||||||
|
WFSKrnAccessListBlock* memoryBlock; // heap for accesslist cache.
|
||||||
|
u32 numBlock;
|
||||||
|
|
||||||
|
WFSKrnAccessListLinkList cache;
|
||||||
|
WFSKrnAccessListLinkList cacheFreeList;
|
||||||
|
#ifdef WFSKRN_ACL_USE_MUTEX
|
||||||
|
WFSKrnMutex mxMutex;
|
||||||
|
#endif // WFSKRN_ACL_USE_MUTEX
|
||||||
|
|
||||||
|
#if WFSDEV
|
||||||
|
struct wfsdev_api::tagSAreaInfo *aclWrapper;
|
||||||
|
#endif
|
||||||
|
WFSBool initialized;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// APIs
|
||||||
|
//
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSKrnAccessListInit
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] A WFS area.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. success
|
||||||
|
// WFSKRN_RESULT_ACL_ERROR .. (see wfskrn_Errors.h)
|
||||||
|
// WFSKRN_RESULT_INVALID
|
||||||
|
// WFSKRN_RESULT_OUT_OF_MEMORY
|
||||||
|
// WFSKRN_RESULT_LIB_ALREADY_INITIALIZED
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function initializes accesslist cache and accesslist index list.
|
||||||
|
// WFSAccessListControlBlock{} in area (AreaInfo{}) must be properly initialized before calling this function.
|
||||||
|
// - Memory blocks for accesslist cache must be set in memoryBlock field of WFSAccessListControlBlock{}.
|
||||||
|
// - The number of blocks must be set in numBlock field.
|
||||||
|
// - initialized field must be set to FALSE.
|
||||||
|
WFSKrnResult WFSKrnAccessListInit(AreaInfo* area);
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSKrnAccessListOpen
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] A WFS area.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. success
|
||||||
|
// WFSKRN_RESULT_OUT_OF_MEMORY
|
||||||
|
// WFSKRN_RESULT_LIB_ALREADY_INITIALIZED
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function initializes accesslist cache and loads accesslist configuration from the device:
|
||||||
|
// - the root block for accesslist files.
|
||||||
|
// - the root block for accesslist namefiles and the index list.
|
||||||
|
// WFSAccessListControlBlock{} in area (AreaInfo{}) must be properly initialized before calling this function.
|
||||||
|
// - Memory blocks for accesslist cache must be set in memoryBlock field of WFSAccessListControlBlock{}.
|
||||||
|
// - The number of blocks must be set in numBlock field.
|
||||||
|
// - initialized field must be set to FALSE.
|
||||||
|
WFSKrnResult WFSKrnAccessListOpen(const AreaInfo* area);
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSKrnAccessListExit
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] A WFS area.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFS_RESULT_OK .. success
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function is not implemented.
|
||||||
|
//
|
||||||
|
WFSKrnResult WFSKrnAccessListExit(const AreaInfo* area);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSKrnDeletePermissions
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] A WFS area.
|
||||||
|
// handle .. [in] Accesslist handle.
|
||||||
|
// titleId .. [in] Title Id to be deleted.
|
||||||
|
// entryCreatorId .. [in] Entry creator's Id.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. success
|
||||||
|
// WFSKRN_RESULT_INVALID
|
||||||
|
// WFSKRN_RESULT_ACL_ERROR
|
||||||
|
// WFSKRN_RESULT_ACL_MAX_ENTRIES
|
||||||
|
// WFSKRN_RESULT_ACL_FILE
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function deletes the specified entry in the specified accesslist.
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnDeletePermissions(const AreaInfo* area,
|
||||||
|
WFSKrnAclHandle* handle, WFSTitleId entryCreatorId, WFSTitleId titleId);
|
||||||
|
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] A WFS area.
|
||||||
|
// handle .. [in] Accesslist handle.
|
||||||
|
// pAccessList .. [out] Buffer for an accesslist.
|
||||||
|
// nMaxElements .. [out] Size of the buffer.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// The number of entries. .. success
|
||||||
|
// WFSKRN_RESULT_ACL_BUFFER_TOO_SMALL
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function gets all entries in the specified accesslist.
|
||||||
|
|
||||||
|
s32 WFSKrnGetAccessList(const AreaInfo* area,
|
||||||
|
WFSKrnAclHandle handle, WFSAccessListEntry *pAccessList, u32 nMaxElements);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSKrnSetAccessList
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] A WFS area.
|
||||||
|
// handle .. [inout] Accesslist handle.
|
||||||
|
// caller .. [in]
|
||||||
|
// nFlags .. [in] Permissions and control levels to be set.
|
||||||
|
// nMask .. [in] Mask of permissions.
|
||||||
|
// entryCreatorId .. [in] Id of the title which created the entry.
|
||||||
|
// titleId .. [in] Title Id of the entry to be modified.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. success
|
||||||
|
// WFSKRN_RESULT_INVALID
|
||||||
|
// WFSKRN_RESULT_ACL_ERROR
|
||||||
|
// WFSKRN_RESULT_ACL_MAX_ENTRIES
|
||||||
|
// WFSKRN_RESULT_ACL_FILE
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function chnages permissions of the specified entry, or creates a new entry.
|
||||||
|
WFSKrnResult WFSKrnSetAccessList(const AreaInfo* area, WFSKrnAclHandle* handle,
|
||||||
|
u32 nFlags, u32 nMask, WFSTitleId entryCreatorId, WFSTitleId titleId);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSKrnReleaseAccessList
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] A WFS area.
|
||||||
|
// handle .. [in] A handle of accesslist .
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. success
|
||||||
|
// WFSKRN_RESULT_ACL_ERROR
|
||||||
|
// WFSKRN_RESULT_ACL_CACHE
|
||||||
|
// WFSKRN_RESULT_ACL_FILE
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function decrements the reference count of the specified accesslist.
|
||||||
|
// When the count reduces to zero, the accesslist is removed.
|
||||||
|
// This is called when deleting a file or directory.
|
||||||
|
WFSKrnResult WFSKrnReleaseAccessList(const AreaInfo* area, WFSKrnAclHandle handle);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSKrnAccessListCheckDirectoryPermission
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] WFS area.
|
||||||
|
// handle .. [in] A handle of an accesslist for a directory.
|
||||||
|
// titleId .. [in] Title ID.
|
||||||
|
// flag .. [in] Permissions to be checked.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// TRUE .. The title has the specified permissions.
|
||||||
|
// FALSE .. The title does not have the permissions.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function checks if the title has the specified directory permissions.
|
||||||
|
//
|
||||||
|
// WFSBool WFSKrnAccessListCheckDirectoryPermission(const AreaInfo* area, WFSKrnAclHandle handle, WFSTitleId titleId, u32 flag);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSKrnAccessListCheckDirectoryPermission
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] WFS area.
|
||||||
|
// handle .. [in] A handle of an accesslist for a file.
|
||||||
|
// titleId .. [in] Title ID.
|
||||||
|
// flag .. [in] Permissions to be checked.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// TRUE .. The title has the specified permissions.
|
||||||
|
// FALSE .. The title does not have the permissions.
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function checks if the title has the specified file permissions.
|
||||||
|
// WFSBool WFSKrnAccessListCheckFilePermission(const AreaInfo* area,
|
||||||
|
// WFSKrnAclHandle handle, WFSTitleId titleId, u32 flag);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Memory block allocator for accesslist cache.
|
||||||
|
//
|
||||||
|
WFSKrnAccessListBlock* WFSKrnMemoryBlockAlloc(const AreaInfo* area, int numBlocks);
|
||||||
|
int WFSKrnMemoryBlockFree(const AreaInfo* area, WFSKrnAccessListBlock* block, u32 numBlocks);
|
||||||
|
|
||||||
|
#endif // __WFSKRN_PERMISSION_ACCESSLIST_H__
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Permission_AccessList_Type.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Permission_AccessList_Type.h,v $
|
||||||
|
Revision 1.1 2008/09/24 07:50:34 ueno
|
||||||
|
Added AclHdr{} to AreaHdr{} to save configuration of accesslists in a disk.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef __WFSKRN_PERMISSION_ACCESSLIST_TYPE_H__
|
||||||
|
#define __WFSKRN_PERMISSION_ACCESSLIST_TYPE_H__
|
||||||
|
|
||||||
|
typedef struct _AclHdr
|
||||||
|
{
|
||||||
|
WFSBlkAdr aclBlock;
|
||||||
|
WFSBlkAdr nameBlock;
|
||||||
|
} AclHdr;
|
||||||
|
|
||||||
|
#endif // __WFSKRN_PERMISSION_ACCESSLIST_TYPE_H__
|
||||||
@ -0,0 +1,107 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfskrn
|
||||||
|
File: wfs_Permission.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Permission_File.h,v $
|
||||||
|
Revision 1.9 2008/07/23 04:18:07 ueno
|
||||||
|
Reduced memory size required for accesslist.
|
||||||
|
|
||||||
|
Revision 1.8 2008/05/23 06:31:52 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.7 2008/05/22 06:36:01 ueno
|
||||||
|
Ported permission APIs to IOP.
|
||||||
|
|
||||||
|
Revision 1.6 2008/05/19 10:12:05 ueno
|
||||||
|
Revised not to use hardlink.
|
||||||
|
|
||||||
|
Revision 1.5 2008/05/15 13:33:46 ueno
|
||||||
|
Implemented initialization using directory module.
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/29 06:25:14 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/25 06:22:55 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 01:22:46 ueno
|
||||||
|
Moved from RVL_SDK to RM_SDK.
|
||||||
|
|
||||||
|
Revision 1.12 2008/04/23 08:59:55 ueno
|
||||||
|
Replaced WFSAreaHdr by AreaInfo.
|
||||||
|
Revised directory permission (change -> add).
|
||||||
|
|
||||||
|
Revision 1.11 2008/04/21 06:07:55 ueno
|
||||||
|
Fixed struct for C99.
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/15 06:45:48 ueno
|
||||||
|
Changed return type to WFSKrnResult.
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/11 06:16:33 ueno
|
||||||
|
Defined WFSAclFileHandle.
|
||||||
|
Cleaned up headers.
|
||||||
|
|
||||||
|
Revision 1.8 2008/03/14 08:02:49 ueno
|
||||||
|
Revised API prefixes (WFS -> WFSKrn).
|
||||||
|
|
||||||
|
Revision 1.7 2008/03/11 12:10:35 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.6 2008/02/29 07:28:45 ueno
|
||||||
|
Added Windows api wrappers.
|
||||||
|
|
||||||
|
Revision 1.5 2008/02/27 13:12:23 ueno
|
||||||
|
Revised to store a filename of an accesslist in a file (*.name).
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/27 10:05:26 ueno
|
||||||
|
Revised to use WFSAreaHdr{} to specifiy WFS area.
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/26 14:12:06 ueno
|
||||||
|
Added WFSAccessListAddEntry() and WFSAccessListRemoveEntry() to edit accesslist.
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/25 09:44:08 ueno
|
||||||
|
Added support for accesslist cache.
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/22 05:15:56 ueno
|
||||||
|
Initial Check-in.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef __WFSKRN_PERMISSION_FILE_H__
|
||||||
|
#define __WFSKRN_PERMISSION_FILE_H__
|
||||||
|
|
||||||
|
#include <revolution/wfs.h>
|
||||||
|
#include "wfssrv_Defs.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_Permission_Type.h"
|
||||||
|
|
||||||
|
#ifndef WFSDEV
|
||||||
|
#define IndexDirInfo(x) (((x)->accessListCb->indexDirInfo))
|
||||||
|
#endif // WFSDEV
|
||||||
|
|
||||||
|
int WFSKrnConvertAccessListToFilename(const WFSKrnAccessList* list, utf8* filename, u32 size);
|
||||||
|
int WFSKrnConvertFilenameToAccessList(const utf8* filename, u32 size, WFSKrnAccessList* list);
|
||||||
|
|
||||||
|
int WFSKrnAccessListIndexListInit(const AreaInfo* area);
|
||||||
|
int WFSKrnAccessListIndexListExit(const AreaInfo* area);
|
||||||
|
int WFSKrnAccessListCreateFile(const AreaInfo* area, const utf8* filename, WFSKrnAccessList** list);
|
||||||
|
WFSKrnResult WFSKrnAccessListDeleteFile(const AreaInfo* area, u32 index);
|
||||||
|
WFSKrnAccessList* WFSKrnAccessListLookupFile(const AreaInfo* area, u32 index);
|
||||||
|
WFSKrnResult WFSKrnAccessListSetFileReferenceCount(const AreaInfo* area, u32 index, u32 ref);
|
||||||
|
WFSKrnResult WFSKrnAccessListGetFileReferenceCount(const AreaInfo* area, u32 index, u32* ref);
|
||||||
|
int WFSKrnAccessListOpenList(const AreaInfo* area, const utf8* filename, AclFileInfo* aclFile,
|
||||||
|
WFSBool create, WFSAclFileHandle *pFh);
|
||||||
|
|
||||||
|
int GetAccessListIndex(const AreaInfo* area, WFSAclFileHandle indexListHandle, WFSKrnAclHandle handle, IndexListEntry* entry);
|
||||||
|
int OpenIndexList(const AreaInfo* area, WFSAclFileHandle* indexListHandle, AclFileInfo* indexListInfo);
|
||||||
|
int CloseIndexList(const AreaInfo* area, WFSAclFileHandle indexListHandle);
|
||||||
|
|
||||||
|
#endif // __WFSKRN_PERMISSION_FILE_H__
|
||||||
@ -0,0 +1,123 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfsKrn
|
||||||
|
File: wfs_Permission_Iop.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Permission_Iop.h,v $
|
||||||
|
Revision 1.7 2008/09/24 07:32:07 ueno
|
||||||
|
Added AclHdr{} to AreaHdr{} to save configuration of accesslists in a disk.
|
||||||
|
|
||||||
|
Revision 1.6 2008/07/23 04:18:07 ueno
|
||||||
|
Reduced memory size required for accesslist.
|
||||||
|
|
||||||
|
Revision 1.5 2008/05/22 06:36:01 ueno
|
||||||
|
Ported permission APIs to IOP.
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/19 10:12:05 ueno
|
||||||
|
Revised not to use hardlink.
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/19 05:31:53 ueno
|
||||||
|
Defined accesslist meta-data types.
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/15 13:33:46 ueno
|
||||||
|
Implemented initialization using directory module.
|
||||||
|
|
||||||
|
Revision 1.1 2008/05/06 07:38:27 ueno
|
||||||
|
Initial Check-in.
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/29 06:25:14 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.5 2008/04/29 01:12:54 ueno
|
||||||
|
Defined WFS_ROOT_ID and WFS_EVERYONE_ID.
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/25 06:22:55 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/25 04:40:47 ueno
|
||||||
|
Added support for WFSDEV.
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/23 08:59:55 ueno
|
||||||
|
Replaced WFSAreaHdr by AreaInfo.
|
||||||
|
Revised directory permission (change -> add).
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/11 06:16:33 ueno
|
||||||
|
Defined WFSAclFileHandle.
|
||||||
|
Cleaned up headers.
|
||||||
|
|
||||||
|
Revision 1.8 2008/04/07 09:17:44 ueno
|
||||||
|
Modified WFSKrnAccessListDirectoryInit() to return an integer.
|
||||||
|
|
||||||
|
Revision 1.7 2008/04/03 09:59:41 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.6 2008/03/14 08:02:49 ueno
|
||||||
|
Revised API prefixes (WFS -> WFSKrn).
|
||||||
|
|
||||||
|
Revision 1.5 2008/02/29 07:28:45 ueno
|
||||||
|
Added Windows api wrappers.
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/28 13:11:58 ueno
|
||||||
|
Revised to keep accesslist cache and indexlist handle in WFSAreaHdr{}.
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/27 13:12:24 ueno
|
||||||
|
Revised to store a filename of an accesslist in a file (*.name).
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/27 10:05:26 ueno
|
||||||
|
Revised to use WFSAreaHdr{} to specifiy WFS area.
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/22 05:15:56 ueno
|
||||||
|
Initial Check-in.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef __WFSKRN_PERMISSION_IOP_H__
|
||||||
|
#define __WFSKRN_PERMISSION_IOP_H__
|
||||||
|
|
||||||
|
#include <revolution/wfs.h>
|
||||||
|
#include "wfssrv_Defs.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_Permission_Type.h"
|
||||||
|
|
||||||
|
#define INDEXLIST_FILENAME "index"
|
||||||
|
#define ACL_NAMEFILE_LEN 14 // including '\0'.
|
||||||
|
|
||||||
|
#define AclBlock(x) (((x)->ah.aclHdr.aclBlock))
|
||||||
|
#define NameBlock(x) (((x)->ah.aclHdr.nameBlock))
|
||||||
|
|
||||||
|
#define ACL_FILEINFO_NAME(aclFileInfo) ((aclFileInfo)->di.name.sStr)
|
||||||
|
|
||||||
|
int CreateNamefile(const AreaInfo* area, WFSKrnAclHandle handle, const AclNameFileHeader* header, const utf8* filename);
|
||||||
|
int DeleteNamefile(const AreaInfo* area, u32 index);
|
||||||
|
int ReadNamefile(const AreaInfo* area, WFSKrnAclHandle handle, void* buf, WFSFileSize size, WFSFileSize offset);
|
||||||
|
int WriteNamefile(const AreaInfo* area, WFSKrnAclHandle handle, const void* buf, WFSFileSize size, WFSFileSize offset);
|
||||||
|
|
||||||
|
int WFSKrnAccessListDirectoryInit(AreaInfo* area);
|
||||||
|
|
||||||
|
int WFSKrnAccessListGetAclFileInfo(const AreaInfo* area, const utf8* filename, u32 type, AclFileInfo* fileInfo);
|
||||||
|
|
||||||
|
int GetAccessListPath(const AreaInfo* area, AclFileInfo* aclFile);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Wrapper
|
||||||
|
//
|
||||||
|
|
||||||
|
WFSResult AclGetFileSize(const AreaInfo* area, WFSAclFileHandle fh, WFSFileSize* fileSize);
|
||||||
|
WFSResult AclWriteFile(const AreaInfo* area, WFSAclFileHandle fh, const void *pFileData, WFSFileSize nSize, WFSFileSize offset);
|
||||||
|
s32 AclReadFile(const AreaInfo* area, WFSAclFileHandle fh, void *pFileDataBuffer, s32 nSize, WFSFileSize offset);
|
||||||
|
|
||||||
|
WFSResult AclCreateFile(const AreaInfo* area, const AclFileInfo* fileInfo, WFSBool create, WFSAclFileHandle *pFh);
|
||||||
|
WFSResult AclCloseFile(WFSAclFileHandle fh);
|
||||||
|
|
||||||
|
WFSResult AclDeleteAccessListFile(const AreaInfo* area, const AclFileInfo* aclFile);
|
||||||
|
WFSResult AclCreateAccessListFile(const AreaInfo* area, const AclFileInfo* aclFile, WFSBool create, WFSAclFileHandle *pFh);
|
||||||
|
WFSBool AclAccessListAlreadyExist(const AreaInfo* area, const AclFileInfo* aclFile);
|
||||||
|
|
||||||
|
#endif // __WFSKRN_PERMISSION_IOP_H__
|
||||||
@ -0,0 +1,133 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfskrn
|
||||||
|
File: wfs_Permission_Private.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Permission_Private.h,v $
|
||||||
|
Revision 1.8 2008/06/05 14:04:11 ueno
|
||||||
|
Modified to reserve accesslist index 0 as the default (empty) accesslist.
|
||||||
|
|
||||||
|
Revision 1.7 2008/06/05 08:09:18 ueno
|
||||||
|
Revised permission APIs.
|
||||||
|
|
||||||
|
Revision 1.6 2008/05/28 01:06:52 ueno
|
||||||
|
Added AclCheckDisk() to check acl meta-data.
|
||||||
|
|
||||||
|
Revision 1.5 2008/05/23 06:31:52 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/22 06:36:01 ueno
|
||||||
|
Ported permission APIs to IOP.
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/29 01:12:54 ueno
|
||||||
|
Defined WFS_ROOT_ID and WFS_EVERYONE_ID.
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 01:22:46 ueno
|
||||||
|
Moved from RVL_SDK to RM_SDK.
|
||||||
|
|
||||||
|
Revision 1.11 2008/04/23 08:59:55 ueno
|
||||||
|
Replaced WFSAreaHdr by AreaInfo.
|
||||||
|
Revised directory permission (change -> add).
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/14 03:02:16 ueno
|
||||||
|
Modified WFSKrnCreateRootAccessList() to create an accesslist only for the root.
|
||||||
|
Added WFSKrnDebugCreateAccessList() for tests.
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/11 06:16:33 ueno
|
||||||
|
Defined WFSAclFileHandle.
|
||||||
|
Cleaned up headers.
|
||||||
|
|
||||||
|
Revision 1.8 2008/04/11 04:54:06 ueno
|
||||||
|
Added WFSKRN_ACL_USE_MUTEX to switch mutex.
|
||||||
|
|
||||||
|
Revision 1.7 2008/04/09 03:01:27 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/08 06:39:41 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.5 2008/04/01 08:25:10 ueno
|
||||||
|
Fixed cache reference count.
|
||||||
|
|
||||||
|
Revision 1.4 2008/03/18 13:42:39 ueno
|
||||||
|
Added a debug function.
|
||||||
|
|
||||||
|
Revision 1.3 2008/03/14 08:02:49 ueno
|
||||||
|
Revised API prefixes (WFS -> WFSKrn).
|
||||||
|
|
||||||
|
Revision 1.2 2008/03/07 05:31:07 ueno
|
||||||
|
Modified WFSCreateAccessList() to be able to create an accesslist for directories.
|
||||||
|
|
||||||
|
Revision 1.1 2008/03/06 10:47:12 ueno
|
||||||
|
New.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef __WFSKRN_PERMISSION_PRIVATE_H__
|
||||||
|
#define __WFSKRN_PERMISSION_PRIVATE_H__
|
||||||
|
|
||||||
|
#include <revolution/wfs.h>
|
||||||
|
#include "wfssrv_Defs.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
|
||||||
|
// private APIs
|
||||||
|
#ifdef WFSDEV
|
||||||
|
int AclUtf8ToWchar(const utf8* utf8, LPWSTR wchar, u32 bytes);
|
||||||
|
int AclWcharToUtf8(const LPWSTR wchar, utf8* utf8, u32 bytes);
|
||||||
|
#endif // WFSDEV
|
||||||
|
|
||||||
|
void WFSKrnAccessListSetNum(WFSKrnAccessList* list, u32 num);
|
||||||
|
u32 WFSKrnAccessListGetNum(const WFSKrnAccessList* list);
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnAccessListAlloc(const AreaInfo* area, u32 numEntries, WFSKrnAccessList** list);
|
||||||
|
int WFSKrnAccessListFree(const AreaInfo* area, WFSKrnAccessList* list);
|
||||||
|
|
||||||
|
int WFSKrnAllocAccessListIndex(const AreaInfo* area, u32 indexFlags, u32* newIndex, u32 num);
|
||||||
|
int WFSKrnFreeAccessListIndex(const AreaInfo* area, u32 index);
|
||||||
|
|
||||||
|
void WFSKrnAccessListCacheAdd(const AreaInfo* area, WFSKrnAccessList* list);
|
||||||
|
void WFSKrnAccessListCacheRemove(const AreaInfo* area, WFSKrnAccessList* list);
|
||||||
|
void WFSKrnAccessListCacheFreeListRemove(const AreaInfo* area, WFSKrnAccessList* list);
|
||||||
|
WFSKrnAccessList* WFSKrnAccessListLookup(const AreaInfo* area, u32 index);
|
||||||
|
WFSKrnAccessList* WFSKrnAccessListLookupByIndex(const AreaInfo* area, u32 index);
|
||||||
|
|
||||||
|
// debug functions.
|
||||||
|
WFSBool VerifyMemoryBlock(const AreaInfo* area);
|
||||||
|
void PrintMemoryBlock(const AreaInfo* area);
|
||||||
|
void WFSKrnDebugPrintAccessList(const AreaInfo* area, u32 index);
|
||||||
|
s32 AclDirList(const AreaInfo* area, WFSBlkAdr block);
|
||||||
|
WFSKrnResult AclCheckDisk(const AreaInfo* area);
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// WFSKrnDebugCreateAccessList
|
||||||
|
//--------------------------------------------------------------------------------------------------------------
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// area .. [in] A WFS area.
|
||||||
|
// aclType .. [in] ACL_FLAG_DIRECTORY (directory) or 0 (file).
|
||||||
|
// titleId .. [in] The first title in the accesslist to be created.
|
||||||
|
// nFlags .. [in] permissions and control levels (WFS_PERM_*)
|
||||||
|
// newHandle .. [out] Pointer to the new accesslist handle.
|
||||||
|
//
|
||||||
|
// Return Values:
|
||||||
|
// --------------
|
||||||
|
// WFSKRN_RESULT_OK .. success
|
||||||
|
// WFSKRN_RESULT_INVALID
|
||||||
|
// WFSKRN_RESULT_ACL_ERROR
|
||||||
|
// WFSKRN_RESULT_ACL_MAX_ENTRIES
|
||||||
|
// WFSKRN_RESULT_ACL_FILE
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// This function creates an accesslist.
|
||||||
|
WFSKrnResult WFSKrnDebugCreateAccessList(const AreaInfo* area, u32 aclType,
|
||||||
|
WFSTitleId entryCreatorId, WFSTitleId titleId, u32 nFlags, WFSKrnAclHandle* newHandle);
|
||||||
|
|
||||||
|
#endif // __WFSKRN_PERMISSION_PRIVATE_H__
|
||||||
@ -0,0 +1,137 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfskrn
|
||||||
|
File: wfs_Permission_Type.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Permission_Type.h,v $
|
||||||
|
Revision 1.12 2008/07/23 04:18:07 ueno
|
||||||
|
Reduced memory size required for accesslist.
|
||||||
|
|
||||||
|
Revision 1.11 2008/07/23 02:01:51 ueno
|
||||||
|
Modified to use mutex on Windows.
|
||||||
|
|
||||||
|
Revision 1.10 2008/05/30 08:50:35 ueno
|
||||||
|
Disabled mutex for IOP.
|
||||||
|
|
||||||
|
Revision 1.9 2008/05/23 06:31:52 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.8 2008/05/22 06:36:01 ueno
|
||||||
|
Ported permission APIs to IOP.
|
||||||
|
|
||||||
|
Revision 1.7 2008/05/19 10:12:05 ueno
|
||||||
|
Revised not to use hardlink.
|
||||||
|
|
||||||
|
Revision 1.6 2008/05/19 05:31:53 ueno
|
||||||
|
Defined accesslist meta-data types.
|
||||||
|
|
||||||
|
Revision 1.5 2008/05/16 11:16:58 ueno
|
||||||
|
Implemented permission APIs with directory module.
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/15 13:33:46 ueno
|
||||||
|
Implemented initialization using directory module.
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/06 02:27:21 ueno
|
||||||
|
Fixed ifdef.
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/29 06:25:14 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/11 06:16:33 ueno
|
||||||
|
Defined WFSAclFileHandle.
|
||||||
|
Cleaned up headers.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef __WFSKRN_PERMISSION_TYPE_H__
|
||||||
|
#define __WFSKRN_PERMISSION_TYPE_H__
|
||||||
|
|
||||||
|
#include <revolution/wfs.h>
|
||||||
|
#include "wfskrn_Dir.h"
|
||||||
|
#include "wfskrn_Handles.h"
|
||||||
|
#include "wfskrn_DirFind.h"
|
||||||
|
#include "wfskrn_DirNodeStack.h"
|
||||||
|
|
||||||
|
// access list handle
|
||||||
|
typedef u32 WFSKrnAclHandle;
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
// The maximum path length of an emulation directory is WFSKRN_MAX_PATH_NAME_SIZE.
|
||||||
|
#define WFSKRN_ACCESSLIST_MAX_PATH_LEN ((WFS_MAX_PATH_NAME_SIZE+1)*2)
|
||||||
|
#else
|
||||||
|
#define WFSKRN_ACCESSLIST_MAX_PATH_LEN (WFS_MAX_PATH_NAME_SIZE+1)
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
// type of metadata.
|
||||||
|
#define ACL_TYPE_INDEXLIST 1
|
||||||
|
#define ACL_TYPE_NAMEFILE 2
|
||||||
|
#define ACL_TYPE_ACLFILE 3
|
||||||
|
|
||||||
|
typedef struct AclFileInfo
|
||||||
|
{
|
||||||
|
u32 type; // ACL_TYPE_*
|
||||||
|
#ifdef WFSDEV
|
||||||
|
utf8 path[WFSKRN_ACCESSLIST_MAX_PATH_LEN];
|
||||||
|
#else
|
||||||
|
DirItr di;
|
||||||
|
#endif // WIN32
|
||||||
|
} AclFileInfo;
|
||||||
|
|
||||||
|
typedef struct AclNameFileHeader
|
||||||
|
{
|
||||||
|
u32 num; // The number of titles in this list.
|
||||||
|
u32 ref; // The number of files and directories associated with this accesslist.
|
||||||
|
} AclNameFileHeader;
|
||||||
|
|
||||||
|
// file handle
|
||||||
|
#ifdef WFSDEV
|
||||||
|
typedef HANDLE WFSAclFileHandle;
|
||||||
|
#else // WFSDEV
|
||||||
|
typedef AclFileInfo* WFSAclFileHandle;
|
||||||
|
#endif // WFSDEV
|
||||||
|
|
||||||
|
// mutex
|
||||||
|
// #define WFSKRN_ACL_USE_MUTEX // [check] how to use mutex on IOP?
|
||||||
|
|
||||||
|
#ifdef WFSKRN_ACL_USE_MUTEX
|
||||||
|
#include "wfskrn_Mutex.h"
|
||||||
|
#define WFSAclInitMutex(x) WFSKrnInitMutex(x)
|
||||||
|
#define WFSAclLockMutex(x) WFSKrnLockMutex(x)
|
||||||
|
#define WFSAclUnlockMutex(x) WFSKrnUnlockMutex(x)
|
||||||
|
#else
|
||||||
|
#define WFSAclInitMutex(x)
|
||||||
|
#define WFSAclLockMutex(x)
|
||||||
|
#define WFSAclUnlockMutex(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// print message
|
||||||
|
#define WFSKRN_ACL_DEBUG
|
||||||
|
|
||||||
|
#ifdef WFSKRN_ACL_DEBUG
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
#define WFSKRN_ACL_ASSERT(x) assert(x)
|
||||||
|
#else // Win32
|
||||||
|
#define WFSKRN_ACL_ASSERT(x) ASSERT(x)
|
||||||
|
#endif // WIN32
|
||||||
|
#define WFSKRN_ACL_REPORT printf
|
||||||
|
|
||||||
|
#else // WFSKRN_ACL_DEBUG
|
||||||
|
|
||||||
|
#define WFSKRN_ACL_ASSERT(x)
|
||||||
|
#define WFSKRN_ACL_REPORT
|
||||||
|
|
||||||
|
#endif // WFSKRN_ACL_DEBUG
|
||||||
|
|
||||||
|
#endif // __WFSKRN_PERMISSION_TYPE_H__
|
||||||
@ -0,0 +1,127 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfsKrn
|
||||||
|
File: wfs_Permission_Win32.h
|
||||||
|
|
||||||
|
Copyright 2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Permission_Win32.h,v $
|
||||||
|
Revision 1.13 2008/09/24 07:32:07 ueno
|
||||||
|
Added AclHdr{} to AreaHdr{} to save configuration of accesslists in a disk.
|
||||||
|
|
||||||
|
Revision 1.12 2008/05/19 10:12:05 ueno
|
||||||
|
Revised not to use hardlink.
|
||||||
|
|
||||||
|
Revision 1.11 2008/05/19 05:31:53 ueno
|
||||||
|
Defined accesslist meta-data types.
|
||||||
|
|
||||||
|
Revision 1.10 2008/05/15 13:33:46 ueno
|
||||||
|
Implemented initialization using directory module.
|
||||||
|
|
||||||
|
Revision 1.9 2008/05/08 08:08:02 ueno
|
||||||
|
Revised AclReadFile() and AclWriteFile() to set offset.
|
||||||
|
|
||||||
|
Revision 1.8 2008/05/06 03:16:07 ueno
|
||||||
|
Added AclGetFileSize() to wrap Windows API..
|
||||||
|
|
||||||
|
Revision 1.7 2008/05/06 02:27:21 ueno
|
||||||
|
Fixed ifdef.
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/29 06:25:14 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.5 2008/04/29 01:12:54 ueno
|
||||||
|
Defined WFS_ROOT_ID and WFS_EVERYONE_ID.
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/25 06:22:55 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/25 04:40:47 ueno
|
||||||
|
Added support for WFSDEV.
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/23 08:59:55 ueno
|
||||||
|
Replaced WFSAreaHdr by AreaInfo.
|
||||||
|
Revised directory permission (change -> add).
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/11 06:16:33 ueno
|
||||||
|
Defined WFSAclFileHandle.
|
||||||
|
Cleaned up headers.
|
||||||
|
|
||||||
|
Revision 1.8 2008/04/07 09:17:44 ueno
|
||||||
|
Modified WFSKrnAccessListDirectoryInit() to return an integer.
|
||||||
|
|
||||||
|
Revision 1.7 2008/04/03 09:59:41 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.6 2008/03/14 08:02:49 ueno
|
||||||
|
Revised API prefixes (WFS -> WFSKrn).
|
||||||
|
|
||||||
|
Revision 1.5 2008/02/29 07:28:45 ueno
|
||||||
|
Added Windows api wrappers.
|
||||||
|
|
||||||
|
Revision 1.4 2008/02/28 13:11:58 ueno
|
||||||
|
Revised to keep accesslist cache and indexlist handle in WFSAreaHdr{}.
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/27 13:12:24 ueno
|
||||||
|
Revised to store a filename of an accesslist in a file (*.name).
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/27 10:05:26 ueno
|
||||||
|
Revised to use WFSAreaHdr{} to specifiy WFS area.
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/22 05:15:56 ueno
|
||||||
|
Initial Check-in.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifndef __WFSKRN_PERMISSION_WIN32_H__
|
||||||
|
#define __WFSKRN_PERMISSION_WIN32_H__
|
||||||
|
|
||||||
|
#include <revolution/wfs.h>
|
||||||
|
#include "wfs_Client.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_Permission_Type.h"
|
||||||
|
|
||||||
|
#define LONGPATH_PREFIX L"\\\\?\\"
|
||||||
|
#define ACCESSLIST_DIR ".WFSAccessLists"
|
||||||
|
#define ACCESSLIST_DIR_WCHAR L".WFSAccessLists"
|
||||||
|
#define INDEXLIST_FILENAME ".wfsaccesslist_indexlist"
|
||||||
|
#define NAMEFILE_DIR "name"
|
||||||
|
#define NAMEFILE_DIR_WCHAR L"name"
|
||||||
|
|
||||||
|
WFSBool AlreadyExist(const LPWSTR path);
|
||||||
|
int Utf8ToWcharAccessList(const AreaInfo* area, const utf8* path, LPWSTR wPath, u32 wPathLen);
|
||||||
|
int EscapeAccessListToWideChar(const char* encoded, LPWSTR wPath, u32 size);
|
||||||
|
int UnescapeAccessListFromWideChar(const LPWSTR wPath, utf8* encoded, u32 size);
|
||||||
|
|
||||||
|
int CreateNamefile(const AreaInfo* area, WFSKrnAclHandle handle, const AclNameFileHeader* header, const utf8* filename);
|
||||||
|
int DeleteNamefile(const AreaInfo* area, u32 index);
|
||||||
|
int ReadNamefile(const AreaInfo* area, WFSKrnAclHandle handle, void* buf, WFSFileSize size, WFSFileSize offset);
|
||||||
|
int WriteNamefile(const AreaInfo* area, WFSKrnAclHandle handle, const void* buf, WFSFileSize size, WFSFileSize offset);
|
||||||
|
|
||||||
|
int WFSKrnAccessListDirectoryInit(AreaInfo* area);
|
||||||
|
|
||||||
|
int WFSKrnAccessListGetAclFileInfo(const AreaInfo* area, const utf8* filename, u32 type, AclFileInfo* fileInfo);
|
||||||
|
|
||||||
|
int GetAccessListPath(const AreaInfo* area, AclFileInfo* aclFile);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Wrapper
|
||||||
|
//
|
||||||
|
|
||||||
|
WFSResult AclGetFileSize(const AreaInfo* area, WFSAclFileHandle fh, WFSFileSize* fileSize);
|
||||||
|
WFSResult AclWriteFile(const AreaInfo* area, WFSAclFileHandle fh, const void *pFileData, WFSFileSize nSize, WFSFileSize offset);
|
||||||
|
s32 AclReadFile(const AreaInfo* area, WFSAclFileHandle fh, void *pFileDataBuffer, s32 nSize, WFSFileSize offset);
|
||||||
|
|
||||||
|
WFSResult AclCreateFile(const AreaInfo* area, const AclFileInfo* fileInfo, WFSBool create, WFSAclFileHandle *pFh);
|
||||||
|
WFSResult AclCloseFile(WFSAclFileHandle fh);
|
||||||
|
|
||||||
|
WFSResult AclDeleteAccessListFile(const AreaInfo* area, const AclFileInfo* aclFile);
|
||||||
|
WFSResult AclCreateAccessListFile(const AreaInfo* area, const AclFileInfo* aclFile, WFSBool create, WFSAclFileHandle *pFh);
|
||||||
|
WFSBool AclAccessListAlreadyExist(const AreaInfo* area, const AclFileInfo* aclFile);
|
||||||
|
|
||||||
|
#endif // __WFSKRN_PERMISSION_WIN32_H__
|
||||||
@ -0,0 +1,176 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Platform.h - low level definitions and types that are primarily platform dependent
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Platform.h,v $
|
||||||
|
Revision 1.6 2008/08/27 04:05:21 nakanose_jin
|
||||||
|
change ospanic definision
|
||||||
|
|
||||||
|
Revision 1.5 2008/07/14 01:01:11 kondo_masahiro
|
||||||
|
Removed _STRICMP
|
||||||
|
|
||||||
|
Revision 1.4 2008/06/26 05:37:33 kondo_masahiro
|
||||||
|
Added function _STRICMP().
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 17:26:30 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/26 05:36:11 paul
|
||||||
|
Added _ATTRIBUTE_PACKED
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/19 05:47:36 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/28 06:32:17 kondo_masahiro
|
||||||
|
Fixed code to accept PPC compiler
|
||||||
|
|
||||||
|
Revision 1.1 2007/11/05 19:03:13 paul
|
||||||
|
first checkin
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Platform_h
|
||||||
|
#define wfskrn_Platform_h
|
||||||
|
|
||||||
|
#include <firm.h>
|
||||||
|
|
||||||
|
//--twl modified
|
||||||
|
#define TWL 1
|
||||||
|
#if 1
|
||||||
|
#define _OSX 0
|
||||||
|
#define _WIN32 0
|
||||||
|
#define _TWL 1
|
||||||
|
#define _RVL 0
|
||||||
|
#define _IOP 0
|
||||||
|
#else
|
||||||
|
//--twl modified
|
||||||
|
#ifdef OSX
|
||||||
|
#define _OSX 1
|
||||||
|
#define _WIN32 0
|
||||||
|
#define _RVL 0
|
||||||
|
#define _IOP 0
|
||||||
|
#else
|
||||||
|
#ifdef WIN32
|
||||||
|
#define _OSX 0
|
||||||
|
#define _WIN32 1
|
||||||
|
#define _RVL 0
|
||||||
|
#define _IOP 0
|
||||||
|
#else
|
||||||
|
#ifdef IOP
|
||||||
|
#define _OSX 0
|
||||||
|
#define _WIN32 0
|
||||||
|
#define _RVL 0
|
||||||
|
#define _IOP 1
|
||||||
|
#elif RVL
|
||||||
|
#define _OSX 0
|
||||||
|
#define _WIN32 0
|
||||||
|
#define _RVL 1
|
||||||
|
#define _IOP 0
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif //twl modified
|
||||||
|
|
||||||
|
// Although the cache line size depends on the platform, it is fixed to
|
||||||
|
// the IOP cache line size, since the goal is not to optimize for different
|
||||||
|
// platforms, but rather to use other platforms as a development aid.
|
||||||
|
#define WFS_CPU_CACHE_LINE_SIZE (1<<5)
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#pragma warning (3: 4101)
|
||||||
|
#pragma warning (3: 4189)
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
#define _ATTRIBUTE_PACKED
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
#define MAX max
|
||||||
|
#define MIN min
|
||||||
|
//#define OSReport printf
|
||||||
|
#include "WinOSReport.h"
|
||||||
|
#define OSPanic MyOSPanic
|
||||||
|
#define SNPRINTF _snprintf
|
||||||
|
#define STRNLEN( str, maxlen ) strlen(str)
|
||||||
|
#define _ATTRIBUTE_PACKED
|
||||||
|
#elif _OSX
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
//#define OSReport printf
|
||||||
|
#include "WinOSReport.h"
|
||||||
|
#define OSPanic MyOSReport
|
||||||
|
#define SNPRINTF snprintf
|
||||||
|
#define STRNLEN( str, maxlen ) strlen(str)
|
||||||
|
#define _ATTRIBUTE_PACKED
|
||||||
|
//-- twl modified
|
||||||
|
#elif _TWL
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#define MyOSReport osTPrintf
|
||||||
|
#define InitMyOSReport()
|
||||||
|
#define SNPRINTF OS_SNPrintf
|
||||||
|
#define STRNLEN( str, maxlen ) stdStrNLen(str, maxlen)
|
||||||
|
#define _ATTRIBUTE_PACKED
|
||||||
|
//-- twl modified
|
||||||
|
#elif _RVL
|
||||||
|
#pragma warn_unusedarg off
|
||||||
|
#pragma warn_implicitconv off
|
||||||
|
#pragma warn_possunwant off
|
||||||
|
#include <ctype.h>
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#define MyOSReport OSReport
|
||||||
|
#define InitMyOSReport()
|
||||||
|
#define SNPRINTF snprintf
|
||||||
|
#define STRNLEN( str, maxlen ) strlen(str)
|
||||||
|
#define _ATTRIBUTE_PACKED
|
||||||
|
#elif _IOP
|
||||||
|
#define BYTES_PER_INT 4
|
||||||
|
#define BITS_PER_INT 32
|
||||||
|
#define BIT_OFFSET_MASK 31
|
||||||
|
#define BIT_OFFSET_TO_INT_OFFSET_SHIFT 5
|
||||||
|
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||||
|
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||||
|
#define MyOSReport printf
|
||||||
|
#define InitMyOSReport()
|
||||||
|
#define SNPRINTF snprintf
|
||||||
|
#define STRNLEN( str, maxlen ) strnlen( str, maxlen )
|
||||||
|
#define _ATTRIBUTE_PACKED __attribute__((packed))
|
||||||
|
#endif // WIN32
|
||||||
|
|
||||||
|
#ifndef BIG_ENDIAN
|
||||||
|
#ifdef WIN32
|
||||||
|
#define BIG_ENDIAN 0
|
||||||
|
#elif TWL
|
||||||
|
#define BIG_ENDIAN 0
|
||||||
|
#else
|
||||||
|
#define BIG_ENDIAN 1
|
||||||
|
#endif // WIN32
|
||||||
|
#endif // BIG_ENDIAN
|
||||||
|
|
||||||
|
|
||||||
|
#endif //define wfskrn_Platform_h
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_SubBlkAlloc.h - Memory Managed Blocks, and functions for allocating sub blocks from them
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_SubBlkAlloc.h,v $
|
||||||
|
Revision 1.6 2008/09/28 23:30:46 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.5 2008/08/27 10:01:32 paul
|
||||||
|
Removed nTotalFree from block header
|
||||||
|
|
||||||
|
Revision 1.4 2008/07/14 23:03:11 paul
|
||||||
|
Changed<EFBFBD>@nOfs to use u16
|
||||||
|
|
||||||
|
Revision 1.3 2008/06/09 18:11:14 paul
|
||||||
|
Changed SbaBlkInit() to support blocks with different header sizes
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 17:26:24 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/19 05:47:18 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/05 03:23:05 paul
|
||||||
|
Added extra check functions
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/21 00:06:19 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_SubBlkAlloc_h
|
||||||
|
#define wfskrn_SubBlkAlloc_h
|
||||||
|
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _DEBUG_SUB_BLK_ALLOC 0 // change to 1 if debug info required
|
||||||
|
#else
|
||||||
|
#define _DEBUG_SUB_BLK_ALLOC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SBA_MIN_LOG2_SUB_BLK_SIZE 3
|
||||||
|
#define SBA_MAX_LOG2_SUB_BLK_SIZE 11
|
||||||
|
#define SBA_MAX_LOG2_SUB_BLK_SIZE_FOR_MIDDLE 10
|
||||||
|
#define SBA_NUM_SUB_BLK_SIZES (SBA_MAX_LOG2_SUB_BLK_SIZE - SBA_MIN_LOG2_SUB_BLK_SIZE + 1)
|
||||||
|
|
||||||
|
//#define SBA_FREE_SUB_BLK_MAGIC 0xFEDCBAF8
|
||||||
|
#define SBA_FREE_SUB_BLK_MAGIC 0xFEDC // NOTE: This magic number is used to mark free sub blocks. It must not represent valid data for any in-use sub blocks using this allocator.
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSIntraBlkOfs nNumFree;
|
||||||
|
WFSIntraBlkOfs nFirstFree;
|
||||||
|
} WFSSubBlkList;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSMetaDataHdr mdh;
|
||||||
|
WFSSubBlkList aSubBlkList[SBA_NUM_SUB_BLK_SIZES];
|
||||||
|
#if _DEBUG_SUB_BLK_ALLOC
|
||||||
|
WFSIntraBlkOfs nTotalFree;
|
||||||
|
u16 pad;
|
||||||
|
#endif
|
||||||
|
} WFSSubBlkAllocHdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u16 nMagic;
|
||||||
|
u16 nNext;
|
||||||
|
u16 nPrev;
|
||||||
|
u16 nLog2Size;
|
||||||
|
} WFSSubBlkFreeHdr;
|
||||||
|
|
||||||
|
void SbaCheckOfs(u16 nOfs);
|
||||||
|
void SbaRemoveSubBlkFromFreeList(WFSSubBlkAllocHdr *pBlkHdr, u16 nOfs, u32 nLog2Size);
|
||||||
|
u16 SbaAllocSubBlk(WFSSubBlkAllocHdr *pBlkHdr, u32 nLog2Size);
|
||||||
|
WFSKrnResult SbaAllocSubBlks(WFSSubBlkAllocHdr *pBlkHdr, u32 nLog2Size, u16 aSubBlkOfs[], u32 nNumSubBlks);
|
||||||
|
void SbaFreeSubBlk(WFSSubBlkAllocHdr *pBlkHdr, u16 nOfs, u32 nLog2Size);
|
||||||
|
void SbaReduceSubBlkSize(WFSSubBlkAllocHdr *pBlkHdr, u16 nOfs, u32 nOldLog2Size, u32 nNewLog2Size);
|
||||||
|
WFSSubBlkAllocHdr *SbaBlkInit(void *pBlk, u32 nLog2BlkSize, u32 nLog2HdrSize);
|
||||||
|
u32 SbaCountFreeSpace(WFSSubBlkAllocHdr *pBlkHdr);
|
||||||
|
u32 SbaCheckFreeSpace(WFSSubBlkAllocHdr *pBlkHdr, u32 *aUtilization);
|
||||||
|
|
||||||
|
|
||||||
|
#endif //wfskrn_SubBlkAlloc_h
|
||||||
197
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Trans.h
Normal file
197
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Trans.h
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Trans.h - Provides access to blocks for transactions including re-mapping functionality
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Trans.h,v $
|
||||||
|
Revision 1.17 2008/12/18 09:03:37 kondo_masahiro
|
||||||
|
Fixed function name and process from BCacheSetBlkAdr() to BCacheRemap()
|
||||||
|
|
||||||
|
Revision 1.16 2008/12/17 01:37:41 kondo_masahiro
|
||||||
|
Added function BCacheSetBlkAdr()
|
||||||
|
|
||||||
|
Revision 1.15 2008/11/26 01:44:35 kondo_masahiro
|
||||||
|
Fixed arguments of several functions in order to improve access speed.
|
||||||
|
|
||||||
|
Revision 1.14 2008/11/05 15:03:40 ueno
|
||||||
|
Fixed a typo.
|
||||||
|
|
||||||
|
Revision 1.13 2008/11/05 05:55:23 kondo_masahiro
|
||||||
|
Added TransSetChainId()
|
||||||
|
|
||||||
|
Revision 1.12 2008/10/21 09:50:09 kondo_masahiro
|
||||||
|
Added new function WFSWriteFileAndDiscard
|
||||||
|
|
||||||
|
Revision 1.11 2008/10/17 08:51:27 kondo_masahiro
|
||||||
|
Added the new MEDIUM size category (40KB-320KB)
|
||||||
|
|
||||||
|
Revision 1.10 2008/10/14 10:27:44 kondo_masahiro
|
||||||
|
Added codes to access very large size file data
|
||||||
|
|
||||||
|
Revision 1.9 2008/10/10 02:11:31 kondo_masahiro
|
||||||
|
Fixed a bug to access large files
|
||||||
|
|
||||||
|
Revision 1.8 2008/10/08 23:20:09 kondo_masahiro
|
||||||
|
Added codes to access large size file data
|
||||||
|
|
||||||
|
Revision 1.7 2008/10/03 08:37:18 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP
|
||||||
|
|
||||||
|
Revision 1.6 2008/09/28 23:30:51 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.5 2008/08/27 09:50:04 paul
|
||||||
|
Started coding to differentiate File/Meta-data blocks
|
||||||
|
|
||||||
|
Revision 1.4 2008/08/06 05:28:46 kondo_masahiro
|
||||||
|
Added debug flags for hash and detach test.
|
||||||
|
|
||||||
|
Revision 1.3 2008/07/25 02:57:22 paul
|
||||||
|
Added TransInfo, TansBegin(), TransEnd()
|
||||||
|
|
||||||
|
Revision 1.2 2008/07/17 05:14:51 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP.
|
||||||
|
|
||||||
|
Revision 1.1 2008/07/09 01:48:14 paul
|
||||||
|
First checkin of transaction API. Currently has no re-mapping.
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfs_Trans_h
|
||||||
|
#define wfs_Trans_h
|
||||||
|
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define TRANS_FLAG_READ_BLK BCACHE_FLAG_READ // Use this flag unless you are ignoring/overwriting any existing data in the blcok
|
||||||
|
#define TRANS_FLAG_WRITE_BLK BCACHE_FLAG_DIRTY // Use this flag if you intend to write to the block
|
||||||
|
#define TRANS_FLAG_RW_BLK (BCACHE_FLAG_READ | BCACHE_FLAG_DIRTY) // Use this flag unless you are ignoring/overwriting any existing data in the blcok
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
struct TransInfo_ *pNext;
|
||||||
|
struct TransInfo_ *pPrev;
|
||||||
|
} TransInfoLink;
|
||||||
|
|
||||||
|
typedef struct TransInfo_ {
|
||||||
|
TransInfoLink link;
|
||||||
|
WFSTitleId nTitleId;
|
||||||
|
} TransInfo;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
AreaInfo *pAreaInfo; // Area info
|
||||||
|
WFSBlkAdr nBlkAdr; // Block address
|
||||||
|
TransInfo *pTransInfo; // Transaction info
|
||||||
|
} TransBlkAdr;
|
||||||
|
|
||||||
|
|
||||||
|
void TransModuleInit();
|
||||||
|
|
||||||
|
TransInfo *TransBegin();
|
||||||
|
void TransEnd(TransInfo *pTransInfo);
|
||||||
|
|
||||||
|
WFSKrnResult TransGetBlk5(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo, u32 nFlags, void **ppBlkPtr);
|
||||||
|
static inline WFSKrnResult TransGetBlk(TransBlkAdr *pTba, u32 nFlags, void **ppBlkPtr) {
|
||||||
|
return TransGetBlk5(pTba->pAreaInfo, pTba->nBlkAdr, pTba->pTransInfo, nFlags, ppBlkPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransGetAndPinBlk5(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo, u32 nFlags, void **ppBlkPtr);
|
||||||
|
static inline WFSKrnResult TransGetAndPinBlk(TransBlkAdr *pTba, u32 nFlags, void **ppBlkPtr) {
|
||||||
|
return TransGetAndPinBlk5(pTba->pAreaInfo, pTba->nBlkAdr, pTba->pTransInfo, nFlags, ppBlkPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransSetChainId4(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo, u32 nChainId);
|
||||||
|
static inline WFSKrnResult TransSetChainId(TransBlkAdr *pTba, u32 nChainId) {
|
||||||
|
return TransSetChainId4(pTba->pAreaInfo, pTba->nBlkAdr, pTba->pTransInfo, nChainId);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransGetChainId4(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo, u32 *pChainId);
|
||||||
|
static inline WFSKrnResult TransGetChainId(TransBlkAdr *pTba, u32 *pChainId) {
|
||||||
|
return TransGetChainId4(pTba->pAreaInfo, pTba->nBlkAdr, pTba->pTransInfo, pChainId);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransUnpinBlk3(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo);
|
||||||
|
static inline WFSKrnResult TransUnpinBlk(TransBlkAdr *pTba) {
|
||||||
|
return TransUnpinBlk3(pTba->pAreaInfo, pTba->nBlkAdr, pTba->pTransInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransDirtyBlk3(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo);
|
||||||
|
static inline WFSKrnResult TransDirtyBlk(TransBlkAdr *pTba) {
|
||||||
|
return TransDirtyBlk3(pTba->pAreaInfo, pTba->nBlkAdr, pTba->pTransInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransFreeBlks6(AreaInfo *pAreaInfo, u32 nLog2BlkSize, u32 nNumBlks, WFSBlkAdr *pBlkAdr, s32 nStride, TransInfo *pTransInfo);
|
||||||
|
static inline WFSKrnResult TransFreeBlks5(AreaInfo *pAreaInfo, u32 nLog2BlkSize, u32 nNumBlks, WFSBlkAdr aBlkAdr[], TransInfo *pTransInfo) {
|
||||||
|
return TransFreeBlks6(pAreaInfo, nLog2BlkSize, nNumBlks, aBlkAdr, sizeof(WFSBlkAdr), pTransInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransUnpinAndFreeBlks(AreaInfo *pAreaInfo, u32 nLog2BlkSize, u32 nNumBlks, WFSBlkAdr aBlkAdr[], TransInfo *pTransInfo);
|
||||||
|
|
||||||
|
WFSKrnResult TransStoreBlk3(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo);
|
||||||
|
static inline WFSKrnResult TransStoreBlk(TransBlkAdr *pTba) {
|
||||||
|
return TransStoreBlk3(pTba->pAreaInfo, pTba->nBlkAdr, pTba->pTransInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransFlushBlk3(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo);
|
||||||
|
static inline WFSKrnResult TransFlushBlk(TransBlkAdr *pTba) {
|
||||||
|
return TransFlushBlk3(pTba->pAreaInfo, pTba->nBlkAdr, pTba->pTransInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransGetFileBlk6(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo, u32 nFlags, void **ppBlkPtr, WFSHashCode *pHash);
|
||||||
|
static inline WFSKrnResult TransGetFileBlk(TransBlkAdr *pTba, u32 nFlags, void **ppBlkPtr, WFSHashCode *pHash) {
|
||||||
|
return TransGetFileBlk6(pTba->pAreaInfo, pTba->nBlkAdr, pTba->pTransInfo, nFlags, ppBlkPtr, pHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult TransGetAndPinFileBlk8(AreaInfo *pAreaInfo, WFSBlkAdr nParentBlkAdr, u16 nHashOfs,
|
||||||
|
WFSBlkAdr nFileBlkAdr, TransInfo *pTransInfo, u32 nFlags, u32 nValidSize, u32 nBCacheGroupId, void **ppBlkPtr);
|
||||||
|
static inline WFSKrnResult TransGetAndPinFileBlk(TransBlkAdr *pTba, WFSBlkAdr nParentBlkAdr, u16 nHashOfs, WFSBlkAdr nFileBlkAdr, u32 nFlags, u32 nValidSize, void **ppBlkPtr) {
|
||||||
|
return TransGetAndPinFileBlk8(pTba->pAreaInfo, nParentBlkAdr, nHashOfs, nFileBlkAdr, pTba->pTransInfo, nFlags, nValidSize, BCACHE_GROUP_ID_USERBLK_8K, ppBlkPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSKrnResult TransGetAndPinFileMediumBlk(TransBlkAdr *pTba, WFSBlkAdr nParentBlkAdr, u16 nHashOfs, WFSBlkAdr nFileBlkAdr, u32 nFlags, u32 nValidSize, void **ppBlkPtr) {
|
||||||
|
return TransGetAndPinFileBlk8(pTba->pAreaInfo, nParentBlkAdr, nHashOfs, nFileBlkAdr, pTba->pTransInfo, nFlags, nValidSize, BCACHE_GROUP_ID_USERBLK_64K, ppBlkPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransUnpinFileBlk3(AreaInfo *pAreaInfo, WFSBlkAdr nFileBlkAdr, TransInfo *pTransInfo);
|
||||||
|
static inline WFSKrnResult TransUnpinFileBlk(TransBlkAdr *pTba, WFSBlkAdr nFileBlkAdr) {
|
||||||
|
return TransUnpinFileBlk3(pTba->pAreaInfo, nFileBlkAdr, pTba->pTransInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransInvalidate3(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo);
|
||||||
|
|
||||||
|
WFSKrnResult TransSetValidSize4(AreaInfo *pAreaInfo, WFSBlkAdr nBlkAdr, TransInfo *pTransInfo, u32 nValidSize);
|
||||||
|
|
||||||
|
WFSKrnResult TransRemapCache6(AreaInfo *pAreaInfo, WFSBlkAdr nSrcBlkAdr, TransInfo *pTransInfo, WFSBlkAdr nDstBlkAdr, WFSBlkAdr nHashBlkAdr, u32 nHashOfs);
|
||||||
|
|
||||||
|
WFSKrnResult TransReadFileBlks7(u8 *pAlignedPtr, AreaInfo *pAreaInfo, u32 nLog2BlkSize, u32 nSize, WFSFileBlkPtr *pFileBlkPtr, s32 nStride, TransInfo *pTransInfo);
|
||||||
|
static inline WFSKrnResult TransReadFileBlks(u8 *pAlignedPtr, AreaInfo *pAreaInfo, u32 nSize, WFSFileBlkPtr *pFileBlkPtr, s32 nStride, TransInfo *pTransInfo){
|
||||||
|
return TransReadFileBlks7(pAlignedPtr, pAreaInfo, pAreaInfo->ah.nLog2BlkSize, nSize, pFileBlkPtr, nStride, pTransInfo);
|
||||||
|
}
|
||||||
|
static inline WFSKrnResult TransReadFileMediumBlks(u8 *pAlignedPtr, AreaInfo *pAreaInfo, u32 nSize, WFSFileBlkPtr *pFileBlkPtr, s32 nStride, TransInfo *pTransInfo){
|
||||||
|
return TransReadFileBlks7(pAlignedPtr, pAreaInfo, pAreaInfo->ah.nLog2MediumBlkSize, nSize, pFileBlkPtr, nStride, pTransInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransWriteFileBlks7(u8 *pAlignedPtr, AreaInfo *pAreaInfo, u32 nLog2BlkSize, u32 nSize, WFSFileBlkPtr *pFileBlkPtr, s32 nStride, TransInfo *pTransInfo, bool bDecryption);
|
||||||
|
static inline WFSKrnResult TransWriteFileBlks(u8 *pAlignedPtr, AreaInfo *pAreaInfo, u32 nSize, WFSFileBlkPtr *pFileBlkPtr, s32 nStride, TransInfo *pTransInfo, bool bDecryption){
|
||||||
|
return TransWriteFileBlks7(pAlignedPtr, pAreaInfo, pAreaInfo->ah.nLog2BlkSize, nSize, pFileBlkPtr, nStride, pTransInfo, bDecryption);
|
||||||
|
}
|
||||||
|
static inline WFSKrnResult TransWriteFileMediumBlks(u8 *pAlignedPtr, AreaInfo *pAreaInfo, u32 nSize, WFSFileBlkPtr *pFileBlkPtr, s32 nStride, TransInfo *pTransInfo, bool bDecryption){
|
||||||
|
return TransWriteFileBlks7(pAlignedPtr, pAreaInfo, pAreaInfo->ah.nLog2MediumBlkSize, nSize, pFileBlkPtr, nStride, pTransInfo, bDecryption);
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult TransReadFileLargeBlks (u8 *pAlignedPtr, AreaInfo *pAreaInfo, u32 nSize, u32 nOffsetBlks,
|
||||||
|
WFSFileLargeBlkPtr *pFileLargeBlkPtr, s32 nStride, TransInfo *pTransInfo);
|
||||||
|
WFSKrnResult TransWriteFileLargeBlks(u8 *pAlignedPtr, AreaInfo *pAreaInfo, u32 nSize, u32 nOffsetBlks,
|
||||||
|
WFSFileLargeBlkPtr *pFileLargeBlkPtr, s32 nStride, TransInfo *pTransInfo, bool bDecryption);
|
||||||
|
|
||||||
|
WFSKrnResult TransTrancateFileBlk(TransBlkAdr *pTba, WFSBlkAdr nParentBlkAdr, u16 nHashOfs, WFSBlkAdr nFileBlkAdr, u32 nOldSize, u32 nNewSize);
|
||||||
|
WFSKrnResult TransTrancateFileMediumBlk(TransBlkAdr *pTba, WFSBlkAdr nParentBlkAdr, u16 nHashOfs, WFSBlkAdr nFileBlkAdr, u32 nOldSize, u32 nNewSize);
|
||||||
|
|
||||||
|
#endif //wfs_Trans_h
|
||||||
165
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Types.h
Normal file
165
trunk/firmware/build/libraries/nfs/common/include/wfskrn_Types.h
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Types.h - global types used by the WFS kernel
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Types.h,v $
|
||||||
|
Revision 1.12 2008/10/24 09:03:09 kondo_masahiro
|
||||||
|
Added decrease block process of DirResize.
|
||||||
|
|
||||||
|
Revision 1.11 2008/10/17 08:51:27 kondo_masahiro
|
||||||
|
Added the new MEDIUM size category (40KB-320KB)
|
||||||
|
|
||||||
|
Revision 1.10 2008/10/10 02:11:31 kondo_masahiro
|
||||||
|
Fixed a bug to access large files
|
||||||
|
|
||||||
|
Revision 1.9 2008/10/08 23:20:09 kondo_masahiro
|
||||||
|
Added codes to access large size file data
|
||||||
|
|
||||||
|
Revision 1.8 2008/09/28 23:30:56 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.7 2008/08/06 02:24:17 paul
|
||||||
|
Added WFSFileBlkPtr and DIR_ENTRY_ATTR* defs
|
||||||
|
|
||||||
|
Revision 1.6 2008/07/28 22:30:56 paul
|
||||||
|
Moved defs related to update counter here
|
||||||
|
|
||||||
|
Revision 1.5 2008/07/25 08:47:53 ooizumi
|
||||||
|
Added WFSKrnAccess.
|
||||||
|
|
||||||
|
Revision 1.4 2008/07/17 05:15:08 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP.
|
||||||
|
|
||||||
|
Revision 1.3 2008/07/09 01:52:00 paul
|
||||||
|
Updated definitions for meta-data flags.
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/10 04:00:48 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.5 2008/04/26 01:25:56 wayne.wong
|
||||||
|
Added magic number values.
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/05 22:43:54 paul
|
||||||
|
Added WFSMetaDataFlags to make wfskrn_Volume.h compile
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/21 00:12:44 paul
|
||||||
|
Added WFSMetaDataHdr
|
||||||
|
|
||||||
|
Revision 1.2 2007/12/27 11:33:28 paul
|
||||||
|
added various types
|
||||||
|
|
||||||
|
Revision 1.1 2007/11/05 19:03:13 paul
|
||||||
|
first checkin
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Types_h
|
||||||
|
#define wfskrn_Types_h
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
|
||||||
|
// Magic numbers for WFS block types. Should be the first u32(4B) of a meta-data block (post decryption)
|
||||||
|
typedef enum { // Flags to identify persistent block types
|
||||||
|
WFS_MDF_NULL = 0x00000000,
|
||||||
|
|
||||||
|
WFS_MDF_DIR_BLK = 0x80000000, // Directory Block
|
||||||
|
WFS_MDF_DIR_ROOT_BLK = 0x40000000, // Always combined with WFS_MDF_DIR_BLK or WFS_MDF_FREE_LIST
|
||||||
|
WFS_MDF_DIR_LEAF_BLK = 0x20000000, // Always combined with WFS_MDF_DIR_BLK or WFS_MDF_FREE_LIST
|
||||||
|
|
||||||
|
WFS_MDF_INDIRECT_BLK = 0x40000000, // Indirect block. (Block of pointers to user data blocks).
|
||||||
|
WFS_MDF_FREE_LIST_BLK = 0x20000000, // Free List Management (B-tree) block
|
||||||
|
WFS_MDF_VOLUME_HDR = 0x10000000, // Master Record. Not combined with anything else
|
||||||
|
WFS_MDF_AREA_HDR = 0x08000000, // Area Header. Not combined with anything else
|
||||||
|
|
||||||
|
WFS_MDF_MAX = 0xffffffff
|
||||||
|
} WFSMetaDataFlags;
|
||||||
|
|
||||||
|
|
||||||
|
#define WFSKRN_MAX_FILE_HANDLES (1<<WFSKRN_FILE_HANDLE_IDX_BITS)
|
||||||
|
#define WFSKRN_MAX_SEARCH_DIR_HANDLES (1<<WFSKRN_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
#define WFSKRN_LOG2_MAX_NUM_HANDLES WFS_NUM_BITS_REQUIRED(WFSKRN_MAX_FILE_HANDLES + WFSKRN_MAX_SEARCH_DIR_HANDLES)
|
||||||
|
|
||||||
|
#define WFSKRN_FILE_HANDLE_INC (1<<WFSKRN_FILE_HANDLE_IDX_BITS)
|
||||||
|
#define WFSKRN_SEARCH_DIR_HANDLE_INC (1<<WFSKRN_SEARCH_DIR_HANDLE_IDX_BITS)
|
||||||
|
|
||||||
|
#define DIR_BLK_REF_COUNT_INC (1<<(32-WFSKRN_LOG2_MAX_NUM_HANDLES))
|
||||||
|
#define WFS_MDF_DIR_COUNTER_MASK (0x1FFFFFFF & (DIR_BLK_REF_COUNT_INC-1)) // counter for DIR blocks - to detect updates
|
||||||
|
|
||||||
|
typedef u32 WFSTransIdx; // Transaction Index
|
||||||
|
typedef u32 WFSVolIdx; // Volume Index
|
||||||
|
|
||||||
|
typedef u32 WFSBlkAdr; // Block Address
|
||||||
|
typedef u32 WFSLglBlkAdr; // Logical Block Address
|
||||||
|
typedef u32 WFSPhyBlkAdr; // Physical Block Address
|
||||||
|
typedef u16 WFSIntraBlkOfs; // Intra Block Offset (for offsets within meta-data blocks)
|
||||||
|
typedef WFSTitleId WFSUserId;
|
||||||
|
|
||||||
|
typedef u32 WFSHashCode[5]; // SHA-1 hash code per block
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct {
|
||||||
|
// This is the format for the start of all metadata blocks
|
||||||
|
WFSMetaDataFlags nFlags; // Contains a few bits for type identification, and the rest update-counter bits
|
||||||
|
WFSHashCode hash;
|
||||||
|
} WFSMetaDataHdr;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct {
|
||||||
|
// This is the format for pointers from meta-data to user-data blocks. (Note: not needed for pointers to meta-data blocks)
|
||||||
|
WFSBlkAdr nBlkAdr;
|
||||||
|
WFSHashCode hash;
|
||||||
|
} WFSFileBlkPtr;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct {
|
||||||
|
// This is the format for pointers from meta-data to user-data blocks. (Note: not needed for pointers to meta-data blocks)
|
||||||
|
WFSBlkAdr nBlkAdr;
|
||||||
|
WFSHashCode aHash[1<<(WFS_LOG2_LARGE_BLK_SIZE-WFS_LOG2_MAX_HASHABLE_BLK_SIZE)];
|
||||||
|
} WFSFileLargeBlkPtr;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
#pragma pack(1)
|
||||||
|
typedef struct {
|
||||||
|
WFSBlkAdr nBlkAdr;
|
||||||
|
WFSHashCode *pHash;
|
||||||
|
} WFSFileBlkInfo;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_SMALL_SIZE 0xA000 // ( 40KB) : Max size = 0x50000 (320KB)
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_MEDIUM_SIZE 0x50000 // (320KB) : Max size = 0x280000 (2.5MB)
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_LARGE_SIZE 0x600000 // ( 6MB) : Max size = 0x600000 ( 6MB)
|
||||||
|
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_SMALL_SIZE_DECREASE 0x2000 // ( 8KB)
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_MEDIUM_SIZE_DECREASE 0x10000 // ( 64KB)
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_LARGE_SIZE_DECREASE 0x80000 // (512KB)
|
||||||
|
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_HDR_SIZE ((size_t)(&((DirEntryAttrHdr*)0)->aCaseBitArray) + (WFS_MAX_FILE_NAME_SIZE>>3)) // 28+31 = 59byte
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_PTR_ARY_SIZE ((1<<SBA_MAX_LOG2_SUB_BLK_SIZE) - DIR_ENTRY_ATTR_MAX_HDR_SIZE)
|
||||||
|
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_SMALL_BLK_PTRS (DIR_ENTRY_ATTR_MAX_SMALL_SIZE >> WFS_LOG2_SMALL_BLK_SIZE)
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_MEDIUM_BLK_PTRS (DIR_ENTRY_ATTR_MAX_MEDIUM_SIZE >> WFS_LOG2_MEDIUM_BLK_SIZE)
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_LARGE_BLK_PTRS (DIR_ENTRY_ATTR_MAX_LARGE_SIZE >> WFS_LOG2_LARGE_BLK_SIZE)
|
||||||
|
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_SMALL_BLK_PTRS_DECREASE (DIR_ENTRY_ATTR_MAX_SMALL_SIZE_DECREASE >> WFS_LOG2_SMALL_BLK_SIZE)
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_MEDIUM_BLK_PTRS_DECREASE (DIR_ENTRY_ATTR_MAX_MEDIUM_SIZE_DECREASE >> WFS_LOG2_MEDIUM_BLK_SIZE)
|
||||||
|
#define DIR_ENTRY_ATTR_MAX_LARGE_BLK_PTRS_DECREASE (DIR_ENTRY_ATTR_MAX_LARGE_SIZE_DECREASE >> WFS_LOG2_LARGE_BLK_SIZE)
|
||||||
|
|
||||||
|
// Internal WFSAccess value
|
||||||
|
typedef enum {
|
||||||
|
WFS_ACCESS_CHANGE_SIZE = 0x04
|
||||||
|
} WFSKrnAccess;
|
||||||
|
|
||||||
|
#endif //define wfskrn_Types_h
|
||||||
@ -0,0 +1,29 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Utils.h
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Utils.h,v $
|
||||||
|
Revision 1.1 2008/12/03 00:11:29 kondo_masahiro
|
||||||
|
Initial check-in.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef wfskrn_Utils_h
|
||||||
|
#define wfskrn_Utils_h
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
|
||||||
|
void _qsort(void *base, size_t num, size_t size, int (*compare)(const void*, const void*) );
|
||||||
|
int CompareBlkAdrForward(const void *pA, const void *pB);
|
||||||
|
int CompareBlkAdrReverse(const void *pA, const void *pB);
|
||||||
|
|
||||||
|
#endif // wfskrn_Utils_h
|
||||||
@ -0,0 +1,73 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Volume.h - handle volume-wide management of area allocation
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Volume.h,v $
|
||||||
|
Revision 1.4 2008/07/17 05:21:49 kondo_masahiro
|
||||||
|
Fixed codes for porting IOP.
|
||||||
|
|
||||||
|
Revision 1.3 2008/07/09 01:54:58 paul
|
||||||
|
Many changes to Volume API to support mounting in namespace, and mounting root directory from an existing volume.
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/12 19:24:00 paul
|
||||||
|
Merged in Wayne's previous changes
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/26 01:26:41 wayne.wong
|
||||||
|
Moved area allocation functionality from Volume to Area module.
|
||||||
|
Changed API appropriately.
|
||||||
|
|
||||||
|
Revision 1.2 2008/03/19 07:41:22 wayne.wong
|
||||||
|
Checkpoint. Added initial alloc/free area functions.
|
||||||
|
|
||||||
|
Revision 1.1 2008/03/11 03:22:09 wayne.wong
|
||||||
|
Checkpoint. Preliminary version.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _WFSKRN_VOLUME_H_
|
||||||
|
#define _WFSKRN_VOLUME_H_
|
||||||
|
|
||||||
|
#include "wfskrn_Device.h"
|
||||||
|
|
||||||
|
#define VOLUME_HDR_BLK_ADR 0 // Absolute block address of the volume header
|
||||||
|
|
||||||
|
typedef struct VolumeHdr_ {
|
||||||
|
// This is the part of the VolumeInfo struct which gets stored on disk
|
||||||
|
WFSMetaDataHdr mdh;
|
||||||
|
u32 nVolId; // Randomly assigned 32 bit identifier
|
||||||
|
u16 nWfsVersion; // WFS version; major upper 8b, minor lower 8b
|
||||||
|
u16 nBuildDate; // Build date (in days since 2008.01.01)
|
||||||
|
} VolumeHdr;
|
||||||
|
|
||||||
|
void VolumeModuleInit();
|
||||||
|
struct VolumeInfo_ *VolumeAlloc();
|
||||||
|
void VolumeFree(struct VolumeInfo_ *pVolInfo);
|
||||||
|
void VolumeRemoveFromMountedList(struct VolumeInfo_ *pVolInfo);
|
||||||
|
void VolumeAddToMountedList(struct VolumeInfo_ *pVolInfo);
|
||||||
|
void VolumeConvertU32ToVolId(WFSVolumeId *pVolId, u32 nVolId);
|
||||||
|
|
||||||
|
WFSKrnResult VolumeInitRootArea(struct VolumeInfo_ *pVolInfo, u8 nLog2BlkSize);
|
||||||
|
WFSKrnResult VolumeInit (struct VolumeInfo_ *pVolInfo, u32 nLog2BlkSize, u32 nNumBlks);
|
||||||
|
WFSKrnResult VolumeUnmount (struct VolumeInfo_ *pVolInfo);
|
||||||
|
|
||||||
|
//#define _DEBUG_WFSKRN_VOLUME_
|
||||||
|
|
||||||
|
#ifdef _DEBUG_WFSKRN_VOLUME_
|
||||||
|
#define dbgv(_s) (_s)
|
||||||
|
#else
|
||||||
|
#define dbgv(_s)
|
||||||
|
#endif // _DEBUG_WFSKRN_VOLUME_
|
||||||
|
|
||||||
|
#endif // _WFSKRN_VOLUME_H_
|
||||||
382
trunk/firmware/build/libraries/nfs/common/include/wfssrv_Defs.h
Normal file
382
trunk/firmware/build/libraries/nfs/common/include/wfssrv_Defs.h
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: Revolution WFSSrv library API = shim layer in RVL version and RPC
|
||||||
|
layer in WFSDEV version.
|
||||||
|
File: wfsdev_Defs.h - Definitions common to WFS client and server
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfssrv_Defs.h,v $
|
||||||
|
Revision 1.34 2008/12/03 00:17:36 kondo_masahiro
|
||||||
|
Added a argument of WFSSrvFlush().
|
||||||
|
|
||||||
|
Revision 1.33 2008/10/21 10:45:09 kondo_masahiro
|
||||||
|
Added new function WFSWriteFileAndDiscard
|
||||||
|
|
||||||
|
Revision 1.32 2008/09/29 01:06:26 kondo_masahiro
|
||||||
|
Added the argument of WFSSrvInit().
|
||||||
|
|
||||||
|
Revision 1.31 2008/07/18 02:59:44 ueno
|
||||||
|
Renamed WFSDeletePermissions() -> WFSDeleteAccessListEntry().
|
||||||
|
|
||||||
|
Revision 1.30 2008/07/17 05:08:41 kondo_masahiro
|
||||||
|
Added WFSSRV_ATTACH_DETACH
|
||||||
|
|
||||||
|
Revision 1.29 2008/07/15 08:43:53 nakanose_jin
|
||||||
|
change arg order
|
||||||
|
|
||||||
|
Revision 1.28 2008/07/14 07:15:46 ueno
|
||||||
|
Implemented WFSGetAccessListAsync(), WFSSetAccessListEntryAsync() and WFSDeletePermissionsAsync().
|
||||||
|
|
||||||
|
Revision 1.27 2008/07/10 06:12:33 nakanose_jin
|
||||||
|
add permissions API
|
||||||
|
|
||||||
|
Revision 1.26 2008/05/22 08:05:49 ueno
|
||||||
|
Added WFSSrvDebugAclTest to run accesslist test.
|
||||||
|
|
||||||
|
Revision 1.25 2008/05/09 14:03:09 nakanose_jin
|
||||||
|
canceling => reduce settitleid argument
|
||||||
|
|
||||||
|
Revision 1.23 2008/04/19 05:52:03 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.22 2008/04/15 02:47:27 ueno
|
||||||
|
Added WFSSrvGetPermissionForUser() and WFSSrvSetPermissionForUser().
|
||||||
|
|
||||||
|
Revision 1.21 2008/03/28 14:14:20 nakanose_jin
|
||||||
|
chance spec of debug proc
|
||||||
|
|
||||||
|
Revision 1.20 2008/02/20 08:10:10 nakanose_jin
|
||||||
|
add WFSExecDebugProcedure
|
||||||
|
|
||||||
|
Revision 1.19 2008/02/08 04:42:00 paul
|
||||||
|
Changed WFSSrvUnmountVolume parameter bForce to WFSBool
|
||||||
|
|
||||||
|
Revision 1.18 2008/02/07 13:02:18 nakanose_jin
|
||||||
|
WFSUnmountVolume : Add force-close option (but only in detach condition)
|
||||||
|
|
||||||
|
Revision 1.17 2008/01/10 05:33:20 nakanose_jin
|
||||||
|
validatePathName => validateDirectory
|
||||||
|
|
||||||
|
Revision 1.16 2007/12/25 14:00:36 ueno
|
||||||
|
Added WFSSrvConnectToServer() to connect to the server again.
|
||||||
|
|
||||||
|
Revision 1.15 2007/12/12 07:51:29 paul
|
||||||
|
Added WFSSrvGetFileSize
|
||||||
|
|
||||||
|
Revision 1.14 2007/12/10 02:51:36 paul
|
||||||
|
Added function codes for WFSSRV_SET_HOME_DIRECTORY, WFSSRV_SET_CURRENT_DIRECTORY. (These do not need to be implemented in the actual server, both call WFSSrvValidatePathName)
|
||||||
|
|
||||||
|
Revision 1.13 2007/11/30 09:43:09 nakanose_jin
|
||||||
|
refine for multi client
|
||||||
|
|
||||||
|
Revision 1.12 2007/11/21 04:17:28 wayne.wong
|
||||||
|
Many changes that included single request/result RPC messages, bug fixes, code factoring, and English C comment adjustments.
|
||||||
|
1. Combined RPC messages into a single request message and single result
|
||||||
|
message. Except for file reads and writes.
|
||||||
|
2. Fixed+factored some Endianess code.
|
||||||
|
3. Enabled larger TCP/IP data transfer size. Previous setting was artifically small
|
||||||
|
to test the code to perform large transfers.
|
||||||
|
4. Changed the volume id parameters utf8*->WFSVolumeId for SrvGetVolumeId
|
||||||
|
and SrvMountDevice. More consistent with the way we send this type at the
|
||||||
|
RPC layer.
|
||||||
|
5. Changed a couple Japanese comments to be compatible with English
|
||||||
|
comments. In particular, the "//" comment with a backslash at the end of
|
||||||
|
the line causes the next line of code to be ignored.
|
||||||
|
6. Removed Windows-specific debugging output defines for RVL build.
|
||||||
|
|
||||||
|
Revision 1.11 2007/11/16 21:54:26 paul
|
||||||
|
Fixed WFSSrvCloseFile to pass nNewSize instead of bTruncateFlag
|
||||||
|
|
||||||
|
Revision 1.10 2007/11/16 02:15:57 wayne.wong
|
||||||
|
Added enumeration and stubs for WFSFlush call.
|
||||||
|
|
||||||
|
Revision 1.9 2007/11/02 00:21:02 paul
|
||||||
|
started logging changes in the file
|
||||||
|
Added StartPosition to WFSSrvReadFile, WFSSrvWriteFile
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef __WFSSRV_DEFS_H__
|
||||||
|
#define __WFSSRV_DEFS_H__
|
||||||
|
|
||||||
|
#include "wfs_Defs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enumeration of functions.
|
||||||
|
// Used by the client to specify functions implemented on the server, or
|
||||||
|
// by the server to specify functions implemented on the client.
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
// server -> client
|
||||||
|
|
||||||
|
WFSSRV_ATTACH_DEVICE,
|
||||||
|
WFSSRV_DETACH_DEVICE,
|
||||||
|
|
||||||
|
// client -> server
|
||||||
|
|
||||||
|
WFSSRV_INIT,
|
||||||
|
WFSSRV_EXIT,
|
||||||
|
|
||||||
|
WFSSRV_GET_DEVICE_INFO,
|
||||||
|
WFSSRV_MOUNT_DEVICE,
|
||||||
|
WFSSRV_UNMOUNT_VOLUME,
|
||||||
|
WFSSRV_INITIALIZE_DEVICE,
|
||||||
|
WFSSRV_GET_VOLUME_ID,
|
||||||
|
WFSSRV_GET_FREE_SPACE_SIZE,
|
||||||
|
WFSSRV_FLUSH,
|
||||||
|
|
||||||
|
WFSSRV_CREATE_DIRECTORY,
|
||||||
|
WFSSRV_SEARCH_DIRECTORY_FIRST,
|
||||||
|
WFSSRV_SEARCH_DIRECTORY_NEXT,
|
||||||
|
WFSSRV_SEARCH_DIRECTORY_CLOSE,
|
||||||
|
|
||||||
|
WFSSRV_SET_HOME_DIRECTORY,
|
||||||
|
WFSSRV_SET_CURRENT_DIRECTORY,
|
||||||
|
|
||||||
|
WFSSRV_VALIDATE_PATH_NAME,
|
||||||
|
WFSSRV_DELETE,
|
||||||
|
WFSSRV_MOVE_LOCAL,
|
||||||
|
WFSSRV_GET_ATTRIBUTES,
|
||||||
|
WFSSRV_CHANGE_PERMISSIONS,
|
||||||
|
|
||||||
|
WFSSRV_CREATE_AND_OPEN_FILE,
|
||||||
|
WFSSRV_OPEN_FILE,
|
||||||
|
WFSSRV_GET_FILE_SIZE,
|
||||||
|
WFSSRV_CLOSE_FILE,
|
||||||
|
WFSSRV_READ_FILE,
|
||||||
|
WFSSRV_WRITE_FILE,
|
||||||
|
WFSSRV_WRITE_FILE_AND_DISCARD,
|
||||||
|
|
||||||
|
WFSSRV_GET_PERMISSIONS,
|
||||||
|
WFSSRV_SET_PERMISSIONS,
|
||||||
|
|
||||||
|
WFSSRV_GET_ACL,
|
||||||
|
WFSSRV_SET_ACL_ENTRY,
|
||||||
|
WFSSRV_DELETE_ACL_ENTRY,
|
||||||
|
|
||||||
|
WFSSRV_SET_TITLE_ID,
|
||||||
|
WFSSRV_TEST,
|
||||||
|
WFSSRV_EXEC_DEBUG,
|
||||||
|
|
||||||
|
WFSSRV_ATTACH_DETACH,
|
||||||
|
|
||||||
|
WFSSRV_DEBUG_ACLTEST // [check]
|
||||||
|
|
||||||
|
} WFSSrvFunc;
|
||||||
|
|
||||||
|
|
||||||
|
typedef u16 WFSSrvFileHandle;
|
||||||
|
typedef u16 WFSSrvSearchDirectoryHandle;
|
||||||
|
|
||||||
|
#ifndef WFSDEV_SERVER
|
||||||
|
|
||||||
|
// The WFSDev server must distinguish between multiple clients.
|
||||||
|
// This can be done by assigning a ClientId based on the client's IP address,
|
||||||
|
// which the server learns whenever it receives a request from a client via sockets.
|
||||||
|
|
||||||
|
// Note: ClientId is orthogonal to TitleId.
|
||||||
|
// There can be multiple clients with the same TitleId.
|
||||||
|
// The same client could change TitleId while the server is running.
|
||||||
|
|
||||||
|
// The home directory is only stored on the client side.
|
||||||
|
// The TitleId, however, is determined by a function in IOS.
|
||||||
|
// (except for the fake debug/wfsdev version)
|
||||||
|
//
|
||||||
|
// This allows a system application built on top of wfs to specify the home directory for
|
||||||
|
// an app prior to launching it.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Path Names
|
||||||
|
// The client<->server API uses absolute WFS path names, becuase the server does not know about
|
||||||
|
// "Current Directory" or "Home Directory".
|
||||||
|
// The absolute path name does not include the full windows path name, it is a WFS path name.
|
||||||
|
|
||||||
|
// For example: "/vol/ABCDEFG/titles/1234/JAKK/gamesave/save1.bin"
|
||||||
|
// On windows, this could map to:
|
||||||
|
// "C:/my_project/my_wfs_device/titles/1234/JAKK/gamesave/save1.bin"
|
||||||
|
// There would be a file called:
|
||||||
|
// "C:/my_project/my_wfs_device/.Wfs" which contains: "Volume Name: ABCDEFG"
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvInit(void *pWorkSpaceBuffer, u32 nWorkSpaceSize);
|
||||||
|
// Contact the WFSSrv server so that it can initialize state for this client.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvExit(void);
|
||||||
|
// Inform the WFSSrv server that this client is terminating.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvInitializeDevice(const WFSDeviceName *pDevName);
|
||||||
|
// pDevName (IN) pointer to device name struct.
|
||||||
|
// Server would create a volume (deleting any existing data within the device assigned to this folder).
|
||||||
|
// The server could have a GUI to allow device attach to be simulated.
|
||||||
|
// It depends on the usage model but this may not be necessary for game developers, so low priority.
|
||||||
|
// (Assuming a system app mounts the drive and assigns home directory in advance, so the
|
||||||
|
// game can access an already-mounted device from the start).
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetDeviceInfo(const WFSDeviceName *pDevName, WFSDeviceInfo *pDi);
|
||||||
|
// pDevName (IN) A pointer to a device name struct.
|
||||||
|
// pDi (OUT) A pointer to a WFSDeviceInfo struct to receive the device information.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvMountDevice(const WFSDeviceName *pDevName, WFSVolumeId *pVolumeIdBuffer);
|
||||||
|
// pDevName (IN) A pointer to a device name struct.
|
||||||
|
// pVolumeIdBuffer (OUT) A pointer to a WFSVolumeId buffer
|
||||||
|
|
||||||
|
WFSResult WFSSrvUnmountVolume(const WFSVolumeId *pVolumeId, WFSBool bForce);
|
||||||
|
// pVolumeId (IN) A pointer to a struct containing a mounted Volume Id.
|
||||||
|
// bForce (IN) If set to true, forces the volume to be unmounted regardless of open files.
|
||||||
|
// NOTE: This flag is only valid if the device is currently detached. Un-flushed data will be lost.
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetVolumeId(const WFSDeviceName *pDevName, WFSVolumeId *sVolumeIdBuffer);
|
||||||
|
// pDevName (IN) A pointer to a device name struct.
|
||||||
|
// sVolumeIdBuffer (OUT) A pointer to a WFSVolumeId buffer
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetFreeSpaceSize(const WFSPathName *pAbsPathName, u64 *pSize);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory.
|
||||||
|
// pSize (OUT) A pointer to a u64 to receive the free space size value.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvFlush(const WFSVolumeId *pVolumeId);
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetAttributes(const WFSPathName *pAbsPathName, WFSFileAttributes *pFa);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory.
|
||||||
|
// pFa (OUT) A pointer to a WFSFileAttributes struct which will be overwritten with the attributes of the specified file or directory.
|
||||||
|
|
||||||
|
WFSResult WFSSrvChangePermissions(const WFSPathName *pAbsPathName, u32 nFlags, u32 nMask);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory.
|
||||||
|
// nFlags (IN) The new permissions flags that are to be set. Should be a combination of the permission flags: WFS_PERM_*
|
||||||
|
// nMask (IN) A mask to specify which flags to change.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvCreateDirectory(const WFSPathName *pAbsPathName, u32 nFlags, u64 nQuota);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory.
|
||||||
|
// nFlags (IN) Should be a combination of the permission flags: WFS_PERM_*. Note: WFS_FLAG_DIRECTORY will be set
|
||||||
|
// whether it is included or not.
|
||||||
|
// nQuota (IN) This parameter that can be used to restrict the total size of the hierarchy beneath the
|
||||||
|
// new directory. A quota of 0 means there is no size restriction, i.e. the quota is Infinity.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSearchDirectoryFirst(const WFSPathName *pPattern, WFSSrvSearchDirectoryHandle *pSsdh, WFSFileInfo *pFi);
|
||||||
|
// pPattern (IN) A pointer to a struct specifying the search pattern as an absolute path name.
|
||||||
|
// pSsdh (OUT) A pointer to a WFSSrvSearchDirectoryHandle handle which is overwritten by the server.
|
||||||
|
// pFi (OUT) A pointer to a WFSFileInfo struct which will be overwritten with the details of the
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSearchDirectoryNext(WFSSrvSearchDirectoryHandle ssdh, WFSFileInfo *pFi);
|
||||||
|
// ssdh (IN) A WFSSrvSearchDirectoryHandle which was created by WFSSrvSearchDirectoryFirst.
|
||||||
|
// pFi (OUT) A pointer to a WFSFileInfo struct which will be overwritten with the details of the
|
||||||
|
// next file which matches the search pattern.
|
||||||
|
//
|
||||||
|
// If they have read permission on the directory, they can list all files/dirs in that directory. Directory read
|
||||||
|
// access was already checked by WFSSrvSearchDirectoryFirst. While they can list the directory contents, they may
|
||||||
|
// not be able to access all contained files/dirs.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSearchDirectoryClose(WFSSrvSearchDirectoryHandle ssdh);
|
||||||
|
// ssdh (IN) A WFSSrvSearchDirectoryHandle which was returned by WFSSrvSearchDirectoryFirst.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvValidateDirectory(const WFSPathName *pAbsPathName);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of a file or directory to validate.
|
||||||
|
// Returns WFS_RESULT_OK if the specified pathname exists, and is accessible to the current title
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvDelete(const WFSPathName *pAbsPathName);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file or directory to delete.
|
||||||
|
|
||||||
|
WFSResult WFSSrvMoveLocal(const WFSPathName *pSrcAbsPathName, const WFSPathName *pDstAbsPathName);
|
||||||
|
// pSrcAbsPathName (IN) A pointer to a struct containing the absolute pathname of the source file or directory.
|
||||||
|
// pDstAbsPathName (IN) A pointer to a struct containing the absolute pathname of the destination file or directory.
|
||||||
|
// Moves or renames the source file/directory to the destination pathname. This function does not work across volumes.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvCreateAndOpenFile(const WFSPathName *pAbsPathName, u32 nFlags, WFSContentIdx nCidx, WFSFileSize nPreAllocateSize, WFSSrvFileHandle *pSfh);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file to create and open.
|
||||||
|
// nFlags (IN) Should be a combination of the permission flags: WFS_PERM_*
|
||||||
|
// nCidx (IN) The content idx, used to control access to purchased content.
|
||||||
|
// nPreAllocateSize (IN) The amount of disk-space to pre-allocate for the file. Hint to the file system.
|
||||||
|
// pSfh (OUT) A pointer to a server file handle which is overwritten by the server.
|
||||||
|
|
||||||
|
WFSResult WFSSrvOpenFile(const WFSPathName *pAbsPathName, WFSAccess nDesiredAccess, WFSSrvFileHandle *pSfh, WFSFileAttributes *pFa);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file to open.
|
||||||
|
// nDesiredAccess (IN) The kind of access that is required: should be one of the WFS_ACCESS_* options.
|
||||||
|
// pSfh (OUT) A pointer to a server file handle, which is overwritten by the server.
|
||||||
|
// pFa (OUT) A pointer to a WFSFileAttributes struct which will be overwritten by the server,
|
||||||
|
|
||||||
|
WFSResult WFSSrvCloseFile(WFSSrvFileHandle sfh, WFSFileSize nNewSize);
|
||||||
|
// sfh (IN) The server file handle which was returned when the file was opened.
|
||||||
|
// nNewSize (IN) This value may be set to truncate the size of a file.
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetFileSize(WFSSrvFileHandle sfh, WFSFileSize *pNewSize);
|
||||||
|
// sfh (IN) The server file handle which was returned when the file was opened.
|
||||||
|
// pNewSize (OUT) A pointer to a WFSFileSize variable which is overwritten by the current file size.
|
||||||
|
|
||||||
|
s32 WFSSrvReadFile(WFSSrvFileHandle sfh, void *pFileDataBuffer, WFSFileSize nStartPosition, s32 nSize);
|
||||||
|
// sfh (IN) The server file handle which was returned when the file was opened.
|
||||||
|
// pFileDataBuffer (OUT) Points to a buffer which will be overwritten with data from the file.
|
||||||
|
// nSize (IN) The number of bytes to be read.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvWriteFile(WFSSrvFileHandle sfh, const void *pFileData, WFSFileSize nStartPosition, WFSFileSize nSize, WFSBool bDiscard);
|
||||||
|
// sfh (IN) The server file handle which was returned when the file was opened.
|
||||||
|
// pFileData (IN) Points to the data to be written to the file.
|
||||||
|
// nSize (IN) The number of bytes to be written.
|
||||||
|
// bDiscard (IN) If it is true, the user buffer is used as work buffer.
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSetTitleId(WFSTitleId titleId,WFSGroupId groupId);
|
||||||
|
// titleId (IN) the title id which is the low 32 bits of the OSTitleId which can be obtained be ESP_GetTitleId()
|
||||||
|
// groupId (IN) the group id from the TMD, which can be obtained by ES_GetTmd()
|
||||||
|
// This function informs the server of the title id and group id of the application linked to this instance of the client.
|
||||||
|
|
||||||
|
WFSResult WFSSrvExecDebugProcedure( u32 cmd , void *arg0 , void *arg1 );
|
||||||
|
// cmd (IN) special command No.
|
||||||
|
// arg0,arg1 (IN/OUT) parameters of special command.
|
||||||
|
// This function let the server do special tasks.
|
||||||
|
|
||||||
|
WFSResult WFSSrvConnectToServer(void);
|
||||||
|
|
||||||
|
WFSResult WFSSrvGetPermissionForUser(const WFSPathName *pAbsPathName, u32 *pFlags, WFSTitleId titleId);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file or the directory.
|
||||||
|
// pFlags (OUT) A pointer to a u32 which will be overwritten with the permissions the specified title id has to
|
||||||
|
// access or modify the specified file or directory. See wfstypes.h for WFS_PERM* flag definitions.
|
||||||
|
// titleId (IN) Title id of the application for which permissions are being set.
|
||||||
|
|
||||||
|
WFSResult WFSSrvSetPermissionForUser(const WFSPathName *pAbsPathName, u32 nFlags, u32 nMask, WFSTitleId titleId);
|
||||||
|
// pAbsPathName (IN) A pointer to a struct containing the absolute pathname of the file or the directory.
|
||||||
|
// nFlags (IN) The new permissions flags that are to be set. Should be a combination of the permission flags: WFS_PERM_* (see wfstypes.h)
|
||||||
|
// nMask (IN) The mask determines which flags will be changed. NewAttributes = (OldAttributes & ~nMask) | (nFlags & nMask)
|
||||||
|
// titleId (IN) Title id of the application for which permissions are being set.
|
||||||
|
|
||||||
|
WFSResult WFSSrvDeleteAccessListEntry(const WFSPathName *pAbsPathName, WFSTitleId titleId, WFSTitleId entryCreatorId);
|
||||||
|
WFSResult WFSSrvSetAccessListEntry(const WFSPathName *pAbsPathName, u32 nFlags, u32 nMask, WFSTitleId titleId);
|
||||||
|
s32 WFSSrvGetAccessList(const WFSPathName *pAbsPathName, WFSAccessListEntry *pAccessList, u32 nMaxElements);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
WFSResult WFSSrvSetWorkspace(void *pWorkSpaceBuffer, u32 nWorkSpaceSize);
|
||||||
|
|
||||||
|
#ifdef ACL_TEST
|
||||||
|
WFSResult WFSSrvDebugAclTest(u32 testNo, void *arg0, void *arg1);
|
||||||
|
#endif // ACL_TEST
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //define __WFSSRV_DEFS_H__
|
||||||
@ -0,0 +1,145 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: WinOSReport.cpp - implementation of WFSDEV higher-level socket
|
||||||
|
library.
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: WinOSReport.cpp,v $
|
||||||
|
Revision 1.9 2008/08/28 00:18:26 nakanose_jin
|
||||||
|
lets standard exception style
|
||||||
|
|
||||||
|
Revision 1.8 2008/08/27 04:50:52 nakanose_jin
|
||||||
|
add function and defines
|
||||||
|
|
||||||
|
Revision 1.7 2008/04/19 05:53:32 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.6 2007/11/26 11:25:13 nakanose_jin
|
||||||
|
deal error on ndev
|
||||||
|
|
||||||
|
Revision 1.5 2007/11/02 01:08:06 paul
|
||||||
|
now logging changes
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !_IOP
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <firm.h>
|
||||||
|
#include "WinOSReport.h"
|
||||||
|
|
||||||
|
static OSReportCallback userCB=0;
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
FILE *fpOSReport;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void DebugPrintCallback(const char *pStr) {
|
||||||
|
#if _WIN32
|
||||||
|
//fpOSReport = fopen("OSReport.txt", "a+, ccs=UTF-8");
|
||||||
|
//fpOSReport = fopen("OSReport.txt", "a+");
|
||||||
|
fprintf(fpOSReport, pStr);
|
||||||
|
//fclose(fpOSReport);
|
||||||
|
//OutputDebugString(pStr);
|
||||||
|
#else
|
||||||
|
osTPrintf(pStr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DebugPrintCallback2(const char *pStr) {
|
||||||
|
#if _WIN32
|
||||||
|
OutputDebugString(pStr);
|
||||||
|
#else
|
||||||
|
osTPrintf(pStr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
OSReportCallback SetOSReportPrintCallback(OSReportCallback cb) {
|
||||||
|
OSReportCallback oldCb = userCB;
|
||||||
|
userCB = cb;
|
||||||
|
return oldCb;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning(disable:4996)
|
||||||
|
|
||||||
|
#if (_MSC_VER) && (_MSC_VER < 1400)
|
||||||
|
#define VSNPRINTF _vsnprintf
|
||||||
|
#else
|
||||||
|
#define VSNPRINTF vsnprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SIZEDUMP 1024
|
||||||
|
|
||||||
|
static char strdump[SIZEDUMP];
|
||||||
|
#include "wfs_Mutex.h"
|
||||||
|
WFSMutex mxOSReport;
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
void InitMyOSReport(void) {
|
||||||
|
WFSInitMutex(&mxOSReport);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
void MyOSReport(const char *format, ...) {
|
||||||
|
if (userCB) {
|
||||||
|
WFSLockMutex(&mxOSReport);
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
VSNPRINTF(strdump, SIZEDUMP, format, ap);
|
||||||
|
userCB(strdump);
|
||||||
|
va_end( ap );
|
||||||
|
WFSUnlockMutex(&mxOSReport);
|
||||||
|
} else {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, format);
|
||||||
|
vfprintf(stderr, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
#include <exception>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void MyOSPanic(const char* file, int line , const char* msg, ...) {
|
||||||
|
#if _WIN32
|
||||||
|
MyOSReport(" in \"%s\" on line %d.\n", file, line);
|
||||||
|
if (userCB) {
|
||||||
|
WFSLockMutex(&mxOSReport);
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, msg);
|
||||||
|
VSNPRINTF(strdump, SIZEDUMP, msg, ap);
|
||||||
|
userCB(strdump);
|
||||||
|
va_end( ap );
|
||||||
|
WFSUnlockMutex(&mxOSReport);
|
||||||
|
} else {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, msg);
|
||||||
|
vfprintf(stderr, msg, ap);
|
||||||
|
va_end(ap);
|
||||||
|
fflush(stderr);
|
||||||
|
}
|
||||||
|
throw std::bad_exception();
|
||||||
|
abort();
|
||||||
|
#else
|
||||||
|
osTPanic( "panic");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,206 @@
|
|||||||
|
#include <math.h>
|
||||||
|
#include "randomlib.h"
|
||||||
|
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
This Random Number Generator is based on the algorithm in a FORTRAN
|
||||||
|
version published by George Marsaglia and Arif Zaman, Florida State
|
||||||
|
University; ref.: see original comments below.
|
||||||
|
At the fhw (Fachhochschule Wiesbaden, W.Germany), Dept. of Computer
|
||||||
|
Science, we have written sources in further languages (C, Modula-2
|
||||||
|
Turbo-Pascal(3.0, 5.0), Basic and Ada) to get exactly the same test
|
||||||
|
results compared with the original FORTRAN version.
|
||||||
|
April 1989
|
||||||
|
Karl-L. Noell <NOELL@DWIFH1.BITNET>
|
||||||
|
and Helmut Weber <WEBER@DWIFH1.BITNET>
|
||||||
|
|
||||||
|
This random number generator originally appeared in "Toward a Universal
|
||||||
|
Random Number Generator" by George Marsaglia and Arif Zaman.
|
||||||
|
Florida State University Report: FSU-SCRI-87-50 (1987)
|
||||||
|
It was later modified by F. James and published in "A Review of Pseudo-
|
||||||
|
random Number Generators"
|
||||||
|
THIS IS THE BEST KNOWN RANDOM NUMBER GENERATOR AVAILABLE.
|
||||||
|
(However, a newly discovered technique can yield
|
||||||
|
a period of 10^600. But that is still in the development stage.)
|
||||||
|
It passes ALL of the tests for random number generators and has a period
|
||||||
|
of 2^144, is completely portable (gives bit identical results on all
|
||||||
|
machines with at least 24-bit mantissas in the floating point
|
||||||
|
representation).
|
||||||
|
The algorithm is a combination of a Fibonacci sequence (with lags of 97
|
||||||
|
and 33, and operation "subtraction plus one, modulo one") and an
|
||||||
|
"arithmetic sequence" (using subtraction).
|
||||||
|
|
||||||
|
Use IJ = 1802 & KL = 9373 to test the random number generator. The
|
||||||
|
subroutine RANMAR should be used to generate 20000 random numbers.
|
||||||
|
Then display the next six random numbers generated multiplied by 4096*4096
|
||||||
|
If the random number generator is working properly, the random numbers
|
||||||
|
should be:
|
||||||
|
6533892.0 14220222.0 7275067.0
|
||||||
|
6172232.0 8354498.0 10633180.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Globals */
|
||||||
|
double u[97],c,cd,cm;
|
||||||
|
int i97,j97;
|
||||||
|
int test = FALSE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is the initialization routine for the random number generator.
|
||||||
|
NOTE: The seed variables can have values between: 0 <= IJ <= 31328
|
||||||
|
0 <= KL <= 30081
|
||||||
|
The random number sequences created by these two seeds are of sufficient
|
||||||
|
length to complete an entire calculation with. For example, if sveral
|
||||||
|
different groups are working on different parts of the same calculation,
|
||||||
|
each group could be assigned its own IJ seed. This would leave each group
|
||||||
|
with 30000 choices for the second seed. That is to say, this random
|
||||||
|
number generator can create 900 million different subsequences -- with
|
||||||
|
each subsequence having a length of approximately 10^30.
|
||||||
|
*/
|
||||||
|
void RandomInitialise(int ij, int kl)
|
||||||
|
{
|
||||||
|
double s,t;
|
||||||
|
int ii,i,j,k,l,jj,m;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Handle the seed range errors
|
||||||
|
First random number seed must be between 0 and 31328
|
||||||
|
Second seed must have a value between 0 and 30081
|
||||||
|
*/
|
||||||
|
if (ij < 0 || ij > 31328 || kl < 0 || kl > 30081) {
|
||||||
|
ij = 1802;
|
||||||
|
kl = 9373;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = (ij / 177) % 177 + 2;
|
||||||
|
j = (ij % 177) + 2;
|
||||||
|
k = (kl / 169) % 178 + 1;
|
||||||
|
l = (kl % 169);
|
||||||
|
|
||||||
|
for (ii=0; ii<97; ii++) {
|
||||||
|
s = 0.0;
|
||||||
|
t = 0.5;
|
||||||
|
for (jj=0; jj<24; jj++) {
|
||||||
|
m = (((i * j) % 179) * k) % 179;
|
||||||
|
i = j;
|
||||||
|
j = k;
|
||||||
|
k = m;
|
||||||
|
l = (53 * l + 1) % 169;
|
||||||
|
if (((l * m % 64)) >= 32)
|
||||||
|
s += t;
|
||||||
|
t *= 0.5;
|
||||||
|
}
|
||||||
|
u[ii] = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = 362436.0 / 16777216.0;
|
||||||
|
cd = 7654321.0 / 16777216.0;
|
||||||
|
cm = 16777213.0 / 16777216.0;
|
||||||
|
i97 = 97;
|
||||||
|
j97 = 33;
|
||||||
|
test = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RandomSetSeedU32(u32 nSeed) {
|
||||||
|
// Seeds between 0x0 and 0x382C7A41 inclusive are unique
|
||||||
|
RandomInitialise((int)(nSeed%31329),(int)((nSeed/31329)%30082));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is the random number generator proposed by George Marsaglia in
|
||||||
|
Florida State University Report: FSU-SCRI-87-50
|
||||||
|
*/
|
||||||
|
double RandomUniform(void)
|
||||||
|
{
|
||||||
|
double uni;
|
||||||
|
|
||||||
|
// Make sure the initialisation routine has been called
|
||||||
|
if (!test)
|
||||||
|
RandomInitialise(1802,9373);
|
||||||
|
|
||||||
|
uni = u[i97-1] - u[j97-1];
|
||||||
|
if (uni <= 0.0)
|
||||||
|
uni++;
|
||||||
|
u[i97-1] = uni;
|
||||||
|
i97--;
|
||||||
|
if (i97 == 0)
|
||||||
|
i97 = 97;
|
||||||
|
j97--;
|
||||||
|
if (j97 == 0)
|
||||||
|
j97 = 97;
|
||||||
|
c -= cd;
|
||||||
|
if (c < 0.0)
|
||||||
|
c += cm;
|
||||||
|
uni -= c;
|
||||||
|
if (uni < 0.0)
|
||||||
|
uni++;
|
||||||
|
|
||||||
|
return(uni);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ALGORITHM 712, COLLECTED ALGORITHMS FROM ACM.
|
||||||
|
THIS WORK PUBLISHED IN TRANSACTIONS ON MATHEMATICAL SOFTWARE,
|
||||||
|
VOL. 18, NO. 4, DECEMBER, 1992, PP. 434-435.
|
||||||
|
The function returns a normally distributed pseudo-random number
|
||||||
|
with a given mean and standard devaiation. Calls are made to a
|
||||||
|
function subprogram which must return independent random
|
||||||
|
numbers uniform in the interval (0,1).
|
||||||
|
The algorithm uses the ratio of uniforms method of A.J. Kinderman
|
||||||
|
and J.F. Monahan augmented with quadratic bounding curves.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !_IOP
|
||||||
|
|
||||||
|
double RandomGaussian(double mean,double stddev)
|
||||||
|
{
|
||||||
|
double q,u,v,x,y;
|
||||||
|
|
||||||
|
// Generate P = (u,v) uniform in rect. enclosing acceptance region
|
||||||
|
// Make sure that any random numbers <= 0 are rejected, since
|
||||||
|
// gaussian() requires uniforms > 0, but RandomUniform() delivers >= 0.
|
||||||
|
do {
|
||||||
|
u = RandomUniform();
|
||||||
|
v = RandomUniform();
|
||||||
|
if (u <= 0.0 || v <= 0.0) {
|
||||||
|
u = 1.0;
|
||||||
|
v = 1.0;
|
||||||
|
}
|
||||||
|
v = 1.7156 * (v - 0.5);
|
||||||
|
|
||||||
|
// Evaluate the quadratic form
|
||||||
|
x = u - 0.449871;
|
||||||
|
y = fabs(v) + 0.386595;
|
||||||
|
q = x * x + y * (0.19600 * y - 0.25472 * x);
|
||||||
|
|
||||||
|
// Accept P if inside inner ellipse
|
||||||
|
if (q < 0.27597)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Reject P if outside outer ellipse, or outside acceptance region
|
||||||
|
} while ((q > 0.27846) || (v * v > -4.0 * log(u) * u * u));
|
||||||
|
|
||||||
|
// Return ratio of P's coordinates as the normal deviate
|
||||||
|
return (mean + stddev * v / u);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Return random integer within a range, lower -> upper INCLUSIVE
|
||||||
|
int RandomInt(int lower,int upper)
|
||||||
|
{
|
||||||
|
return((int)(RandomUniform() * (upper - lower + 1)) + lower);
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 RandomU32() {
|
||||||
|
double rX = RandomUniform();
|
||||||
|
double rY = RandomUniform();
|
||||||
|
return (u32)((rX * 4294967296.0)+(rY * 65536));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return random float within a range, lower -> upper
|
||||||
|
double RandomDouble(double lower,double upper)
|
||||||
|
{
|
||||||
|
return((upper - lower) * RandomUniform() + lower);
|
||||||
|
}
|
||||||
@ -0,0 +1,708 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_AsyncUtils.cpp
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_AsyncUtils.cpp,v $
|
||||||
|
Revision 1.42 2008/12/03 00:17:05 kondo_masahiro
|
||||||
|
Fixed case WFSSRV_FLUSH.
|
||||||
|
|
||||||
|
Revision 1.41 2008/10/31 05:37:09 ooizumi
|
||||||
|
Fixed a bug in WFSExecFunction().
|
||||||
|
|
||||||
|
Revision 1.40 2008/10/23 11:15:28 nakanose_jin
|
||||||
|
Open and Search should give a invalid file handle if he fails to execute.
|
||||||
|
|
||||||
|
Revision 1.39 2008/10/21 10:45:20 kondo_masahiro
|
||||||
|
Added new function WFSWriteFileAndDiscard
|
||||||
|
|
||||||
|
Revision 1.38 2008/07/18 02:59:46 ueno
|
||||||
|
Renamed WFSDeletePermissions() -> WFSDeleteAccessListEntry().
|
||||||
|
|
||||||
|
Revision 1.37 2008/07/14 07:15:24 ueno
|
||||||
|
Implemented WFSGetAccessListAsync(), WFSSetAccessListEntryAsync() and WFSDeletePermissionsAsync().
|
||||||
|
|
||||||
|
Revision 1.36 2008/04/24 04:26:29 nakanose_jin
|
||||||
|
byebye nPermissions param
|
||||||
|
|
||||||
|
Revision 1.35 2008/04/18 07:45:03 nakanose_jin
|
||||||
|
merge acl
|
||||||
|
|
||||||
|
Revision 1.34 2008/04/10 13:35:38 ueno
|
||||||
|
Added WFSSetPermissionsForUser[Async] and WFSGetPermissionsForUser[Async].
|
||||||
|
|
||||||
|
Revision 1.33 2008/02/25 08:33:20 paul
|
||||||
|
BOOL -> WFSBool
|
||||||
|
|
||||||
|
Revision 1.32 2008/02/07 13:02:21 nakanose_jin
|
||||||
|
WFSUnmountVolume : Add force-close option (but only in detach condition)
|
||||||
|
|
||||||
|
Revision 1.31 2008/01/23 00:44:30 ueno
|
||||||
|
Fixed to copy volume ID only when the result is WFS_RESULT_OK.
|
||||||
|
|
||||||
|
Revision 1.30 2008/01/23 00:07:02 paul
|
||||||
|
Fixed WFSGetVolumeIdAsync to only overwrite buffer when result==WFS_RESULT_OK
|
||||||
|
|
||||||
|
Revision 1.29 2008/01/10 09:23:26 paul
|
||||||
|
bugfix for WFSSRV_SET_CURRENT_DIRECTORY, WFSSRV_SET_HOME_DIRECTORY
|
||||||
|
|
||||||
|
Revision 1.28 2008/01/10 05:33:23 nakanose_jin
|
||||||
|
validatePathName => validateDirectory
|
||||||
|
|
||||||
|
Revision 1.27 2008/01/08 09:49:46 ueno
|
||||||
|
Modified WFSExecFunction() to support WFSSRV_MOUNT_DEVICE.
|
||||||
|
|
||||||
|
Revision 1.26 2007/12/27 06:02:37 paul
|
||||||
|
bugfix for WFSSRV_SET_HOME_DIRECTORY, WFSSRV_SET_CURRENT_DIRECTORY
|
||||||
|
|
||||||
|
Revision 1.25 2007/12/27 01:43:19 ueno
|
||||||
|
Added WFSIsThreadTerminated() and WFSJoinThread().
|
||||||
|
|
||||||
|
Revision 1.24 2007/12/26 05:43:45 ueno
|
||||||
|
Fixed WFSAsyncUtilsInit() to create a thread.
|
||||||
|
Fixed WFSAsyncUtilsClose() to send signal to wake up async thread.
|
||||||
|
|
||||||
|
Revision 1.23 2007/12/25 14:03:50 ueno
|
||||||
|
Modified to initialize mutex, thread and heap only once.
|
||||||
|
|
||||||
|
Revision 1.22 2007/12/12 19:57:07 paul
|
||||||
|
Changed WFSSearchDirectoryFirstAsync to not create a search directory handle, and pass sdh=0 to the callback if WFSSrvSearchDirectoryFirst returns an error code.
|
||||||
|
|
||||||
|
Revision 1.21 2007/12/12 07:52:10 paul
|
||||||
|
Added WFSSRV_GET_FILE_SIZE
|
||||||
|
|
||||||
|
Revision 1.20 2007/12/11 00:10:06 paul
|
||||||
|
Fixed a bug in WFSWriteFileAsync
|
||||||
|
|
||||||
|
Revision 1.19 2007/12/10 02:48:49 paul
|
||||||
|
Fixed WFSSetCurrentDirectoryAsync, WFSSetHomeDirectoryAsync
|
||||||
|
|
||||||
|
Revision 1.18 2007/11/21 04:17:45 wayne.wong
|
||||||
|
Many changes that included single request/result RPC messages, bug fixes, code factoring, and English C comment adjustments.
|
||||||
|
1. Combined RPC messages into a single request message and single result
|
||||||
|
message. Except for file reads and writes.
|
||||||
|
2. Fixed+factored some Endianess code.
|
||||||
|
3. Enabled larger TCP/IP data transfer size. Previous setting was artifically small
|
||||||
|
to test the code to perform large transfers.
|
||||||
|
4. Changed the volume id parameters utf8*->WFSVolumeId for SrvGetVolumeId
|
||||||
|
and SrvMountDevice. More consistent with the way we send this type at the
|
||||||
|
RPC layer.
|
||||||
|
5. Changed a couple Japanese comments to be compatible with English
|
||||||
|
comments. In particular, the "//" comment with a backslash at the end of
|
||||||
|
the line causes the next line of code to be ignored.
|
||||||
|
6. Removed Windows-specific debugging output defines for RVL build.
|
||||||
|
|
||||||
|
Revision 1.17 2007/11/16 21:55:08 paul
|
||||||
|
Changed WFSSrvCloseFile to pass nNewSize instead of bTruncateFlag
|
||||||
|
|
||||||
|
Revision 1.16 2007/11/16 02:06:40 paul
|
||||||
|
Added WFSFlush()
|
||||||
|
|
||||||
|
Revision 1.15 2007/11/09 01:17:29 paul
|
||||||
|
Added sub-directory validation check for WFSMoveLocal
|
||||||
|
|
||||||
|
Revision 1.14 2007/11/02 01:57:40 paul
|
||||||
|
bugfix
|
||||||
|
|
||||||
|
Revision 1.13 2007/11/02 00:52:21 paul
|
||||||
|
now logging changes
|
||||||
|
added nStartPosition to WFSSrvReadFile, WFSSrvWriteFile
|
||||||
|
|
||||||
|
---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfs_Client.h"
|
||||||
|
|
||||||
|
#undef dbg
|
||||||
|
#if _DEBUG_ASYNC_UTILS
|
||||||
|
#define dbg(s) s
|
||||||
|
#else
|
||||||
|
#define dbg(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static BOOL bMutexInitialized;
|
||||||
|
|
||||||
|
void WFSExecFunction(WFSAsyncParamHdr *pParamHdr);
|
||||||
|
|
||||||
|
void WFSExecFunction(WFSAsyncParamHdr *pParamHdr) {
|
||||||
|
dbg(MyOSReport("Processing Function: %d\n", pParamHdr->nFunction));
|
||||||
|
void *pPtr = (void*)((size_t)pParamHdr + sizeof(WFSAsyncParamHdr));
|
||||||
|
WFSResult nResult = WFS_RESULT_OK;
|
||||||
|
switch(pParamHdr->nFunction) {
|
||||||
|
case WFSSRV_EXIT: {
|
||||||
|
//WFSAsyncUtilsClose();
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
WFSExitThread(NULL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_GET_DEVICE_INFO: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, utf8 *, sDeviceName);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSDeviceInfo *, pDi);
|
||||||
|
WFSDeviceName *pDevName = (WFSDeviceName *)pPtr;
|
||||||
|
nResult = WFSSrvGetDeviceInfo(pDevName, pDi);
|
||||||
|
((WFSDeviceInfoCallback)pParamHdr->cb)(nResult, sDeviceName, pDi, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_MOUNT_DEVICE: {
|
||||||
|
WFSVolumeId volId;
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, const utf8 *, sDeviceName);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, utf8 *, sVolumeIdBuffer);
|
||||||
|
WFSDeviceName *pDevName = (WFSDeviceName *)pPtr;
|
||||||
|
nResult = WFSSrvMountDevice(pDevName, &volId);
|
||||||
|
if (nResult == WFS_RESULT_OK)
|
||||||
|
{
|
||||||
|
strncpy(sVolumeIdBuffer, volId.sStr, WFS_MAX_VOLUME_ID_SIZE+1);
|
||||||
|
}
|
||||||
|
((WFSDeviceVolumeCallback)pParamHdr->cb)(nResult, sDeviceName, sVolumeIdBuffer, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_UNMOUNT_VOLUME: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, const utf8 *, sVolumeId);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSBool, bForce);
|
||||||
|
WFSVolumeId *pVolumeId = (WFSVolumeId *)pPtr;
|
||||||
|
nResult = WFSSrvUnmountVolume(pVolumeId, bForce);
|
||||||
|
((WFSUnmountVolumeCallback)pParamHdr->cb)(nResult, sVolumeId, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_INITIALIZE_DEVICE: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, const utf8 *, sDeviceName);
|
||||||
|
WFSDeviceName *pDevName = (WFSDeviceName *)pPtr;
|
||||||
|
nResult = WFSSrvInitializeDevice(pDevName);
|
||||||
|
((WFSInitializeDeviceCallback)pParamHdr->cb)(nResult, sDeviceName, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_GET_VOLUME_ID: {
|
||||||
|
WFSVolumeId volId;
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, const utf8 *, sDeviceName);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, utf8 *, sVolumeIdBuffer);
|
||||||
|
WFSDeviceName *pDevName = (WFSDeviceName *)pPtr;
|
||||||
|
nResult = WFSSrvGetVolumeId(pDevName, &volId);
|
||||||
|
if (nResult == WFS_RESULT_OK) {
|
||||||
|
strncpy(sVolumeIdBuffer, volId.sStr, WFS_MAX_VOLUME_ID_SIZE+1);
|
||||||
|
}
|
||||||
|
((WFSDeviceVolumeCallback)pParamHdr->cb)(nResult, sDeviceName, sVolumeIdBuffer, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_GET_FREE_SPACE_SIZE: {
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
u64 nSize;
|
||||||
|
nResult = WFSSrvGetFreeSpaceSize(pAbsPathName, &nSize);
|
||||||
|
((WFSGetFreeSpaceCallback)pParamHdr->cb)(nResult, nSize, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_SET_HOME_DIRECTORY: {
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvValidateDirectory(pAbsPathName);
|
||||||
|
if (nResult == WFS_RESULT_OK) {
|
||||||
|
WFSLockMutex(&wcg.pg.mxAccessPathGlobals);
|
||||||
|
if (pAbsPathName->sStr[pAbsPathName->nLen-1]!='/') {
|
||||||
|
pAbsPathName->sStr[pAbsPathName->nLen++] ='/';
|
||||||
|
pAbsPathName->sStr[pAbsPathName->nLen] =0;
|
||||||
|
}
|
||||||
|
WFSPathResolve(&wcg.pg.pathHome.pn, &wcg.pg.pathHome.ppoa, pAbsPathName->sStr, PATH_TYPE_ABS_DIR_ONLY);
|
||||||
|
WFSUnlockMutex(&wcg.pg.mxAccessPathGlobals);
|
||||||
|
}
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_SET_CURRENT_DIRECTORY: {
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvValidateDirectory(pAbsPathName);
|
||||||
|
if (nResult == WFS_RESULT_OK) {
|
||||||
|
WFSLockMutex(&wcg.pg.mxAccessPathGlobals);
|
||||||
|
if (pAbsPathName->sStr[pAbsPathName->nLen-1]!='/') {
|
||||||
|
pAbsPathName->sStr[pAbsPathName->nLen++] ='/';
|
||||||
|
pAbsPathName->sStr[pAbsPathName->nLen] =0;
|
||||||
|
}
|
||||||
|
WFSPathResolve(&wcg.pg.pathCurrent.pn, &wcg.pg.pathCurrent.ppoa, pAbsPathName->sStr, PATH_TYPE_ABS_DIR_ONLY);
|
||||||
|
WFSUnlockMutex(&wcg.pg.mxAccessPathGlobals);
|
||||||
|
}
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_VALIDATE_PATH_NAME: {
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvValidateDirectory(pAbsPathName);
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_CREATE_DIRECTORY: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nFlags);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u64, nQuota);
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvCreateDirectory(pAbsPathName, nFlags, nQuota);
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_GET_ATTRIBUTES: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSFileAttributes *, pFa);
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvGetAttributes(pAbsPathName, pFa);
|
||||||
|
((WFSGetAttributesCallback)pParamHdr->cb)(nResult, pFa, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_CHANGE_PERMISSIONS: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nFlags);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nMask);
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvChangePermissions(pAbsPathName, nFlags, nMask);
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_DELETE: {
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvDelete(pAbsPathName);
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_DELETE_ACL_ENTRY: {
|
||||||
|
WFSPathName *pAbsPathName;
|
||||||
|
|
||||||
|
// restore arguments.
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSTitleId, titleId);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSTitleId, entryCreatorId);
|
||||||
|
pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
|
||||||
|
nResult = WFSSrvDeleteAccessListEntry(pAbsPathName, titleId, entryCreatorId);
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_SET_ACL_ENTRY: {
|
||||||
|
WFSPathName *pAbsPathName;
|
||||||
|
|
||||||
|
// restore arguments.
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nFlags);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nMask);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSTitleId, titleId);
|
||||||
|
pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvSetAccessListEntry(pAbsPathName, nFlags, nMask, titleId);
|
||||||
|
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_GET_ACL: {
|
||||||
|
WFSPathName *pAbsPathName;
|
||||||
|
s32 nResultOrNumAclEntries;
|
||||||
|
|
||||||
|
// restore arguments.
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSAccessListEntry*, pAccessList);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nMaxElements);
|
||||||
|
pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResultOrNumAclEntries = WFSSrvGetAccessList(pAbsPathName, pAccessList, nMaxElements);
|
||||||
|
|
||||||
|
((WFSGetAccessListCallback)pParamHdr->cb)(nResultOrNumAclEntries, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_MOVE_LOCAL: {
|
||||||
|
WFSPathName *pSrcAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
WFSPathName *pDstAbsPathName = (WFSPathName *)((size_t)pPtr + pSrcAbsPathName->nLen + sizeof(WFSPathName) - WFS_MAX_PATH_NAME_SIZE - 1);
|
||||||
|
nResult = WFSSrvMoveLocal(pSrcAbsPathName, pDstAbsPathName);
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_CREATE_AND_OPEN_FILE: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nFlags);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSContentIdx, nCidx);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nPreAllocateSize);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSCliFileInfo *, pFi);
|
||||||
|
WFSSrvFileHandle sfh;
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvCreateAndOpenFile(pAbsPathName, nFlags, nCidx, nPreAllocateSize, &sfh);
|
||||||
|
WFSFileHandle fh;
|
||||||
|
if (nResult == WFS_RESULT_OK) {
|
||||||
|
fh = pFi->nHandle |= sfh;
|
||||||
|
pFi->fa.nFileSize = pFi->nPosition = 0;
|
||||||
|
pFi->fa.nFlags = nFlags;
|
||||||
|
pFi->fa.nCidx = nCidx;
|
||||||
|
pFi->nAccess = WFS_ACCESS_RW;
|
||||||
|
} else {
|
||||||
|
WFSCliFileInfoFree(pFi);
|
||||||
|
fh = NULL;
|
||||||
|
}
|
||||||
|
((WFSFileOpCallback)pParamHdr->cb)(nResult, fh, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_OPEN_FILE: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSAccess, nDesiredAccess);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSCliFileInfo *, pFi);
|
||||||
|
WFSSrvFileHandle sfh;
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvOpenFile(pAbsPathName, nDesiredAccess, &sfh, &pFi->fa);
|
||||||
|
WFSFileHandle fh;
|
||||||
|
if (nResult == WFS_RESULT_OK) {
|
||||||
|
fh = pFi->nHandle |= sfh;
|
||||||
|
pFi->nPosition = 0;
|
||||||
|
pFi->nAccess = nDesiredAccess;
|
||||||
|
} else {
|
||||||
|
WFSCliFileInfoFree(pFi); // fh = NULL;
|
||||||
|
fh = WFS_INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
((WFSFileOpCallback)pParamHdr->cb)(nResult, fh, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_GET_FILE_SIZE: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM(pPtr, WFSFileHandle, fh);
|
||||||
|
WFSSrvFileHandle sfh = (WFSSrvFileHandle)fh;
|
||||||
|
WFSFileSize nFileSize;
|
||||||
|
nResult = WFSSrvGetFileSize(sfh, &nFileSize);
|
||||||
|
((WFSGetFileSizeCallback)pParamHdr->cb)(nResult, nFileSize, fh, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_READ_FILE: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSFileHandle, fh);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, void *, pFileDataBuffer);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSFileSize, nStartPosition);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM(pPtr, s32, nSize);
|
||||||
|
WFSSrvFileHandle sfh = (WFSSrvFileHandle)fh;
|
||||||
|
s32 nResultOrNumBytesRead = WFSSrvReadFile(sfh, pFileDataBuffer, nStartPosition, nSize);
|
||||||
|
#if 0 // This code has been disabled, because we are no longer updating file position after async read/write
|
||||||
|
if (nResultOrNumBytesRead >= 0) {
|
||||||
|
WFSCliFileInfo *pFi;
|
||||||
|
WFSGetCliFileInfo(&pFi, fh);
|
||||||
|
pFi->nPosition += nResultOrNumBytesRead;
|
||||||
|
if (pFi->fa.nFileSize < pFi->nPosition) {
|
||||||
|
pFi->fa.nFileSize = pFi->nPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
((WFSReadFileCallback)pParamHdr->cb)(nResultOrNumBytesRead, fh, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_WRITE_FILE: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSFileHandle, fh);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, const void *, pFileData);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSFileSize, nStartPosition);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM(pPtr, WFSFileSize, nSize);
|
||||||
|
WFSSrvFileHandle sfh = (WFSSrvFileHandle)fh;
|
||||||
|
nResult = WFSSrvWriteFile(sfh, pFileData, nStartPosition, nSize, FALSE);
|
||||||
|
if (nResult == WFS_RESULT_OK) {
|
||||||
|
WFSCliFileInfo *pFi;
|
||||||
|
WFSGetCliFileInfo(&pFi, fh);
|
||||||
|
u32 nEndPosition = nStartPosition + nSize;
|
||||||
|
if (pFi->fa.nFileSize < nEndPosition) {
|
||||||
|
pFi->fa.nFileSize = nEndPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
((WFSFileOpCallback)pParamHdr->cb)(nResult, fh, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_WRITE_FILE_AND_DISCARD: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSFileHandle, fh);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, const void *, pFileData);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSFileSize, nStartPosition);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM(pPtr, WFSFileSize, nSize);
|
||||||
|
WFSSrvFileHandle sfh = (WFSSrvFileHandle)fh;
|
||||||
|
nResult = WFSSrvWriteFile(sfh, pFileData, nStartPosition, nSize, TRUE);
|
||||||
|
if (nResult == WFS_RESULT_OK) {
|
||||||
|
WFSCliFileInfo *pFi;
|
||||||
|
WFSGetCliFileInfo(&pFi, fh);
|
||||||
|
u32 nEndPosition = nStartPosition + nSize;
|
||||||
|
if (pFi->fa.nFileSize < nEndPosition) {
|
||||||
|
pFi->fa.nFileSize = nEndPosition;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
((WFSFileOpCallback)pParamHdr->cb)(nResult, fh, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_CLOSE_FILE: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSFileHandle, fh);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM(pPtr, WFSFileSize, nNewSize);
|
||||||
|
WFSSrvFileHandle sfh = (WFSSrvFileHandle)fh;
|
||||||
|
nResult = WFSSrvCloseFile(sfh, nNewSize);
|
||||||
|
if (nResult == WFS_RESULT_OK) {
|
||||||
|
WFSCliFileInfo *pFi;
|
||||||
|
WFSGetCliFileInfo(&pFi, fh);
|
||||||
|
WFSCliFileInfoFree(pFi);
|
||||||
|
}
|
||||||
|
((WFSFileOpCallback)pParamHdr->cb)(nResult, fh, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_FLUSH: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, const utf8 *, sVolumeId);
|
||||||
|
WFSVolumeId *pVolumeId = (WFSVolumeId *)pPtr;
|
||||||
|
nResult = WFSSrvFlush(pVolumeId);
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_SEARCH_DIRECTORY_FIRST: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSCliSearchDirInfo *, pSdi);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSFileInfo *, pFi);
|
||||||
|
WFSPathName *pAbsPattern = (WFSPathName *)pPtr;
|
||||||
|
WFSSrvSearchDirectoryHandle ssdh;
|
||||||
|
nResult = WFSSrvSearchDirectoryFirst(pAbsPattern, &ssdh, pFi);
|
||||||
|
pSdi->nHandle |= ssdh;
|
||||||
|
WFSFileHandle fh = pSdi->nHandle;
|
||||||
|
if (nResult != WFS_RESULT_OK) {
|
||||||
|
WFSCliSearchDirInfoFree(pSdi);
|
||||||
|
fh = WFS_INVALID_HANDLE_VALUE; // fh = 0;
|
||||||
|
}
|
||||||
|
((WFSSearchDirectoryCallback)pParamHdr->cb)(nResult, fh, pFi, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_SEARCH_DIRECTORY_NEXT: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSSearchDirectoryHandle, sdh);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM(pPtr, WFSFileInfo *, pFi);
|
||||||
|
WFSSrvSearchDirectoryHandle ssdh = (WFSSrvSearchDirectoryHandle)sdh;
|
||||||
|
nResult = WFSSrvSearchDirectoryNext(ssdh, pFi);
|
||||||
|
((WFSSearchDirectoryCallback)pParamHdr->cb)(nResult, sdh, pFi, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_SEARCH_DIRECTORY_CLOSE: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSSearchDirectoryHandle, sdh);
|
||||||
|
WFSSrvSearchDirectoryHandle ssdh = (WFSSrvSearchDirectoryHandle)sdh;
|
||||||
|
nResult = WFSSrvSearchDirectoryClose(ssdh);
|
||||||
|
if (nResult == WFS_RESULT_OK) {
|
||||||
|
WFSCliSearchDirInfo *pSdi;
|
||||||
|
WFSGetCliSearchDirInfo(&pSdi, sdh);
|
||||||
|
WFSCliSearchDirInfoFree(pSdi);
|
||||||
|
}
|
||||||
|
((WFSSearchDirectoryCloseCallback)pParamHdr->cb)(nResult, sdh, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_GET_PERMISSIONS: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSTitleId, titleId);
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
u32 nFlags;
|
||||||
|
nResult = WFSSrvGetPermissionForUser(pAbsPathName, &nFlags, titleId);
|
||||||
|
((WFSGetPermissionsForUserCallback)pParamHdr->cb)(nResult, nFlags, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WFSSRV_SET_PERMISSIONS: {
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nFlags);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, u32, nMask);
|
||||||
|
WFSCLI_DECLARE_AND_READ_ASYNC_PARAM_THEN_INC_PTR(pPtr, WFSTitleId, titleId);
|
||||||
|
WFSPathName *pAbsPathName = (WFSPathName *)pPtr;
|
||||||
|
nResult = WFSSrvSetPermissionForUser(pAbsPathName, nFlags, nMask, titleId);
|
||||||
|
((WFSResultCallback)pParamHdr->cb)(nResult, pParamHdr->pUserData);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
DWORD WINAPI WFSAsyncExecThread(LPVOID pParam);
|
||||||
|
#elif _RVL
|
||||||
|
void *WFSAsyncExecThread(void *pParam);
|
||||||
|
#elif _TWL
|
||||||
|
void *WFSAsyncExecThread(void *pParam);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
DWORD WINAPI WFSAsyncExecThread(LPVOID pParam)
|
||||||
|
#elif _RVL
|
||||||
|
void *WFSAsyncExecThread(void *pParam)
|
||||||
|
#elif _TWL
|
||||||
|
void *WFSAsyncExecThread(void *pParam)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#pragma unused(pParam)
|
||||||
|
|
||||||
|
(void)osEnableInterrupts();
|
||||||
|
dbg(MyOSReport("Starting WFSAsyncExecThread()\n"));
|
||||||
|
while(1) {
|
||||||
|
WFSLockMutex(&wcg.ag.mxAccessTheParamQueue);
|
||||||
|
while (wcg.ag.anchor.pHead == (WFSAsyncParamHdr*)&wcg.ag.anchor) {
|
||||||
|
if (wcg.bLibInitialized==false) {
|
||||||
|
WFSSignalCond(&wcg.ag.condParamQueueEmpty);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
WFSWaitCond(&wcg.ag.condParamQueueNotEmpty, &wcg.ag.mxAccessTheParamQueue);
|
||||||
|
}
|
||||||
|
WFSResetCond(&wcg.ag.condParamQueueNotEmpty);
|
||||||
|
WFSAsyncParamHdr *pParamHdr = wcg.ag.anchor.pHead;
|
||||||
|
wcg.ag.anchor.pHead = pParamHdr->l.pNext;
|
||||||
|
pParamHdr->l.pNext->l.pPrev = (WFSAsyncParamHdr*)&wcg.ag.anchor;
|
||||||
|
WFSUnlockMutex(&wcg.ag.mxAccessTheParamQueue);
|
||||||
|
WFSExecFunction(pParamHdr);
|
||||||
|
WFSHeapFree(&wcg.heap, pParamHdr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSAsyncUtilsInit() {
|
||||||
|
wcg.ag.anchor.pHead = wcg.ag.anchor.pTail = (WFSAsyncParamHdr*)&wcg.ag.anchor;
|
||||||
|
if (!bMutexInitialized)
|
||||||
|
{
|
||||||
|
bMutexInitialized = true;
|
||||||
|
WFSInitMutex(&wcg.ag.mxAccessTheParamQueue);
|
||||||
|
WFSInitCond(&wcg.ag.condParamQueueNotEmpty);
|
||||||
|
}
|
||||||
|
wcg.ag.pAsyncExecStack = WFSHeapAlloc(&wcg.heap, WFS_ASYNC_EXEC_STACK_SIZE);
|
||||||
|
WFSCreateThread(&wcg.ag.asyncExecThread, WFSAsyncExecThread, 0, wcg.ag.pAsyncExecStack, WFS_ASYNC_EXEC_STACK_SIZE, 15);
|
||||||
|
WFSResumeThread(&wcg.ag.asyncExecThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSAsyncUtilsClose() {
|
||||||
|
WFSLockMutex(&wcg.ag.mxAccessTheParamQueue);
|
||||||
|
WFSSignalCond(&wcg.ag.condParamQueueNotEmpty); // [check]
|
||||||
|
if (wcg.ag.anchor.pHead != wcg.ag.anchor.pTail) {
|
||||||
|
WFSWaitCond(&wcg.ag.condParamQueueEmpty, &wcg.ag.mxAccessTheParamQueue);
|
||||||
|
}
|
||||||
|
WFSUnlockMutex(&wcg.ag.mxAccessTheParamQueue);
|
||||||
|
WFSJoinThread(&wcg.ag.asyncExecThread, NULL);
|
||||||
|
// Assumes all workspace memory will be deleted, so does not bother to free space
|
||||||
|
// ToDo: blocking wait for last async to finish
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WfsPrepareAsyncCallCommon(void **ppPtr, u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize, u32 nSize, WFSAsyncParamHdr *pParamHdr) {
|
||||||
|
pParamHdr->nSize = nSize;
|
||||||
|
pParamHdr->nFunction = nFunction;
|
||||||
|
pParamHdr->cb = cb;
|
||||||
|
pParamHdr->pUserData = pUserData;
|
||||||
|
WFSLockMutex(&wcg.ag.mxAccessTheParamQueue);
|
||||||
|
if (wcg.ag.anchor.pHead == (WFSAsyncParamHdr*)&wcg.ag.anchor) {
|
||||||
|
// ParamQueue was previously empty, but will now have an entry added.
|
||||||
|
// It is OK to signal in advance of actually adding the entry, becuase
|
||||||
|
// the async execution thread won't be able to proceed until we unlock the mutex.
|
||||||
|
WFSSignalCond(&wcg.ag.condParamQueueNotEmpty);
|
||||||
|
}
|
||||||
|
pParamHdr->l.pNext = (WFSAsyncParamHdr*)&wcg.ag.anchor;
|
||||||
|
pParamHdr->l.pPrev = wcg.ag.anchor.pTail;
|
||||||
|
wcg.ag.anchor.pTail->l.pNext = pParamHdr;
|
||||||
|
wcg.ag.anchor.pTail = pParamHdr;
|
||||||
|
if (nOtherParamSize==0) {
|
||||||
|
WFSUnlockMutex(&wcg.ag.mxAccessTheParamQueue);
|
||||||
|
}
|
||||||
|
if (ppPtr) {
|
||||||
|
*ppPtr = (void*)((size_t)pParamHdr + sizeof(WFSAsyncParamHdr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSPrepareAsyncCall(void **ppPtr, u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize) {
|
||||||
|
// This function allocates memory for storing away parameters of asynchronous function calls which do not include path names.
|
||||||
|
// If any errors occur, it releases the allocated memory and returns with an error code.
|
||||||
|
// If no errors occur, the memory remains allocated, and a parameter header entry is added to the async execution ParamQueue.
|
||||||
|
// If nOtherParamSize is 0, the ParamQueue item is complete, and the access mutex is unlocked.
|
||||||
|
// otherwise, it is assumed that the calling function will fill out the remaining elements and will unlock the mutex.
|
||||||
|
size_t nTotalAllocSize = sizeof(WFSAsyncParamHdr) + nOtherParamSize;
|
||||||
|
WFSAsyncParamHdr *pParamHdr = (WFSAsyncParamHdr *)WFSHeapAlloc(&wcg.heap, nTotalAllocSize);
|
||||||
|
if (pParamHdr == 0) {
|
||||||
|
return WFS_RESULT_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
WfsPrepareAsyncCallCommon(ppPtr, nFunction, pUserData, cb, nOtherParamSize, nTotalAllocSize, pParamHdr);
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSPrepareAsyncCallWithPathName(void **ppPtr, const utf8 *sInPathName,
|
||||||
|
WFSPathNameType nPathType, u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize)
|
||||||
|
{
|
||||||
|
// This function allocates memory for storing away parameters of asynchronous function calls, including a pathname parameter.
|
||||||
|
// It resolves, stores, and validates the specified pathname.
|
||||||
|
// If any errors occur, it releases the allocated memory and returns with an error code.
|
||||||
|
// If no errors occur, the memory remains allocated, and a parameter header entry is added to the async execution ParamQueue.
|
||||||
|
// If nOtherParamSize is 0, the ParamQueue item is complete, and the access mutex is unlocked.
|
||||||
|
// otherwise, it is assumed that the calling function will fill out the remaining elements and will unlock the mutex.
|
||||||
|
size_t nOffset = sizeof(WFSAsyncParamHdr) + nOtherParamSize;
|
||||||
|
size_t nTotalAllocSize = nOffset + sizeof(WFSPathName);
|
||||||
|
WFSAsyncParamHdr *pParamHdr = (WFSAsyncParamHdr *)WFSHeapAlloc(&wcg.heap, nTotalAllocSize);
|
||||||
|
if (pParamHdr == 0) {
|
||||||
|
return WFS_RESULT_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
WFSPathPartOffsetArray ppoa;
|
||||||
|
WFSPathName *pPnAbs = (WFSPathName *)((u8*)pParamHdr + nOffset);
|
||||||
|
WFSResult nResult = WFSPathResolve(pPnAbs, &ppoa, sInPathName, nPathType);
|
||||||
|
if (nResult != WFS_RESULT_OK) {
|
||||||
|
WFSHeapFree(&wcg.heap, pParamHdr);
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
WfsPrepareAsyncCallCommon(ppPtr, nFunction, pUserData, cb, nOtherParamSize, nTotalAllocSize, pParamHdr);
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSPrepareMoveLocalAsyncCall(void **ppPtr, const utf8 *sSrcPathName, const utf8 *sDstPathName,
|
||||||
|
WFSPathNameType nPathType, u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize)
|
||||||
|
{
|
||||||
|
// This function allocates memory for storing away parameters of asynchronous function calls, including a pathname parameter.
|
||||||
|
// It resolves, stores, and validates the specified pathname.
|
||||||
|
// If any errors occur, it releases the allocated memory and returns with an error code.
|
||||||
|
// If no errors occur, the memory remains allocated, and a parameter header entry is added to the async execution ParamQueue.
|
||||||
|
// If nOtherParamSize is 0, the ParamQueue item is complete, and the access mutex is unlocked.
|
||||||
|
// otherwise, it is assumed that the calling function will fill out the remaining elements and will unlock the mutex.
|
||||||
|
size_t nOffset = sizeof(WFSAsyncParamHdr) + nOtherParamSize;
|
||||||
|
size_t nTotalAllocSize = nOffset + (2 * sizeof(WFSPathName));
|
||||||
|
WFSAsyncParamHdr *pParamHdr = (WFSAsyncParamHdr *)WFSHeapAlloc(&wcg.heap, nTotalAllocSize);
|
||||||
|
if (pParamHdr == 0) {
|
||||||
|
return WFS_RESULT_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
WFSPathPartOffsetArray ppoa;
|
||||||
|
WFSPathName *pPnSrcAbs = (WFSPathName *)((u8*)pParamHdr + nOffset);
|
||||||
|
WFSResult nResult = WFSPathResolve(pPnSrcAbs, &ppoa, sSrcPathName, nPathType);
|
||||||
|
if (nResult != WFS_RESULT_OK) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
nOffset += pPnSrcAbs->nLen + sizeof(WFSPathName) - WFS_MAX_PATH_NAME_SIZE - 1;
|
||||||
|
WFSPathName *pPnDstAbs = (WFSPathName *)((u8*)pParamHdr + nOffset);
|
||||||
|
nResult = WFSPathResolve(pPnDstAbs, &ppoa, sDstPathName, nPathType);
|
||||||
|
if (nResult != WFS_RESULT_OK) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
if (strncmp(pPnSrcAbs->sStr, pPnDstAbs->sStr, pPnSrcAbs->nLen)==0) {
|
||||||
|
if (pPnDstAbs->sStr[pPnSrcAbs->nLen]=='/') {
|
||||||
|
// trying to move a directory to it's own sub-directory
|
||||||
|
nResult = WFS_RESULT_INVALID;
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nOffset += pPnDstAbs->nLen + sizeof(WFSPathName) - WFS_MAX_PATH_NAME_SIZE - 1;
|
||||||
|
WfsPrepareAsyncCallCommon(ppPtr, nFunction, pUserData, cb, nOtherParamSize, nOffset, pParamHdr);
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
Error:
|
||||||
|
WFSHeapFree(&wcg.heap, pParamHdr);
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSPrepareAsyncCallWithDeviceName(void **ppPtr, const utf8 *sDeviceName,
|
||||||
|
u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize)
|
||||||
|
{
|
||||||
|
size_t nDeviceNameOffset = sizeof(WFSAsyncParamHdr) + sizeof(const utf8 *) + nOtherParamSize;
|
||||||
|
size_t nTotalAllocSize = nDeviceNameOffset + sizeof(WFSDeviceName);
|
||||||
|
WFSAsyncParamHdr *pParamHdr = (WFSAsyncParamHdr *)WFSHeapAlloc(&wcg.heap, nTotalAllocSize);
|
||||||
|
if (pParamHdr == 0) {
|
||||||
|
return WFS_RESULT_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
void *pPtr = (void*)((size_t)pParamHdr + sizeof(WFSAsyncParamHdr));
|
||||||
|
WFSCLI_WRITE_ASYNC_PARAM(pPtr, const utf8 *, sDeviceName);
|
||||||
|
WFSDeviceName *pDeviceName = (WFSDeviceName *)((u8*)pParamHdr + nDeviceNameOffset);
|
||||||
|
WFSResult nResult = WFSSetDeviceName(pDeviceName, sDeviceName);
|
||||||
|
if (nResult != WFS_RESULT_OK) {
|
||||||
|
WFSHeapFree(&wcg.heap, pParamHdr);
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
WfsPrepareAsyncCallCommon(ppPtr, nFunction, pUserData, cb, nOtherParamSize, nTotalAllocSize, pParamHdr);
|
||||||
|
if (ppPtr) {
|
||||||
|
*ppPtr = (void*)((size_t)*ppPtr + sizeof(const utf8 *));
|
||||||
|
}
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSPrepareAsyncCallWithVolumeId(void **ppPtr, const utf8 *sVolumeId,
|
||||||
|
u8 nFunction, void *pUserData, void *cb, size_t nOtherParamSize)
|
||||||
|
{
|
||||||
|
size_t nVolumeIdOffset = sizeof(WFSAsyncParamHdr) + sizeof(const utf8 *) + nOtherParamSize;
|
||||||
|
size_t nTotalAllocSize = nVolumeIdOffset + sizeof(WFSVolumeId);
|
||||||
|
WFSAsyncParamHdr *pParamHdr = (WFSAsyncParamHdr *)WFSHeapAlloc(&wcg.heap, nTotalAllocSize);
|
||||||
|
if (pParamHdr == 0) {
|
||||||
|
return WFS_RESULT_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
void *pPtr = (void*)((size_t)pParamHdr + sizeof(WFSAsyncParamHdr));
|
||||||
|
WFSCLI_WRITE_ASYNC_PARAM(pPtr, const utf8 *, sVolumeId);
|
||||||
|
WFSVolumeId *pVolumeId = (WFSVolumeId *)((u8*)pParamHdr + nVolumeIdOffset);
|
||||||
|
WFSResult nResult = WFSSetVolumeId(pVolumeId, sVolumeId);
|
||||||
|
if (nResult != WFS_RESULT_OK) {
|
||||||
|
WFSHeapFree(&wcg.heap, pParamHdr);
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
WfsPrepareAsyncCallCommon(ppPtr, nFunction, pUserData, cb, nOtherParamSize, nTotalAllocSize, pParamHdr);
|
||||||
|
if (ppPtr) {
|
||||||
|
*ppPtr = (void*)((size_t)*ppPtr + sizeof(const utf8 *));
|
||||||
|
}
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,170 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: Revolution WFS library
|
||||||
|
File: wfs_Debug.cpp - implementation of debugging routines for WFS
|
||||||
|
implementation
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Debug.cpp,v $
|
||||||
|
Revision 1.14 2008/12/10 06:55:50 kondo_masahiro
|
||||||
|
Added the new device types WFS_DEVTYPE_USB_MSC_??.
|
||||||
|
|
||||||
|
Revision 1.13 2008/10/23 11:15:28 nakanose_jin
|
||||||
|
Open and Search should give a invalid file handle if he fails to execute.
|
||||||
|
|
||||||
|
Revision 1.12 2008/07/15 08:43:57 nakanose_jin
|
||||||
|
change arg order
|
||||||
|
|
||||||
|
Revision 1.11 2008/06/25 01:00:08 nakanose_jin
|
||||||
|
add control level error
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/21 04:39:42 nakanose_jin
|
||||||
|
merging acl
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/18 07:45:03 nakanose_jin
|
||||||
|
merge acl
|
||||||
|
|
||||||
|
Revision 1.8 2008/03/26 01:18:02 nakanose_jin
|
||||||
|
move wfs_Debug.h from local to private folder.
|
||||||
|
|
||||||
|
Revision 1.7 2008/02/08 09:52:05 paul
|
||||||
|
Added WFS_RESULT_DEV_IN_USE
|
||||||
|
|
||||||
|
Revision 1.6 2008/02/07 13:02:21 nakanose_jin
|
||||||
|
WFSUnmountVolume : Add force-close option (but only in detach condition)
|
||||||
|
|
||||||
|
Revision 1.5 2007/12/26 10:25:51 paul
|
||||||
|
Changed to use WFS_RANGE_CHK, WFS_INDEX_COUNT from wfs_defs.h, instead of linking jut_utility.cpp
|
||||||
|
|
||||||
|
Revision 1.4 2007/12/17 13:29:17 nakanose_jin
|
||||||
|
add debug utility function
|
||||||
|
|
||||||
|
Revision 1.3 2007/11/02 00:55:00 paul
|
||||||
|
now logging changes
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfs_Defs.h"
|
||||||
|
#include "private/wfs_Debug.h"
|
||||||
|
|
||||||
|
// Print to stdout for now via printf's
|
||||||
|
|
||||||
|
void WFSDevTypePrint(WFSDevType devType) {
|
||||||
|
switch(devType) {
|
||||||
|
case WFS_DEVTYPE_NONE:
|
||||||
|
printf("WFS_DEVTYPE_NONE");
|
||||||
|
break;
|
||||||
|
case WFS_DEVTYPE_SD:
|
||||||
|
printf("WFS_DEVTYPE_SD");
|
||||||
|
break;
|
||||||
|
case WFS_DEVTYPE_USB_MSC_10:
|
||||||
|
printf("WFS_DEVTYPE_USB_MSC_10");
|
||||||
|
break;
|
||||||
|
case WFS_DEVTYPE_USB_MSC_11:
|
||||||
|
printf("WFS_DEVTYPE_USB_MSC_11");
|
||||||
|
break;
|
||||||
|
case WFS_DEVTYPE_USB_MSC_20:
|
||||||
|
printf("WFS_DEVTYPE_USB_MSC_20");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("unknown");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSDevInfoPrint(WFSDeviceInfo *pDevInfo) {
|
||||||
|
printf("DevTotalCapacity (MB) = %I64u\n", pDevInfo->nDevTotalCapacity/(1024*1024));
|
||||||
|
printf("DevType = "); WFSDevTypePrint((WFSDevType)pDevInfo->nDevType); printf("\n");
|
||||||
|
printf("DevFlags = 0x%1x\n", pDevInfo->nDevFlags);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSFileAttrPrint(WFSFileAttributes *pFileAttr) {
|
||||||
|
if (pFileAttr->nFlags & WFS_FLAG_IS_A_DIRECTORY)
|
||||||
|
printf("NumEntries = %u\n", pFileAttr->nNumEntries);
|
||||||
|
else
|
||||||
|
printf("FileSize (MB) = %I64u\n", pFileAttr->nFileSize/(1024*1024));
|
||||||
|
|
||||||
|
printf("Permissions = 0x%8x\n", pFileAttr->nFlags);
|
||||||
|
// printf("ContentIdx = %u\n", pFileAttr->nNumEntries);
|
||||||
|
printf("timeCreated = %u\n", pFileAttr->timeCreated);
|
||||||
|
printf("timeUpdated = %u\n", pFileAttr->timeUpdated);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSFileInfoPrint(WFSFileInfo *pFileInfo) {
|
||||||
|
WFSFileAttrPrint(&pFileInfo->attr);
|
||||||
|
printf("sFilename = %s\n", pFileInfo->sFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *_result_strings[] = {
|
||||||
|
"OK ",
|
||||||
|
"BUSY ",
|
||||||
|
"OUT_OF_MEMORY ",
|
||||||
|
"INVALID ",
|
||||||
|
"ACCESS ",
|
||||||
|
"LIB_NOT_INITIAL",
|
||||||
|
"LIB_ALREADY_INI",
|
||||||
|
"FILE_TOO_BIG ",
|
||||||
|
"NO_CHANGE_SIZE ",
|
||||||
|
"MEDIA_ERROR ",
|
||||||
|
"DEV_UNUSABLE ",
|
||||||
|
"DEV_NOT_INITIAL",
|
||||||
|
"DEV_IN_USE ",
|
||||||
|
"VOL_ID_ERROR ",
|
||||||
|
"WRITE_PROTECTED",
|
||||||
|
"ALREADY_MOUNTED",
|
||||||
|
"PERMISSION ",
|
||||||
|
"PERMISSION_CL ",
|
||||||
|
"ACL_FULL ",
|
||||||
|
"ACL_NOT_FOUND ",
|
||||||
|
"AUTHENTICATION ",
|
||||||
|
"CORRUPTION ",
|
||||||
|
"DIRECTORY_QUOTA",
|
||||||
|
"MAX_HANDLES ",
|
||||||
|
"ALREADY_EXISTS ",
|
||||||
|
"NOT_FOUND ",
|
||||||
|
"NOT_EMPTY ",
|
||||||
|
"NOT_FILE ",
|
||||||
|
"NOT_DIRECTORY ",
|
||||||
|
"FILE_OPEN ",
|
||||||
|
"LOCKED ",
|
||||||
|
"RESOURCE_LIMIT_",
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
static char *_result_strings2[] = {
|
||||||
|
"NOT_IMPLEMENTED",
|
||||||
|
"UNKNOWN ",
|
||||||
|
"FATAL_ERROR "
|
||||||
|
};
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
//! \fn iiFSDev_PrintResult(WFSResult result)
|
||||||
|
//! \par <20>à–¾:
|
||||||
|
//!
|
||||||
|
//! \param result
|
||||||
|
//! \return
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
const char *
|
||||||
|
WFSDebug_GetResultString(WFSResult result)
|
||||||
|
{
|
||||||
|
s32 idx = -1 * (s32)result;
|
||||||
|
if (WFS_RANGE_CHK(idx , 0 , WFS_INDEX_COUNT(_result_strings)))
|
||||||
|
{
|
||||||
|
return _result_strings[idx];
|
||||||
|
}
|
||||||
|
else if (WFS_RANGE_CHK(idx , -WFS_RESULT_NOT_IMPLEMENTED , -WFS_RESULT_NOT_IMPLEMENTED+WFS_INDEX_COUNT(_result_strings2)) )
|
||||||
|
{
|
||||||
|
return _result_strings2[idx+WFS_RESULT_NOT_IMPLEMENTED];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,119 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Heap.cpp
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Heap.cpp,v $
|
||||||
|
Revision 1.8 2007/12/26 04:26:18 paul
|
||||||
|
changed pAllocator to &allocator
|
||||||
|
|
||||||
|
Revision 1.7 2007/12/26 04:14:14 paul
|
||||||
|
Changed RVL version of WFSHeap
|
||||||
|
|
||||||
|
Revision 1.6 2007/12/26 00:19:07 paul
|
||||||
|
Added WFSHeapDestroy()
|
||||||
|
|
||||||
|
Revision 1.5 2007/12/25 14:03:49 ueno
|
||||||
|
Modified to initialize mutex, thread and heap only once.
|
||||||
|
|
||||||
|
Revision 1.4 2007/11/02 00:55:27 paul
|
||||||
|
now logging changes
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfs_Heap.h"
|
||||||
|
|
||||||
|
#undef dbg
|
||||||
|
#if _DEBUG_HEAP
|
||||||
|
#define dbg(s) s
|
||||||
|
#else
|
||||||
|
#define dbg(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
dbg(u32 nSizeAvaliable=0;)
|
||||||
|
|
||||||
|
void WFSCreateHeap(WFSHeap *pHeap, void *pBase, size_t nSize) {
|
||||||
|
*pHeap = HeapCreate(0, nSize, nSize);
|
||||||
|
dbg(nSizeAvaliable = nSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *WFSHeapAlloc(WFSHeap *pHeap, size_t nSize) {
|
||||||
|
void *pAddr = HeapAlloc(*pHeap, 0, nSize);
|
||||||
|
dbg(nSizeAvaliable -= nSize;
|
||||||
|
MyOSReport("A:Heap:%d\n", nSizeAvaliable));
|
||||||
|
return pAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSHeapFree(WFSHeap *pHeap, void *pAddr) {
|
||||||
|
dbg(nSizeAvaliable += HeapSize(pHeap, NULL, pAddr);
|
||||||
|
MyOSReport("F:Heap:%d\n", nSizeAvaliable));
|
||||||
|
HeapFree(*pHeap, 0, pAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSHeapDestroy(WFSHeap *pHeap) {
|
||||||
|
dbg(MyOSReport("WFSHeapDestroy()\n"));
|
||||||
|
HeapDestroy(*pHeap);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- twl modified
|
||||||
|
#elif _TWL
|
||||||
|
|
||||||
|
void WFSCreateHeap(WFSHeap *pHeap, void *pBase, size_t nSize) {
|
||||||
|
osTPrintf( "%s needs modify.\n", __FUNCTION__);
|
||||||
|
//main.c‚Å<E2809A>s‚Á‚Ä‚¢‚é
|
||||||
|
}
|
||||||
|
|
||||||
|
void *WFSHeapAlloc(WFSHeap *pHeap, size_t nSize) {
|
||||||
|
// void *pAddr = OS_AllocFromHeap( OS_ARENA_MAIN_SUBPRIV, *pHeap, nSize);
|
||||||
|
void *pAddr = osAlloc( nSize);
|
||||||
|
if( pAddr == NULL) {
|
||||||
|
osTPrintf( "%s error!\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
return pAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSHeapFree(WFSHeap *pHeap, void *pAddr) {
|
||||||
|
osFree( pAddr);
|
||||||
|
// OS_FreeToHeap( OS_ARENA_MAIN_SUBPRIV, *pHeap, pAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSHeapDestroy(WFSHeap *pHeap) {
|
||||||
|
osTPrintf( "%s needs modify.\n", __FUNCTION__);
|
||||||
|
// OS_DestroyHeap( OS_ARENA_MAIN_SUBPRIV, *pHeap);
|
||||||
|
}
|
||||||
|
//-- twl modified
|
||||||
|
|
||||||
|
#elif _RVL
|
||||||
|
|
||||||
|
void WFSCreateHeap(WFSHeap *pHeap, void *pBase, size_t nSize) {
|
||||||
|
pHeap->handle = MEMCreateExpHeap(pBase, nSize);
|
||||||
|
MEMInitAllocatorForExpHeap(&pHeap->allocator, pHeap->handle, WFS_HEAP_DEFAULT_ALIGNMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *WFSHeapAlloc(WFSHeap *pHeap, size_t nSize) {
|
||||||
|
// printf("==> %s:%d pHeap: 0x%08x size: %d\n", __FILE__, __LINE__, pHeap->pAllocator, nSize);
|
||||||
|
void *pAddr = MEMAllocFromAllocator(&pHeap->allocator, nSize);
|
||||||
|
// printf("==> %s:%d pAddr: 0x%08x\n", __FILE__, __LINE__, pAddr);
|
||||||
|
return pAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSHeapFree(WFSHeap *pHeap, void *pAddr) {
|
||||||
|
MEMFreeToAllocator(&pHeap->allocator, pAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSHeapDestroy(WFSHeap *pHeap) {
|
||||||
|
MEMDestroyExpHeap(pHeap->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,242 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Mutex.cpp
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Mutex.cpp,v $
|
||||||
|
Revision 1.9 2008/04/19 05:53:50 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.8 2007/12/27 01:43:19 ueno
|
||||||
|
Added WFSIsThreadTerminated() and WFSJoinThread().
|
||||||
|
|
||||||
|
Revision 1.7 2007/12/25 14:01:49 ueno
|
||||||
|
Added WFSSuspendThread().
|
||||||
|
|
||||||
|
Revision 1.6 2007/11/02 01:00:36 paul
|
||||||
|
now logging changes
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfs_Mutex.h"
|
||||||
|
|
||||||
|
#undef dbg
|
||||||
|
#if _DEBUG_MUTEX
|
||||||
|
#define dbg(s) s
|
||||||
|
#else
|
||||||
|
#define dbg(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
dbg(u32 aSignalCounter[0x2000]);
|
||||||
|
|
||||||
|
void WFSInitMutex(WFSMutex *pMx) {
|
||||||
|
pMx->hHandle = CreateMutex(NULL, false, NULL);
|
||||||
|
ReleaseMutex(pMx->hHandle);
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]=1;
|
||||||
|
MyOSReport("InitMutex(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSLockMutex(WFSMutex *pMx) {
|
||||||
|
dbg(MyOSReport("Wait(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff]));
|
||||||
|
WaitForSingleObject(pMx->hHandle, INFINITE);
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]--);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSTryLockMutex(WFSMutex *pMx) {
|
||||||
|
return (WaitForSingleObject(pMx->hHandle, 0) != WAIT_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSUnlockMutex(WFSMutex *pMx) {
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]++;
|
||||||
|
MyOSReport("Release(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff]));
|
||||||
|
ReleaseMutex(pMx->hHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSInitCond(WFSCond *pCond) {
|
||||||
|
pCond->hAutoResetEvent = CreateEvent(NULL, false, false, NULL);
|
||||||
|
dbg(aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]=0;
|
||||||
|
MyOSReport("InitCond(%x:%d)\n", pCond->hAutoResetEvent, aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]));
|
||||||
|
//ResetEvent(pCond->hAutoResetEvent);
|
||||||
|
//pCond->hManualResetEvent = CreateEvent(NULL, true, false, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSSignalCond(WFSCond *pCond) {
|
||||||
|
//PulseEvent(pCond->hAutoResetEvent);
|
||||||
|
dbg(aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]++;
|
||||||
|
MyOSReport("Signal(%x:%d)\n", pCond->hAutoResetEvent, aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]));
|
||||||
|
SetEvent(pCond->hAutoResetEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSWaitCond(WFSCond *pCond, WFSMutex* pMx) {
|
||||||
|
#if 1
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]++;
|
||||||
|
MyOSReport("Signal(%x:%d) And Wait(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff], pCond->hAutoResetEvent, aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]));
|
||||||
|
DWORD nRet = SignalObjectAndWait(pMx->hHandle, pCond->hAutoResetEvent, INFINITE, false);
|
||||||
|
dbg(aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]--);
|
||||||
|
#else
|
||||||
|
ReleaseMutex(pMx->hHandle);
|
||||||
|
WaitForSingleObject(pCond->hAutoResetEvent, INFINITE);
|
||||||
|
#endif
|
||||||
|
dbg(MyOSReport("Wait(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff]));
|
||||||
|
WaitForSingleObject(pMx->hHandle, INFINITE);
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]--);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSResetCond(WFSCond *pCond) {
|
||||||
|
ResetEvent(pCond->hAutoResetEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSCreateThread(WFSThread *pThread,
|
||||||
|
WFSThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority)
|
||||||
|
{
|
||||||
|
pThread->hThread = CreateThread(NULL, stackSize, threadFunc, param, CREATE_SUSPENDED, 0);
|
||||||
|
SetThreadPriority(pThread->hThread, 16-priority);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSResumeThread(WFSThread *pThread) {
|
||||||
|
return ResumeThread(pThread->hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSCancelThread(WFSThread *pThread) {
|
||||||
|
// Note: On windows, this does not do any cleanup - should avoid using
|
||||||
|
TerminateThread(pThread->hThread, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSExitThread(void *pVal) {
|
||||||
|
ExitThread((DWORD)pVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSSuspendThread(WFSThread *pThread)
|
||||||
|
{
|
||||||
|
return SuspendThread(pThread->hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSIsThreadTerminated(WFSThread *pThread)
|
||||||
|
{
|
||||||
|
switch (WaitForSingleObject(pThread->hThread, 0))
|
||||||
|
{
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return false;
|
||||||
|
case WAIT_OBJECT_0: // the thread has exited.
|
||||||
|
case WAIT_ABANDONED: // [check]
|
||||||
|
case WAIT_FAILED: // the thread does not exist. [check] should check error code?
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSJoinThread(WFSThread *pThread, void** val)
|
||||||
|
{
|
||||||
|
#pragma unused (val) // exit value is not supported.
|
||||||
|
switch (WaitForSingleObject(pThread->hThread, INFINITE))
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
return true;
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
case WAIT_ABANDONED:
|
||||||
|
case WAIT_FAILED:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#elif _RVL
|
||||||
|
|
||||||
|
|
||||||
|
bool WFSCreateThread(WFSThread *pThread,
|
||||||
|
WFSThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority)
|
||||||
|
{
|
||||||
|
return OSCreateThread(pThread, threadFunc, param, (void*)((u32)stackBase+stackSize), stackSize, priority, 0); // joinable
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-- twl modified
|
||||||
|
#elif _TWL
|
||||||
|
typedef void (*MyThreadFunc)(void*);
|
||||||
|
bool WFSCreateThread(WFSThread *pThread,
|
||||||
|
WFSThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority)
|
||||||
|
{
|
||||||
|
osCreateThread( pThread, (MyThreadFunc)threadFunc, param, (void*)((u32)stackBase+stackSize), stackSize, priority);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSResumeThread(WFSThread *pThread) {
|
||||||
|
osWakeupThreadDirect( pThread);
|
||||||
|
// osTPrintf( "Need TWL modifies.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSCancelThread(WFSThread *pThread) {
|
||||||
|
osDestroyThread( pThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSExitThread(void *pVal) {
|
||||||
|
osExitThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSSuspendThread(WFSThread *pThread)
|
||||||
|
{
|
||||||
|
osTPrintf( "Need TWL modifies.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSIsThreadTerminated(WFSThread *pThread)
|
||||||
|
{
|
||||||
|
return( osIsThreadTerminated( pThread));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSJoinThread(WFSThread *pThread, void** val)
|
||||||
|
{
|
||||||
|
#pragma unused (val) // exit value is not supported.
|
||||||
|
osJoinThread( pThread);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSInitCond(WFSCond *pCond) {
|
||||||
|
osInitEvent( pCond);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSSignalCond(WFSCond *pCond) {
|
||||||
|
osSignalEvent( pCond, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSWaitCond(WFSCond *pCond, WFSMutex* pMx) {
|
||||||
|
osUnlockMutex( pMx);
|
||||||
|
osWaitEventEx( pCond, 1, OS_EVENT_MODE_OR, 1); //イベント待ち後にクリアを伴う
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSResetCond(WFSCond *pCond) {
|
||||||
|
osClearAllEvent( pCond);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- twl modified
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_Names.cpp - Functions for setting and validating name types
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_Names.cpp,v $
|
||||||
|
Revision 1.5 2007/11/19 13:28:27 nakanose_jin
|
||||||
|
bug fix for null pointer check
|
||||||
|
|
||||||
|
Revision 1.4 2007/11/06 22:42:56 paul
|
||||||
|
Added validation checks for NULL pointers passed in
|
||||||
|
|
||||||
|
Revision 1.3 2007/11/02 01:01:00 paul
|
||||||
|
now logging changes
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfs_Names.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
WFSResult WFSSetPathName(WFSPathName *pPathName, const utf8 *sPathName) {
|
||||||
|
WFSReturnOnNullParameter(sPathName);
|
||||||
|
u32 nStrLen = strlen(sPathName);
|
||||||
|
if (nStrLen > WFS_MAX_PATH_NAME_SIZE) {
|
||||||
|
return WFS_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
pPathName->nLen = (WFSPathNameLengthType)nStrLen;
|
||||||
|
strcpy(pPathName->sStr, sPathName);
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSSetFileName(WFSFileName *pFileName, const utf8 *sFileName) {
|
||||||
|
WFSReturnOnNullParameter(sFileName);
|
||||||
|
u32 nStrLen = strlen(sFileName);
|
||||||
|
if (nStrLen > WFS_MAX_FILE_NAME_SIZE) {
|
||||||
|
return WFS_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
pFileName->nLen = (WFSFileNameLengthType)nStrLen;
|
||||||
|
strcpy(pFileName->sStr, sFileName);
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSSetDeviceName(WFSDeviceName *pDeviceName, const utf8 *sDeviceName) {
|
||||||
|
WFSReturnOnNullParameter(sDeviceName);
|
||||||
|
u32 nStrLen = strlen(sDeviceName);
|
||||||
|
if (nStrLen > WFS_MAX_DEVICE_NAME_SIZE) {
|
||||||
|
return WFS_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
pDeviceName->nLen = (WFSDeviceNameLengthType)nStrLen;
|
||||||
|
strcpy(pDeviceName->sStr, sDeviceName);
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSSetVolumeId(WFSVolumeId *pVolumeId, const utf8 *sVolumeId) {
|
||||||
|
WFSReturnOnNullParameter(sVolumeId);
|
||||||
|
u32 nStrLen = strlen(sVolumeId);
|
||||||
|
if (nStrLen > WFS_MAX_VOLUME_ID_SIZE) {
|
||||||
|
return WFS_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
pVolumeId->nLen = (WFSVolumeIdLengthType)nStrLen;
|
||||||
|
strcpy(pVolumeId->sStr, sVolumeId);
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
@ -0,0 +1,353 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfs_PathNames.cpp - Functions for concatenating relative and absolute path names
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfs_PathNames.cpp,v $
|
||||||
|
Revision 1.23 2008/08/19 14:12:41 nakanose_jin
|
||||||
|
bug : relative dir from long path current dir causes buffer-overflow
|
||||||
|
|
||||||
|
Revision 1.22 2008/07/15 02:32:17 paul
|
||||||
|
Fixed so that single "/" is still accepted
|
||||||
|
|
||||||
|
Revision 1.21 2008/07/09 02:50:34 paul
|
||||||
|
Changed to ensure absolute paths do not end with a '/'
|
||||||
|
|
||||||
|
Revision 1.20 2008/04/28 18:37:29 paul
|
||||||
|
Fixed a bug with parsing relative patterns which start with a wildcard character
|
||||||
|
|
||||||
|
Revision 1.19 2008/04/19 05:53:44 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.18 2008/02/29 07:21:55 paul
|
||||||
|
The previous fix was not adequate. Should be fixed now.
|
||||||
|
|
||||||
|
Revision 1.17 2008/02/29 02:07:16 paul
|
||||||
|
Fixed a bug where pathnames which ended with a filename that was 1 byte too long were incorrectly accepted.
|
||||||
|
|
||||||
|
Revision 1.16 2008/02/25 05:37:06 paul
|
||||||
|
Fixed bug in pathname length check
|
||||||
|
|
||||||
|
Revision 1.15 2008/02/13 05:47:08 paul
|
||||||
|
Changed spec to make empty pathnames "" invalid. Previously it was treated as current directory.
|
||||||
|
|
||||||
|
Revision 1.14 2008/02/07 06:32:06 paul
|
||||||
|
fixed a problem with filenames such as ~File
|
||||||
|
|
||||||
|
Revision 1.13 2008/02/04 05:44:00 paul
|
||||||
|
Fixed a bug with checking the length of a directory entry
|
||||||
|
|
||||||
|
Revision 1.12 2008/01/25 04:33:39 paul
|
||||||
|
Fixed a bug with WFSPathResolve for directories relative to the home directory "~/dir"
|
||||||
|
|
||||||
|
Revision 1.11 2008/01/17 10:18:11 paul
|
||||||
|
Fixed a bug where characters >=0x80 were being treated as -ve indexes in the table lookup
|
||||||
|
|
||||||
|
Revision 1.10 2007/12/25 14:03:49 ueno
|
||||||
|
Modified to initialize mutex, thread and heap only once.
|
||||||
|
|
||||||
|
Revision 1.9 2007/12/10 02:49:38 paul
|
||||||
|
Added debug output
|
||||||
|
|
||||||
|
Revision 1.8 2007/11/09 01:19:32 paul
|
||||||
|
Added a new start state to allow validation of path name depth for paths ending in directories
|
||||||
|
|
||||||
|
Revision 1.7 2007/11/06 22:43:12 paul
|
||||||
|
Added validation checks for NULL pointers passed in
|
||||||
|
|
||||||
|
Revision 1.6 2007/11/02 01:06:49 paul
|
||||||
|
now logging changes
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// File created by Paul Donnelly on 2007.10.05
|
||||||
|
|
||||||
|
#include "wfs_Client.h"
|
||||||
|
|
||||||
|
#undef dbg
|
||||||
|
#if _DEBUG_PATHNAMES
|
||||||
|
#define dbg(s) s
|
||||||
|
#else
|
||||||
|
#define dbg(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// A Lookup table is used to categorize characters for the purposes of resolving path names.
|
||||||
|
// It maps a single utf-8 byte to one of the following categories:
|
||||||
|
#define CHAR_CATEGORY_NORMAL 0
|
||||||
|
#define CHAR_CATEGORY_DOT 1
|
||||||
|
#define CHAR_CATEGORY_SLASH 2
|
||||||
|
#define CHAR_CATEGORY_TILDA 3
|
||||||
|
#define CHAR_CATEGORY_NULL 4
|
||||||
|
#define CHAR_CATEGORY_BAD 5
|
||||||
|
#define NUM_CHAR_CATEGORIES 6
|
||||||
|
|
||||||
|
// Invalid Utf-8 bytes, control characters, and wildcards are not allowed in path names
|
||||||
|
utf8 aCharCategory[256] = {
|
||||||
|
CHAR_CATEGORY_NULL, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
|
||||||
|
// ! " # $ % & ' ( ) * + , - . /
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAR_CATEGORY_BAD, 0, 0, 0, CHAR_CATEGORY_DOT, CHAR_CATEGORY_SLASH,
|
||||||
|
|
||||||
|
// 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAR_CATEGORY_BAD,
|
||||||
|
|
||||||
|
// @ A B C D E F G H I J K L M N O
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// P Q R S T U V W X Y Z [ \ ] ^ _
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// ` a b c d e f g h i j k l m n o
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// p q r s t u v w x y z { | } ~ DEL
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, CHAR_CATEGORY_TILDA, CHAR_CATEGORY_BAD,
|
||||||
|
|
||||||
|
// 0x80..0x8F (128..143)
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// 0x90..0x9F (144..159)
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// 0xA0..0xAF (160..175)
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// 0xB0..0xBF (176..191)
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// 0xC0..0xCF (192..207)
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// 0xD0..0xDF (208..223)
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// 0xE0..0xEF (224..239)
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
// 0xF0..0xFF (240..255)
|
||||||
|
0, 0, 0, 0, 0, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD, CHAR_CATEGORY_BAD,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Finite State Machine for resolving and normalizing path names
|
||||||
|
typedef enum {
|
||||||
|
// Initial states - see wfs_PathNames.h
|
||||||
|
STATE_START_REL = PATH_TYPE_REL_OR_ABS,
|
||||||
|
STATE_START_REL_DIR = PATH_TYPE_REL_OR_ABS_DIR,
|
||||||
|
STATE_START_ABS_DIR = PATH_TYPE_ABS_DIR_ONLY,
|
||||||
|
STATE_START_PTN = PATH_TYPE_PATTERN,
|
||||||
|
|
||||||
|
// Mid-parsing states
|
||||||
|
STATE_START_DOT,
|
||||||
|
STATE_START_SLASH,
|
||||||
|
STATE_START_TILDA,
|
||||||
|
STATE_START_NAME,
|
||||||
|
STATE_START_WILD,
|
||||||
|
STATE_TWO_DOTS,
|
||||||
|
STATE_IGNORE,
|
||||||
|
STATE_MID,
|
||||||
|
STATE_DOT,
|
||||||
|
STATE_TILDA,
|
||||||
|
STATE_HOME,
|
||||||
|
STATE_SLASH,
|
||||||
|
STATE_PARENT,
|
||||||
|
|
||||||
|
// for parsing search patterns including wild-cards
|
||||||
|
STATE_CHK_WILD,
|
||||||
|
STATE_WILD,
|
||||||
|
|
||||||
|
// End states (Do not require an entry in the state table, since no further transition is possible)
|
||||||
|
STATE_END,
|
||||||
|
STATE_HOME_END,
|
||||||
|
STATE_NAME_END,
|
||||||
|
STATE_PARENT_END,
|
||||||
|
STATE_ERROR
|
||||||
|
} WFSPathFsmState;
|
||||||
|
|
||||||
|
|
||||||
|
u8 aStateMachine[][NUM_CHAR_CATEGORIES] = {
|
||||||
|
// A-Z . / ~ NULL * ?
|
||||||
|
{ STATE_START_NAME, STATE_START_DOT, STATE_START_SLASH, STATE_START_TILDA, STATE_ERROR, STATE_ERROR }, // STATE_START_REL
|
||||||
|
{ STATE_START_NAME, STATE_START_DOT, STATE_START_SLASH, STATE_START_TILDA, STATE_ERROR, STATE_ERROR }, // STATE_START_REL_DIR
|
||||||
|
{ STATE_ERROR, STATE_ERROR, STATE_START_SLASH, STATE_ERROR, STATE_ERROR, STATE_ERROR }, // STATE_START_ABS_DIR
|
||||||
|
{ STATE_START_NAME, STATE_START_DOT, STATE_START_SLASH, STATE_START_TILDA, STATE_ERROR, STATE_START_WILD}, // STATE_START_PTN
|
||||||
|
|
||||||
|
{ STATE_MID, STATE_TWO_DOTS, STATE_IGNORE, STATE_MID, STATE_END, STATE_CHK_WILD }, // STATE_START_DOT
|
||||||
|
{ STATE_MID, STATE_DOT, STATE_IGNORE, STATE_TILDA, STATE_END, STATE_CHK_WILD }, // STATE_START_SLASH
|
||||||
|
{ STATE_START_NAME, STATE_START_NAME, STATE_HOME, STATE_START_NAME, STATE_HOME_END, STATE_CHK_WILD }, // STATE_START_TILDA
|
||||||
|
{ STATE_MID, STATE_MID, STATE_SLASH, STATE_MID, STATE_NAME_END, STATE_CHK_WILD }, // STATE_START_NAME
|
||||||
|
{ STATE_WILD, STATE_WILD, STATE_ERROR, STATE_WILD, STATE_NAME_END, STATE_WILD }, // STATE_START_WILD
|
||||||
|
{ STATE_MID, STATE_MID, STATE_PARENT, STATE_MID, STATE_PARENT_END, STATE_CHK_WILD }, // STATE_TWO_DOTS
|
||||||
|
{ STATE_MID, STATE_DOT, STATE_IGNORE, STATE_TILDA, STATE_END, STATE_CHK_WILD }, // STATE_IGNORE
|
||||||
|
{ STATE_MID, STATE_MID, STATE_SLASH, STATE_MID, STATE_NAME_END, STATE_CHK_WILD }, // STATE_MID
|
||||||
|
{ STATE_MID, STATE_TWO_DOTS, STATE_IGNORE, STATE_MID, STATE_END, STATE_CHK_WILD }, // STATE_DOT
|
||||||
|
{ STATE_MID, STATE_MID, STATE_ERROR, STATE_MID, STATE_ERROR, STATE_CHK_WILD }, // STATE_TILDA
|
||||||
|
{ STATE_MID, STATE_DOT, STATE_IGNORE, STATE_TILDA, STATE_END, STATE_CHK_WILD }, // STATE_HOME
|
||||||
|
{ STATE_MID, STATE_DOT, STATE_IGNORE, STATE_TILDA, STATE_END, STATE_CHK_WILD }, // STATE_SLASH
|
||||||
|
{ STATE_MID, STATE_DOT, STATE_IGNORE, STATE_TILDA, STATE_END, STATE_CHK_WILD }, // STATE_PARENT
|
||||||
|
{ STATE_WILD, STATE_WILD, STATE_ERROR, STATE_WILD, STATE_NAME_END, STATE_WILD }, // STATE_CHK_WILD
|
||||||
|
{ STATE_WILD, STATE_WILD, STATE_ERROR, STATE_WILD, STATE_NAME_END, STATE_WILD }, // STATE_WILD
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool bMutexInitialized;
|
||||||
|
|
||||||
|
static void WfsPathClear(WFSPathName *pPn, WFSPathPartOffsetArray *pPpoa) {
|
||||||
|
pPn->nLen = 1;
|
||||||
|
pPpoa->nNumParts = 0;
|
||||||
|
pPpoa->aPart[pPpoa->nNumParts] = pPn->nLen;
|
||||||
|
pPn->sStr[0] = '/';
|
||||||
|
pPn->sStr[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSPathInit() {
|
||||||
|
if (!bMutexInitialized)
|
||||||
|
{
|
||||||
|
bMutexInitialized = true;
|
||||||
|
WFSInitMutex(&wcg.pg.mxAccessPathGlobals);
|
||||||
|
}
|
||||||
|
WfsPathClear(&wcg.pg.pathCurrent.pn, &wcg.pg.pathCurrent.ppoa);
|
||||||
|
WfsPathClear(&wcg.pg.pathHome.pn, &wcg.pg.pathHome.ppoa);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void WfsPathParent(WFSPathName *pPn, WFSPathPartOffsetArray *pPpoa) {
|
||||||
|
if (pPpoa->nNumParts == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pPpoa->nNumParts--;
|
||||||
|
pPn->nLen = pPpoa->aPart[pPpoa->nNumParts];
|
||||||
|
pPn->sStr[pPn->nLen] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSPathCopy(WFSPathName *pPnDst, WFSPathPartOffsetArray *pPpoaDst, WFSPathName *pPnSrc, WFSPathPartOffsetArray *pPpoaSrc, bool bAppendSeparator, bool bNullTermination) {
|
||||||
|
pPnDst->nLen = pPnSrc->nLen;
|
||||||
|
pPpoaDst->nNumParts = pPpoaSrc->nNumParts;
|
||||||
|
memcpy(pPpoaDst->aPart, pPpoaSrc->aPart, sizeof(pPpoaSrc->aPart[0]) * (pPpoaSrc->nNumParts+1));
|
||||||
|
memcpy(pPnDst->sStr, pPnSrc->sStr, sizeof(pPnSrc->sStr[0]) * pPnSrc->nLen);
|
||||||
|
if ((bAppendSeparator) && (pPnDst->sStr[pPnDst->nLen-1]!='/')) {
|
||||||
|
pPnDst->sStr[pPnDst->nLen++] = '/';
|
||||||
|
pPpoaDst->aPart[pPpoaDst->nNumParts]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bNullTermination)
|
||||||
|
{
|
||||||
|
pPnDst->sStr[pPnDst->nLen] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSPathResolve(WFSPathName *pPnOutAbs, WFSPathPartOffsetArray *pPpoaOutAbs, const utf8 *sInPathName, WFSPathNameType nPathType) {
|
||||||
|
// Arguments:
|
||||||
|
// ----------
|
||||||
|
// pOutAbsPath .. The output normalized absolute path name
|
||||||
|
// sInPathName .. The input path name
|
||||||
|
// nPathType .. Specifies whether to allow relative or absolute, absolute-only, or patterns
|
||||||
|
//
|
||||||
|
// Description:
|
||||||
|
// ------------
|
||||||
|
// Uses a state machine to process input path names or search patterns.
|
||||||
|
// Relative paths are concatenated to the current directory or home directory.
|
||||||
|
// The output is a normalized absolute path name or pattern.
|
||||||
|
// normalized means "../" == "go back one directory" are processed and removed.
|
||||||
|
// Invalid path names are detected, and cause a WFS_RESULT_INVALID error.
|
||||||
|
WFSPathPartOffsetArray ppoa;
|
||||||
|
WFSReturnOnNullParameter(sInPathName);
|
||||||
|
if (pPpoaOutAbs == NULL) {
|
||||||
|
pPpoaOutAbs = &ppoa;
|
||||||
|
}
|
||||||
|
const utf8 *pParse = sInPathName;
|
||||||
|
const utf8 *pName = pParse;
|
||||||
|
s32 nState = (WFSPathFsmState)nPathType;
|
||||||
|
s32 nDepthLimit = WFS_MAX_PATH_DEPTH;
|
||||||
|
s32 nLenAdjust = 0;
|
||||||
|
if ((nPathType==STATE_START_REL_DIR)||(nPathType==STATE_START_ABS_DIR)) {
|
||||||
|
nDepthLimit--;
|
||||||
|
}
|
||||||
|
WFSLockMutex(&wcg.pg.mxAccessPathGlobals);
|
||||||
|
WfsPathClear(pPnOutAbs, pPpoaOutAbs);
|
||||||
|
while(nState < STATE_END) {
|
||||||
|
s32 nCharCategory = aCharCategory[*((u8*)pParse++)];
|
||||||
|
nState = aStateMachine[nState][nCharCategory];
|
||||||
|
switch(nState) {
|
||||||
|
case STATE_START_DOT: // ". "
|
||||||
|
case STATE_START_NAME: // "A "
|
||||||
|
case STATE_START_WILD: // "* "
|
||||||
|
WFSPathCopy(pPnOutAbs, pPpoaOutAbs, &wcg.pg.pathCurrent.pn, &wcg.pg.pathCurrent.ppoa, true, false);
|
||||||
|
break;
|
||||||
|
case STATE_START_SLASH: // "/ "
|
||||||
|
WfsPathClear(pPnOutAbs, pPpoaOutAbs);
|
||||||
|
pName++;
|
||||||
|
break;
|
||||||
|
case STATE_HOME:
|
||||||
|
case STATE_HOME_END:
|
||||||
|
WFSPathCopy(pPnOutAbs, pPpoaOutAbs, &wcg.pg.pathHome.pn, &wcg.pg.pathHome.ppoa, true, false);
|
||||||
|
// Falls through
|
||||||
|
case STATE_IGNORE:
|
||||||
|
pName = pParse;
|
||||||
|
break;
|
||||||
|
case STATE_NAME_END:
|
||||||
|
nLenAdjust = -1;
|
||||||
|
// Falls through
|
||||||
|
case STATE_SLASH: {
|
||||||
|
s32 nPartLen = pParse - pName;
|
||||||
|
if (nPartLen>(WFS_MAX_FILE_NAME_SIZE+1)) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
s32 nNewLen = pPnOutAbs->nLen + nPartLen + nLenAdjust;
|
||||||
|
s32 nNewDepth = pPpoaOutAbs->nNumParts+1;
|
||||||
|
if ((nNewLen>WFS_MAX_PATH_NAME_SIZE)||(nNewDepth>nDepthLimit)) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
memcpy(&pPnOutAbs->sStr[pPnOutAbs->nLen], pName, (u32)nPartLen);
|
||||||
|
pPnOutAbs->nLen = (WFSPathNameLengthType)nNewLen;
|
||||||
|
pPpoaOutAbs->nNumParts++;
|
||||||
|
pPpoaOutAbs->aPart[pPpoaOutAbs->nNumParts] = (WFSPathNameLengthType)pPnOutAbs->nLen;
|
||||||
|
pName = pParse;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case STATE_PARENT:
|
||||||
|
case STATE_PARENT_END:
|
||||||
|
WfsPathParent(pPnOutAbs, pPpoaOutAbs);
|
||||||
|
pName = pParse;
|
||||||
|
break;
|
||||||
|
case STATE_CHK_WILD:
|
||||||
|
if (nPathType != PATH_TYPE_PATTERN) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case STATE_ERROR:
|
||||||
|
goto Error;
|
||||||
|
case STATE_START_TILDA: case STATE_TILDA: case STATE_DOT:
|
||||||
|
case STATE_START_REL: case STATE_TWO_DOTS: case STATE_MID: case STATE_END:
|
||||||
|
case STATE_START_REL_DIR: case STATE_START_ABS_DIR:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((pPnOutAbs->sStr[pPnOutAbs->nLen-1] == '/') && (pPnOutAbs->nLen>1)) {
|
||||||
|
pPnOutAbs->sStr[--pPnOutAbs->nLen] = 0;
|
||||||
|
--pPpoaOutAbs->aPart[pPpoaOutAbs->nNumParts];
|
||||||
|
}
|
||||||
|
pPnOutAbs->sStr[pPnOutAbs->nLen] = 0;
|
||||||
|
WFSUnlockMutex(&wcg.pg.mxAccessPathGlobals);
|
||||||
|
dbg(MyOSReport("path: %s\n", pPnOutAbs->sStr));
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
Error:
|
||||||
|
WFSUnlockMutex(&wcg.pg.mxAccessPathGlobals);
|
||||||
|
dbg(MyOSReport("path: WFS_RESULT_INVALID\n"));
|
||||||
|
return WFS_RESULT_INVALID;
|
||||||
|
}
|
||||||
@ -0,0 +1,125 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfscli_Handles.cpp - Module for file handles and search directory handles
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfscli_Handles.cpp,v $
|
||||||
|
Revision 1.11 2008/10/07 06:41:51 ueno
|
||||||
|
Modified WFSCliFileInfoAlloc to set WFSCLI_HANDLE_ALLOCATED in order to indicate the handle is allocated.
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/19 05:53:38 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.9 2007/12/25 14:03:49 ueno
|
||||||
|
Modified to initialize mutex, thread and heap only once.
|
||||||
|
|
||||||
|
Revision 1.8 2007/11/16 02:15:59 wayne.wong
|
||||||
|
Added enumeration and stubs for WFSFlush call.
|
||||||
|
|
||||||
|
Revision 1.7 2007/11/02 01:07:38 paul
|
||||||
|
now logging changes
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
// File created by Paul Donnelly on 2007.10.06
|
||||||
|
|
||||||
|
#include "wfs_Client.h"
|
||||||
|
|
||||||
|
static bool bMutexInitialized; // [check]
|
||||||
|
|
||||||
|
void WFSCliInitHandles() {
|
||||||
|
if (!bMutexInitialized)
|
||||||
|
{
|
||||||
|
bMutexInitialized = true;
|
||||||
|
WFSInitMutex(&wcg.hnd.mxAccessTheFileInfo);
|
||||||
|
WFSInitMutex(&wcg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
}
|
||||||
|
wcg.hnd.nFileHandleCounter = 0;
|
||||||
|
wcg.hnd.nSearchDirHandleCounter = 0;
|
||||||
|
wcg.hnd.nFirstFreeFileHandle = 0;
|
||||||
|
wcg.hnd.nFirstFreeSearchDirHandle = 0;
|
||||||
|
wcg.hnd.nNumUsedFileHandles = 0;
|
||||||
|
wcg.hnd.nNumUsedSearchDirHandles = 0;
|
||||||
|
//wcg.hnd.nFirstUsedFileHandle = WFSCLI_MAX_FILE_HANDLES; // A value of WFSCLI_MAX_FILE_HANDLES is the list terminator
|
||||||
|
//wcg.hnd.nFirstUsedSearchDirHandle = WFSCLI_MAX_SEARCH_DIR_HANDLES; // A value of WFSCLI_MAX_SEARCH_DIR_HANDLES is the list terminator
|
||||||
|
for(u32 nI=0; nI<WFSCLI_MAX_FILE_HANDLES; nI++) {
|
||||||
|
wcg.hnd.aCliFileInfo[nI].nNext = nI+1;
|
||||||
|
}
|
||||||
|
for(u32 nI=0; nI<WFSCLI_MAX_SEARCH_DIR_HANDLES; nI++) {
|
||||||
|
wcg.hnd.aCliSearchDirInfo[nI].nNext = nI+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSGetCliFileInfo(WFSCliFileInfo **ppFi, WFSFileHandle fh) {
|
||||||
|
*ppFi = &wcg.hnd.aCliFileInfo[(fh>>16)&(WFSCLI_MAX_FILE_HANDLES-1)];
|
||||||
|
return ((*ppFi)->nHandle == fh)?WFS_RESULT_OK:WFS_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSGetCliSearchDirInfo(WFSCliSearchDirInfo **ppSdi, WFSSearchDirectoryHandle sdh) {
|
||||||
|
*ppSdi = &wcg.hnd.aCliSearchDirInfo[(sdh>>16)&(WFSCLI_MAX_SEARCH_DIR_HANDLES-1)];
|
||||||
|
return ((*ppSdi)->nHandle == sdh)?WFS_RESULT_OK:WFS_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSCliFileInfoAlloc(WFSCliFileInfo **ppFi) {
|
||||||
|
WFSLockMutex(&wcg.hnd.mxAccessTheFileInfo);
|
||||||
|
if (wcg.hnd.nFirstFreeFileHandle == WFSCLI_MAX_FILE_HANDLES) {
|
||||||
|
WFSUnlockMutex(&wcg.hnd.mxAccessTheFileInfo);
|
||||||
|
return WFS_RESULT_MAX_HANDLES;
|
||||||
|
}
|
||||||
|
wcg.hnd.nNumUsedFileHandles++;
|
||||||
|
u32 nIdx = wcg.hnd.nFirstFreeFileHandle;
|
||||||
|
wcg.hnd.nFirstFreeFileHandle = wcg.hnd.aCliFileInfo[nIdx].nNext;
|
||||||
|
wcg.hnd.aCliFileInfo[nIdx].nNext = WFSCLI_HANDLE_ALLOCATED; // this means the handle is open.
|
||||||
|
*ppFi = &wcg.hnd.aCliFileInfo[nIdx];
|
||||||
|
wcg.hnd.aCliFileInfo[nIdx].nHandle = WFSCLI_FILE_HANDLE_TT_FIELD | wcg.hnd.nFileHandleCounter | (nIdx<<16);
|
||||||
|
wcg.hnd.nFileHandleCounter += WFSCLI_FILE_HANDLE_INC;
|
||||||
|
wcg.hnd.nFileHandleCounter &= WFSCLI_HANDLE_COUNTER_MASK;
|
||||||
|
WFSUnlockMutex(&wcg.hnd.mxAccessTheFileInfo);
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSResult WFSCliSearchDirInfoAlloc(WFSCliSearchDirInfo **ppSdi) {
|
||||||
|
WFSLockMutex(&wcg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
if (wcg.hnd.nFirstFreeSearchDirHandle == WFSCLI_MAX_SEARCH_DIR_HANDLES) {
|
||||||
|
WFSUnlockMutex(&wcg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
return WFS_RESULT_MAX_HANDLES;
|
||||||
|
}
|
||||||
|
wcg.hnd.nNumUsedSearchDirHandles++;
|
||||||
|
u32 nIdx = wcg.hnd.nFirstFreeSearchDirHandle;
|
||||||
|
wcg.hnd.nFirstFreeSearchDirHandle = wcg.hnd.aCliSearchDirInfo[nIdx].nNext;
|
||||||
|
wcg.hnd.aCliSearchDirInfo[nIdx].nNext = WFSCLI_HANDLE_ALLOCATED; // this means the handle is open.
|
||||||
|
*ppSdi = &wcg.hnd.aCliSearchDirInfo[nIdx];
|
||||||
|
wcg.hnd.aCliSearchDirInfo[nIdx].nHandle = WFSCLI_SEARCH_DIR_HANDLE_TT_FIELD | wcg.hnd.nSearchDirHandleCounter | (nIdx<<16);
|
||||||
|
wcg.hnd.nSearchDirHandleCounter += WFSCLI_SEARCH_DIR_HANDLE_INC;
|
||||||
|
wcg.hnd.nSearchDirHandleCounter &= WFSCLI_HANDLE_COUNTER_MASK;
|
||||||
|
WFSUnlockMutex(&wcg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
return WFS_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSCliFileInfoFree(WFSCliFileInfo *pFi) {
|
||||||
|
WFSLockMutex(&wcg.hnd.mxAccessTheFileInfo);
|
||||||
|
u32 nIdx = (u32)(pFi - wcg.hnd.aCliFileInfo);
|
||||||
|
pFi->nHandle ^= 0x55555555; // ensures the deleted handle is invalid
|
||||||
|
pFi->nNext = wcg.hnd.nFirstFreeFileHandle;
|
||||||
|
wcg.hnd.nNumUsedFileHandles--;
|
||||||
|
wcg.hnd.nFirstFreeFileHandle = nIdx;
|
||||||
|
WFSUnlockMutex(&wcg.hnd.mxAccessTheFileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSCliSearchDirInfoFree(WFSCliSearchDirInfo *pSdi) {
|
||||||
|
WFSLockMutex(&wcg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
u32 nIdx = (u32)(pSdi - wcg.hnd.aCliSearchDirInfo);
|
||||||
|
pSdi->nHandle ^= 0x55555555; // ensures the deleted handle is invalid
|
||||||
|
pSdi->nNext = wcg.hnd.nFirstFreeSearchDirHandle;
|
||||||
|
wcg.hnd.nNumUsedSearchDirHandles--;
|
||||||
|
wcg.hnd.nFirstFreeSearchDirHandle = nIdx;
|
||||||
|
WFSUnlockMutex(&wcg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
}
|
||||||
@ -0,0 +1,203 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: TWL - rtfs interface for SD Memory Card
|
||||||
|
File: drnand.h
|
||||||
|
|
||||||
|
Copyright 2006-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Date:: #$
|
||||||
|
$Rev$
|
||||||
|
$Author$
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <brom.h>
|
||||||
|
#include <brom/nand/nand.h>
|
||||||
|
#include <sdmc.h>
|
||||||
|
#include <drnand.h>
|
||||||
|
|
||||||
|
#define PRINTDEBUG( ...) ((void)0)
|
||||||
|
/*
|
||||||
|
#if (SD_DEBUG_PRINT_ON == 1)
|
||||||
|
#define PRINTDEBUG osTPrintf
|
||||||
|
#else
|
||||||
|
#define PRINTDEBUG( ...) ((void)0)
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
定数
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#define NUM_SD_PAGES
|
||||||
|
#define SD_PAGE_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
extern変数
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
/*SDメモリカードのスペック構造体*/
|
||||||
|
SdmcSpec sdmc_current_spec;
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
extern関数
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
extern void nandReset( void);
|
||||||
|
void i_nandCalcSize( void); //TODO:sdmc_current_specを構造体に入れること
|
||||||
|
BOOL nandCrashBootSectors( u32* buf);
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
static変数
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
static FATSpec NandFatSpec[4]; //FATパラメータ(パーティション0~3個別)
|
||||||
|
static int nand_calculated_fat_params = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
static関数
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
BOOL nandFillPartition( int partition_no, u32* buf, u32 blocks);
|
||||||
|
void i_nandCalcSize( void);
|
||||||
|
|
||||||
|
|
||||||
|
#if 1 //アプリケーションでパーティション構成を決めたいとき
|
||||||
|
|
||||||
|
u32 NAND_FAT_PARTITION_COUNT;
|
||||||
|
u32 NAND_RAW_SECTORS;
|
||||||
|
u32 NAND_FAT0_SECTORS = 0;
|
||||||
|
u32 NAND_FAT1_SECTORS;
|
||||||
|
u32 NAND_FAT2_SECTORS;
|
||||||
|
u32 NAND_FAT3_SECTORS;
|
||||||
|
|
||||||
|
void nandSetFormatRequest( u16 partition_num, u32* partition_sectors);
|
||||||
|
void nandSetFormatRequest( u16 partition_num, u32* partition_sectors)
|
||||||
|
{
|
||||||
|
NAND_RAW_SECTORS = partition_sectors[0];
|
||||||
|
NAND_FAT0_SECTORS = partition_sectors[1] + NAND_RAW_SECTORS;
|
||||||
|
NAND_FAT1_SECTORS = partition_sectors[2];
|
||||||
|
NAND_FAT2_SECTORS = partition_sectors[3];
|
||||||
|
NAND_FAT3_SECTORS = partition_sectors[4];
|
||||||
|
NAND_FAT_PARTITION_COUNT = partition_num;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else //パーティション構成を決め打ちするとき
|
||||||
|
/* RAW:1MB, FAT0:206MB, FAT1:32.75MB */
|
||||||
|
#define NAND_FAT_PARTITION_COUNT (3)
|
||||||
|
#define NAND_RAW_SECTORS (( 1*1024*1024)/512);
|
||||||
|
#define NAND_FAT0_SECTORS (((206*1024*1024)/512) + NAND_RAW_SECTORS); //計算上RAWを含めておく
|
||||||
|
#define NAND_FAT1_SECTORS ((33536*1024)/512);
|
||||||
|
#define NAND_FAT2_SECTORS (( 1*1024*1024)/512);
|
||||||
|
#define NAND_FAT3_SECTORS (0);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Name: nandNfsIo
|
||||||
|
|
||||||
|
Description: 上位層からのセクタリード/ライト要求を受ける
|
||||||
|
|
||||||
|
Arguments: driveno : ドライブ番号
|
||||||
|
block : 開始ブロック番号
|
||||||
|
buffer :
|
||||||
|
count : ブロック数
|
||||||
|
reading : リード要求時にTRUE
|
||||||
|
|
||||||
|
Returns: TRUE/FALSE
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
BOOL nandNfsIo( int driveno, u32 block, void* buffer, u16 count, BOOL reading)
|
||||||
|
{
|
||||||
|
if( reading) {
|
||||||
|
PRINTDEBUG( "DEVCTL_IO_READ ... block:%x, count:%x -> buf:%x\n", block, count, buffer);
|
||||||
|
nandReadSector( buffer, block, count);
|
||||||
|
}else{
|
||||||
|
PRINTDEBUG( "DEVCTL_IO_WRITE ... block:%x, count:%x <- buf:%x\n", block, count, buffer);
|
||||||
|
nandWriteSector( buffer, block, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Name: nandNfsCtrl
|
||||||
|
|
||||||
|
Description: 上位層からのコントロール要求を受ける
|
||||||
|
|
||||||
|
Arguments: driveno : ドライブ番号
|
||||||
|
opcode : 要求の種類
|
||||||
|
pargs :
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Memo : DRIVE_FLAGS_REMOVABLEの場合、ドライバのIO関数を呼ぶ前に
|
||||||
|
CTRL関数のDEVCTL_CHECK_STATUSが呼ばれる。
|
||||||
|
DEVTEST_CHANGED→DEVTEST_NOCHANGEが確認されるとRTFSはセクタ0を
|
||||||
|
読みに行き、FATパラメータを取得した上で目的のセクタを読みに行く。
|
||||||
|
CTRL関数の前にはDEVCTL_CHECK_STATUSが呼ばれないので、DEVCTL_
|
||||||
|
GET_GEOMETRYでは自前で再挿入をチェックする必要がある。
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
int nandNfsCtrl( int driveno, int opcode, void* pargs)
|
||||||
|
{
|
||||||
|
switch( opcode) {
|
||||||
|
case NFS_DEVCTL_GET_GEOMETRY: //formatまたはpartirionするときにRTFSが使うパラメータ
|
||||||
|
return( 0);
|
||||||
|
|
||||||
|
case NFS_DEVCTL_FORMAT:
|
||||||
|
PRINTDEBUG( "DEVCTL_FORMAT\n");
|
||||||
|
return( 0);
|
||||||
|
|
||||||
|
case NFS_DEVCTL_REPORT_REMOVE: //抜かれたとき
|
||||||
|
PRINTDEBUG( "DEVCTL_REPORT_REMOVE\n");
|
||||||
|
return( 0);
|
||||||
|
|
||||||
|
case NFS_DEVCTL_CHECKSTATUS: //REMOVABLEの場合、毎回R/W前に呼ばれる
|
||||||
|
PRINTDEBUG( "DEVCTL_CHECKSTATUS\n");
|
||||||
|
return(DEVTEST_NOCHANGE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
case NFS_DEVCTL_WARMSTART: //attachのときしか呼ばれない
|
||||||
|
PRINTDEBUG( "DEVCTL_WARMSTART\n");
|
||||||
|
/*-- NANDのみ初期化 --*/
|
||||||
|
// nandReset();
|
||||||
|
/*--------------------*/
|
||||||
|
return( 0);
|
||||||
|
|
||||||
|
case NFS_DEVCTL_POWER_RESTORE:
|
||||||
|
PRINTDEBUG( "DEVCTL_POWER_RESTORE\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NFS_DEVCTL_POWER_LOSS:
|
||||||
|
PRINTDEBUG( "DEVCTL_POWER_LOSS\n");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
PRINTDEBUG( "DEVCTL_unknown\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return( 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Name: i_nandCalcSize
|
||||||
|
|
||||||
|
Description:
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Returns: None
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
void i_nandCalcSize( void)
|
||||||
|
{
|
||||||
|
sdmc_current_spec.csd_ver2_flag = 0;
|
||||||
|
sdmc_current_spec.protected_capacity = (20*256); //20Blocks
|
||||||
|
sdmc_current_spec.card_capacity = NAND_GUARANTEED_SECTORS;
|
||||||
|
sdmc_current_spec.memory_capacity = sdmc_current_spec.card_capacity -
|
||||||
|
sdmc_current_spec.protected_capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//#endif /*(INCLUDE_SD)*/
|
||||||
@ -0,0 +1,545 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Device.cpp - storage device abstraction.
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfskrn_Device.h"
|
||||||
|
#include "wfskrn_Api.h"
|
||||||
|
#include <brom/nand/nand.h>
|
||||||
|
#include <drnand.h>
|
||||||
|
|
||||||
|
//TODO:‘¼‚Å<E2809A>錾‚µ‚Äinclude‚·‚é
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
BOOL nandNfsIo( int driveno, u32 block, void* buffer, u16 count, BOOL reading);
|
||||||
|
int nandNfsCtrl( int driveno, int opcode, void* pargs);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct{
|
||||||
|
u32 cmd;
|
||||||
|
s32 status;
|
||||||
|
WFSHashCode *pHash;
|
||||||
|
WFSHashCode readHash;
|
||||||
|
} DeviceMscResourceRequest;
|
||||||
|
|
||||||
|
static DeviceMscResourceRequest gPmrr[DEVICE_IOP_MAX_ASYNC_NUM];
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
char sDevicePathWin32[sizeof(WFSKRN_SIMULATED_DISK_PATH)+WFS_MAX_DEVICE_NAME_SIZE+1] = WFSKRN_SIMULATED_DISK_PATH;
|
||||||
|
|
||||||
|
char *DeviceGetWin32PathName(const utf8 *sDevName) {
|
||||||
|
memcpy(&sDevicePathWin32[sizeof(WFSKRN_SIMULATED_DISK_PATH)-1], sDevName, WFS_MAX_DEVICE_NAME_SIZE+1);
|
||||||
|
return sDevicePathWin32;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSHashCode aHashDummyData = {0xbeefbeef,0xbeefbeef,0xbeefbeef,0xbeefbeef,0xbeefbeef};
|
||||||
|
|
||||||
|
#elif _IOP
|
||||||
|
|
||||||
|
static IOSMessageQueueId gMqidPmrr;
|
||||||
|
static IOSMessage gMqPmrr[DEVICE_IOP_MAX_ASYNC_NUM];
|
||||||
|
|
||||||
|
static IOSMessageQueueId gMqidIrrFb;
|
||||||
|
static IOSMessage gMqIrrFb[1];
|
||||||
|
static IOSResourceRequest gIrrFuncBlock;
|
||||||
|
|
||||||
|
static DeviceAttachDetachCallback gCbAttach = 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static s32 cntDebugPseudoDetachDrive = -1;
|
||||||
|
static s32 cntDebugPseudoHashInconsistent = -1;
|
||||||
|
|
||||||
|
#define WFS_MAX_DEVICE_PATH (sizeof(WFS_DEVICE_DIRECTORY) + WFS_MAX_DEVICE_NAME_SIZE + 2)
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize Device library
|
||||||
|
// x86 - initialize parameter
|
||||||
|
void DeviceInitLib() {
|
||||||
|
dbgd(osTPrintf("DeviceInitLib()\n"));
|
||||||
|
wkg.nNumDevices = 0;
|
||||||
|
memset(&wkg.aDevInfo, 0, sizeof(wkg.aDevInfo));
|
||||||
|
memset(&gPmrr, 0, sizeof(DeviceMscResourceRequest)*DEVICE_IOP_MAX_ASYNC_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DeviceDebugSetPseudoDetachDevice(s32 cnt)
|
||||||
|
{
|
||||||
|
cntDebugPseudoDetachDrive = cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceDebugSetPseudoHashInconsistent(s32 cnt)
|
||||||
|
{
|
||||||
|
cntDebugPseudoHashInconsistent = cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 DeviceDebugGetPseudoDetachDevice()
|
||||||
|
{
|
||||||
|
return cntDebugPseudoDetachDrive;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 DeviceDebugGetPseudoHashInconsistent()
|
||||||
|
{
|
||||||
|
return cntDebugPseudoHashInconsistent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
static IOSError _WIN32DeviceRead(DeviceInfo *pDevInfo, u32 nSectorAdr, u8 *pData, u16 nSectors, u8 *pHash, u16 nHashSectors, s32 nHashStride)
|
||||||
|
{
|
||||||
|
u64 filePos = (u64)nSectorAdr * pDevInfo->nSectorSize;
|
||||||
|
filePos += 2 * sizeof(u32); // initial bytes have sector size + dev capacity
|
||||||
|
LONG posLow = (LONG) filePos & 0xffffffff;
|
||||||
|
LONG posHigh = filePos >> 32;
|
||||||
|
SetFilePointer(pDevInfo->hSimulatedDeviceFile, posLow, &posHigh, FILE_BEGIN);
|
||||||
|
|
||||||
|
DWORD numBytes = pDevInfo->nSectorSize * nSectors;
|
||||||
|
DWORD bytesRead;
|
||||||
|
if (!ReadFile(pDevInfo->hSimulatedDeviceFile, pData, numBytes, &bytesRead, NULL)) {
|
||||||
|
dbgd(osTPrintf("DeviceRead: read failed\n"));
|
||||||
|
return IOS_ERROR_MSC_COMMAND_FAILED;
|
||||||
|
}
|
||||||
|
if(pData[0] == 0xaa){
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
if (numBytes != bytesRead) {
|
||||||
|
dbgd(osTPrintf("DeviceRead: bytes read does not match\n"));
|
||||||
|
return IOS_ERROR_MSC_COMMAND_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 nSize = numBytes;
|
||||||
|
int nNumBlks = 0;
|
||||||
|
while(nSize>0){
|
||||||
|
u8 *pHashPtr = (u8*)pHash+(nNumBlks*nHashStride);
|
||||||
|
u32 *pHashDummyData32 = (u32*)aHashDummyData;
|
||||||
|
*pHashDummyData32++ = nSectorAdr+(nNumBlks*nHashSectors);
|
||||||
|
*pHashDummyData32++ = nSize < (nHashSectors<<pDevInfo->dh.nLog2SectorSize) ? nSize : (nHashSectors<<pDevInfo->dh.nLog2SectorSize);
|
||||||
|
if(memcmp(pHashPtr, (u8*)aHashDummyData, sizeof(WFSHashCode))){
|
||||||
|
return IOS_ERROR_MSC_HASH_INCONSISTENT;
|
||||||
|
}
|
||||||
|
nSize -= (nHashSectors<<pDevInfo->dh.nLog2SectorSize);
|
||||||
|
++nNumBlks;
|
||||||
|
}
|
||||||
|
return IOS_ERROR_MSC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IOSError _WIN32DeviceWrite(DeviceInfo *pDevInfo, u32 nSectorAdr, u8 *pData, u16 nSectors, u8 *pHash, u16 nHashSectors, s32 nHashStride, bool bDecryption)
|
||||||
|
{
|
||||||
|
u64 filePos = (u64)nSectorAdr * pDevInfo->nSectorSize;
|
||||||
|
filePos += sizeof(pDevInfo->dh); // initial bytes have sector size + dev capacity
|
||||||
|
LONG posLow = (LONG) filePos & 0xffffffff;
|
||||||
|
LONG posHigh = filePos >> 32;
|
||||||
|
SetFilePointer(pDevInfo->hSimulatedDeviceFile, posLow, &posHigh, FILE_BEGIN);
|
||||||
|
|
||||||
|
DWORD numBytes = pDevInfo->nSectorSize * nSectors;
|
||||||
|
DWORD bytesWritten;
|
||||||
|
s32 nSize = numBytes;
|
||||||
|
int nNumBlks = 0;
|
||||||
|
while(nSize>0){
|
||||||
|
u8 *pHashPtr = (u8*)pHash+(nNumBlks*nHashStride);
|
||||||
|
u32 *pHashDummyData32 = (u32*)aHashDummyData;
|
||||||
|
*pHashDummyData32++ = nSectorAdr+(nNumBlks*nHashSectors);
|
||||||
|
if(nSectorAdr+(nNumBlks*nHashSectors) == 0x180){
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
*pHashDummyData32++ = nSize < (nHashSectors<<pDevInfo->dh.nLog2SectorSize) ? nSize : (nHashSectors<<pDevInfo->dh.nLog2SectorSize);
|
||||||
|
memcpy(pHashPtr, (u8*)aHashDummyData, sizeof(WFSHashCode));
|
||||||
|
nSize -= (nHashSectors<<pDevInfo->dh.nLog2SectorSize);
|
||||||
|
++nNumBlks;
|
||||||
|
}
|
||||||
|
if (!WriteFile(pDevInfo->hSimulatedDeviceFile, pData, numBytes, &bytesWritten, NULL)) {
|
||||||
|
dbgd(osTPrintf("DeviceWrite: write failed\n"));
|
||||||
|
return IOS_ERROR_MSC_COMMAND_FAILED;
|
||||||
|
}
|
||||||
|
if(pData[0] == 0xaa){
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
if (numBytes != bytesWritten) {
|
||||||
|
dbgd(osTPrintf("DeviceWrite: bytes written does not match\n"));
|
||||||
|
return IOS_ERROR_MSC_COMMAND_FAILED;
|
||||||
|
}
|
||||||
|
if(!bDecryption){
|
||||||
|
memset(pData, 0xaa, numBytes);
|
||||||
|
}
|
||||||
|
return IOS_ERROR_MSC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Read nNumSectors sectors from device devHandle starting at LBA nSectorAdr into buffer
|
||||||
|
// pBuffer. nSectorAdr == LBA.
|
||||||
|
WFSKrnResult DeviceRead(DeviceInfo *pDevInfo, u32 nSectorAdr, u8 *pBuffer, u32 nSectors, WFSHashCode *pHash, u32 nLog2HashSectors, u32 nOffsetHashBlks, s32 nHashStride, s32 nHashStridePerMaxLBlks)
|
||||||
|
{
|
||||||
|
dbgd(osTPrintf("DeviceRead()\n"));
|
||||||
|
ASSERT(nLog2HashSectors <= (WFS_LOG2_MAX_HASHABLE_BLK_SIZE-pDevInfo->dh.nLog2SectorSize)); // ~64KB
|
||||||
|
#if _DEBUG
|
||||||
|
//osTPrintf("Read: nSectorAdr = 0x%x, pDevInfo->dh.nNumSectors = 0x%x\n", nSectorAdr, pDevInfo->dh.nNumSectors);
|
||||||
|
if (nSectorAdr >= pDevInfo->dh.nNumSectors) {
|
||||||
|
WFSKrnOutputErrorStr("Attempted access beyond end of device");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
DeviceMscResourceRequest *pCurrentReply;
|
||||||
|
u32 nMaxSectors = 1<<(WFS_LOG2_LARGE_BLK_SIZE-pDevInfo->dh.nLog2SectorSize);
|
||||||
|
u32 nHashSectors = (1<<nLog2HashSectors);
|
||||||
|
u8 *pData = pBuffer;
|
||||||
|
u32 nNumBlks = nSectors ? ((nSectors-1)>>nLog2HashSectors)+1 : 0;
|
||||||
|
u32 nNumLoop = (((nHashSectors<<pDevInfo->dh.nLog2SectorSize)*(nNumBlks+nOffsetHashBlks)-1)>>WFS_LOG2_LARGE_BLK_SIZE)+1;
|
||||||
|
u32 nRcvLoop = nNumLoop < DEVICE_IOP_MAX_ASYNC_NUM ? nNumLoop : DEVICE_IOP_MAX_ASYNC_NUM;
|
||||||
|
int i;
|
||||||
|
for(i=0;i<nNumLoop+nRcvLoop;i++){
|
||||||
|
#if _TWL
|
||||||
|
pCurrentReply = &gPmrr[0];
|
||||||
|
if(i>=nRcvLoop){
|
||||||
|
#endif
|
||||||
|
switch(pCurrentReply->status){
|
||||||
|
case IOS_ERROR_MSC_DEVICE_DETACH:
|
||||||
|
case IOS_ERROR_MSC_COMMAND_FAILED:
|
||||||
|
case IOS_ERROR_MSC_PHASE_ERROR:
|
||||||
|
case IOS_ERROR_MSC_INVALID_CBW_SIGNATURE:
|
||||||
|
case IOS_ERROR_MSC_INVALID_CBW_TAG:
|
||||||
|
nResult = WFSKRN_RESULT_DEVICE_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
#if DEVICE_VERIFY_HASH_DATA
|
||||||
|
case IOS_ERROR_MSC_HASH_INCONSISTENT:
|
||||||
|
pDevInfo->nFlags |= WFS_DEVFLAG_NOT_INITIALIZED;
|
||||||
|
nResult = WFSKRN_RESULT_DEVICE_HASH_INCONSISTENT;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if DEVICE_DEBUG_PSEUDO_DEVICE_ERROR
|
||||||
|
if(cntDebugPseudoDetachDrive == 0){
|
||||||
|
cntDebugPseudoDetachDrive = -1;
|
||||||
|
nResult = WFSKRN_RESULT_DEVICE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
else if(cntDebugPseudoDetachDrive){
|
||||||
|
--cntDebugPseudoDetachDrive;
|
||||||
|
}
|
||||||
|
#if DEVICE_VERIFY_HASH_DATA
|
||||||
|
if(cntDebugPseudoHashInconsistent == 0){
|
||||||
|
pDevInfo->nFlags |= WFS_DEVFLAG_NOT_INITIALIZED;
|
||||||
|
nResult = WFSKRN_RESULT_DEVICE_HASH_INCONSISTENT;
|
||||||
|
cntDebugPseudoHashInconsistent = -1;
|
||||||
|
}
|
||||||
|
else if(cntDebugPseudoHashInconsistent){
|
||||||
|
--cntDebugPseudoHashInconsistent;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if(i<nNumLoop){
|
||||||
|
u32 nSec = (nSectors+(nOffsetHashBlks<<nLog2HashSectors)) < nMaxSectors ? nSectors : (nMaxSectors-(nOffsetHashBlks<<nLog2HashSectors));
|
||||||
|
pCurrentReply->pHash = pHash;
|
||||||
|
IOSError ie;
|
||||||
|
#if _WIN32
|
||||||
|
ie = _WIN32DeviceRead(pDevInfo, nSectorAdr, pData, (u16)nSec, (u8*)pCurrentReply->pHash, (u16)(1<<nLog2HashSectors), nHashStride);
|
||||||
|
#elif _TWL
|
||||||
|
if( nandNfsIo( 0, nSectorAdr, pData, nSec, TRUE) == FALSE) {
|
||||||
|
ie = IOS_ERROR_MSC_COMMAND_FAILED;
|
||||||
|
nResult = WFSKRN_RESULT_MEDIA_ERROR;
|
||||||
|
}else{
|
||||||
|
ie = IOS_ERROR_MSC_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ie < IOS_ERROR_MSC_OK){
|
||||||
|
pCurrentReply->status = ie;
|
||||||
|
}
|
||||||
|
nSectors -= nSec;
|
||||||
|
pData += nSec<<pDevInfo->dh.nLog2SectorSize;
|
||||||
|
nSectorAdr += nSec;
|
||||||
|
u32 nBlks = ((nSec-1)>>nLog2HashSectors)+1;
|
||||||
|
pHash = (WFSHashCode*)((u8*)pHash+nBlks*nHashStride+nHashStridePerMaxLBlks);
|
||||||
|
nOffsetHashBlks = 0;
|
||||||
|
}
|
||||||
|
#if _TWL
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Write nNumSectors sectors to device devHandle starting at LBA nSectorAdr from buffer
|
||||||
|
// pBuffer. nSectorAdr == LBA.
|
||||||
|
WFSKrnResult DeviceWrite(DeviceInfo *pDevInfo, u32 nSectorAdr, u8 *pBuffer, u32 nSectors, WFSHashCode *pHash, u32 nLog2HashSectors, u32 nOffsetHashBlks, s32 nHashStride, s32 nHashStridePerMaxLBlks, bool bDecryption)
|
||||||
|
{
|
||||||
|
#if _DEBUG_BREAK_POINT
|
||||||
|
if (nSectorAdr==0x28800) {
|
||||||
|
int a;a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
dbgd(osTPrintf("DeviceWrite()\n"));
|
||||||
|
ASSERT(nLog2HashSectors <= (WFS_LOG2_MAX_HASHABLE_BLK_SIZE-pDevInfo->dh.nLog2SectorSize)); // ~64KB
|
||||||
|
#if _DEBUG
|
||||||
|
//osTPrintf("Write: nSectorAdr = 0x%x, pDevInfo->dh.nNumSectors = 0x%x\n", nSectorAdr, pDevInfo->dh.nNumSectors);
|
||||||
|
if (nSectorAdr >= pDevInfo->dh.nNumSectors) {
|
||||||
|
WFSKrnOutputErrorStr("Attempted access beyond end of device");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
DeviceMscResourceRequest *pCurrentReply;
|
||||||
|
u32 nMaxSectors = 1<<(WFS_LOG2_LARGE_BLK_SIZE-pDevInfo->dh.nLog2SectorSize);
|
||||||
|
u32 nHashSectors = (1<<nLog2HashSectors);
|
||||||
|
u8 *pData = pBuffer;
|
||||||
|
u32 nNumBlks = nSectors ? ((nSectors-1)>>nLog2HashSectors)+1 : 0;
|
||||||
|
u32 nNumLoop = (((nHashSectors<<pDevInfo->dh.nLog2SectorSize)*(nNumBlks+nOffsetHashBlks)-1)>>WFS_LOG2_LARGE_BLK_SIZE)+1;
|
||||||
|
u32 nRcvLoop = nNumLoop < DEVICE_IOP_MAX_ASYNC_NUM ? nNumLoop : DEVICE_IOP_MAX_ASYNC_NUM;
|
||||||
|
int i;
|
||||||
|
for(i=0;i<nNumLoop+nRcvLoop;i++){
|
||||||
|
#if _TWL
|
||||||
|
pCurrentReply = &gPmrr[0];
|
||||||
|
if( i>=1 && i<=nNumLoop ){
|
||||||
|
#endif
|
||||||
|
switch(pCurrentReply->status){
|
||||||
|
case IOS_ERROR_MSC_DEVICE_DETACH:
|
||||||
|
case IOS_ERROR_MSC_COMMAND_FAILED:
|
||||||
|
case IOS_ERROR_MSC_PHASE_ERROR:
|
||||||
|
case IOS_ERROR_MSC_INVALID_CBW_SIGNATURE:
|
||||||
|
case IOS_ERROR_MSC_INVALID_CBW_TAG:
|
||||||
|
nResult = WFSKRN_RESULT_DEVICE_NOT_FOUND;
|
||||||
|
}
|
||||||
|
#if DEVICE_DEBUG_PSEUDO_DEVICE_ERROR
|
||||||
|
if(cntDebugPseudoDetachDrive == 0){
|
||||||
|
nResult = WFSKRN_RESULT_DEVICE_NOT_FOUND;
|
||||||
|
cntDebugPseudoDetachDrive = -1;
|
||||||
|
}
|
||||||
|
else if(cntDebugPseudoDetachDrive){
|
||||||
|
--cntDebugPseudoDetachDrive;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if(i<nNumLoop){
|
||||||
|
u32 nSec = (nSectors+(nOffsetHashBlks<<nLog2HashSectors)) < nMaxSectors ? nSectors : (nMaxSectors-(nOffsetHashBlks<<nLog2HashSectors));
|
||||||
|
pCurrentReply->pHash = pHash;
|
||||||
|
IOSError ie;
|
||||||
|
#if _WIN32
|
||||||
|
ie = _WIN32DeviceWrite(pDevInfo, nSectorAdr, pData, (u16)nSec, (u8*)pCurrentReply->pHash, (u16)(1<<nLog2HashSectors), nHashStride, bDecryption);
|
||||||
|
#elif _TWL
|
||||||
|
if( nandNfsIo( 0, nSectorAdr, pData, nSec, FALSE) == FALSE) {
|
||||||
|
ie = IOS_ERROR_MSC_COMMAND_FAILED;
|
||||||
|
nResult = WFSKRN_RESULT_MEDIA_ERROR;
|
||||||
|
}else{
|
||||||
|
ie = IOS_ERROR_MSC_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ie < IOS_ERROR_MSC_OK){
|
||||||
|
pCurrentReply->status = ie;
|
||||||
|
}
|
||||||
|
nSectors -= nSec;
|
||||||
|
pData += nSec<<pDevInfo->dh.nLog2SectorSize;
|
||||||
|
nSectorAdr += nSec;
|
||||||
|
u32 nBlks = ((nSec-1)>>nLog2HashSectors)+1;
|
||||||
|
pHash = (WFSHashCode*)((u8*)pHash+nBlks*nHashStride+nHashStridePerMaxLBlks);
|
||||||
|
nOffsetHashBlks = 0;
|
||||||
|
}
|
||||||
|
#if _TWL
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceInfo *DeviceGetDeviceInfo(const WFSDeviceName *pDevName) {
|
||||||
|
dbgd(osTPrintf("DeviceGetDeviceInfo()\n"));
|
||||||
|
utf8 sDevPath[WFS_MAX_DEVICE_NAME_SIZE + 6];
|
||||||
|
void *pDevInfo;
|
||||||
|
RxtItr rxi;
|
||||||
|
rxi.pStrPtr = sDevPath;
|
||||||
|
osSNPrintf(sDevPath, WFS_MAX_DEVICE_NAME_SIZE + 6,"/dev/%s", pDevName->sStr);
|
||||||
|
if ((!PathCacheFind3(&rxi, pDevName->nLen+5, &pDevInfo)) ||
|
||||||
|
((DeviceInfo*)pDevInfo < wkg.aDevInfo) ||
|
||||||
|
((DeviceInfo*)pDevInfo >= &wkg.aDevInfo[WFSKRN_MAX_DEVICES]))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (DeviceInfo*)pDevInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DeviceGetVolumeId(const WFSDeviceName *pDevName, WFSVolumeId *pVolId) {
|
||||||
|
dbgd(osTPrintf("DeviceGetVolumeInfo()\n"));
|
||||||
|
DeviceInfo *pDevInfo = DeviceGetDeviceInfo(pDevName);
|
||||||
|
if(!pDevInfo || !pDevInfo->bInUse) {
|
||||||
|
return WFSKRN_RESULT_NOT_FOUND;
|
||||||
|
}
|
||||||
|
else if (pDevInfo->nFlags & WFS_DEVFLAG_UNUSABLE) {
|
||||||
|
return WFSKRN_RESULT_DEV_UNUSABLE;
|
||||||
|
}
|
||||||
|
else if (pDevInfo->nFlags & WFS_DEVFLAG_NOT_INITIALIZED) {
|
||||||
|
return WFSKRN_RESULT_DEV_NOT_INITIALIZED;
|
||||||
|
}
|
||||||
|
else if(pDevInfo->pVolInfo){
|
||||||
|
VolumeConvertU32ToVolId(pVolId, pDevInfo->pVolInfo->vh.nVolId);
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
VolumeInfo tempVolInfo;
|
||||||
|
tempVolInfo.pDevInfo = pDevInfo;
|
||||||
|
pDevInfo->pVolInfo = &tempVolInfo;
|
||||||
|
BCacheEntry* pBce;
|
||||||
|
WFSKrnResult nResult = BCacheAllocMetaBlk(&tempVolInfo, VOLUME_HDR_BLK_ADR, BCACHE_FLAG_PINNED | BCACHE_FLAG_READ, &pBce);
|
||||||
|
if(nResult < WFSKRN_RESULT_OK){
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
VolumeHdr *pVh = (VolumeHdr *)pBce->pBlkPtr;
|
||||||
|
VolumeConvertU32ToVolId(pVolId, pVh->nVolId);
|
||||||
|
nResult = BCacheUnpin(&tempVolInfo, VOLUME_HDR_BLK_ADR);
|
||||||
|
pDevInfo->pVolInfo = 0;
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DeviceMountVolume(DeviceInfo *pDevInfo) {
|
||||||
|
dbgd(osTPrintf("DeviceMountVolume()\n"));
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
VolumeInfo tempVolInfo;
|
||||||
|
tempVolInfo.pDevInfo = pDevInfo;
|
||||||
|
pDevInfo->pVolInfo = &tempVolInfo;
|
||||||
|
BCacheEntry* pBce;
|
||||||
|
nResult = BCacheAllocMetaBlk(&tempVolInfo, VOLUME_HDR_BLK_ADR, BCACHE_FLAG_PINNED | BCACHE_FLAG_READ, &pBce);
|
||||||
|
if(nResult < WFSKRN_RESULT_OK){
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
VolumeHdr *pVh = (VolumeHdr *)pBce->pBlkPtr;
|
||||||
|
tempVolInfo.vh = *(VolumeHdr *)pVh;
|
||||||
|
BCacheUnpin(&tempVolInfo, VOLUME_HDR_BLK_ADR);
|
||||||
|
VolumeInfo *pVolInfo = wkg.pMountedVolListAnchor->vl.pNext;
|
||||||
|
while(pVolInfo != wkg.pMountedVolListAnchor) {
|
||||||
|
if (pVh->nVolId == pVolInfo->vh.nVolId) {
|
||||||
|
// The volume Id matches a currently mounted volume
|
||||||
|
if (pVolInfo->bDetached) {
|
||||||
|
// ToDo: Check Session ID
|
||||||
|
pVolInfo->bDetached = false;
|
||||||
|
pDevInfo->pVolInfo = pVolInfo;
|
||||||
|
//pDevInfo->nFlags &= ~WFS_DEVFLAG_NOT_MOUNTED;
|
||||||
|
} else {
|
||||||
|
nResult = WFSKRN_RESULT_VOL_ID_ERROR;
|
||||||
|
}
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BCacheReTag(&tempVolInfo, VOLUME_HDR_BLK_ADR, pVolInfo, VOLUME_HDR_BLK_ADR);
|
||||||
|
// The volume Id did not match any currently mounted volumes
|
||||||
|
pVolInfo = pDevInfo->pVolInfo = VolumeAlloc();
|
||||||
|
pVolInfo->pDevInfo = pDevInfo;
|
||||||
|
pVolInfo->vh = tempVolInfo.vh;
|
||||||
|
VolumeAddToMountedList(pVolInfo);
|
||||||
|
pVolInfo->rootAreaInfo.pVolInfo = pVolInfo;
|
||||||
|
pVolInfo->rootAreaInfo.pParent = 0;
|
||||||
|
pVolInfo->rootAreaInfo.nRelStartBlkAdr = 0;
|
||||||
|
//pVolInfo->rootAreaInfo.ah.nLog2BlkSize = nLog2BlkSize;
|
||||||
|
//pVolInfo->rootAreaInfo.ah.nNumBlks = nNumBlks;
|
||||||
|
nResult = AreaOpen(&pVolInfo->rootAreaInfo); // for debug wfskrn
|
||||||
|
BCacheUnpin(pVolInfo, VOLUME_HDR_BLK_ADR); // kondo_masahiro 080729
|
||||||
|
Exit:
|
||||||
|
//BCacheUnpin(pVolInfo, VOLUME_HDR_BLK_ADR);
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DeviceAttach(DeviceInfo *pDevInfo, WFSDevType nDevType, u32 nDevIdx, u32 nLog2SectorSize, u32 nNumSectors) {
|
||||||
|
dbgd(osTPrintf("DeviceAttach()\n"));
|
||||||
|
// Called when user physically attaches a drive
|
||||||
|
if(pDevInfo->bInUse){
|
||||||
|
// return WFSKRN_RESULT_OK;
|
||||||
|
DeviceDetach(pDevInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
nandNfsCtrl( 0, NFS_DEVCTL_WARMSTART, NULL);
|
||||||
|
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
++wkg.nNumDevices;
|
||||||
|
pDevInfo->bInUse = true;
|
||||||
|
pDevInfo->nDevType = nDevType;
|
||||||
|
pDevInfo->dh.nLog2SectorSize = nLog2SectorSize;
|
||||||
|
pDevInfo->nSectorSize = 1<<nLog2SectorSize;
|
||||||
|
pDevInfo->dh.nNumSectors = nNumSectors;
|
||||||
|
pDevInfo->nTotalCapacity = (u64)nNumSectors * (u64)(pDevInfo->nSectorSize);
|
||||||
|
WFSPathName path;
|
||||||
|
switch(nDevType) {
|
||||||
|
case WFS_DEVTYPE_USB_MSC_10:
|
||||||
|
osTPrintf("Attach device with USB1.0\n");
|
||||||
|
break;
|
||||||
|
case WFS_DEVTYPE_USB_MSC_11:
|
||||||
|
osTPrintf("Attach device with USB1.1\n");
|
||||||
|
break;
|
||||||
|
case WFS_DEVTYPE_USB_MSC_20:
|
||||||
|
osTPrintf("Attach device with USB2.0\n");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return WFSKRN_RESULT_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
pDevInfo->devName.nLen = 5;
|
||||||
|
osSNPrintf(pDevInfo->devName.sStr, pDevInfo->devName.nLen+1, "msc%02d", nDevIdx+1);
|
||||||
|
path.nLen = sizeof(WFS_MAX_DEVICE_PATH)+1+ pDevInfo->devName.nLen;
|
||||||
|
osSNPrintf(path.sStr, WFS_MAX_DEVICE_PATH, WFS_DEVICE_DIRECTORY"/%s", pDevInfo->devName.sStr);
|
||||||
|
PathCacheEntry *pEntry = PathCacheInsertAfterCursorEntry2(wkg.pathCache.pPinAnchor, path.sStr);
|
||||||
|
pEntry->pcd.pData = pDevInfo;
|
||||||
|
#if _IOP
|
||||||
|
if(__p_hd[nDevIdx]->state < HARDDISC_STATUS_IDLE){
|
||||||
|
return WFSKRN_RESULT_DEVICE_ERROR;
|
||||||
|
}
|
||||||
|
pDevInfo->nDeviceDevHandle = __p_hd[nDevIdx];
|
||||||
|
#endif
|
||||||
|
if (wkg.bMountedDeviceWasDetached) {
|
||||||
|
DeviceMountVolume(pDevInfo);
|
||||||
|
} else {
|
||||||
|
pDevInfo->pVolInfo = 0;
|
||||||
|
//pDevInfo->nFlags = WFS_DEVFLAG_NOT_MOUNTED;
|
||||||
|
}
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DeviceDetach(DeviceInfo *pDevInfo) {
|
||||||
|
dbgd(osTPrintf("DeviceDetach()\n"));
|
||||||
|
if(!pDevInfo->bInUse){
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
// Called when user physically detaches a drive
|
||||||
|
utf8 sDevicePathWfs[WFS_MAX_DEVICE_PATH];
|
||||||
|
osSNPrintf(sDevicePathWfs, WFS_MAX_DEVICE_PATH, WFS_DEVICE_DIRECTORY"/%s", pDevInfo->devName.sStr);
|
||||||
|
WFSPathName path;
|
||||||
|
path.nLen = sizeof(WFS_MAX_DEVICE_PATH)+1+ pDevInfo->devName.nLen;
|
||||||
|
PathCacheItr pci;
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
WFSKrnExitOnError(WFSKrnValidateCopyStrAndConvertToLowerCase(path.sStr, sDevicePathWfs, path.nLen, WFS_MAX_FILE_NAME_SIZE));
|
||||||
|
WFSKrnExitOnError(PathCacheFindPath(&path, path.sStr, &pci));
|
||||||
|
PathCacheDeleteEntry(pci.pEntry);
|
||||||
|
#if _DEBUG
|
||||||
|
WFSDeviceName devName;
|
||||||
|
//WFSSetDeviceName(&devName, pDevInfo->devName.sStr);
|
||||||
|
devName.nLen = STRNLEN(pDevInfo->devName.sStr, WFS_MAX_DEVICE_NAME_SIZE);
|
||||||
|
strncpy(devName.sStr, pDevInfo->devName.sStr, WFS_MAX_DEVICE_NAME_SIZE);
|
||||||
|
DeviceInfo *pFoundDevInfo = DeviceGetDeviceInfo(&devName);
|
||||||
|
if (pFoundDevInfo != 0) {
|
||||||
|
WFSKrnOutputErrorStr("Delete failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
pDevInfo->bInUse = false;
|
||||||
|
VolumeInfo *pVolInfo = pDevInfo->pVolInfo;
|
||||||
|
if (pVolInfo){
|
||||||
|
if (pVolInfo->nClientsMountedBy) {
|
||||||
|
wkg.bMountedDeviceWasDetached = true;
|
||||||
|
pVolInfo->bDetached = true;
|
||||||
|
} else {
|
||||||
|
VolumeRemoveFromMountedList(pDevInfo->pVolInfo);
|
||||||
|
VolumeFree(pDevInfo->pVolInfo);
|
||||||
|
pDevInfo->pVolInfo = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--wkg.nNumDevices;
|
||||||
|
Exit:
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
3530
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Api.cpp
Normal file
3530
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Api.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1276
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Area.cpp
Normal file
1276
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Area.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1463
trunk/firmware/build/libraries/nfs/common/src/wfskrn_BCache.cpp
Normal file
1463
trunk/firmware/build/libraries/nfs/common/src/wfskrn_BCache.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,477 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_BitField.cpp - functions for manipulating bitfields within bit arrays
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_BitField.cpp,v $
|
||||||
|
Revision 1.4 2008/12/22 08:57:15 ueno
|
||||||
|
Fixed WfsSetBitField() when 32 < nNumBits.
|
||||||
|
|
||||||
|
Revision 1.3 2008/07/17 22:45:41 paul
|
||||||
|
fixed a performance problem
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/10 03:59:43 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/19 05:51:14 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/04 20:54:35 paul
|
||||||
|
Added WfsSetBitField, WfsTestAndSetBitField (used by dir check code to map coverage of used and free parts of block)
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/28 06:32:02 kondo_masahiro
|
||||||
|
Fixed code to accept PPC compiler
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/27 11:14:47 paul
|
||||||
|
Most of this is not used at the moment.. but I'll leave it here for now
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfskrn_BitField.h"
|
||||||
|
#include "wfskrn_Platform.h"
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
#define _BITFIELD_NUM_TESTS 10000
|
||||||
|
#else
|
||||||
|
#define _BITFIELD_NUM_TESTS 10000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BITFIELD_MASK ((1<<nNumBits)-1)
|
||||||
|
|
||||||
|
|
||||||
|
u32 WfsCalculateFieldSizeInBytes(u32 nVal) {
|
||||||
|
if (nVal<256) return 1; else if (nVal<256) return 2; else if (nVal<256) return 3; else return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 WfsCalculateFieldSizeInBits(u32 nVal) {
|
||||||
|
u8 nRet=0;
|
||||||
|
static const u8 aBitTbl[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 };
|
||||||
|
for(; nVal>=16; nVal>>=4) {
|
||||||
|
nRet+=4;
|
||||||
|
}
|
||||||
|
return (u8)( nRet + aBitTbl[nVal] );
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned WfsReadBitField(unsigned *aBitArray, int nStartBit, int nNumBits) {
|
||||||
|
// Masking should be performed by the caller
|
||||||
|
unsigned *pBitArray = &aBitArray[nStartBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
int nShift=BITS_PER_INT-(nStartBit&BIT_OFFSET_MASK)-nNumBits;
|
||||||
|
if (nShift>0) {
|
||||||
|
return (pBitArray[0]>>nShift);
|
||||||
|
} else {
|
||||||
|
if (nShift==0) {
|
||||||
|
return pBitArray[0];
|
||||||
|
} else {
|
||||||
|
return pBitArray[1]>>(BITS_PER_INT+nShift) | pBitArray[0]<<(-nShift);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if BITFIELD_USE_TEMPLATES
|
||||||
|
template<unsigned nNumBits>
|
||||||
|
unsigned WfsReadBitField (unsigned *aBitArray, int nStartBit) {
|
||||||
|
unsigned *pBitArray = &aBitArray[nStartBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
int nShift=BITS_PER_INT-(nStartBit&BIT_OFFSET_MASK)-nNumBits;
|
||||||
|
if (nShift>0) {
|
||||||
|
return (pBitArray[0]>>nShift) & BITFIELD_MASK;
|
||||||
|
} else {
|
||||||
|
if (nShift==0) {
|
||||||
|
return pBitArray[0] & BITFIELD_MASK;
|
||||||
|
} else {
|
||||||
|
return (pBitArray[1]>>(BITS_PER_INT+nShift) | pBitArray[0]<<(-nShift)) & BITFIELD_MASK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //BITFIELD_USE_TEMPLATES
|
||||||
|
|
||||||
|
|
||||||
|
void WfsOverwriteBitField(unsigned *aBitArray, int nStartBit, unsigned nValue, int nNumBits, unsigned nMask) {
|
||||||
|
unsigned *pBitArray = &aBitArray[nStartBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
int nShift=BITS_PER_INT-(nStartBit&BIT_OFFSET_MASK)-nNumBits;
|
||||||
|
if (nShift>0)
|
||||||
|
pBitArray[0] = (pBitArray[0]&~(nMask<<nShift)) | (nValue<<nShift);
|
||||||
|
else if (nShift<0) {
|
||||||
|
int nS1 = -nShift;
|
||||||
|
pBitArray[0] = (pBitArray[0]&~(nMask>>nS1)) | (nValue>>nS1);
|
||||||
|
int nS2 = BITS_PER_INT+nShift;
|
||||||
|
pBitArray[1] = (pBitArray[1]&~(nMask<<nS2)) | (nValue<<nS2);
|
||||||
|
} else {
|
||||||
|
pBitArray[0] = (pBitArray[0]&~nMask) | nValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if BITFIELD_USE_TEMPLATES
|
||||||
|
template<unsigned nNumBits>
|
||||||
|
void WfsOverwriteBitField(unsigned *aBitArray, int nStartBit, int nValue) {
|
||||||
|
unsigned *pBitArray = &aBitArray[nStartBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
int nShift=BITS_PER_INT-(nStartBit&BIT_OFFSET_MASK)-nNumBits;
|
||||||
|
if (nShift>0)
|
||||||
|
pBitArray[0] = (pBitArray[0]&~(BITFIELD_MASK<<nShift)) | (nValue<<nShift);
|
||||||
|
else {
|
||||||
|
int nS1 = -nShift;
|
||||||
|
pBitArray[0] = (pBitArray[0]&~(BITFIELD_MASK>>nS1)) | (nValue>>nS1);
|
||||||
|
int nS2 = BITS_PER_INT+nShift;
|
||||||
|
pBitArray[1] = (pBitArray[1]&~(BITFIELD_MASK<<nS2)) | (nValue<<nS2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //BITFIELD_USE_TEMPLATES
|
||||||
|
|
||||||
|
|
||||||
|
void WfsBitArrayInsertBitField(unsigned *aBitArray, int nBitArrayLength, int nBitPos, int nNumBits, unsigned nValue) {
|
||||||
|
unsigned *pCopyFrom = &aBitArray[nBitArrayLength>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned *pCopyTo = &aBitArray[(nBitArrayLength+nNumBits)>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned *pStart = &aBitArray[nBitPos>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned nOldStartWord = *pStart;
|
||||||
|
unsigned nStartShift = (u32)(nBitPos&BIT_OFFSET_MASK);
|
||||||
|
unsigned nStartMask = ((unsigned)-1) >> nStartShift;
|
||||||
|
// Insert right side of value
|
||||||
|
s32 nValueShift = (s32)(BITS_PER_INT - nStartShift);
|
||||||
|
*pStart &= nStartMask;
|
||||||
|
if (nStartShift) {
|
||||||
|
*pStart |= (nValue<<nValueShift);
|
||||||
|
}
|
||||||
|
if (nNumBits!=BITS_PER_INT) {
|
||||||
|
unsigned nShiftLeft = (u32)(BITS_PER_INT - nNumBits);
|
||||||
|
unsigned nTrailingBits = (u32)(nBitArrayLength & BIT_OFFSET_MASK);
|
||||||
|
if (nTrailingBits >= nShiftLeft) {
|
||||||
|
if (nTrailingBits > nShiftLeft) {
|
||||||
|
*pCopyTo = *pCopyFrom<<nShiftLeft;
|
||||||
|
}
|
||||||
|
pCopyTo--;
|
||||||
|
}
|
||||||
|
while(pCopyFrom > pStart) {
|
||||||
|
*pCopyTo-- = (pCopyFrom[-1]<<nShiftLeft) | (pCopyFrom[0]>>nNumBits);
|
||||||
|
pCopyFrom--;
|
||||||
|
}
|
||||||
|
*pCopyTo-- = pCopyFrom[0]>>nNumBits;
|
||||||
|
} else {
|
||||||
|
// Need a special case for no shift right, becuase shift left by 32 does nothing
|
||||||
|
if ((nBitArrayLength & BIT_OFFSET_MASK)==0) {
|
||||||
|
pCopyTo--;
|
||||||
|
pCopyFrom--;
|
||||||
|
}
|
||||||
|
while(pCopyFrom >= pStart) {
|
||||||
|
*pCopyTo-- = *pCopyFrom--;
|
||||||
|
}
|
||||||
|
*pCopyTo = 0;
|
||||||
|
}
|
||||||
|
// Insert left side of value
|
||||||
|
*pStart |= nOldStartWord & ~nStartMask;
|
||||||
|
nValueShift -= nNumBits;
|
||||||
|
if (nValueShift > 0) {
|
||||||
|
*pStart |= nValue<<nValueShift;
|
||||||
|
} else {
|
||||||
|
*pStart |= nValue>>-nValueShift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WfsBitArrayDeleteBitField(unsigned *aBitArray, int nBitArrayLength, int nBitPos, int nNumBits) {
|
||||||
|
unsigned *pCopyStart = &aBitArray[ nBitPos >>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned nOldCopyStart = *pCopyStart & ~(((unsigned)-1)>>(nBitPos&BIT_OFFSET_MASK));
|
||||||
|
unsigned nFromBit = (u32)(nBitPos+nNumBits);
|
||||||
|
unsigned *pCopyFrom = &aBitArray[nFromBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned *pCopyTo = pCopyStart;
|
||||||
|
unsigned *pCopyEnd = &aBitArray[(nBitArrayLength-nNumBits)>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned nShiftLeft = (u32)(nNumBits & BIT_OFFSET_MASK);
|
||||||
|
unsigned nShiftRight = BITS_PER_INT - nShiftLeft;
|
||||||
|
*pCopyFrom &= (((unsigned)-1) >> (nFromBit&BIT_OFFSET_MASK));
|
||||||
|
if (pCopyTo == pCopyFrom) {
|
||||||
|
while(pCopyTo <= pCopyEnd) {
|
||||||
|
pCopyTo[0] = (pCopyTo[0]<<nShiftLeft) | (pCopyTo[1]>>nShiftRight);
|
||||||
|
pCopyTo++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (nShiftLeft) {
|
||||||
|
if ((((pCopyFrom-pCopyTo)*BITS_PER_INT) + nShiftLeft) > nNumBits) {
|
||||||
|
*pCopyTo++ = pCopyFrom[0]>>nShiftRight;
|
||||||
|
}
|
||||||
|
while(pCopyTo <= pCopyEnd) {
|
||||||
|
pCopyTo[0] = (pCopyFrom[0]<<nShiftLeft) | (pCopyFrom[1]>>nShiftRight);
|
||||||
|
pCopyTo++; pCopyFrom++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while(pCopyTo <= pCopyEnd) {
|
||||||
|
*pCopyTo++ = *pCopyFrom++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*pCopyStart |= nOldCopyStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WfsSetBitField(unsigned *aBitArray, int nStartBit, int nNumBits) {
|
||||||
|
unsigned *pBitArray = &aBitArray[nStartBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned nEndBit = (unsigned)(nStartBit + nNumBits - 1);
|
||||||
|
unsigned *pEnd = &aBitArray[nEndBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned nLeftShift = nStartBit&BIT_OFFSET_MASK;
|
||||||
|
unsigned nRightShift= (nEndBit&BIT_OFFSET_MASK)^BIT_OFFSET_MASK;
|
||||||
|
if (pBitArray == pEnd) {
|
||||||
|
*pBitArray |= (((unsigned)-1)<<nLeftShift) & (((unsigned)-1)>>nRightShift);
|
||||||
|
} else {
|
||||||
|
*pBitArray |= ((u32)-1)<<nLeftShift;
|
||||||
|
nNumBits -= (BITS_PER_INT - nLeftShift);
|
||||||
|
while(nNumBits >= BITS_PER_INT) {
|
||||||
|
*(++pBitArray) = ((u32)-1);
|
||||||
|
nNumBits -= BITS_PER_INT;
|
||||||
|
}
|
||||||
|
*(++pBitArray) |= ((u32)-1)>>nRightShift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned WfsTestAndSetBitField(unsigned *aBitArray, int nStartBit, int nNumBits) {
|
||||||
|
unsigned *pBitArray = &aBitArray[nStartBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned nEndBit = (unsigned)(nStartBit + nNumBits - 1);
|
||||||
|
unsigned *pEnd = &aBitArray[nEndBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned nLeftShift = nStartBit&BIT_OFFSET_MASK;
|
||||||
|
unsigned nRightShift= (nEndBit&BIT_OFFSET_MASK)^BIT_OFFSET_MASK;
|
||||||
|
unsigned nTest;
|
||||||
|
if (pBitArray == pEnd) {
|
||||||
|
nTest = *pBitArray & (((unsigned)-1)<<nLeftShift) & (((unsigned)-1)>>nRightShift);
|
||||||
|
*pBitArray |= (((unsigned)-1)<<nLeftShift) & (((unsigned)-1)>>nRightShift);
|
||||||
|
} else {
|
||||||
|
nTest = *pBitArray & (((u32)-1)<<nLeftShift);
|
||||||
|
*pBitArray |= ((u32)-1)<<nLeftShift;
|
||||||
|
nNumBits -= nLeftShift;
|
||||||
|
while(++pBitArray < pEnd) {
|
||||||
|
nTest |= *pBitArray;
|
||||||
|
*pBitArray = ((u32)-1);
|
||||||
|
}
|
||||||
|
nTest |= *pBitArray & (((u32)-1)>>nRightShift);
|
||||||
|
*pBitArray |= ((u32)-1)>>nRightShift;
|
||||||
|
}
|
||||||
|
return nTest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WfsBitFieldCopy(unsigned *aDstBitArray, int nDstOffset, unsigned *aSrcBitArray, int nSrcOffset, int nCopyLength) {
|
||||||
|
unsigned *pDstStart = &aDstBitArray[ nDstOffset>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned *pSrcStart = &aSrcBitArray[ nSrcOffset>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned nDstEndBit = (u32)(nDstOffset + nCopyLength - 1);
|
||||||
|
unsigned *pDstEnd = &aDstBitArray[nDstEndBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT];
|
||||||
|
unsigned nOldDstStart = *pDstStart;
|
||||||
|
unsigned nOldDstEnd = *pDstEnd;
|
||||||
|
int nShift = (nDstOffset&BIT_OFFSET_MASK) - (nSrcOffset&BIT_OFFSET_MASK);
|
||||||
|
unsigned nShiftRight = (u32)(nShift & BIT_OFFSET_MASK);
|
||||||
|
unsigned nShiftLeft = BITS_PER_INT - nShiftRight;
|
||||||
|
if (nShift<0) {
|
||||||
|
if (pDstStart <= pSrcStart) {
|
||||||
|
unsigned *pDst = pDstStart;
|
||||||
|
unsigned *pSrc = pSrcStart;
|
||||||
|
while(pDst <= pDstEnd) {
|
||||||
|
pDst[0] = (pSrc[0]<<nShiftLeft) | (pSrc[1]>>nShiftRight);
|
||||||
|
pDst++; pSrc++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsigned *pDst = pDstEnd;
|
||||||
|
unsigned *pSrc = pSrcStart+(pDstEnd-pDstStart);
|
||||||
|
while(pDst >= pDstStart) {
|
||||||
|
pDst[0] = (pSrc[0]<<nShiftLeft) | (pSrc[1]>>nShiftRight);
|
||||||
|
pDst--; pSrc--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (nShift>0) {
|
||||||
|
if (pDstStart < pSrcStart) {
|
||||||
|
unsigned *pDst = pDstStart;
|
||||||
|
unsigned *pSrc = pSrcStart;
|
||||||
|
while(pDst <= pDstEnd) {
|
||||||
|
pDst[0] = (pSrc[-1]<<nShiftLeft) | (pSrc[0]>>nShiftRight);
|
||||||
|
pDst++; pSrc++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsigned *pDst = pDstEnd;
|
||||||
|
unsigned *pSrc = pSrcStart+(pDstEnd-pDstStart);
|
||||||
|
while(pDst >= pDstStart) {
|
||||||
|
pDst[0] = (pSrc[-1]<<nShiftLeft) | (pSrc[0]>>nShiftRight);
|
||||||
|
pDst--; pSrc--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pDstStart < pSrcStart) {
|
||||||
|
unsigned *pDst = pDstStart;
|
||||||
|
unsigned *pSrc = pSrcStart;
|
||||||
|
while(pDst <= pDstEnd) {
|
||||||
|
*pDst++ = *pSrc++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unsigned *pDst = pDstEnd;
|
||||||
|
unsigned *pSrc = pSrcStart+(pDstEnd-pDstStart);
|
||||||
|
while(pDst >= pDstStart) {
|
||||||
|
*pDst-- = *pSrc--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unsigned nDstStartMask = (((unsigned)-1) >>(nDstOffset&BIT_OFFSET_MASK));
|
||||||
|
unsigned nDstEndMask = ((((unsigned)-1)>>1)>>(nDstEndBit&BIT_OFFSET_MASK));
|
||||||
|
*pDstStart = (*pDstStart & nDstStartMask) | (nOldDstStart & ~nDstStartMask);
|
||||||
|
*pDstEnd = (*pDstEnd & ~nDstEndMask ) | (nOldDstEnd & nDstEndMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define BitMask(b) (1<<(BIT_OFFSET_MASK-((b)&BIT_OFFSET_MASK)))
|
||||||
|
#include "randomlib.h"
|
||||||
|
|
||||||
|
void WfsTestBitFieldModule() {
|
||||||
|
#if _BITFIELD_NUM_TESTS
|
||||||
|
int nDstOffset, nSrcOffset, nCopyLength;
|
||||||
|
unsigned aOldBitArray[8];
|
||||||
|
unsigned aNewBitArray[8];
|
||||||
|
|
||||||
|
s32 nRandomSeed;
|
||||||
|
#ifdef WIN32
|
||||||
|
LARGE_INTEGER sysClock;
|
||||||
|
QueryPerformanceCounter(&sysClock);
|
||||||
|
nRandomSeed = ((u32*)&sysClock)[0] ^ ((u32*)&sysClock)[1];
|
||||||
|
#else
|
||||||
|
nRandomSeed = 0x1;
|
||||||
|
#endif
|
||||||
|
RandomSetSeedU32((u32)nRandomSeed);
|
||||||
|
osTPrintf("nRandomSeed=0x%08x\n", nRandomSeed);
|
||||||
|
|
||||||
|
osTPrintf("WfsBitArrayInsertBitField() Test\n");
|
||||||
|
int nTest;
|
||||||
|
for(nTest=1; nTest<=_BITFIELD_NUM_TESTS; nTest++) {
|
||||||
|
//for(unsigned nI=0; nI<8; nI++) { aOldBitArray[nI] = 0xFFFFFFFF; } //RandomU32(); }
|
||||||
|
unsigned nI;
|
||||||
|
for(nI=0; nI<8; nI++) { aOldBitArray[nI] = RandomU32(); }
|
||||||
|
int nNumBits = RandomInt(1, 32);
|
||||||
|
int nBitArrayLength = RandomInt(0, 256-nNumBits);
|
||||||
|
int nInsertBit = RandomInt(0, nBitArrayLength);
|
||||||
|
unsigned nValue = RandomU32();
|
||||||
|
nValue >>= (32-nNumBits);
|
||||||
|
aOldBitArray[(nBitArrayLength-1)>>BIT_OFFSET_TO_INT_OFFSET_SHIFT] |= BitMask(nBitArrayLength);
|
||||||
|
int nBit;
|
||||||
|
for(nBit=nBitArrayLength; nBit<256; nBit++) {
|
||||||
|
aOldBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT] &= ~BitMask(nBit);
|
||||||
|
}
|
||||||
|
for(nI=0; nI<8; nI++) { aNewBitArray[nI] = aOldBitArray[nI]; } //RandomU32(); }
|
||||||
|
WfsBitArrayInsertBitField(aNewBitArray, nBitArrayLength, nInsertBit, nNumBits, nValue);
|
||||||
|
for(nBit=0; nBit<nInsertBit; nBit++) {
|
||||||
|
if ((aOldBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit)) !=
|
||||||
|
(aNewBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit))) {
|
||||||
|
osTPrintf("ERROR! Test:%d Mismatch before insertion point at bit %02X\n", nTest, nBit);
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(; nBit<nInsertBit+nNumBits; nBit++) {
|
||||||
|
if (((aNewBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit))==0) ^
|
||||||
|
((nValue&(1<<(nNumBits-1-(nBit-nInsertBit))))==0)) {
|
||||||
|
osTPrintf("ERROR! Test:%d Mismatch in inserted Value at bit %02X:%02x\n", nTest, nBit, nNumBits-1-(nBit-nInsertBit));
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(; nBit<256; nBit++) {
|
||||||
|
if (((aOldBitArray[(nBit-nNumBits)>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit-nNumBits))==0) ^
|
||||||
|
((aNewBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit))==0)) {
|
||||||
|
osTPrintf("ERROR! Test:%d Mismatch after insertion point at bit %02x:%02x\n(aOldBitArray[%d] & %08x = %08x)\n(aNewBitArray[%d] & %08x = %08x)\n",
|
||||||
|
nTest, nBit, nBit-nNumBits,
|
||||||
|
(nBit-nNumBits)>>BIT_OFFSET_TO_INT_OFFSET_SHIFT, BitMask(nBit-nNumBits),
|
||||||
|
(aOldBitArray[(nBit-nNumBits)>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit-nNumBits)),
|
||||||
|
nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT, BitMask(nBit),
|
||||||
|
(aNewBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit)));
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osTPrintf("WfsDeleteBitField() Test\n");
|
||||||
|
for(nTest=1; nTest<=_BITFIELD_NUM_TESTS; nTest++) {
|
||||||
|
unsigned nI;
|
||||||
|
for(nI=0; nI<8; nI++) { aOldBitArray[nI] = RandomU32(); }
|
||||||
|
int nBitArrayLength = RandomInt(0, 256);
|
||||||
|
int nDeleteStartBit = RandomInt(0, nBitArrayLength-1);
|
||||||
|
int nDeleteNumBits = RandomInt(1, 96);
|
||||||
|
if (nDeleteNumBits >(nBitArrayLength-nDeleteStartBit)) {
|
||||||
|
nDeleteNumBits = nBitArrayLength-nDeleteStartBit;
|
||||||
|
}
|
||||||
|
int nBit;
|
||||||
|
for(nBit=nBitArrayLength; nBit<256; nBit++) {
|
||||||
|
aOldBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT] &= ~BitMask(nBit);
|
||||||
|
}
|
||||||
|
for(nI=0; nI<8; nI++) { aNewBitArray[nI] = aOldBitArray[nI]; }
|
||||||
|
WfsBitArrayDeleteBitField(aNewBitArray, nBitArrayLength, nDeleteStartBit, nDeleteNumBits);
|
||||||
|
for(nBit=0; nBit<nDeleteStartBit; nBit++) {
|
||||||
|
if ((aOldBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit)) !=
|
||||||
|
(aNewBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit))) {
|
||||||
|
osTPrintf("ERROR! Test:%d Mismatch at bit %02X\n", nTest, nBit);
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nBit += nDeleteNumBits;
|
||||||
|
for(; nBit<nBitArrayLength; nBit++) {
|
||||||
|
if (((aNewBitArray[(nBit-nDeleteNumBits)>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit-nDeleteNumBits))==0) ^
|
||||||
|
((aOldBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit))==0)) {
|
||||||
|
osTPrintf("ERROR! Test:%d Mismatch between bits %02x:%02x\n(aOldBitArray[%d] & %08x = %08x)\n(aNewBitArray[%d] & %08x = %08x)\n",
|
||||||
|
nTest, nBit, nBit-nDeleteNumBits,
|
||||||
|
(nBit-nDeleteNumBits)>>BIT_OFFSET_TO_INT_OFFSET_SHIFT, BitMask(nBit-nDeleteNumBits),
|
||||||
|
(aOldBitArray[(nBit-nDeleteNumBits)>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit-nDeleteNumBits)),
|
||||||
|
nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT, BitMask(nBit),
|
||||||
|
(aNewBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit)));
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
osTPrintf("WfsBitFieldCopy() Test\n");
|
||||||
|
for(nTest=1; nTest<=_BITFIELD_NUM_TESTS; nTest++) {
|
||||||
|
unsigned nI;
|
||||||
|
for(nI=0; nI<8; nI++) { aOldBitArray[nI] = RandomU32(); }
|
||||||
|
nDstOffset = RandomInt(0, 255);
|
||||||
|
nSrcOffset = RandomInt(0, 255);
|
||||||
|
int nMaxLength = 256 - max(nSrcOffset, nDstOffset);
|
||||||
|
nCopyLength = RandomInt(1, nMaxLength);
|
||||||
|
int nBit;
|
||||||
|
/*for(nBit=nBitArrayLength; nBit<256; nBit++) {
|
||||||
|
aOldBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT] &= ~BitMask(nBit);
|
||||||
|
}*/
|
||||||
|
for(nI=0; nI<8; nI++) { aNewBitArray[nI] = aOldBitArray[nI]; }
|
||||||
|
WfsBitFieldCopy(aNewBitArray, nDstOffset, aNewBitArray, nSrcOffset, nCopyLength);
|
||||||
|
for(nBit=0; nBit<nDstOffset; nBit++) {
|
||||||
|
if ((aOldBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit)) !=
|
||||||
|
(aNewBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit))) {
|
||||||
|
osTPrintf("ERROR! Test:%d Mismatch at bit %02X\n", nTest, nBit);
|
||||||
|
goto WfsBitFieldCopyError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(; nBit<nDstOffset+nCopyLength; nBit++) {
|
||||||
|
int nSrcBit = nBit-nDstOffset+nSrcOffset;
|
||||||
|
if (((aOldBitArray[nSrcBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nSrcBit))==0) ^
|
||||||
|
((aNewBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit))==0)) {
|
||||||
|
osTPrintf("ERROR! Test:%d Mismatch at bit %02X\n", nTest, nBit);
|
||||||
|
goto WfsBitFieldCopyError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(; nBit<256; nBit++) {
|
||||||
|
if ((aOldBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit)) !=
|
||||||
|
(aNewBitArray[nBit>>BIT_OFFSET_TO_INT_OFFSET_SHIFT]&BitMask(nBit))) {
|
||||||
|
osTPrintf("ERROR! Test:%d Mismatch at bit %02X\n", nTest, nBit);
|
||||||
|
goto WfsBitFieldCopyError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
WfsBitFieldCopyError:;
|
||||||
|
osTPrintf("WfsBitFieldCopy(New, nDstOffset=%02x, Src, nSrcOffset=%02x, nCopyLength=%02x)\n", nDstOffset, nSrcOffset, nCopyLength);
|
||||||
|
goto Error;
|
||||||
|
Error:;
|
||||||
|
unsigned nI;
|
||||||
|
osTPrintf("Old: "); for(nI=0; nI<8; nI++) { osTPrintf("%08x", aOldBitArray[nI]); } osTPrintf("\n");
|
||||||
|
osTPrintf("New: "); for(nI=0; nI<8; nI++) { osTPrintf("%08x", aNewBitArray[nI]); } osTPrintf("\n");
|
||||||
|
osTPrintf(" 0 1 2 3 4 5 6 7 8 9 a b c d e f \n");
|
||||||
|
osTPrintf(" 048c048c048c048c048c048c048c048c048c048c048c048c048c048c048c048c\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// nStartBit = 9
|
||||||
|
// nBitArrayLength = 45
|
||||||
|
// nNumGapBits = 18
|
||||||
|
// nBitArrayLength - nNumGapBits = 36
|
||||||
|
// pStart = &aBitArray[0]
|
||||||
|
// pCopyTo = &aBitArray[1]
|
||||||
|
// pCopyFrom = &aBitArray[1]
|
||||||
4439
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Dir.cpp
Normal file
4439
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Dir.cpp
Normal file
File diff suppressed because it is too large
Load Diff
695
trunk/firmware/build/libraries/nfs/common/src/wfskrn_DirApi.cpp
Normal file
695
trunk/firmware/build/libraries/nfs/common/src/wfskrn_DirApi.cpp
Normal file
@ -0,0 +1,695 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_DirApi.cpp - Top layer of the Directory module
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_DirApi.cpp,v $
|
||||||
|
Revision 1.26 2008/11/05 15:08:20 ueno
|
||||||
|
Modified DirItrMapBlks() to roll back the update map in case of error.
|
||||||
|
|
||||||
|
Revision 1.25 2008/10/31 09:51:11 ueno
|
||||||
|
Modified WFSSrvAPIs to return WFSKRN_RESULT_RESOURCE_LIMIT_EXCEEDED when path cache is short of memory.
|
||||||
|
|
||||||
|
Revision 1.24 2008/10/30 04:51:28 kondo_masahiro
|
||||||
|
Fixed DirDeleteFile
|
||||||
|
|
||||||
|
Revision 1.23 2008/10/20 00:30:54 nakanose_jin
|
||||||
|
(none)
|
||||||
|
|
||||||
|
Revision 1.22 2008/10/17 08:50:48 kondo_masahiro
|
||||||
|
Added the new MEDIUM size category (40KB-320KB)
|
||||||
|
|
||||||
|
Revision 1.21 2008/10/16 09:30:39 ooizumi
|
||||||
|
Fixed definitions for debug build.
|
||||||
|
|
||||||
|
Revision 1.20 2008/10/15 00:14:57 kondo_masahiro
|
||||||
|
Fixed a bug about 4GB-1
|
||||||
|
|
||||||
|
Revision 1.19 2008/10/14 12:11:49 kondo_masahiro
|
||||||
|
Fixed a bug in DirDeleteFile
|
||||||
|
|
||||||
|
Revision 1.18 2008/10/14 10:26:24 kondo_masahiro
|
||||||
|
Added codes to access very large size file data
|
||||||
|
|
||||||
|
Revision 1.17 2008/10/10 02:11:20 kondo_masahiro
|
||||||
|
Fixed a bug to access large files
|
||||||
|
|
||||||
|
Revision 1.16 2008/10/09 04:16:53 kondo_masahiro
|
||||||
|
Fixed member of AreaHdr and AreaInfo
|
||||||
|
|
||||||
|
Revision 1.15 2008/10/08 23:19:54 kondo_masahiro
|
||||||
|
Added codes to access large size file data
|
||||||
|
|
||||||
|
Revision 1.14 2008/09/28 23:31:51 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.13 2008/09/02 23:34:39 ooizumi
|
||||||
|
Added several casting.
|
||||||
|
|
||||||
|
Revision 1.12 2008/09/02 23:02:47 ooizumi
|
||||||
|
Fixed a bug failed to treat utf8 as unsigned value.
|
||||||
|
|
||||||
|
Revision 1.11 2008/08/05 03:58:49 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.10 2008/07/28 22:05:32 paul
|
||||||
|
Improved updateMap processing. Fixed a bug in DirDeleteSubDir().
|
||||||
|
|
||||||
|
Revision 1.9 2008/07/25 02:51:28 paul
|
||||||
|
Changed from nTransIdx to *pTransInfo
|
||||||
|
|
||||||
|
Revision 1.8 2008/07/21 22:39:16 paul
|
||||||
|
Fixed a bug in DirItrCheckAndUnmapBlks()
|
||||||
|
Changed name from DirItrPinBlkAndUpdatePtrs() -> DirItrPinBlkAndFixPtrs()
|
||||||
|
|
||||||
|
Revision 1.7 2008/07/17 22:47:11 paul
|
||||||
|
Added functions to support updateMap
|
||||||
|
|
||||||
|
Revision 1.6 2008/07/09 00:30:20 paul
|
||||||
|
Changes to make directory code work with block cache.
|
||||||
|
|
||||||
|
Revision 1.5 2008/06/09 17:21:58 paul
|
||||||
|
Added WFSKrnValidateCopyStrAndConvertToLowerCase()
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/12 22:35:37 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/12 19:11:22 paul
|
||||||
|
Moved DirModuleInit here from wfskrn_Dir.cpp.
|
||||||
|
Updated DirItrClose to remove pDi from list of open iterators.
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/10 03:59:44 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/25 17:29:16 kondo_masahiro
|
||||||
|
Initial check-in
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/23 00:25:23 paul
|
||||||
|
Modified some functions to take utf8 strings instead of WFSFileName structs
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/21 18:58:30 paul
|
||||||
|
*** empty log message ***
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#undef _KRN_FILE_
|
||||||
|
#define _KRN_FILE_ "DirApi"
|
||||||
|
|
||||||
|
#include "wfskrn_Api.h"
|
||||||
|
#include "wfskrn_Dir.h"
|
||||||
|
#include "wfskrn_DirFind.h"
|
||||||
|
#include "wfskrn_DirNodeStack.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_PTree.h"
|
||||||
|
#include "wfskrn_Handles.h"
|
||||||
|
|
||||||
|
DirGlobals dirGlobals;
|
||||||
|
|
||||||
|
|
||||||
|
void DirModuleInit() {
|
||||||
|
u32 nI=0;
|
||||||
|
for(nI=0; nI<256; nI++) {
|
||||||
|
dirGlobals.aToLower[nI] = dirGlobals.aToUpper[nI] = (utf8)nI;
|
||||||
|
}
|
||||||
|
for(nI='A'; nI<='Z'; nI++) {
|
||||||
|
dirGlobals.aToLower[nI] = (utf8)(nI + ('a'-'A'));
|
||||||
|
}
|
||||||
|
for(nI='a'; nI<='z'; nI++) {
|
||||||
|
dirGlobals.aToUpper[nI] = (utf8)(nI - ('a'-'A'));
|
||||||
|
}
|
||||||
|
DirAllocateMoreNodeStackEntries();
|
||||||
|
dirGlobals.pOpenDirItrListAnchor = (DirItr *)((u8*)&dirGlobals.openDirItrListAnchor - (size_t)&((DirItr *)0)->link);
|
||||||
|
dirGlobals.openDirItrListAnchor.pNext = dirGlobals.openDirItrListAnchor.pPrev = dirGlobals.pOpenDirItrListAnchor;
|
||||||
|
PathCacheInit(); //dirGlobals.nUpdateCtr = 0;
|
||||||
|
dirGlobals.updateMapAllocator.pBase = (void*)&wkg.pathCache.pRxtHdr->sbah;
|
||||||
|
dirGlobals.updateMapAllocator.fpAllocNode = (PTreeAllocNodeFunc) PTreeAllocNodeFromSba;
|
||||||
|
dirGlobals.updateMapAllocator.fpAllocNodes = (PTreeAllocNodesFunc)PTreeAllocNodesFromSba;
|
||||||
|
dirGlobals.updateMapAllocator.fpFreeNode = (PTreeFreeNodeFunc) PTreeFreeNodeToSba;
|
||||||
|
PTreeInit(&dirGlobals.updateMap, &dirGlobals.updateMapAllocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnCopyFileName(WFSFileName *pDst, WFSFileName *pSrc) {
|
||||||
|
if (pSrc->nLen > WFS_MAX_FILE_NAME_SIZE) {
|
||||||
|
pSrc->nLen = WFS_MAX_FILE_NAME_SIZE;
|
||||||
|
}
|
||||||
|
pDst->nLen = pSrc->nLen;
|
||||||
|
strncpy(pDst->sStr, pSrc->sStr, pDst->nLen);
|
||||||
|
pDst->sStr[pDst->nLen] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void WFSKrnCopyStrAndConvertToLowerCase(utf8 *pDstStr, const utf8 *pSrcStr, u32 nLen) {
|
||||||
|
const utf8 *pSrcEnd = pSrcStr + nLen;
|
||||||
|
for(; pSrcStr<pSrcEnd; ++pSrcStr, ++pDstStr) {
|
||||||
|
*pDstStr = dirGlobals.aToLower[(u32)*(u8*)pSrcStr]; // sometimes VC cannot treat 0x80 over utf8 value.
|
||||||
|
}
|
||||||
|
*pDstStr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnValidateCopyStrAndConvertToLowerCase(utf8 *pDstStr, const utf8 *pSrcStr, u32 nLen, u32 nMaxLen) {
|
||||||
|
if (nLen > nMaxLen) {
|
||||||
|
return WFSKRN_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
WFSKrnCopyStrAndConvertToLowerCase(pDstStr, pSrcStr, nLen);
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnCopyFileNameAndConvertToLowerCase(WFSFileName *pDst, WFSFileName *pSrc) {
|
||||||
|
if (pSrc->nLen > WFS_MAX_FILE_NAME_SIZE) {
|
||||||
|
pSrc->nLen = WFS_MAX_FILE_NAME_SIZE;
|
||||||
|
}
|
||||||
|
pDst->nLen = pSrc->nLen;
|
||||||
|
WFSKrnCopyStrAndConvertToLowerCase(pDst->sStr, pSrc->sStr, pSrc->nLen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnCopyFileNameAndRestoreCase(utf8 *pDst, WFSFileName *pSrc, u8 *pCaseBitArray) {
|
||||||
|
u32 nCaseBits = (u32)(256 + *pCaseBitArray);
|
||||||
|
if (pSrc->nLen > WFS_MAX_FILE_NAME_SIZE) {
|
||||||
|
pSrc->nLen = WFS_MAX_FILE_NAME_SIZE;
|
||||||
|
}
|
||||||
|
utf8 *pDstStr = pDst;
|
||||||
|
utf8 *pSrcStr = pSrc->sStr;
|
||||||
|
utf8 *pSrcEnd = pSrcStr + pSrc->nLen;
|
||||||
|
for(; pSrcStr<pSrcEnd; ++pSrcStr, ++pDstStr) {
|
||||||
|
if (nCaseBits & 1) {
|
||||||
|
*pDstStr = dirGlobals.aToUpper[(u32)*(u8*)pSrcStr]; // sometimes VC cannot treat 0x80 over utf8 value.
|
||||||
|
} else {
|
||||||
|
*pDstStr = *pSrcStr;
|
||||||
|
}
|
||||||
|
nCaseBits >>= 1;
|
||||||
|
if (nCaseBits == 1) {
|
||||||
|
nCaseBits = (u32)(256 + *(++pCaseBitArray));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*pDstStr = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnStoreCaseInformationStr(u8 *pCaseBitArray, const utf8 *pStr, u32 nLen) {
|
||||||
|
u32 nCaseBit = 1;
|
||||||
|
u8 nCaseByte = 0;
|
||||||
|
const utf8 *pStrEnd = pStr + nLen;
|
||||||
|
for(; pStr<pStrEnd; ++pStr) {
|
||||||
|
if (*pStr != dirGlobals.aToLower[(u32)*(u8*)pStr]) { // sometimes VC cannot treat 0x80 over utf8 value.
|
||||||
|
nCaseByte |= nCaseBit;
|
||||||
|
}
|
||||||
|
nCaseBit += nCaseBit;
|
||||||
|
if (nCaseBit == 256) {
|
||||||
|
*pCaseBitArray++ = nCaseByte;
|
||||||
|
nCaseByte = 0;
|
||||||
|
nCaseBit = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nCaseBit > 1) {
|
||||||
|
*pCaseBitArray = nCaseByte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Update Counter & Update Map Operations:
|
||||||
|
//
|
||||||
|
// BlkAdr:
|
||||||
|
// * Blocks must be referred to by absolute block address in the update map.
|
||||||
|
//
|
||||||
|
// Interaction with the transaction process:
|
||||||
|
// * In transactions, the block to be updated is first re-mapped to a different physical block.
|
||||||
|
// * When the update has been commited, it is copied to the logical block address.
|
||||||
|
// * For the purpose of update map processing, it should be OK to ignore the transaction process.
|
||||||
|
//
|
||||||
|
// When a block is initialized as a directory block:
|
||||||
|
// - First check the update map to see if any iterator is already referring to it. If so, copy the initial update count from there.
|
||||||
|
// Otherwise, the initial update count is initialized to 0.
|
||||||
|
//
|
||||||
|
// When a directory meta-data block gets freed:
|
||||||
|
// - If the block is in the update-map, increment its counter, then reduce its reference count, removing it if the reference count is zero.
|
||||||
|
//
|
||||||
|
// When a block is accessed by a directory iterator during DirFind or DirFindNext
|
||||||
|
// - The iterator copies the update counter of the block to its DirNodeStack.
|
||||||
|
//
|
||||||
|
// When a block is to be updated in the course of a executing a WFS command
|
||||||
|
// - Update the update counter in the block. //ToDo: it would be better if we only updated the counter when an existing sub-block is moved or deleted.
|
||||||
|
// - If the counter exists in the update map, increment it. Otherwise (in debug mode at least), reset the counter to 0.
|
||||||
|
//
|
||||||
|
// When an iterator is to be left open by a WFS command:
|
||||||
|
// - Increment the reference count of the blocks in the update map, or add them to the update map if neccessary.
|
||||||
|
// - Update the counter
|
||||||
|
//
|
||||||
|
// When an iterator is to re-used after a gap
|
||||||
|
// - The blocks it references should be found in the update map, and checked against the values stored in the iterator.
|
||||||
|
// - If necessary, the file attributes should be re-located using DirFind.
|
||||||
|
|
||||||
|
|
||||||
|
static DirNodeStack* MapBlks(DirItr *pDi) {
|
||||||
|
#if _DEBUG_BREAK_POINT
|
||||||
|
static int c=0;++c;if(c>=7019){//8194){
|
||||||
|
int a;a=0;
|
||||||
|
}
|
||||||
|
if (wkg.pathCache.pRxtHdr->sbah.aSubBlkList[0].nNumFree > 16) {
|
||||||
|
int a;a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// When a new iterator is to be left open, we need to register the address of any blocks referenced in its DirNodeStack,
|
||||||
|
// and map each of these to the latest value of that block's update counter.
|
||||||
|
// However there are some complications:
|
||||||
|
// The same block could be referenced by multiple iterators, so they need to be reference-counted.
|
||||||
|
// An update operation consists of incrementing the reference count, and overwriting the update counter.
|
||||||
|
DirNodeStack *pDns = pDi->dni.pDns;
|
||||||
|
WFSBlkAdr nAbsStartBlkAdr = pDi->tba.pAreaInfo->nAbsStartBlkAdr;
|
||||||
|
WFSBlkAdr nBlkAdr = pDi->tba.nBlkAdr;
|
||||||
|
u32 nUpdateCtr = (u32)(pDi->nUpdateCtr & WFS_MDF_DIR_COUNTER_MASK);
|
||||||
|
while(nBlkAdr) {
|
||||||
|
WFSBlkAdr nAbsBlkAdr = nAbsStartBlkAdr + nBlkAdr;
|
||||||
|
PTreeItr pti;
|
||||||
|
u32 nData = DIR_BLK_REF_COUNT_INC | (nUpdateCtr & WFS_MDF_DIR_COUNTER_MASK);
|
||||||
|
Retry:;
|
||||||
|
WFSKrnResult nResult = PTreeInsert(&dirGlobals.updateMap, &pti, nAbsBlkAdr, nData, &dirGlobals.updateMapAllocator);
|
||||||
|
if (nResult == WFSKRN_RESULT_PTREE_ENTRY_FOUND) {
|
||||||
|
pti.pLeaf->aData[pti.aEntryIdx[0]] = nData + (pti.pLeaf->aData[pti.aEntryIdx[0]] & (u32)(-DIR_BLK_REF_COUNT_INC));
|
||||||
|
} else if (nResult == WFSKRN_RESULT_PTREE_FULL) {
|
||||||
|
nResult = PathCacheDeleteLru();
|
||||||
|
if (nResult != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
return pDns;
|
||||||
|
}
|
||||||
|
goto Retry;
|
||||||
|
}
|
||||||
|
#if _DEBUG
|
||||||
|
else if (nResult != WFSKRN_RESULT_OK) {
|
||||||
|
WFSKrnOutputErrorCode(nResult);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (pDns==0) {
|
||||||
|
return pDns;
|
||||||
|
}
|
||||||
|
while(pDns->nBlkAdr == nBlkAdr) {
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
if (pDns==0) {
|
||||||
|
return pDns;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nBlkAdr = pDns->nBlkAdr;
|
||||||
|
nUpdateCtr = pDns->nUpdateCtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void UnmapBlks(DirItr* pDi, DirNodeStack* pDns)
|
||||||
|
{
|
||||||
|
PTreeItr pti;
|
||||||
|
WFSBlkAdr nAbsBlkAdr;
|
||||||
|
WFSKrnResult nResult;
|
||||||
|
u32 nUpdateCtr;
|
||||||
|
WFSBlkAdr nBlkAdr;
|
||||||
|
WFSBlkAdr nAbsStartBlkAdr = pDi->tba.pAreaInfo->nAbsStartBlkAdr;
|
||||||
|
DirNodeStack* pDnsEnd = pDi->dni.pDns;
|
||||||
|
|
||||||
|
while (pDns != pDnsEnd)
|
||||||
|
{
|
||||||
|
// [check] must check this rollback routine.
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
nBlkAdr = pDns->nBlkAdr;
|
||||||
|
nUpdateCtr = pDns->nUpdateCtr;
|
||||||
|
|
||||||
|
nAbsBlkAdr = nAbsStartBlkAdr + nBlkAdr;
|
||||||
|
nResult = PTreeFind(&dirGlobals.updateMap, &pti, nAbsBlkAdr, &dirGlobals.updateMapAllocator);
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
if (nResult != WFSKRN_RESULT_PTREE_ENTRY_FOUND)
|
||||||
|
{
|
||||||
|
WFSKrnOutputErrorStr("DirItr block not found in updateMap");
|
||||||
|
}
|
||||||
|
ASSERT(nResult == WFSKRN_RESULT_PTREE_ENTRY_FOUND);
|
||||||
|
#endif
|
||||||
|
// Decrement the reference counter
|
||||||
|
pti.pLeaf->aData[pti.aEntryIdx[0]] -= DIR_BLK_REF_COUNT_INC;
|
||||||
|
if ((pti.pLeaf->aData[pti.aEntryIdx[0]] & (u32)(-DIR_BLK_REF_COUNT_INC)) == 0)
|
||||||
|
{
|
||||||
|
// The reference counter is zero, so remove the mapping
|
||||||
|
PTreeDelete(&dirGlobals.updateMap, &pti, &dirGlobals.updateMapAllocator);
|
||||||
|
}
|
||||||
|
while (pDns->nBlkAdr == nBlkAdr)
|
||||||
|
{
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult DirItrMapBlks(DirItr *pDi)
|
||||||
|
{
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
DirNodeStack* pDns;
|
||||||
|
pDns = MapBlks(pDi);
|
||||||
|
if (pDns) // [check] name.
|
||||||
|
{
|
||||||
|
// roll back.
|
||||||
|
nResult = WFSKRN_RESULT_RESOURCE_LIMIT_EXCEEDED;
|
||||||
|
UnmapBlks(pDi, pDns);
|
||||||
|
#if _DEBUG
|
||||||
|
WFSKrnOutputErrorStr("DirItrMapBlks() : WFSKRN_RESULT_RESOURCE_LIMIT_EXCEEDED\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DirItrUnmapBlks(DirItr *pDi) {
|
||||||
|
#if _DEBUG_BREAK_POINT
|
||||||
|
static int c=0;++c;if(c>=2284){
|
||||||
|
int a;a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if _DEBUG
|
||||||
|
if (dirGlobals.updateMap.nRootOfs == 0) {
|
||||||
|
WFSKrnOutputErrorStr("updateMap invalid");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Reduce the reference count of the blocks referenced by an iterator, and unmap them if the reference count reaches 0
|
||||||
|
DirNodeStack *pDns = pDi->dni.pDns;
|
||||||
|
WFSBlkAdr nAbsStartBlkAdr = pDi->tba.pAreaInfo->nAbsStartBlkAdr;
|
||||||
|
WFSBlkAdr nBlkAdr = pDi->tba.nBlkAdr;
|
||||||
|
u32 nUpdateCtr = (u32)(pDi->nUpdateCtr & WFS_MDF_DIR_COUNTER_MASK);
|
||||||
|
while(nBlkAdr) {
|
||||||
|
WFSBlkAdr nAbsBlkAdr = nAbsStartBlkAdr + nBlkAdr;
|
||||||
|
PTreeItr pti;
|
||||||
|
WFSKrnResult nResult = PTreeFind(&dirGlobals.updateMap, &pti, nAbsBlkAdr, &dirGlobals.updateMapAllocator);
|
||||||
|
if (nResult != WFSKRN_RESULT_PTREE_ENTRY_FOUND) {
|
||||||
|
WFSKrnOutputErrorStr("DirItr block not found in updateMap");
|
||||||
|
}
|
||||||
|
#if _DEBUG
|
||||||
|
else if (nResult != WFSKRN_RESULT_PTREE_ENTRY_FOUND) {
|
||||||
|
WFSKrnOutputErrorCode(nResult);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Decrement the reference counter
|
||||||
|
pti.pLeaf->aData[pti.aEntryIdx[0]] -= DIR_BLK_REF_COUNT_INC;
|
||||||
|
if ((pti.pLeaf->aData[pti.aEntryIdx[0]] & (u32)(-DIR_BLK_REF_COUNT_INC)) == 0) {
|
||||||
|
// The reference counter is zero, so remove the mapping
|
||||||
|
PTreeDelete(&dirGlobals.updateMap, &pti, &dirGlobals.updateMapAllocator);
|
||||||
|
}
|
||||||
|
if (pDns==0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while(pDns->nBlkAdr == nBlkAdr) {
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
if (pDns==0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nBlkAdr = pDns->nBlkAdr;
|
||||||
|
nUpdateCtr = pDns->nUpdateCtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirItrCheckMapBlks(DirItr *pDi) {
|
||||||
|
// Check the updateCounter of blocks referenced by an iterator.
|
||||||
|
DirNodeStack *pDns = pDi->dni.pDns;
|
||||||
|
WFSBlkAdr nAbsStartBlkAdr = pDi->tba.pAreaInfo->nAbsStartBlkAdr;
|
||||||
|
WFSBlkAdr nBlkAdr = pDi->tba.nBlkAdr;
|
||||||
|
u32 nUpdateCtr = (u32)(pDi->nUpdateCtr & WFS_MDF_DIR_COUNTER_MASK);
|
||||||
|
while(nBlkAdr) {
|
||||||
|
WFSBlkAdr nAbsBlkAdr = nAbsStartBlkAdr + nBlkAdr;
|
||||||
|
PTreeItr pti;
|
||||||
|
WFSKrnResult nResult = PTreeFind(&dirGlobals.updateMap, &pti, nAbsBlkAdr, &dirGlobals.updateMapAllocator);
|
||||||
|
if (nResult != WFSKRN_RESULT_PTREE_ENTRY_FOUND) {
|
||||||
|
WFSKrnOutputErrorStr("DirItr block not found in updateMap");
|
||||||
|
}
|
||||||
|
#if _DEBUG
|
||||||
|
else if (nResult != WFSKRN_RESULT_PTREE_ENTRY_FOUND) {
|
||||||
|
WFSKrnOutputErrorCode(nResult);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if ((pti.nData ^ nUpdateCtr) & WFS_MDF_DIR_COUNTER_MASK) {
|
||||||
|
return WFSKRN_RESULT_DIR_ITR_INVALID;
|
||||||
|
}
|
||||||
|
if (pDns==0) {
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
while(pDns->nBlkAdr == nBlkAdr) {
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
if (pDns==0) {
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nBlkAdr = pDns->nBlkAdr;
|
||||||
|
nUpdateCtr = pDns->nUpdateCtr;
|
||||||
|
}
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirItrCheckAndUnmapBlks(DirItr *pDi) {
|
||||||
|
#if _DEBUG_BREAK_POINT
|
||||||
|
static int c=0;++c;if(c>=4749){//5045
|
||||||
|
int a;a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// Check the updateCounter of blocks referenced by an iterator, and decrement the reference count for all blocks.
|
||||||
|
DirNodeStack *pDns = pDi->dni.pDns;
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
WFSBlkAdr nAbsStartBlkAdr = pDi->tba.pAreaInfo->nAbsStartBlkAdr;
|
||||||
|
WFSBlkAdr nBlkAdr = pDi->tba.nBlkAdr;
|
||||||
|
u32 nUpdateCtr = (u32)(pDi->nUpdateCtr & WFS_MDF_DIR_COUNTER_MASK);
|
||||||
|
while(nBlkAdr) {
|
||||||
|
WFSBlkAdr nAbsBlkAdr = nAbsStartBlkAdr + nBlkAdr;
|
||||||
|
PTreeItr pti;
|
||||||
|
WFSKrnResult nTempResult = PTreeFind(&dirGlobals.updateMap, &pti, nAbsBlkAdr, &dirGlobals.updateMapAllocator);
|
||||||
|
// #if _DEBUG
|
||||||
|
if (nTempResult != WFSKRN_RESULT_PTREE_ENTRY_FOUND) {
|
||||||
|
WFSKrnOutputErrorStr("DirItr block not found in updateMap");
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
if ((pti.nData ^ nUpdateCtr) & WFS_MDF_DIR_COUNTER_MASK) {
|
||||||
|
nResult = WFSKRN_RESULT_DIR_ITR_INVALID;
|
||||||
|
}
|
||||||
|
// Decrement the reference counter
|
||||||
|
pti.pLeaf->aData[pti.aEntryIdx[0]] -= DIR_BLK_REF_COUNT_INC;
|
||||||
|
if ((pti.pLeaf->aData[pti.aEntryIdx[0]] & (u32)(-DIR_BLK_REF_COUNT_INC)) == 0) {
|
||||||
|
// The reference counter is zero, so remove the mapping
|
||||||
|
PTreeDelete(&dirGlobals.updateMap, &pti, &dirGlobals.updateMapAllocator);
|
||||||
|
}
|
||||||
|
if (pDns==0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while(pDns->nBlkAdr == nBlkAdr) {
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
if (pDns==0) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nBlkAdr = pDns->nBlkAdr;
|
||||||
|
nUpdateCtr = pDns->nUpdateCtr;
|
||||||
|
}
|
||||||
|
Done:
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirItrClose(DirItr *pDi) {
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
if (pDi->ppDnsRootParent) {
|
||||||
|
nResult = TransUnpinBlk(&pDi->tba);
|
||||||
|
//MyOSReport("%d: Close(%p)\n", nDirTest, pDi);
|
||||||
|
DirNodeStackFree(&pDi->dni, pDi->ppDnsRootParent);
|
||||||
|
//#if _DEBUG
|
||||||
|
pDi->ppDnsRootParent = 0;
|
||||||
|
//#endif
|
||||||
|
pDi->link.pNext->link.pPrev = pDi->link.pPrev;
|
||||||
|
pDi->link.pPrev->link.pNext = pDi->link.pNext;
|
||||||
|
}
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirItrCloseNoUnpin(DirItr *pDi) {
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
if (pDi->ppDnsRootParent) {
|
||||||
|
//MyOSReport("%d: Close(%p)\n", nDirTest, pDi);
|
||||||
|
DirNodeStackFree(&pDi->dni, pDi->ppDnsRootParent);
|
||||||
|
//#if _DEBUG
|
||||||
|
pDi->ppDnsRootParent = 0;
|
||||||
|
//#endif
|
||||||
|
pDi->link.pNext->link.pPrev = pDi->link.pPrev;
|
||||||
|
pDi->link.pPrev->link.pNext = pDi->link.pNext;
|
||||||
|
}
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirItrPinBlkAndFixPtrs(DirItr *pDi, u32 nTransFlags) {
|
||||||
|
// Ensure that the block referenced to by the directory iterator is in memory,
|
||||||
|
// If not, load it into memory and adjust the pDi->pAttrHdr and pDi->dni.pOfs pointers to point to the new location
|
||||||
|
s32 nPtrAdjustment = -(s32)pDi->pBlkHdr;
|
||||||
|
DirBlkHdr *pBlkHdr;
|
||||||
|
WFSKrnReturnOnError(DirGetBlk(pDi, nTransFlags | BCACHE_FLAG_PINNED, &pBlkHdr));
|
||||||
|
nPtrAdjustment += (s32)pBlkHdr;
|
||||||
|
pDi->dni.pOfs = (u16*)((u8*)pDi->dni.pOfs + nPtrAdjustment);
|
||||||
|
pDi->pAttrHdr = (DirEntryAttrHdr *)((u8*)pDi->pAttrHdr + nPtrAdjustment);
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirFindName(WFSFileName *pName, DirItr *pDi) {
|
||||||
|
WFSKrnCopyFileNameAndConvertToLowerCase(&pDi->name, pName);
|
||||||
|
pDi->nBlkDepth = 0;
|
||||||
|
WFSKrnResult nResult = DirFind(&pDi->name, pDi, DIR_MAX_BLK_DEPTH, DIR_FIND_MODE_NORMAL);
|
||||||
|
switch(nResult) {
|
||||||
|
case WFSKRN_RESULT_DIR_ENTRY_FOUND:
|
||||||
|
WFSKrnCopyFileNameAndRestoreCase(pName->sStr, &pDi->name, pDi->pAttrHdr->aCaseBitArray);
|
||||||
|
pName->nLen = pDi->name.nLen;
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_STRING_MISMATCH:
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_CHOICE_NOT_FOUND:
|
||||||
|
return WFSKRN_RESULT_NOT_FOUND;
|
||||||
|
default:
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirFindRaw(DirItr *pDi) {
|
||||||
|
pDi->nBlkDepth = 0;
|
||||||
|
WFSKrnResult nResult = DirFind(&pDi->name, pDi, DIR_MAX_BLK_DEPTH, DIR_FIND_MODE_NORMAL);
|
||||||
|
switch(nResult) {
|
||||||
|
case WFSKRN_RESULT_DIR_ENTRY_FOUND:
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_STRING_MISMATCH:
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_CHOICE_NOT_FOUND:
|
||||||
|
return WFSKRN_RESULT_NOT_FOUND;
|
||||||
|
default:
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirFindFirstNamePrefixMatch(WFSFileName *pName, DirItr *pDi) {
|
||||||
|
pDi->nBlkDepth = 0;
|
||||||
|
WFSKrnCopyFileNameAndConvertToLowerCase(&pDi->name, pName);
|
||||||
|
WFSKrnResult nResult = DirFind(&pDi->name, pDi, DIR_MAX_BLK_DEPTH, DIR_FIND_MODE_PREFIX_SEARCH);
|
||||||
|
switch(nResult) {
|
||||||
|
case WFSKRN_RESULT_DIR_ENTRY_FOUND:
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_STRING_PREFIX:
|
||||||
|
case WFSKRN_RESULT_DIR_CHOICE_PREFIX:
|
||||||
|
WFSKrnCopyFileNameAndRestoreCase(pName->sStr, &pDi->name, pDi->pAttrHdr->aCaseBitArray);
|
||||||
|
pName->nLen = pDi->name.nLen;
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_STRING_MISMATCH:
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_CHOICE_NOT_FOUND:
|
||||||
|
return WFSKRN_RESULT_NOT_FOUND;
|
||||||
|
default:
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirNextName(WFSFileName *pName, DirItr *pDi) {
|
||||||
|
pDi->nBlkDepth = 0;
|
||||||
|
//WFSKrnCopyFileNameAndConvertToLowerCase(&pDi->name, pName);
|
||||||
|
WFSKrnResult nResult = DirNextRaw(&pDi->name, pDi);
|
||||||
|
switch(nResult) {
|
||||||
|
case WFSKRN_RESULT_OK:
|
||||||
|
case WFSKRN_RESULT_DIR_ENTRY_FOUND:
|
||||||
|
WFSKrnCopyFileNameAndRestoreCase(pName->sStr, &pDi->name, pDi->pAttrHdr->aCaseBitArray);
|
||||||
|
pName->nLen = pDi->name.nLen;
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
default:
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirInsertName(WFSFileName *pName, DirItr *pDi, u32 nAllocSize) {
|
||||||
|
WFSKrnCopyFileNameAndConvertToLowerCase(&pDi->name, pName);
|
||||||
|
WFSKrnReturnOnError(DirInsertRaw(&pDi->name, pDi, nAllocSize));
|
||||||
|
WFSKrnStoreCaseInformation(pDi->pAttrHdr->aCaseBitArray, pName);
|
||||||
|
// ToDo: Add other file attributes to pDi->pAttrHdr
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DirInitFileEntryAttrHdr(DirEntryAttrHdr *pAttrHdr) {
|
||||||
|
memset(pAttrHdr, 0, sizeof(DirEntryAttrHdr));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DirInitDirEntryAttrHdr(DirEntryAttrHdr *pAttrHdr) {
|
||||||
|
memset(pAttrHdr, 0, sizeof(DirEntryAttrHdr));
|
||||||
|
pAttrHdr->nAccessListIdx = WFS_FLAG_IS_A_DIRECTORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirDeleteFile(DirItr *pDi) {
|
||||||
|
DirEntryAttrHdr *pAttrHdr = pDi->pAttrHdr;
|
||||||
|
TransBlkAdr tba = pDi->tba;
|
||||||
|
switch(pAttrHdr->nSizeCategory){
|
||||||
|
case FILE_SIZE_CATEGORY_VERY_SMALL:
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
case FILE_SIZE_CATEGORY_SMALL:{
|
||||||
|
u32 nNumBlks = pAttrHdr->nAllocSize ? ((pAttrHdr->nAllocSize-1) >> tba.pAreaInfo->ah.nLog2BlkSize) + 1 : 0;
|
||||||
|
WFSFileBlkPtr *pFileBlkPtr = WFSKrnGetFileBlkPtrForCategorySmall(pAttrHdr, pAttrHdr->nAttrLog2Size, 0);
|
||||||
|
return TransFreeBlks6(tba.pAreaInfo, tba.pAreaInfo->ah.nLog2BlkSize, nNumBlks, (WFSBlkAdr*)pFileBlkPtr, -(s32)sizeof(WFSFileBlkPtr), tba.pTransInfo);
|
||||||
|
}
|
||||||
|
case FILE_SIZE_CATEGORY_MEDIUM:{
|
||||||
|
u32 nNumMediumBlks = pAttrHdr->nAllocSize ? ((pAttrHdr->nAllocSize-1) >> tba.pAreaInfo->ah.nLog2MediumBlkSize) + 1 : 0;
|
||||||
|
WFSFileBlkPtr *pFileBlkPtr = WFSKrnGetFileBlkPtrForCategoryMedium(pAttrHdr, pAttrHdr->nAttrLog2Size, 0);
|
||||||
|
return TransFreeBlks6(tba.pAreaInfo, tba.pAreaInfo->ah.nLog2MediumBlkSize, nNumMediumBlks, (WFSBlkAdr*)pFileBlkPtr, -(s32)sizeof(WFSFileBlkPtr), tba.pTransInfo);
|
||||||
|
}
|
||||||
|
case FILE_SIZE_CATEGORY_LARGE: {
|
||||||
|
u32 nNumLargeBlks = pAttrHdr->nAllocSize ? ((pAttrHdr->nAllocSize-1) >> tba.pAreaInfo->ah.nLog2LargeBlkSize) + 1 : 0;
|
||||||
|
WFSFileLargeBlkPtr *pFileBlkLargePtr = WFSKrnGetFileLargeBlkPtrForCategoryLarge(pAttrHdr, pAttrHdr->nAttrLog2Size, 0);
|
||||||
|
return TransFreeBlks6(tba.pAreaInfo, tba.pAreaInfo->ah.nLog2LargeBlkSize, nNumLargeBlks,
|
||||||
|
(WFSBlkAdr*)pFileBlkLargePtr, -(s32)sizeof(WFSFileLargeBlkPtr), tba.pTransInfo);
|
||||||
|
}
|
||||||
|
case FILE_SIZE_CATEGORY_VERY_LARGE: {
|
||||||
|
u32 nNumLargeBlks = pAttrHdr->nAllocSize ? ((pAttrHdr->nAllocSize-1) >> tba.pAreaInfo->ah.nLog2LargeBlkSize) + 1 : 0;
|
||||||
|
u32 nNumIndirectBlks = (nNumLargeBlks+tba.pAreaInfo->nNumLargeBlkPtrsPerBlk-1)/tba.pAreaInfo->nNumLargeBlkPtrsPerBlk;
|
||||||
|
WFSBlkAdr *pIndirectBlkAdr = WFSKrnGetBlkAdrPtrFromAttrHdrAndIndirectBlkIdxForCategoryVeryLarge(tba.pAreaInfo, pAttrHdr, pAttrHdr->nAttrLog2Size, 0);
|
||||||
|
s32 nI;
|
||||||
|
for(nI=0;nI<nNumIndirectBlks;nI++){
|
||||||
|
u8 *pIndirectBlkPtr;
|
||||||
|
WFSKrnReturnOnError(TransGetAndPinBlk5(tba.pAreaInfo, pIndirectBlkAdr[-nI], tba.pTransInfo, TRANS_FLAG_READ_BLK, (void**)&pIndirectBlkPtr));
|
||||||
|
if(nI+1==nNumIndirectBlks){
|
||||||
|
WFSKrnReturnOnError(TransFreeBlks6(tba.pAreaInfo, tba.pAreaInfo->ah.nLog2LargeBlkSize, (nNumLargeBlks-1)%tba.pAreaInfo->nNumLargeBlkPtrsPerBlk+1,
|
||||||
|
(WFSBlkAdr*)(pIndirectBlkPtr+sizeof(WFSMetaDataHdr)), (s32)sizeof(WFSFileLargeBlkPtr), tba.pTransInfo));
|
||||||
|
} else {
|
||||||
|
WFSKrnReturnOnError(TransFreeBlks6(tba.pAreaInfo, tba.pAreaInfo->ah.nLog2LargeBlkSize, tba.pAreaInfo->nNumLargeBlkPtrsPerBlk,
|
||||||
|
(WFSBlkAdr*)(pIndirectBlkPtr+sizeof(WFSMetaDataHdr)), (s32)sizeof(WFSFileLargeBlkPtr), tba.pTransInfo));
|
||||||
|
}
|
||||||
|
WFSKrnReturnOnError(TransUnpinBlk3(tba.pAreaInfo, pIndirectBlkAdr[-nI], tba.pTransInfo));
|
||||||
|
}
|
||||||
|
return TransFreeBlks6(tba.pAreaInfo, tba.pAreaInfo->ah.nLog2BlkSize, nNumIndirectBlks, pIndirectBlkAdr, -(s32)sizeof(WFSBlkAdr), tba.pTransInfo);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return WFSKRN_RESULT_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirDeleteSubDir(DirItr *pDi) {
|
||||||
|
DirEntryAttrHdr *pAttrHdr = pDi->pAttrHdr;
|
||||||
|
TransBlkAdr tba = pDi->tba;
|
||||||
|
tba.nBlkAdr = pAttrHdr->dir.nSubDirBlkAdr;
|
||||||
|
DirBlkHdr *pSubDirBlkHdr;
|
||||||
|
|
||||||
|
WFSKrnReturnOnError(TransGetAndPinBlk(&tba, TRANS_FLAG_READ_BLK, (void**)&pSubDirBlkHdr));
|
||||||
|
/*
|
||||||
|
nResult = TransGetAndPinBlk(&tba, TRANS_FLAG_READ_BLK, (void**)&pSubDirBlkHdr);
|
||||||
|
if (nResult < WFSKRN_RESULT_OK){
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if (pSubDirBlkHdr->nNumRecs) {
|
||||||
|
TransUnpinBlk(&tba);
|
||||||
|
return WFSKRN_RESULT_NOT_EMPTY;
|
||||||
|
}
|
||||||
|
WFSKrnReturnOnError(TransUnpinAndFreeBlks(pDi->tba.pAreaInfo, pDi->tba.pAreaInfo->ah.nLog2BlkSize, 1, &tba.nBlkAdr, pDi->tba.pTransInfo));
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
@ -0,0 +1,655 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_DirCheck.cpp
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_DirCheck.cpp,v $
|
||||||
|
Revision 1.14 2008/11/18 04:57:12 saito_tomoya
|
||||||
|
Modified SetBit() and added SetBitArray().
|
||||||
|
|
||||||
|
Revision 1.13 2008/10/30 04:50:45 kondo_masahiro
|
||||||
|
Added DirCheckDisk
|
||||||
|
|
||||||
|
Revision 1.12 2008/10/17 08:50:48 kondo_masahiro
|
||||||
|
Added the new MEDIUM size category (40KB-320KB)
|
||||||
|
|
||||||
|
Revision 1.11 2008/10/16 09:30:39 ooizumi
|
||||||
|
Fixed definitions for debug build.
|
||||||
|
|
||||||
|
Revision 1.10 2008/09/01 01:57:26 kondo_masahiro
|
||||||
|
Minor fixed for IOP compiler.
|
||||||
|
|
||||||
|
Revision 1.9 2008/08/27 23:02:55 ooizumi
|
||||||
|
Fixed newline to CR+LF(Windows format).
|
||||||
|
|
||||||
|
Revision 1.8 2008/08/27 09:47:43 paul
|
||||||
|
Removed nTotalFree from block header. Added pAttrHdr->nAttrLog2Size
|
||||||
|
|
||||||
|
Revision 1.7 2008/07/09 00:31:36 paul
|
||||||
|
Minor changes
|
||||||
|
|
||||||
|
Revision 1.6 2008/06/09 17:22:38 paul
|
||||||
|
Changed comment
|
||||||
|
|
||||||
|
Revision 1.5 2008/05/27 18:44:19 paul
|
||||||
|
Made utf8 variable definitions more consistent, and use (unsigned) for comparisons
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/14 02:16:52 paul
|
||||||
|
Fixed the node choice ordering check to prevent utf8 being upgraded to signed int
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/10 03:59:44 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 17:29:46 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.5 2008/04/22 23:26:55 paul
|
||||||
|
Changed areaHdrRoot to areaInfoRoot
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/19 05:50:57 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/15 18:51:26 paul
|
||||||
|
Made some changes to debug code
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/08 00:25:34 paul
|
||||||
|
Added an extra check for radix tree nodes with 0 entries
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/05 00:03:30 paul
|
||||||
|
Integrity checks for directory node blocks and directory leaf blocks
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#undef _KRN_FILE_
|
||||||
|
#define _KRN_FILE_ "DirCheck"
|
||||||
|
|
||||||
|
#include "wfskrn_Dir.h"
|
||||||
|
#include "wfskrn_SubBlkAlloc.h"
|
||||||
|
#include "wfskrn_DirNodeStack.h"
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_BitField.h"
|
||||||
|
#include "wfskrn_Heap.h"
|
||||||
|
#include "wfskrn_Api.h"
|
||||||
|
#include "wfskrn_Mutex.h"
|
||||||
|
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
bool bCheckDirBlks = true; // extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static
|
||||||
|
void DirSubBlkDebugPrint(DirSubBlkHdr *pSubBlkHdr) {
|
||||||
|
utf8 *pChoiceChar = &pSubBlkHdr->aFirstChar[pSubBlkHdr->nStrLen];
|
||||||
|
utf8 cTemp = *pChoiceChar;
|
||||||
|
*pChoiceChar = 0;
|
||||||
|
MyOSReport("%d,%d,\"%s\"", pSubBlkHdr->nStrLen, pSubBlkHdr->nNumEntries, pSubBlkHdr->aFirstChar);
|
||||||
|
*pChoiceChar = cTemp;
|
||||||
|
u32 nI;
|
||||||
|
for(nI=0; nI<pSubBlkHdr->nNumEntries; nI++) {
|
||||||
|
if ((*pChoiceChar<32)||(*pChoiceChar>127)) {
|
||||||
|
MyOSReport(",%d", *pChoiceChar);
|
||||||
|
} else {
|
||||||
|
MyOSReport(",'%c'", *pChoiceChar);
|
||||||
|
}
|
||||||
|
++pChoiceChar;
|
||||||
|
}
|
||||||
|
MyOSReport("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirLeafCheckBlk(DirItr *pDi) {
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
// Checks that all allocated sub blocks of pDi->pBlkHdr are reachable, and all non-allocated blocks are on the free list
|
||||||
|
if (!bCheckDirBlks) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
bool bOldCheckDirNodeStack = bCheckDirNodeStack;
|
||||||
|
bCheckDirNodeStack = false;
|
||||||
|
#endif
|
||||||
|
DirItr di = *pDi;
|
||||||
|
|
||||||
|
di.dni.nDnsDepth = 0;
|
||||||
|
WFSKrnResult nResult = DirNodeStackGetEntry(&di.dni);
|
||||||
|
di.ppDnsRootParent = &di.dni.pDns->pParent;
|
||||||
|
|
||||||
|
DirBlkHdr *pBlkHdr = (DirBlkHdr *)di.pBlkHdr;
|
||||||
|
u32 nSrcNodeOfs = pBlkHdr->nRootOfs;
|
||||||
|
utf8 *pChoiceChar;
|
||||||
|
u32 nConnectedSize=(1<<WFS_NUM_BITS_REQUIRED(sizeof(DirBlkHdr)));
|
||||||
|
u32 aUtilization[1<<(WFS_LOG2_MEDIUM_BLK_SIZE - SBA_MIN_LOG2_SUB_BLK_SIZE - 5)];
|
||||||
|
memset(aUtilization, 0, sizeof(aUtilization));
|
||||||
|
WfsSetBitField((unsigned*)aUtilization, 0, 1<<(WFS_NUM_BITS_REQUIRED(sizeof(DirBlkHdr))-SBA_MIN_LOG2_SUB_BLK_SIZE));
|
||||||
|
u32 nRecIdx = 0;
|
||||||
|
u32 nSrcLeafStartDepth = di.dni.nDnsDepth;
|
||||||
|
while(1) {
|
||||||
|
di.dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + nSrcNodeOfs);
|
||||||
|
WFSSubBlkFreeHdr *pSbfHdr = (WFSSubBlkFreeHdr *)di.dni.pSubBlkHdr;
|
||||||
|
if (pSbfHdr->nMagic == SBA_FREE_SUB_BLK_MAGIC) {
|
||||||
|
WFSKrnOutputErrorStr("Pointer to deleted sub block detected!");
|
||||||
|
}
|
||||||
|
di.dni.nLog2Size = DirLeafGetSubBlkLog2Size(di.dni.pSubBlkHdr);
|
||||||
|
di.dni.pDns->nBlkAdr = di.tba.nBlkAdr;
|
||||||
|
di.dni.pDns->nSubBlkOfs = nSrcNodeOfs;
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
if ((nDirTest>=nDirTestBreakPoint-1)&&(nDirTest<=nDirTestBreakPoint)) {
|
||||||
|
u32 nI;
|
||||||
|
for(nI=nSrcLeafStartDepth; nI<di.dni.nDnsDepth; nI++) {
|
||||||
|
MyOSReport(" ");
|
||||||
|
}
|
||||||
|
MyOSReport("%03x: ", nSrcNodeOfs);
|
||||||
|
DirSubBlkDebugPrint(di.dni.pSubBlkHdr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (WfsTestAndSetBitField((unsigned*)aUtilization, nSrcNodeOfs>>SBA_MIN_LOG2_SUB_BLK_SIZE, 1<<(di.dni.nLog2Size-SBA_MIN_LOG2_SUB_BLK_SIZE))) {
|
||||||
|
WFSKrnOutputErrorStr("Overlap!");
|
||||||
|
}
|
||||||
|
nConnectedSize += (u32)(1<<di.dni.nLog2Size);
|
||||||
|
u16 *pSrcNodeOfsTblEnd = (u16*)((u8*)di.dni.pSubBlkHdr + (1<<di.dni.nLog2Size));
|
||||||
|
di.dni.pDns->nEntryIdx = 1;
|
||||||
|
if (di.dni.pSubBlkHdr->nNumEntries == 0) {
|
||||||
|
if (pBlkHdr->nNumRecs) {
|
||||||
|
WFSKrnOutputErrorStr("No entries!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pChoiceChar = &di.dni.pSubBlkHdr->aFirstChar[di.dni.pSubBlkHdr->nStrLen];
|
||||||
|
if (*pChoiceChar == 0) {
|
||||||
|
// String terminator char indicates this is a record, so increment the record count
|
||||||
|
u32 nAttrOfs = pSrcNodeOfsTblEnd[-1];
|
||||||
|
SbaCheckOfs(nAttrOfs);
|
||||||
|
DirEntryAttrHdr *pAttrHdr = (DirEntryAttrHdr *)((u8*)pBlkHdr + nAttrOfs);
|
||||||
|
WFSSubBlkFreeHdr *pSbfHdr = (WFSSubBlkFreeHdr *)pAttrHdr;
|
||||||
|
if (pSbfHdr->nMagic == SBA_FREE_SUB_BLK_MAGIC) {
|
||||||
|
WFSKrnOutputErrorStr("Pointer to deleted attr block detected!");
|
||||||
|
}
|
||||||
|
u8 nSizeCategory;
|
||||||
|
u16 nAttrLog2Size = (u16)DirCalculateAttrSubBlkLog2Size(di.tba.pAreaInfo, pAttrHdr->nAllocSize, pAttrHdr->nNameLen, &nSizeCategory);
|
||||||
|
if (nSizeCategory != pAttrHdr->nSizeCategory) {
|
||||||
|
nAttrLog2Size = (u16)DirCalculateAttrSubBlkLog2SizeDecrease(di.tba.pAreaInfo, pAttrHdr->nAllocSize, pAttrHdr->nNameLen, &nSizeCategory);
|
||||||
|
if (nSizeCategory != pAttrHdr->nSizeCategory) {
|
||||||
|
WFSKrnOutputErrorStr("Size category incorrect");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (WfsTestAndSetBitField((unsigned*)aUtilization, nAttrOfs>>SBA_MIN_LOG2_SUB_BLK_SIZE, 1<<(nAttrLog2Size-SBA_MIN_LOG2_SUB_BLK_SIZE))) {
|
||||||
|
WFSKrnOutputErrorStr("Overlap!");
|
||||||
|
}
|
||||||
|
if (nAttrLog2Size != pAttrHdr->nAttrLog2Size) {
|
||||||
|
WFSKrnOutputErrorStr("Attr log 2 size incorrect");
|
||||||
|
}
|
||||||
|
if (nSizeCategory != pAttrHdr->nSizeCategory) {
|
||||||
|
WFSKrnOutputErrorStr("Size category incorrect");
|
||||||
|
}
|
||||||
|
nConnectedSize += (u32)(1<<nAttrLog2Size);
|
||||||
|
++nRecIdx;
|
||||||
|
++di.dni.pDns->nEntryIdx;
|
||||||
|
} else if (di.dni.pSubBlkHdr->nNumEntries == 1) {
|
||||||
|
WFSKrnOutputErrorStr("Non-terminating single-choice node!");
|
||||||
|
}
|
||||||
|
if (di.dni.pDns->nEntryIdx > di.dni.pSubBlkHdr->nNumEntries) {
|
||||||
|
do {
|
||||||
|
if (di.dni.nDnsDepth == nSrcLeafStartDepth) {
|
||||||
|
// We reached the top of the stack, so this should be the last record
|
||||||
|
goto CheckFreeSpace;
|
||||||
|
}
|
||||||
|
DirPopNodeStackEntry(&di.dni);
|
||||||
|
di.dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + di.dni.pDns->nSubBlkOfs);
|
||||||
|
++di.dni.pDns->nEntryIdx;
|
||||||
|
} while(di.dni.pDns->nEntryIdx > di.dni.pSubBlkHdr->nNumEntries);
|
||||||
|
pChoiceChar = &di.dni.pSubBlkHdr->aFirstChar[di.dni.pSubBlkHdr->nStrLen + di.dni.pDns->nEntryIdx-1];
|
||||||
|
if ((unsigned)pChoiceChar[-1] >= (unsigned)*pChoiceChar) {
|
||||||
|
WFSKrnOutputErrorStr("Choice out of order!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nSrcNodeOfs = DirLeafGetIntraBlkOfs(di.dni.pDns->nEntryIdx, di.dni.pSubBlkHdr);
|
||||||
|
SbaCheckOfs(nSrcNodeOfs);
|
||||||
|
nResult = DirNodeStackGetEntry(&di.dni);
|
||||||
|
if (nResult != WFSKRN_RESULT_OK) {
|
||||||
|
WFSKrnOutputErrorCode(nResult);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CheckFreeSpace:;
|
||||||
|
// Next check the free space
|
||||||
|
u32 nTotalFree = SbaCheckFreeSpace((WFSSubBlkAllocHdr *)pBlkHdr, aUtilization);
|
||||||
|
if ((nTotalFree + nConnectedSize) != pDi->tba.pAreaInfo->nBlkSize) {
|
||||||
|
WFSKrnOutputErrorStr("Memory Leak detected within block!");
|
||||||
|
}
|
||||||
|
if (nRecIdx != pBlkHdr->nNumRecs) {
|
||||||
|
WFSKrnOutputErrorStr("NumRecs Error!");
|
||||||
|
}
|
||||||
|
DirNodeStackFree(&di.dni, di.ppDnsRootParent);
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
if ((nDirTest>=nDirTestBreakPoint-1)&&(nDirTest<=nDirTestBreakPoint)) {
|
||||||
|
MyOSReport("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
bCheckDirNodeStack = bOldCheckDirNodeStack;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirNodeCheckBlk(DirItr *pDi) {
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
// Checks that all allocated sub blocks of pDi->pBlkHdr are reachable, and all non-allocated blocks are on the free list
|
||||||
|
if (!bCheckDirBlks) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
bool bOldCheckDirNodeStack = bCheckDirNodeStack;
|
||||||
|
bCheckDirNodeStack = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DirItr di = *pDi;
|
||||||
|
DirBlkHdr *pBlkHdr = (DirBlkHdr *)di.pBlkHdr;
|
||||||
|
u32 nSrcNodeOfs = pBlkHdr->nRootOfs;
|
||||||
|
utf8 *pChoiceChar;
|
||||||
|
u32 nConnectedSize=(1<<WFS_NUM_BITS_REQUIRED(sizeof(DirBlkHdr)));
|
||||||
|
u32 aUtilization[1<<(WFS_LOG2_MEDIUM_BLK_SIZE - SBA_MIN_LOG2_SUB_BLK_SIZE - 5)];
|
||||||
|
memset(aUtilization, 0, sizeof(aUtilization));
|
||||||
|
WfsSetBitField((unsigned*)aUtilization, 0, 1<<(WFS_NUM_BITS_REQUIRED(sizeof(DirBlkHdr))-SBA_MIN_LOG2_SUB_BLK_SIZE));
|
||||||
|
u32 nRecIdx = 0;
|
||||||
|
u32 nSrcNodeStartDepth = di.dni.nDnsDepth;
|
||||||
|
WFSKrnResult nResult;
|
||||||
|
while(1) {
|
||||||
|
di.dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + nSrcNodeOfs);
|
||||||
|
WFSSubBlkFreeHdr *pSbfHdr = (WFSSubBlkFreeHdr *)di.dni.pSubBlkHdr;
|
||||||
|
if (pSbfHdr->nMagic == SBA_FREE_SUB_BLK_MAGIC) {
|
||||||
|
WFSKrnOutputErrorStr("Pointer to deleted sub block detected!");
|
||||||
|
}
|
||||||
|
di.dni.nLog2Size = DirNodeGetSubBlkLog2Size(di.dni.pSubBlkHdr);
|
||||||
|
di.dni.pDns->nBlkAdr = di.tba.nBlkAdr;
|
||||||
|
di.dni.pDns->nSubBlkOfs = nSrcNodeOfs;
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
if ((nDirTest>=nDirTestBreakPoint-1)&&(nDirTest<=nDirTestBreakPoint)) {
|
||||||
|
u32 nI;
|
||||||
|
for(nI=nSrcNodeStartDepth; nI<di.dni.nDnsDepth; nI++) {
|
||||||
|
MyOSReport(" ");
|
||||||
|
}
|
||||||
|
MyOSReport("%03x: ", nSrcNodeOfs);
|
||||||
|
DirSubBlkDebugPrint(di.dni.pSubBlkHdr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (WfsTestAndSetBitField((unsigned*)aUtilization, nSrcNodeOfs>>SBA_MIN_LOG2_SUB_BLK_SIZE, 1<<(di.dni.nLog2Size-SBA_MIN_LOG2_SUB_BLK_SIZE))) {
|
||||||
|
WFSKrnOutputErrorStr("Overlap!");
|
||||||
|
}
|
||||||
|
nConnectedSize += (u32)(1<<di.dni.nLog2Size);
|
||||||
|
di.dni.pDns->nEntryIdx = 1;
|
||||||
|
if (di.dni.pSubBlkHdr->nNumEntries == 0) {
|
||||||
|
if (pBlkHdr->nNumRecs) {
|
||||||
|
WFSKrnOutputErrorStr("No entries!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pChoiceChar = &di.dni.pSubBlkHdr->aFirstChar[di.dni.pSubBlkHdr->nStrLen];
|
||||||
|
if (*pChoiceChar == 0) {
|
||||||
|
// String terminator char indicates this is a record, so increment the record count
|
||||||
|
++nRecIdx;
|
||||||
|
++di.dni.pDns->nEntryIdx;
|
||||||
|
} else if (di.dni.pSubBlkHdr->nNumEntries == 1) {
|
||||||
|
WFSKrnOutputErrorStr("Non-terminating single-choice node!");
|
||||||
|
}
|
||||||
|
if (di.dni.pDns->nEntryIdx > di.dni.pSubBlkHdr->nNumEntries) {
|
||||||
|
do {
|
||||||
|
if (di.dni.nDnsDepth == nSrcNodeStartDepth) {
|
||||||
|
// We reached the top of the stack, so this should be the last record
|
||||||
|
goto CheckFreeSpace;
|
||||||
|
}
|
||||||
|
DirPopNodeStackEntry(&di.dni);
|
||||||
|
di.dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + di.dni.pDns->nSubBlkOfs);
|
||||||
|
++di.dni.pDns->nEntryIdx;
|
||||||
|
} while(di.dni.pDns->nEntryIdx > di.dni.pSubBlkHdr->nNumEntries);
|
||||||
|
pChoiceChar = &di.dni.pSubBlkHdr->aFirstChar[di.dni.pSubBlkHdr->nStrLen + di.dni.pDns->nEntryIdx -1];
|
||||||
|
if ((unsigned)pChoiceChar[-1] >= (unsigned)*pChoiceChar) {
|
||||||
|
WFSKrnOutputErrorStr("Choice out of order!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nSrcNodeOfs = DirNodeGetIntraBlkOfs(di.dni.pDns->nEntryIdx, di.dni.pSubBlkHdr);
|
||||||
|
SbaCheckOfs(nSrcNodeOfs);
|
||||||
|
nResult = DirNodeStackGetEntry(&di.dni);
|
||||||
|
if (nResult != WFSKRN_RESULT_OK) {
|
||||||
|
WFSKrnOutputErrorCode(nResult);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CheckFreeSpace:;
|
||||||
|
// Next check the free space
|
||||||
|
u32 nTotalFree = SbaCheckFreeSpace((WFSSubBlkAllocHdr *)pBlkHdr, aUtilization);
|
||||||
|
if ((nTotalFree + nConnectedSize) != pDi->tba.pAreaInfo->nBlkSize) {
|
||||||
|
WFSKrnOutputErrorStr("Memory Leak detected within block!");
|
||||||
|
}
|
||||||
|
if (nRecIdx != pBlkHdr->nNumRecs) {
|
||||||
|
WFSKrnOutputErrorStr("NumRecs Error!");
|
||||||
|
}
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
if ((nDirTest>=nDirTestBreakPoint-1)&&(nDirTest<=nDirTestBreakPoint)) {
|
||||||
|
MyOSReport("\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
bCheckDirNodeStack = bOldCheckDirNodeStack;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirCheckBlk(DirItr *pDi) {
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
// Checks that all allocated blocks are reachable, and all non-allocated blocks are on the free list
|
||||||
|
if (!bCheckDirBlks) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (pDi->pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) {
|
||||||
|
DirLeafCheckBlk(pDi);
|
||||||
|
} else {
|
||||||
|
DirNodeCheckBlk(pDi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void SetBit(WFSSrvFileHandle fh, u32 diskAddr)
|
||||||
|
{
|
||||||
|
u32 byte = diskAddr / 8;
|
||||||
|
u32 bit = diskAddr % 8;
|
||||||
|
u8 flag = (1 << bit);
|
||||||
|
|
||||||
|
u8 dst;
|
||||||
|
|
||||||
|
WFSResult nResult;
|
||||||
|
nResult = (WFSResult)WFSSrvReadFile(fh, &dst, byte, 1);
|
||||||
|
if(nResult < WFS_RESULT_OK){
|
||||||
|
osTPrintf("SetBit() error %d\n", nResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(0 == (dst & flag));
|
||||||
|
dst |= flag;
|
||||||
|
nResult = WFSSrvWriteFile(fh, &dst, byte, 1, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetBitArrayInternal(WFSSrvFileHandle fh, u8* pBuffer, u32 bufferSize, u32 diskAddr, u32 length){
|
||||||
|
|
||||||
|
u32 byte = diskAddr / 8;
|
||||||
|
u32 bit = diskAddr % 8;
|
||||||
|
u32 byteLength = (diskAddr + length - 1) / 8 - byte + 1;
|
||||||
|
|
||||||
|
WFSResult nResult;
|
||||||
|
|
||||||
|
// read
|
||||||
|
nResult = (WFSResult)WFSSrvReadFile(fh, pBuffer, byte, byteLength);
|
||||||
|
if(nResult < WFS_RESULT_OK){
|
||||||
|
osTPrintf("SetBitArray() error %d\n", nResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set bits
|
||||||
|
int i;
|
||||||
|
for(i=bit; i<bit+length; ++i){
|
||||||
|
u8 flag = 1 << (i & 0x07);
|
||||||
|
ASSERT( !(pBuffer[i/8] & flag) );
|
||||||
|
pBuffer[i/8] |= flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write
|
||||||
|
nResult = WFSSrvWriteFile(fh, pBuffer, byte, byteLength, true);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void SetBitArray(WFSSrvFileHandle fh, u8* pBuffer, u32 bufferSize, u32 diskAddr, u32 length){
|
||||||
|
|
||||||
|
while(length > (bufferSize-1)*8){
|
||||||
|
SetBitArrayInternal(fh, pBuffer, bufferSize, diskAddr, (bufferSize-1)*8);
|
||||||
|
length -= (bufferSize-1)*8;
|
||||||
|
diskAddr += (bufferSize-1)*8;
|
||||||
|
}
|
||||||
|
SetBitArrayInternal(fh, pBuffer, bufferSize, diskAddr, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirCheckDisk(WFSBlkAdr rootBlkAdr, DirItr *pDi, WFSSrvFileHandle fh, u8* pBuffer, u32 bufferSize, u32 nFlag) {
|
||||||
|
|
||||||
|
DirBlkHdr *pBlkHdr;
|
||||||
|
pDi->tba.nBlkAdr = rootBlkAdr;
|
||||||
|
|
||||||
|
///
|
||||||
|
//pCheckDiskArray[rootBlkAdr/8] |= 1<<(rootBlkAdr%8);
|
||||||
|
SetBit(fh, rootBlkAdr);
|
||||||
|
|
||||||
|
pDi->nBlkDepth = 0;
|
||||||
|
WFSKrnReturnOnError(DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr));
|
||||||
|
|
||||||
|
pDi->dni.nDnsDepth = 0;
|
||||||
|
WFSKrnReturnOnError(DirNodeStackGetEntry(&pDi->dni));
|
||||||
|
pDi->ppDnsRootParent = &pDi->dni.pDns->pParent;
|
||||||
|
|
||||||
|
pDi->dni.pDns->nBlkAdr = 0; //tba.nBlkAdr;
|
||||||
|
pDi->dni.pDns->nSubBlkOfs = pBlkHdr->nRootOfs;
|
||||||
|
SbaCheckOfs(pDi->dni.pDns->nSubBlkOfs);
|
||||||
|
pDi->dni.pDns->nEntryIdx = 1;
|
||||||
|
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
pDi->dni.pOfs = &pBlkHdr->nRootOfs;
|
||||||
|
SbaCheckOfs(*pDi->dni.pOfs);
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
if (pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) {
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
} else {
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1){
|
||||||
|
#if _DEBUG_BREAK_POINT
|
||||||
|
static int c=0; c++; if(c==0x2b){
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (pDi->dni.nEntryIdx > pDi->dni.pSubBlkHdr->nNumEntries) {
|
||||||
|
if(pDi->dni.pDns->nBlkAdr == 0){
|
||||||
|
TransUnpinBlk(&pDi->tba);
|
||||||
|
DirPopNodeStackEntry(&pDi->dni);
|
||||||
|
pDi->nBlkDepth = 0;
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
if(pDi->tba.nBlkAdr != pDi->dni.pDns->nBlkAdr){
|
||||||
|
TransUnpinBlk(&pDi->tba);
|
||||||
|
pDi->tba.nBlkAdr = pDi->dni.pDns->nBlkAdr;
|
||||||
|
WFSKrnReturnOnError( DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr) );
|
||||||
|
}
|
||||||
|
pDi->dni.nEntryIdx = ++pDi->dni.pDns->nEntryIdx;
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + pDi->dni.pDns->nSubBlkOfs);
|
||||||
|
if (pDi->dni.nEntryIdx <= pDi->dni.pSubBlkHdr->nNumEntries){
|
||||||
|
if (pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) {
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
pDi->dni.pOfs = DirLeafGetIntraBlkOfsPtr_l2s((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
} else {
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr_l2s((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
}
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
} else {
|
||||||
|
DirPopNodeStackEntry(&pDi->dni);
|
||||||
|
--pDi->nBlkDepth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
WFSKrnReturnOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
++pDi->nBlkDepth;
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
|
||||||
|
if (pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) {
|
||||||
|
if(pDi->dni.nEntryIdx == 1 && pDi->dni.pSubBlkHdr->aFirstChar[pDi->dni.pSubBlkHdr->nStrLen] == 0){
|
||||||
|
u16 nOfs = *DirLeafGetIntraBlkOfsPtr_l2s(1, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
pDi->pAttrHdr = (DirEntryAttrHdr *)((u8*)pBlkHdr + nOfs);
|
||||||
|
if (pDi->pAttrHdr->nAccessListIdx & WFS_FLAG_IS_A_DIRECTORY) {
|
||||||
|
TransUnpinBlk(&pDi->tba);
|
||||||
|
pDi->tba.nBlkAdr = pDi->pAttrHdr->dir.nSubDirBlkAdr;
|
||||||
|
|
||||||
|
///
|
||||||
|
//pCheckDiskArray[pDi->tba.nBlkAdr/8] |= 1<<(pDi->tba.nBlkAdr%8);
|
||||||
|
SetBit(fh, pDi->tba.nBlkAdr);
|
||||||
|
|
||||||
|
WFSKrnReturnOnError( DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr) );
|
||||||
|
pDi->dni.pOfs = &pBlkHdr->nRootOfs;
|
||||||
|
SbaCheckOfs(*pDi->dni.pOfs);
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
if (pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) {
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
} else {
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
}
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
} else {
|
||||||
|
if(nFlag == DIR_CHECK_DISK_FOR_DIR_TREE){
|
||||||
|
switch(pDi->pAttrHdr->nSizeCategory){
|
||||||
|
case FILE_SIZE_CATEGORY_SMALL:{
|
||||||
|
u32 nI, nNumSmallBlks = pDi->pAttrHdr->nAllocSize>>pDi->tba.pAreaInfo->ah.nLog2BlkSize;
|
||||||
|
for(nI=0;nI<nNumSmallBlks;nI++){
|
||||||
|
WFSFileBlkPtr *pFileBlkPtr = WFSKrnGetFileBlkPtrForCategorySmall(pDi->pAttrHdr, pDi->pAttrHdr->nAttrLog2Size, nI);
|
||||||
|
//if(pCheckDiskArray[pFileBlkPtr->nBlkAdr/8]&(1<<(pFileBlkPtr->nBlkAdr%8))){
|
||||||
|
// int a; a=0;
|
||||||
|
//}
|
||||||
|
|
||||||
|
///
|
||||||
|
//pCheckDiskArray[pFileBlkPtr->nBlkAdr/8] |= 1<<(pFileBlkPtr->nBlkAdr%8);
|
||||||
|
SetBit(fh, pFileBlkPtr->nBlkAdr);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FILE_SIZE_CATEGORY_MEDIUM:{
|
||||||
|
u32 nI, nNumMediumBlks = pDi->pAttrHdr->nAllocSize>>pDi->tba.pAreaInfo->ah.nLog2MediumBlkSize;
|
||||||
|
for(nI=0;nI<nNumMediumBlks;nI++){
|
||||||
|
WFSFileBlkPtr *pFileBlkPtr = WFSKrnGetFileBlkPtrForCategoryMedium(pDi->pAttrHdr, pDi->pAttrHdr->nAttrLog2Size, nI);
|
||||||
|
//u8 flag = 0xff<<(pFileBlkPtr->nBlkAdr%8);
|
||||||
|
|
||||||
|
///
|
||||||
|
SetBitArray(fh, pBuffer, bufferSize, pFileBlkPtr->nBlkAdr, 8); // array!
|
||||||
|
/*
|
||||||
|
pCheckDiskArray[pFileBlkPtr->nBlkAdr/8] |= flag;
|
||||||
|
|
||||||
|
if(~flag){
|
||||||
|
|
||||||
|
///
|
||||||
|
pCheckDiskArray[pFileBlkPtr->nBlkAdr/8+1] |= ~flag;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FILE_SIZE_CATEGORY_LARGE:{
|
||||||
|
u32 nI, nJ, nNumLargeBlks = pDi->pAttrHdr->nAllocSize>>pDi->tba.pAreaInfo->ah.nLog2LargeBlkSize;
|
||||||
|
for(nJ=0;nJ<nNumLargeBlks;nJ++){
|
||||||
|
WFSFileLargeBlkPtr *pFileLargeBlkPtr = WFSKrnGetFileLargeBlkPtrForCategoryLarge(pDi->pAttrHdr, pDi->pAttrHdr->nAttrLog2Size, nJ);
|
||||||
|
for(nI=0;nI<(1<<pDi->tba.pAreaInfo->nLog2MediumBlkPerLargeBlk);nI++){
|
||||||
|
WFSFileBlkInfo fileBlkInfo = WFSKrnGetFileBlkInfoForCategoryLarge(pDi->tba.pAreaInfo, pFileLargeBlkPtr, nI);
|
||||||
|
//u8 flag = 0xff<<(fileBlkInfo.nBlkAdr%8);
|
||||||
|
|
||||||
|
SetBitArray(fh, pBuffer, bufferSize, fileBlkInfo.nBlkAdr, 8); // array!
|
||||||
|
/*
|
||||||
|
///
|
||||||
|
pCheckDiskArray[fileBlkInfo.nBlkAdr/8] |= flag;
|
||||||
|
if(~flag){
|
||||||
|
|
||||||
|
///
|
||||||
|
pCheckDiskArray[fileBlkInfo.nBlkAdr/8+1] |= ~flag;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case FILE_SIZE_CATEGORY_VERY_LARGE: {
|
||||||
|
WFSBlkAdr nBlkAdr = pDi->tba.nBlkAdr;
|
||||||
|
u32 nI, nJ, nK;
|
||||||
|
u32 nNumLargeBlks = pDi->pAttrHdr->nAllocSize>>pDi->tba.pAreaInfo->ah.nLog2LargeBlkSize;
|
||||||
|
u32 nNumIndirectBlks = (nNumLargeBlks-1)/pDi->tba.pAreaInfo->nNumLargeBlkPtrsPerBlk+1;
|
||||||
|
for(nK=0;nK<nNumIndirectBlks;nK++){
|
||||||
|
u8* pIndirectPtr;
|
||||||
|
WFSBlkAdr *pBlkAdr = WFSKrnGetBlkAdrPtrFromAttrHdrAndIndirectBlkIdxForCategoryVeryLarge(pDi->tba.pAreaInfo, pDi->pAttrHdr, pDi->pAttrHdr->nAttrLog2Size, nK);
|
||||||
|
|
||||||
|
///
|
||||||
|
//pCheckDiskArray[*pBlkAdr/8] |= 1<<(*pBlkAdr%8);
|
||||||
|
SetBit(fh, *pBlkAdr);
|
||||||
|
pDi->tba.nBlkAdr = *pBlkAdr;
|
||||||
|
WFSKrnReturnOnError( DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, (DirBlkHdr**)&pIndirectPtr) );
|
||||||
|
for(nJ=0;nJ<pDi->tba.pAreaInfo->nNumLargeBlkPtrsPerBlk;nJ++){
|
||||||
|
WFSFileLargeBlkPtr *pFileLargeBlkPtr = WFSKrnGetFileLargeBlkPtrFromIndirectBlkForCategoryVeryLarge(pIndirectPtr, nJ);
|
||||||
|
for(nI=0;nI<(1<<pDi->tba.pAreaInfo->nLog2MediumBlkPerLargeBlk);nI++){
|
||||||
|
WFSFileBlkInfo fileBlkInfo = WFSKrnGetFileBlkInfoForCategoryLarge(pDi->tba.pAreaInfo, pFileLargeBlkPtr, nI);
|
||||||
|
//u8 nFlag = 0xff<<(fileBlkInfo.nBlkAdr%8);
|
||||||
|
|
||||||
|
SetBitArray(fh, pBuffer, bufferSize, fileBlkInfo.nBlkAdr, 8); // array!
|
||||||
|
|
||||||
|
/*
|
||||||
|
///
|
||||||
|
pCheckDiskArray[fileBlkInfo.nBlkAdr/8] |= nFlag;
|
||||||
|
nFlag = ~nFlag;
|
||||||
|
if(nFlag){
|
||||||
|
|
||||||
|
///
|
||||||
|
pCheckDiskArray[fileBlkInfo.nBlkAdr/8+1] |= nFlag;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
if(--nNumLargeBlks == 0){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
TransUnpinBlk(&pDi->tba);
|
||||||
|
}
|
||||||
|
pDi->tba.nBlkAdr = nBlkAdr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DirPopNodeStackEntry(&pDi->dni);
|
||||||
|
pDi->dni.nEntryIdx = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
pDi->dni.pOfs = DirLeafGetIntraBlkOfsPtr_l2s((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
SbaCheckOfs(*pDi->dni.pOfs);
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pDi->dni.nEntryIdx == 1 && pDi->dni.pSubBlkHdr->aFirstChar[pDi->dni.pSubBlkHdr->nStrLen] == 0){
|
||||||
|
u32 nNewBlkAdr = DirNodeGetBlkAdr_l2s(pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
|
||||||
|
///
|
||||||
|
//pCheckDiskArray[nNewBlkAdr/8] |= 1<<(nNewBlkAdr%8);
|
||||||
|
SetBit(fh, nNewBlkAdr);
|
||||||
|
|
||||||
|
TransUnpinBlk(&pDi->tba);
|
||||||
|
pDi->tba.nBlkAdr = nNewBlkAdr;
|
||||||
|
WFSKrnReturnOnError( DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr) );
|
||||||
|
pDi->dni.pOfs = &pBlkHdr->nRootOfs;
|
||||||
|
SbaCheckOfs(*pDi->dni.pOfs);
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
if (pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) {
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
} else {
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr_l2s((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
SbaCheckOfs(*pDi->dni.pOfs);
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
}
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
774
trunk/firmware/build/libraries/nfs/common/src/wfskrn_DirFind.cpp
Normal file
774
trunk/firmware/build/libraries/nfs/common/src/wfskrn_DirFind.cpp
Normal file
@ -0,0 +1,774 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_DirFind.cpp - Functions for finding
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_DirFind.cpp,v $
|
||||||
|
Revision 1.15 2008/10/30 04:49:31 kondo_masahiro
|
||||||
|
Deleted the function of DirItrCheckList
|
||||||
|
|
||||||
|
Revision 1.14 2008/10/14 10:27:14 kondo_masahiro
|
||||||
|
Added #define _DEBUG_BREAK_POINT
|
||||||
|
|
||||||
|
Revision 1.13 2008/09/28 23:32:04 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.12 2008/08/27 09:46:48 paul
|
||||||
|
Added pAttrHdr->nAttrLog2Size
|
||||||
|
|
||||||
|
Revision 1.11 2008/08/05 03:58:43 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.10 2008/07/28 22:17:10 paul
|
||||||
|
Improved updateMap processing.
|
||||||
|
|
||||||
|
Revision 1.9 2008/07/25 02:51:28 paul
|
||||||
|
Changed from nTransIdx to *pTransInfo
|
||||||
|
|
||||||
|
Revision 1.8 2008/07/09 00:37:03 paul
|
||||||
|
Changes to make directory code work with block cache.
|
||||||
|
|
||||||
|
Revision 1.7 2008/06/09 17:25:31 paul
|
||||||
|
Fixed a bug in DirFindNext()
|
||||||
|
|
||||||
|
Revision 1.6 2008/05/27 18:44:44 paul
|
||||||
|
Made utf8 variable definitions more consistent, and use (unsigned) for comparisons
|
||||||
|
|
||||||
|
Revision 1.5 2008/05/17 03:54:59 paul
|
||||||
|
Fixed a bug in DirFindNext
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/16 18:42:15 paul
|
||||||
|
Added DirFindNext to allow WFSSrvSearchDirectoryNext to work while adding/deleting files in the directory
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/12 19:13:34 paul
|
||||||
|
Removed dni local variable from DirFind.
|
||||||
|
Made DirFind add pDi to a list of open iterators.
|
||||||
|
|
||||||
|
Revision 1.2 2008/05/10 03:59:44 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/25 17:29:11 kondo_masahiro
|
||||||
|
Initial check-in
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/22 23:28:12 paul
|
||||||
|
WfsArea* -> Area*
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/21 18:58:31 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#undef _KRN_FILE_
|
||||||
|
#define _KRN_FILE_ "DirFind"
|
||||||
|
|
||||||
|
#include "wfskrn_SubBlkAlloc.h"
|
||||||
|
|
||||||
|
#include "wfskrn_Dir.h"
|
||||||
|
#include "wfskrn_DirFind.h"
|
||||||
|
#include "wfskrn_DirNodeStack.h"
|
||||||
|
#include "wfskrn_DirRxTree.h"
|
||||||
|
|
||||||
|
#undef dbg
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
#define dbg(s) s
|
||||||
|
#else
|
||||||
|
#define dbg(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirFind(WFSFileName *pName, DirItr *pDi, u32 nMaxBlkDepth, u32 nMode) {
|
||||||
|
// This function searches for a particular named entry in a directory up to a given max depth.
|
||||||
|
// If the name is found, its location within the appropriate leaf block is returned in pDi, and the function returns WFSKRN_RESULT_DIR_ENTRY_FOUND.
|
||||||
|
// If the name is not found, the location where it should be inserted within the appropriate leaf block, is returned in pDi, and the function returns ....
|
||||||
|
// In addition, if the input name is a prefix of one or more entries in the directory, then the characters beyond the end of the input string
|
||||||
|
// will be filled with the characters of the first matching entry from the directory. This can be used to help implement pattern searches,
|
||||||
|
// or just to get the first entry in a directory (by searching for "").
|
||||||
|
#if _DEBUG_BREAK_POINT
|
||||||
|
static int c=0;++c;if(c>=6979){
|
||||||
|
int a;a=0;
|
||||||
|
}
|
||||||
|
if (nDbgCommandCount==2850){
|
||||||
|
int a;a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
if (nDirTest == nDirTestBreakPoint) {
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
DirBlkHdr *pBlkHdr;
|
||||||
|
WFSKrnReturnOnError(DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr));
|
||||||
|
DirNodeItr dniTemp;
|
||||||
|
utf8 *pStrEnd = pName->sStr + pName->nLen;
|
||||||
|
u32 nStrIdx, nPrefixStrIdx;
|
||||||
|
utf8 *pChoiceStrPtr = pName->sStr; // To keep track of how many characters are common between adjacent splitters when we move to a child block, so that it can implement prefix suppression.
|
||||||
|
utf8 cSubBlkChar, cSearchChar=pChoiceStrPtr[0];
|
||||||
|
u16 *pOfsTblEnd;
|
||||||
|
u32 nSubBlkStrLen;
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
if ((pDi->dni.nDnsDepth == 0) && (pDi->ppDnsRootParent != 0)) {
|
||||||
|
WFSKrnOutputErrorStr("Directory Iterator already opened");
|
||||||
|
}
|
||||||
|
// Check pDi is not already on the open iterator list
|
||||||
|
DirItr *pListDi = dirGlobals.openDirItrListAnchor.pNext;
|
||||||
|
while(pListDi != dirGlobals.pOpenDirItrListAnchor) {
|
||||||
|
if (pListDi == pDi) {
|
||||||
|
WFSKrnOutputErrorStr("pDi already on open iterator list");
|
||||||
|
}
|
||||||
|
if (pListDi->link.pNext->link.pPrev != pListDi) {
|
||||||
|
WFSKrnOutputErrorStr("pDi link error");
|
||||||
|
}
|
||||||
|
pListDi = pListDi->link.pNext;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//MyOSReport("%d: Open(%p)\n", nDirTest, pDi);
|
||||||
|
pDi->link.pNext = dirGlobals.openDirItrListAnchor.pNext;
|
||||||
|
pDi->link.pPrev = dirGlobals.pOpenDirItrListAnchor;
|
||||||
|
dirGlobals.openDirItrListAnchor.pNext->link.pPrev = pDi;
|
||||||
|
dirGlobals.openDirItrListAnchor.pNext = pDi;
|
||||||
|
|
||||||
|
pDi->dni.nDnsDepth = 0;
|
||||||
|
WFSKrnReturnOnError(DirNodeStackGetEntry(&pDi->dni));
|
||||||
|
pDi->ppDnsRootParent = &pDi->dni.pDns->pParent;
|
||||||
|
|
||||||
|
pDi->dni.pDns->nBlkAdr = 0; //tba.nBlkAdr;
|
||||||
|
pDi->dni.pDns->nSubBlkOfs = pBlkHdr->nRootOfs;
|
||||||
|
dbg(SbaCheckOfs(pDi->dni.pDns->nSubBlkOfs));
|
||||||
|
pDi->dni.pDns->nEntryIdx = 1;
|
||||||
|
nPrefixStrIdx=0;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
nStrIdx = nPrefixStrIdx-1;
|
||||||
|
#if DIR_PREFIX_SUPPRESSION
|
||||||
|
pDi->dni.pStrPtr = pChoiceStrPtr; // This should skip any common prefix shared by all file name key fields or splitters in the block
|
||||||
|
#else
|
||||||
|
pDi->dni.pStrPtr = pName->sStr;
|
||||||
|
#endif
|
||||||
|
pDi->dni.pOfs = &pBlkHdr->nRootOfs;
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
if ((pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) || (pDi->nBlkDepth >= nMaxBlkDepth)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++pDi->nBlkDepth;
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
while(1) {
|
||||||
|
nSubBlkStrLen = pDi->dni.pSubBlkHdr->nStrLen;
|
||||||
|
nStrIdx += nSubBlkStrLen + 1;
|
||||||
|
pDi->dni.pNodeStrPtr = pDi->dni.pSubBlkHdr->aFirstChar;
|
||||||
|
if ((pStrEnd - pDi->dni.pStrPtr) < nSubBlkStrLen) {
|
||||||
|
do {
|
||||||
|
cSearchChar = *pDi->dni.pStrPtr++;
|
||||||
|
cSubBlkChar = *pDi->dni.pNodeStrPtr++;
|
||||||
|
} while(cSearchChar == cSubBlkChar);
|
||||||
|
if ((unsigned)cSearchChar < (unsigned)cSubBlkChar) {
|
||||||
|
goto BackTrack;
|
||||||
|
}
|
||||||
|
goto ChooseMaxDescendent;
|
||||||
|
}
|
||||||
|
while(nSubBlkStrLen--) {
|
||||||
|
cSearchChar = *pDi->dni.pStrPtr++;
|
||||||
|
cSubBlkChar = *pDi->dni.pNodeStrPtr++;
|
||||||
|
if (cSearchChar != cSubBlkChar) {
|
||||||
|
if ((unsigned)cSearchChar < (unsigned)cSubBlkChar) {
|
||||||
|
goto BackTrack;
|
||||||
|
}
|
||||||
|
goto ChooseMaxDescendent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// matched all the characters from the prefix. pDi->dni.pNodeStrPtr should now be pointing to the array of choices following the prefix.
|
||||||
|
cSearchChar = *pDi->dni.pStrPtr;
|
||||||
|
pOfsTblEnd = (u16*)((u8*)pDi->dni.pSubBlkHdr + (1<<pDi->dni.nLog2Size));
|
||||||
|
|
||||||
|
WFSBool bFound = DirBinarySplitSearchChoices(pDi->dni.pNodeStrPtr, pDi->dni.pSubBlkHdr->nNumEntries, cSearchChar, &pDi->dni.nEntryIdx);
|
||||||
|
#if DIR_PREFIX_SUPPRESSION
|
||||||
|
if ((pDi->dni.nEntryIdx>=1) && (pDi->dni.nEntryIdx < pDi->dni.pSubBlkHdr->nNumEntries)) {
|
||||||
|
// ToDo: Implement prefix suppression
|
||||||
|
nPrefixStrIdx = nStrIdx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
if (bFound) {
|
||||||
|
// Found the search character.
|
||||||
|
pDi->dni.pDns->nStrIdx = (u8)nStrIdx;
|
||||||
|
if (cSearchChar==0) {
|
||||||
|
// We matched a 0 .. means the file name matched one of the splitters exactly
|
||||||
|
// This may still be a valid file name.
|
||||||
|
// Note: A splitter can be arbitrary. It does not even have to be a prefix of an existing file name.
|
||||||
|
// (This can happen after deleting the filename which was originally chosen as a split point).
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pDi->dni.pSubBlkHdr->nNumEntries>1) {
|
||||||
|
if (pDi->dni.nEntryIdx>1) {
|
||||||
|
// Update the previous record information
|
||||||
|
dniTemp = pDi->dni;
|
||||||
|
--dniTemp.nEntryIdx;
|
||||||
|
}
|
||||||
|
pChoiceStrPtr = pDi->dni.pStrPtr;
|
||||||
|
}
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr_ote((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pOfsTblEnd);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
++pDi->dni.pStrPtr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDi->dni.nEntryIdx==0) {
|
||||||
|
// The binary split search determined that the search character was smaller than the smallest choice
|
||||||
|
BackTrack:
|
||||||
|
while(pDi->dni.pDns != dniTemp.pDns) {
|
||||||
|
DirPopNodeStackEntry(&pDi->dni);
|
||||||
|
};
|
||||||
|
pDi->dni = dniTemp;
|
||||||
|
pDi->dni.pDns->nEntryIdx = pDi->dni.nEntryIdx;
|
||||||
|
nStrIdx = (u32)(pDi->dni.pDns->nStrIdx);// + pDi->dni.pSubBlkHdr->nStrLen + 1);
|
||||||
|
pChoiceStrPtr = pDi->dni.pStrPtr;
|
||||||
|
pOfsTblEnd = (u16*)((u8*)pDi->dni.pSubBlkHdr + (1<<pDi->dni.nLog2Size));
|
||||||
|
pDi->dni.pNodeStrPtr = &pDi->dni.pSubBlkHdr->aFirstChar[pDi->dni.pSubBlkHdr->nStrLen];
|
||||||
|
}
|
||||||
|
pDi->dni.pDns->nStrIdx = (u8)nStrIdx;
|
||||||
|
if ((pDi->dni.nEntryIdx==1)&&(pDi->dni.pNodeStrPtr[0]==0)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Offset is an intra block offset
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr_ote((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pOfsTblEnd);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
nStrIdx += pDi->dni.pSubBlkHdr->nStrLen + 1;
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
ChooseMaxDescendent:
|
||||||
|
// Follow intra block offsets until max splitter end is encountered
|
||||||
|
if (pDi->dni.pSubBlkHdr->nNumEntries > 1) {
|
||||||
|
while(1) {
|
||||||
|
pDi->dni.nEntryIdx = pDi->dni.pSubBlkHdr->nNumEntries;
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
nStrIdx += pDi->dni.pSubBlkHdr->nStrLen;
|
||||||
|
pDi->dni.pDns->nStrIdx = (u8)nStrIdx;
|
||||||
|
if (pDi->dni.pSubBlkHdr->nNumEntries == 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++nStrIdx;
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr_l2s(pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
};
|
||||||
|
pOfsTblEnd = (u16*)((u8*)pDi->dni.pSubBlkHdr + (1<<pDi->dni.nLog2Size));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// we should now be at the end of the line
|
||||||
|
pOfsTblEnd = (u16*)((u8*)pDi->dni.pSubBlkHdr + (1<<pDi->dni.nLog2Size));
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
pDi->dni.pDns->nStrIdx = nStrIdx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nMode == DIR_FIND_MODE_NODE_SEARCH) {
|
||||||
|
if (pDi->nBlkDepth >= nMaxBlkDepth) {
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
u32 nNewBlkAdr = DirNodeGetBlkAdr_ote(pDi->dni.pSubBlkHdr, pOfsTblEnd);
|
||||||
|
TransUnpinBlk(&pDi->tba);
|
||||||
|
pDi->tba.nBlkAdr = nNewBlkAdr;
|
||||||
|
WFSKrnExitOnError( DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (DIR_PREFIX_SUPPRESSION==0)
|
||||||
|
// ToDo: Prefix suppression not yet implemented
|
||||||
|
pDi->dni.pStrPtr = pName->sStr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Search the leaf node
|
||||||
|
if (pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) {
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
} else {
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
}
|
||||||
|
while(1) {
|
||||||
|
nSubBlkStrLen = pDi->dni.pSubBlkHdr->nStrLen;
|
||||||
|
nStrIdx += nSubBlkStrLen + 1;
|
||||||
|
pDi->dni.pNodeStrPtr = pDi->dni.pSubBlkHdr->aFirstChar;
|
||||||
|
if ((pStrEnd - pDi->dni.pStrPtr) < nSubBlkStrLen) {
|
||||||
|
while(*pDi->dni.pStrPtr == *pDi->dni.pNodeStrPtr) {
|
||||||
|
++pDi->dni.pStrPtr; ++pDi->dni.pNodeStrPtr;
|
||||||
|
}
|
||||||
|
nSubBlkStrLen -= (pDi->dni.pNodeStrPtr - pDi->dni.pSubBlkHdr->aFirstChar);
|
||||||
|
nResult = WFSKRN_RESULT_DIR_NODE_STRING_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while((nSubBlkStrLen) && (*pDi->dni.pStrPtr == *pDi->dni.pNodeStrPtr)) {
|
||||||
|
++pDi->dni.pStrPtr; ++pDi->dni.pNodeStrPtr; --nSubBlkStrLen;
|
||||||
|
}
|
||||||
|
if (nSubBlkStrLen) {
|
||||||
|
nResult = WFSKRN_RESULT_DIR_NODE_STRING_MISMATCH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// matched all the characters from the prefix. pDi->dni.pNodeStrPtr should now be pointing to the array of choices following the prefix.
|
||||||
|
cSearchChar = *pDi->dni.pStrPtr;
|
||||||
|
if (!DirBinarySplitSearchChoices(pDi->dni.pNodeStrPtr, pDi->dni.pSubBlkHdr->nNumEntries, cSearchChar, &pDi->dni.nEntryIdx)) {
|
||||||
|
nResult = WFSKRN_RESULT_DIR_NODE_CHOICE_NOT_FOUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
pDi->dni.pDns->nStrIdx = nStrIdx;
|
||||||
|
// Found the search character.
|
||||||
|
if (cSearchChar==0) {
|
||||||
|
// We matched a 0 .. which means we have found the filename
|
||||||
|
nResult = WFSKRN_RESULT_DIR_ENTRY_FOUND;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) {
|
||||||
|
pDi->dni.pOfs = DirLeafGetIntraBlkOfsPtr_l2s((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
} else {
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr_l2s((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
}
|
||||||
|
++pDi->dni.pStrPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the location passed back to the caller
|
||||||
|
pDi->pBlkHdr = pBlkHdr;
|
||||||
|
|
||||||
|
if ((*pDi->dni.pStrPtr) || (pBlkHdr->nNumRecs==0) || (!(pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK))) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nResult == WFSKRN_RESULT_DIR_ENTRY_FOUND) {
|
||||||
|
goto GetAttr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nMode != DIR_FIND_MODE_PREFIX_SEARCH) {
|
||||||
|
goto Done;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nResult == WFSKRN_RESULT_DIR_NODE_STRING_MISMATCH) {
|
||||||
|
nResult = WFSKRN_RESULT_DIR_NODE_STRING_PREFIX;
|
||||||
|
} else {
|
||||||
|
nResult = WFSKRN_RESULT_DIR_CHOICE_PREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The exact name was not found, but it was a prefix of one or more exising names.
|
||||||
|
// We continue traversing to find the left-most descendent.
|
||||||
|
// This is useful for iterating through the directory, and wildcard pattern search.
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
while(1) {
|
||||||
|
while(nSubBlkStrLen--) {
|
||||||
|
*pDi->dni.pStrPtr++ = *pDi->dni.pNodeStrPtr++;
|
||||||
|
}
|
||||||
|
//if (pDi->dni.pSubBlkHdr->nNumEntries > 1) {
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
pDi->dni.pDns->nStrIdx = nStrIdx;
|
||||||
|
//}
|
||||||
|
cSubBlkChar = pDi->dni.pSubBlkHdr->aFirstChar[pDi->dni.pSubBlkHdr->nStrLen];
|
||||||
|
*pDi->dni.pStrPtr++ = cSubBlkChar;
|
||||||
|
if (cSubBlkChar==0) {
|
||||||
|
//pDi->dni = pDi->dni;
|
||||||
|
pName->nLen = nStrIdx;
|
||||||
|
goto GetAttr;
|
||||||
|
}
|
||||||
|
pOfsTblEnd = (u16*)((u8*)pDi->dni.pSubBlkHdr + (1<<pDi->dni.nLog2Size));
|
||||||
|
pDi->dni.pOfs = &pOfsTblEnd[-1];
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
nSubBlkStrLen = pDi->dni.pSubBlkHdr->nStrLen;
|
||||||
|
nStrIdx += nSubBlkStrLen + 1;
|
||||||
|
pDi->dni.pNodeStrPtr = pDi->dni.pSubBlkHdr->aFirstChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetAttr:
|
||||||
|
pDi->dni.pOfs = DirLeafGetIntraBlkOfsPtr_l2s(1, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
pDi->pAttrHdr = (DirEntryAttrHdr *)((u8*)pDi->pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = pDi->pAttrHdr->nAttrLog2Size;
|
||||||
|
Done:
|
||||||
|
return nResult;
|
||||||
|
Exit:
|
||||||
|
pDi->pBlkHdr = pBlkHdr;
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirFindNext(WFSFileName *pName, DirItr *pDi) {
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
if (nDirTest == nDirTestBreakPoint) {
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
DirBlkHdr *pBlkHdr;
|
||||||
|
WFSKrnReturnOnError( DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr) );
|
||||||
|
DirNodeItr dniPrev, dniNext;
|
||||||
|
utf8 *pStrEnd = pName->sStr + pName->nLen;
|
||||||
|
u32 nStrIdx, nPrefixStrIdx;
|
||||||
|
utf8 *pChoiceStrPtr = pName->sStr; // To keep track of how many characters are common between adjacent splitters when we move to a child block, so that it can implement prefix suppression.
|
||||||
|
utf8 cSubBlkChar, cSearchChar=pChoiceStrPtr[0];
|
||||||
|
u16 *pOfsTblEnd;
|
||||||
|
u32 nSubBlkStrLen;
|
||||||
|
WFSKrnResult nResult = WFSKRN_RESULT_OK;
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
if ((pDi->dni.nDnsDepth == 0) && (pDi->ppDnsRootParent != 0)) {
|
||||||
|
WFSKrnOutputErrorStr("Directory Iterator already opened");
|
||||||
|
}
|
||||||
|
// Check pDi is not already on the open iterator list
|
||||||
|
DirItr *pListDi = dirGlobals.openDirItrListAnchor.pNext;
|
||||||
|
while(pListDi != dirGlobals.pOpenDirItrListAnchor) {
|
||||||
|
if (pListDi == pDi) {
|
||||||
|
WFSKrnOutputErrorStr("pDi already on open iterator list");
|
||||||
|
}
|
||||||
|
if (pListDi->link.pNext->link.pPrev != pListDi) {
|
||||||
|
WFSKrnOutputErrorStr("pDi link error");
|
||||||
|
}
|
||||||
|
pListDi = pListDi->link.pNext;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
//MyOSReport("%d: Open(%p)\n", nDirTest, pDi);
|
||||||
|
pDi->link.pNext = dirGlobals.openDirItrListAnchor.pNext;
|
||||||
|
pDi->link.pPrev = dirGlobals.pOpenDirItrListAnchor;
|
||||||
|
dirGlobals.openDirItrListAnchor.pNext->link.pPrev = pDi;
|
||||||
|
dirGlobals.openDirItrListAnchor.pNext = pDi;
|
||||||
|
|
||||||
|
pDi->dni.nDnsDepth = 0;
|
||||||
|
WFSKrnReturnOnError(DirNodeStackGetEntry(&pDi->dni));
|
||||||
|
pDi->ppDnsRootParent = &pDi->dni.pDns->pParent;
|
||||||
|
|
||||||
|
pDi->dni.pDns->nBlkAdr = 0; //tba.nBlkAdr;
|
||||||
|
pDi->dni.pDns->nSubBlkOfs = pBlkHdr->nRootOfs;
|
||||||
|
dbg(SbaCheckOfs(pDi->dni.pDns->nSubBlkOfs));
|
||||||
|
pDi->dni.pDns->nEntryIdx = 1;
|
||||||
|
nPrefixStrIdx = 0;
|
||||||
|
dniNext.nEntryIdx = 0;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
nStrIdx = nPrefixStrIdx-1;
|
||||||
|
#if DIR_PREFIX_SUPPRESSION
|
||||||
|
pDi->dni.pStrPtr = pChoiceStrPtr; // This should skip any common prefix shared by all file name key fields or splitters in the block
|
||||||
|
#else
|
||||||
|
pDi->dni.pStrPtr = pName->sStr;
|
||||||
|
#endif
|
||||||
|
pDi->dni.pOfs = &pBlkHdr->nRootOfs;
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
if (pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
/*if (nDirTest == nDirTestBreakPoint) {
|
||||||
|
nDirTest = nDirTestBreakPoint;
|
||||||
|
pDi->pBlkHdr = pBlkHdr;
|
||||||
|
DirNodeCheckBlk(pDi);
|
||||||
|
}*/
|
||||||
|
#endif
|
||||||
|
++pDi->nBlkDepth;
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
while(1) {
|
||||||
|
nSubBlkStrLen = pDi->dni.pSubBlkHdr->nStrLen;
|
||||||
|
nStrIdx += nSubBlkStrLen + 1;
|
||||||
|
pDi->dni.pNodeStrPtr = pDi->dni.pSubBlkHdr->aFirstChar;
|
||||||
|
if ((pStrEnd - pDi->dni.pStrPtr) < nSubBlkStrLen) {
|
||||||
|
do {
|
||||||
|
cSearchChar = *pDi->dni.pStrPtr++;
|
||||||
|
cSubBlkChar = *pDi->dni.pNodeStrPtr++;
|
||||||
|
} while(cSearchChar == cSubBlkChar);
|
||||||
|
if ((unsigned)cSearchChar < (unsigned)cSubBlkChar) {
|
||||||
|
goto BackTrackNodePrev;
|
||||||
|
}
|
||||||
|
goto ChooseMaxDescendent;
|
||||||
|
}
|
||||||
|
while(nSubBlkStrLen--) {
|
||||||
|
cSearchChar = *pDi->dni.pStrPtr++;
|
||||||
|
cSubBlkChar = *pDi->dni.pNodeStrPtr++;
|
||||||
|
if (cSearchChar != cSubBlkChar) {
|
||||||
|
if ((unsigned)cSearchChar < (unsigned)cSubBlkChar) {
|
||||||
|
goto BackTrackNodePrev;
|
||||||
|
}
|
||||||
|
goto ChooseMaxDescendent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// matched all the characters from the prefix. pDi->dni.pNodeStrPtr should now be pointing to the array of choices following the prefix.
|
||||||
|
cSearchChar = *pDi->dni.pStrPtr;
|
||||||
|
pOfsTblEnd = (u16*)((u8*)pDi->dni.pSubBlkHdr + (1<<pDi->dni.nLog2Size));
|
||||||
|
|
||||||
|
WFSBool bFound = DirBinarySplitSearchChoices(pDi->dni.pNodeStrPtr, pDi->dni.pSubBlkHdr->nNumEntries, cSearchChar, &pDi->dni.nEntryIdx);
|
||||||
|
#if DIR_PREFIX_SUPPRESSION
|
||||||
|
if ((pDi->dni.nEntryIdx>=1) && (pDi->dni.nEntryIdx < pDi->dni.pSubBlkHdr->nNumEntries)) {
|
||||||
|
// ToDo: Implement prefix suppression
|
||||||
|
nPrefixStrIdx = nStrIdx;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
if (pDi->dni.nEntryIdx < pDi->dni.pSubBlkHdr->nNumEntries) {
|
||||||
|
dniNext = pDi->dni;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bFound) {
|
||||||
|
// Found the search character.
|
||||||
|
pDi->dni.pDns->nStrIdx = (u8)nStrIdx;
|
||||||
|
if (cSearchChar==0) {
|
||||||
|
// We matched a 0 .. means the file name matched one of the splitters exactly
|
||||||
|
// This may still be a valid file name.
|
||||||
|
// Note: A splitter can be arbitrary. It does not even have to be a prefix of an existing file name.
|
||||||
|
// (This can happen after deleting the filename which was originally chosen as a split point).
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pDi->dni.pSubBlkHdr->nNumEntries>1) {
|
||||||
|
if (pDi->dni.nEntryIdx>1) {
|
||||||
|
// Update the previous record information
|
||||||
|
dniPrev = pDi->dni;
|
||||||
|
}
|
||||||
|
pChoiceStrPtr = pDi->dni.pStrPtr;
|
||||||
|
}
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr_ote((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pOfsTblEnd);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
++pDi->dni.pStrPtr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pDi->dni.nEntryIdx==0) {
|
||||||
|
// The binary split search determined that the search character was smaller than the smallest choice
|
||||||
|
BackTrackNodePrev:
|
||||||
|
while(pDi->dni.pDns != dniPrev.pDns) {
|
||||||
|
DirPopNodeStackEntry(&pDi->dni);
|
||||||
|
};
|
||||||
|
pDi->dni = dniPrev;
|
||||||
|
pDi->dni.pDns->nEntryIdx = --pDi->dni.nEntryIdx;
|
||||||
|
dniNext = pDi->dni;
|
||||||
|
nStrIdx = (u32)(pDi->dni.pDns->nStrIdx);// + pDi->dni.pSubBlkHdr->nStrLen + 1);
|
||||||
|
pChoiceStrPtr = pDi->dni.pStrPtr;
|
||||||
|
pOfsTblEnd = (u16*)((u8*)pDi->dni.pSubBlkHdr + (1<<pDi->dni.nLog2Size));
|
||||||
|
pDi->dni.pNodeStrPtr = &pDi->dni.pSubBlkHdr->aFirstChar[pDi->dni.pSubBlkHdr->nStrLen];
|
||||||
|
}
|
||||||
|
pDi->dni.pDns->nStrIdx = (u8)nStrIdx;
|
||||||
|
if ((pDi->dni.nEntryIdx==1)&&(pDi->dni.pNodeStrPtr[0]==0)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Offset is an intra block offset
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr_ote((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pOfsTblEnd);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
nStrIdx += pDi->dni.pSubBlkHdr->nStrLen + 1;
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
ChooseMaxDescendent:
|
||||||
|
// Follow intra block offsets until max splitter end is encountered
|
||||||
|
if (pDi->dni.pSubBlkHdr->nNumEntries > 1) {
|
||||||
|
while(1) {
|
||||||
|
pDi->dni.nEntryIdx = pDi->dni.pSubBlkHdr->nNumEntries;
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
nStrIdx += pDi->dni.pSubBlkHdr->nStrLen;
|
||||||
|
pDi->dni.pDns->nStrIdx = (u8)nStrIdx;
|
||||||
|
if (pDi->dni.pSubBlkHdr->nNumEntries == 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++nStrIdx;
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr_l2s(pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirNodeGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
};
|
||||||
|
pOfsTblEnd = (u16*)((u8*)pDi->dni.pSubBlkHdr + (1<<pDi->dni.nLog2Size));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// we should now be at the end of the line
|
||||||
|
pOfsTblEnd = (u16*)((u8*)pDi->dni.pSubBlkHdr + (1<<pDi->dni.nLog2Size));
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
pDi->dni.pDns->nStrIdx = nStrIdx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
u32 nNewBlkAdr = DirNodeGetBlkAdr_ote(pDi->dni.pSubBlkHdr, pOfsTblEnd);
|
||||||
|
TransUnpinBlk(&pDi->tba);
|
||||||
|
pDi->tba.nBlkAdr = nNewBlkAdr;
|
||||||
|
WFSKrnExitOnError( DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if (DIR_PREFIX_SUPPRESSION==0)
|
||||||
|
// ToDo: Prefix suppression not yet implemented
|
||||||
|
pDi->dni.pStrPtr = pName->sStr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
/*if (nDirTest == nDirTestBreakPoint) {
|
||||||
|
pDi->pBlkHdr = pBlkHdr;
|
||||||
|
DirLeafCheckBlk(pDi);
|
||||||
|
}*/
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Search the leaf node
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
while(1) {
|
||||||
|
nSubBlkStrLen = pDi->dni.pSubBlkHdr->nStrLen;
|
||||||
|
nStrIdx += nSubBlkStrLen + 1;
|
||||||
|
pDi->dni.pNodeStrPtr = pDi->dni.pSubBlkHdr->aFirstChar;
|
||||||
|
if ((pStrEnd - pDi->dni.pStrPtr) < nSubBlkStrLen) {
|
||||||
|
while(*pDi->dni.pStrPtr == *pDi->dni.pNodeStrPtr) {
|
||||||
|
++pDi->dni.pStrPtr; ++pDi->dni.pNodeStrPtr;
|
||||||
|
}
|
||||||
|
nSubBlkStrLen -= (pDi->dni.pNodeStrPtr - pDi->dni.pSubBlkHdr->aFirstChar);
|
||||||
|
} else {
|
||||||
|
while((nSubBlkStrLen) && (*pDi->dni.pStrPtr == *pDi->dni.pNodeStrPtr)) {
|
||||||
|
++pDi->dni.pStrPtr; ++pDi->dni.pNodeStrPtr; --nSubBlkStrLen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nSubBlkStrLen) {
|
||||||
|
if (*pDi->dni.pStrPtr > *pDi->dni.pNodeStrPtr) {
|
||||||
|
goto BackTrack;
|
||||||
|
}
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
goto ChooseMinDescendentLeaf;
|
||||||
|
}
|
||||||
|
// matched all the characters from the prefix. pDi->dni.pNodeStrPtr should now be pointing to the array of choices following the prefix.
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
pDi->dni.pDns->nStrIdx = nStrIdx;
|
||||||
|
cSearchChar = *pDi->dni.pStrPtr;
|
||||||
|
if (DirBinarySplitSearchChoices(pDi->dni.pNodeStrPtr, pDi->dni.pSubBlkHdr->nNumEntries, cSearchChar, &pDi->dni.nEntryIdx)) {
|
||||||
|
pDi->dni.pDns->nEntryIdx = pDi->dni.nEntryIdx;
|
||||||
|
if (pDi->dni.nEntryIdx < pDi->dni.pSubBlkHdr->nNumEntries) {
|
||||||
|
dniNext = pDi->dni;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//*pDi->dni.pStrPtr++ = pDi->dni.pNodeStrPtr[pDi->dni.nEntryIdx];
|
||||||
|
pDi->dni.pNodeStrPtr += pDi->dni.nEntryIdx;
|
||||||
|
++pDi->dni.nEntryIdx;
|
||||||
|
if (pDi->dni.nEntryIdx > pDi->dni.pSubBlkHdr->nNumEntries) {
|
||||||
|
goto BackTrack;
|
||||||
|
}
|
||||||
|
goto ChooseMinDescendentLeaf;
|
||||||
|
}
|
||||||
|
// Found the search character.
|
||||||
|
if (cSearchChar==0) {
|
||||||
|
// We matched a 0 .. which means we have found the filename
|
||||||
|
// However an exact match is not what we are looking for. We want the next entry.
|
||||||
|
BackTrack:
|
||||||
|
if (dniNext.nEntryIdx == 0) {
|
||||||
|
nResult = WFSKRN_RESULT_NOT_FOUND;
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
nResult = WFSKRN_RESULT_DIR_ENTRY_FOUND;
|
||||||
|
//WFSBlkAdr nLeafBlkAdr = pDi->dni.pDns->nBlkAdr;
|
||||||
|
while(pDi->dni.pDns != dniNext.pDns) {
|
||||||
|
DirPopNodeStackEntry(&pDi->dni);
|
||||||
|
}
|
||||||
|
pDi->dni = dniNext;
|
||||||
|
if (pDi->tba.nBlkAdr != dniNext.pDns->nBlkAdr) {
|
||||||
|
// We have back tracked to a previous node
|
||||||
|
TransUnpinBlk(&pDi->tba);
|
||||||
|
pDi->tba.nBlkAdr = dniNext.pDns->nBlkAdr;
|
||||||
|
WFSKrnExitOnError( DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr) );
|
||||||
|
++pDi->dni.pDns->nEntryIdx;
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr(pDi->dni.pDns->nEntryIdx, pDi->dni.pSubBlkHdr);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.nEntryIdx=1;
|
||||||
|
do {
|
||||||
|
while(1) {
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
if (pDi->dni.pSubBlkHdr->aFirstChar[pDi->dni.pSubBlkHdr->nStrLen] == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pDi->dni.pOfs = DirNodeGetIntraBlkOfsPtr(pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
WFSBlkAdr nNewBlkAdr = DirNodeGetBlkAdr(pDi->dni.pSubBlkHdr);
|
||||||
|
TransUnpinBlk(&pDi->tba);
|
||||||
|
pDi->tba.nBlkAdr = nNewBlkAdr;
|
||||||
|
WFSKrnExitOnError( DirGetBlk(pDi, TRANS_FLAG_READ_BLK | BCACHE_FLAG_PINNED, &pBlkHdr) );
|
||||||
|
}
|
||||||
|
DirCheckBlk(pDi);
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
/*if (nDirTest == nDirTestBreakPoint) {
|
||||||
|
pDi->pBlkHdr = pBlkHdr;
|
||||||
|
DirCheckBlk(pDi);
|
||||||
|
}*/
|
||||||
|
#endif
|
||||||
|
pDi->dni.pOfs = &pBlkHdr->nRootOfs;
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
} while(!(pBlkHdr->sbah.mdh.nFlags & WFS_MDF_DIR_LEAF_BLK));
|
||||||
|
nStrIdx = (u32)-1;
|
||||||
|
pDi->dni.pStrPtr = pName->sStr;
|
||||||
|
} else {
|
||||||
|
nStrIdx = dniNext.pDns->nStrIdx;
|
||||||
|
*pDi->dni.pStrPtr++ = pDi->dni.pNodeStrPtr[dniNext.nEntryIdx];
|
||||||
|
++dniNext.nEntryIdx;
|
||||||
|
pDi->dni.pOfs = DirLeafGetIntraBlkOfsPtr(dniNext.nEntryIdx, pDi->dni.pSubBlkHdr);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
}
|
||||||
|
nSubBlkStrLen = pDi->dni.pSubBlkHdr->nStrLen;
|
||||||
|
nStrIdx += nSubBlkStrLen + 1;
|
||||||
|
pDi->dni.pNodeStrPtr = pDi->dni.pSubBlkHdr->aFirstChar;
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
|
||||||
|
ChooseMinDescendentLeaf:
|
||||||
|
++nSubBlkStrLen;
|
||||||
|
while(1) {
|
||||||
|
memcpy(pDi->dni.pStrPtr, pDi->dni.pNodeStrPtr, nSubBlkStrLen);
|
||||||
|
pDi->dni.pStrPtr += nSubBlkStrLen;
|
||||||
|
if(pDi->dni.pDns->nBlkAdr != pDi->tba.nBlkAdr || pDi->dni.pDns->nSubBlkOfs != *pDi->dni.pOfs){
|
||||||
|
WFSKrnReturnOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
} else {
|
||||||
|
pDi->dni.pDns->nEntryIdx = (u8)pDi->dni.nEntryIdx;
|
||||||
|
}
|
||||||
|
//WFSKrnExitOnError(DirPushNodeStackEntry(&pDi->dni, pDi->tba.nBlkAdr));
|
||||||
|
pDi->dni.pDns->nUpdateCtr = pDi->nUpdateCtr;
|
||||||
|
pDi->dni.pDns->nStrIdx = (u8)nStrIdx;
|
||||||
|
pDi->dni.pOfs = DirLeafGetIntraBlkOfsPtr(pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
if (pDi->dni.pNodeStrPtr[nSubBlkStrLen-1] == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.pNodeStrPtr = pDi->dni.pSubBlkHdr->aFirstChar;
|
||||||
|
nSubBlkStrLen = pDi->dni.pSubBlkHdr->nStrLen + 1;
|
||||||
|
nStrIdx += nSubBlkStrLen;
|
||||||
|
pDi->dni.nEntryIdx = 1;
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pDi->dni.pOfs = DirLeafGetIntraBlkOfsPtr_l2s((s32)pDi->dni.nEntryIdx, pDi->dni.pSubBlkHdr, pDi->dni.nLog2Size);
|
||||||
|
dbg(SbaCheckOfs(*pDi->dni.pOfs));
|
||||||
|
pDi->dni.pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->dni.nLog2Size = DirLeafGetSubBlkLog2Size(pDi->dni.pSubBlkHdr);
|
||||||
|
++pDi->dni.pStrPtr;
|
||||||
|
}
|
||||||
|
pDi->pAttrHdr = (DirEntryAttrHdr*)((u8*)pBlkHdr + *pDi->dni.pOfs);
|
||||||
|
pDi->name.nLen = nStrIdx;
|
||||||
|
Exit:
|
||||||
|
pDi->pBlkHdr = pBlkHdr;
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
@ -0,0 +1,418 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_DirNodeStack.cpp
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_DirNodeStack.cpp,v $
|
||||||
|
Revision 1.8 2008/10/16 09:30:39 ooizumi
|
||||||
|
Fixed definitions for debug build.
|
||||||
|
|
||||||
|
Revision 1.7 2008/10/14 10:27:14 kondo_masahiro
|
||||||
|
Added #define _DEBUG_BREAK_POINT
|
||||||
|
|
||||||
|
Revision 1.6 2008/09/28 23:32:04 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.5 2008/08/05 03:58:31 kondo_masahiro
|
||||||
|
Added error handling for hash error and detach device.
|
||||||
|
|
||||||
|
Revision 1.4 2008/07/09 00:37:52 paul
|
||||||
|
Changes to make directory code work with block cache.
|
||||||
|
|
||||||
|
Revision 1.3 2008/05/10 03:59:44 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 17:29:50 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.10 2008/04/23 01:56:07 paul
|
||||||
|
Fixed bCheckDirNodeStack to be visible from wfskrn_Dir.cpp
|
||||||
|
|
||||||
|
Revision 1.9 2008/04/22 22:12:40 paul
|
||||||
|
Changed WFSArea* to Area*
|
||||||
|
|
||||||
|
Revision 1.8 2008/04/19 05:50:51 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.7 2008/04/15 18:45:09 paul
|
||||||
|
Added some debug code to output calling locations for NodeStack functions
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/04 22:53:33 paul
|
||||||
|
Changed debug triggers to use bCheckDirNodeStack
|
||||||
|
|
||||||
|
Revision 1.5 2008/04/04 21:16:33 paul
|
||||||
|
Fixed loop-detecting code
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/03 23:38:31 kondo_masahiro
|
||||||
|
change name of debug parameter
|
||||||
|
|
||||||
|
Revision 1.3 2008/03/05 11:02:13 paul
|
||||||
|
Changed stack checking functions to not allocate memory
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/28 06:31:49 kondo_masahiro
|
||||||
|
Fixed code to accept PPC compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/27 09:46:53 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/27 00:38:44 paul
|
||||||
|
Updated debug code
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/21 04:35:34 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#undef _KRN_FILE_
|
||||||
|
#define _KRN_FILE_ "DirNS"
|
||||||
|
|
||||||
|
#include "wfskrn_DirNodeStack.h"
|
||||||
|
#include "wfskrn_Mutex.h"
|
||||||
|
#include "wfskrn_Api.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
#define dbg_check(s) s
|
||||||
|
#define dbg_output(s)
|
||||||
|
#else
|
||||||
|
#define dbg_check(s)
|
||||||
|
#define dbg_output(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
bool bCheckDirNodeStack = false; // extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
WFSKrnMutex mxMutex;
|
||||||
|
dbg_check(u32 nTotalAllocated;)
|
||||||
|
dbg_check(u32 nNumUsed;)
|
||||||
|
u32 nNumFreeDnsPoolEntries;
|
||||||
|
DirNodeStack *pDnsPoolFreeList;
|
||||||
|
} DirNodeStackGlobals;
|
||||||
|
|
||||||
|
DirNodeStackGlobals dnsg;
|
||||||
|
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
void DebugCheckNumFreeDnsPoolEntries(char *str) {
|
||||||
|
static u32 nPrev=0;
|
||||||
|
char *s; s = str; // for warning
|
||||||
|
if (nPrev != dnsg.nNumFreeDnsPoolEntries) {
|
||||||
|
nPrev = dnsg.nNumFreeDnsPoolEntries;
|
||||||
|
dbg_output(MyOSReport("%s: dnsg.nNumFreeDnsPoolEntries=%d\n", str, dnsg.nNumFreeDnsPoolEntries));
|
||||||
|
if ((dnsg.nNumFreeDnsPoolEntries!=WFS_DIR_NODE_STACK_ENTRY_POOL_ALLOC_UNIT)&&
|
||||||
|
(dnsg.nNumFreeDnsPoolEntries!=(WFS_DIR_NODE_STACK_ENTRY_POOL_ALLOC_UNIT*2))) {
|
||||||
|
//int a=0; // for warning
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif //_DEBUG_DIR
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
|
||||||
|
DirNodeStack *pDebugLastNodeStackAlloc;
|
||||||
|
u32 nDebugCountNodeStackCheckAlloc = 0;
|
||||||
|
u32 nDebugCountNodeStackCheckFreeList = 0;
|
||||||
|
|
||||||
|
static
|
||||||
|
void DirNodeStackCheckAlloc(DirNodeItr *pDni) {
|
||||||
|
nDebugCountNodeStackCheckAlloc++;
|
||||||
|
dbg_output(MyOSReport("%d. ", nDebugCountNodeStackCheckAlloc));
|
||||||
|
DirNodeStack *pDns = pDni->pDns;
|
||||||
|
u32 nI;
|
||||||
|
for(nI=pDni->nDnsDepth; --nI; ) {
|
||||||
|
//s32 nIdx = pDns-pDebugLastNodeStackAlloc; // unused
|
||||||
|
dbg_output(MyOSReport("%d,", nIdx));
|
||||||
|
if ((u32)pDns==0xbaadf00d) {
|
||||||
|
WFSKrnOutputErrorStr("DirNodeStack Error! Bad entry!\n");
|
||||||
|
}
|
||||||
|
DirNodeStack *pDns2 = pDns;
|
||||||
|
u32 nJ;
|
||||||
|
for(nJ=nI; --nJ; ) {
|
||||||
|
pDns2 = pDns2->pParent;
|
||||||
|
if (pDns2 == pDns) {
|
||||||
|
WFSKrnOutputErrorStr("DirNodeStack Error! Same entry appears twice!\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//u32 nOfs = pDns->nSubBlkOfs; // unused
|
||||||
|
//u32 nBlkAdr = pDns->nBlkAdr;
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
/*if ((nI>1) && (pDns->nSubBlkOfs == nOfs) && (pDns->nBlkAdr == nBlkAdr)) {
|
||||||
|
WFSKrnOutputErrorStr("DirNodeStack Error! Same offset repeats!\n");
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
dbg_output(MyOSReport(": "));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirNodeStackCheckFreeList() {
|
||||||
|
nDebugCountNodeStackCheckFreeList++;
|
||||||
|
DirNodeStack *pDns = dnsg.pDnsPoolFreeList;
|
||||||
|
u32 nI;
|
||||||
|
for(nI=0; nI<dnsg.nNumFreeDnsPoolEntries; nI++) {
|
||||||
|
//s32 nIdx = pDns-pDebugLastNodeStackAlloc; // unused
|
||||||
|
dbg_output(MyOSReport("%d,", nIdx));
|
||||||
|
if ((u32)pDns==0xbaadf00d) {
|
||||||
|
WFSKrnOutputErrorStr("DirNodeStack Error! Bad entry on free list!\n");
|
||||||
|
}
|
||||||
|
DirNodeStack *pDns2 = dnsg.pDnsPoolFreeList;
|
||||||
|
u32 nJ;
|
||||||
|
for(nJ=0; nJ<nI; nJ++) {
|
||||||
|
if (pDns2 == pDns) {
|
||||||
|
WFSKrnOutputErrorStr("DirNodeStack Error! Same entry appears twice on free list!\n");
|
||||||
|
}
|
||||||
|
pDns2 = pDns2->pParent;
|
||||||
|
}
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
}
|
||||||
|
dbg_output(MyOSReport("\n"));
|
||||||
|
//WFSKrnHeapFree(&wkg.heap, ppDns);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //_DEBUG_DIR_NODE_STACK
|
||||||
|
|
||||||
|
|
||||||
|
WFSKrnResult DirAllocateMoreNodeStackEntries() {
|
||||||
|
dnsg.pDnsPoolFreeList = (DirNodeStack *)WFSKrnHeapAlloc(&wkg.heap, WFS_DIR_NODE_STACK_ENTRY_POOL_ALLOC_UNIT * sizeof(DirNodeStack));
|
||||||
|
dbg_check(pDebugLastNodeStackAlloc = dnsg.pDnsPoolFreeList);
|
||||||
|
if (dnsg.pDnsPoolFreeList == 0) {
|
||||||
|
return WFSKRN_RESULT_OUT_OF_MEMORY;
|
||||||
|
}
|
||||||
|
u32 nI;
|
||||||
|
for(nI=0; nI<WFS_DIR_NODE_STACK_ENTRY_POOL_ALLOC_UNIT-1; nI++) {
|
||||||
|
dnsg.pDnsPoolFreeList[nI].pParent = &dnsg.pDnsPoolFreeList[nI+1];
|
||||||
|
}
|
||||||
|
dbg_check(dnsg.nTotalAllocated += WFS_DIR_NODE_STACK_ENTRY_POOL_ALLOC_UNIT);
|
||||||
|
dnsg.nNumFreeDnsPoolEntries += WFS_DIR_NODE_STACK_ENTRY_POOL_ALLOC_UNIT;
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
static u32 nDebugDirNodeStackGetEntryCount=0;
|
||||||
|
WFSKrnResult _DirNodeStackGetEntry(char *sFile, u32 nLine, DirNodeItr *pDni) {
|
||||||
|
++nDebugDirNodeStackGetEntryCount;
|
||||||
|
++dnsg.nNumUsed;
|
||||||
|
if (bCheckDirNodeStack)
|
||||||
|
MyOSReport("Dns:%d, %s Ln:%d GetEntry\n", dnsg.nNumUsed, sFile, nLine);
|
||||||
|
#else
|
||||||
|
WFSKrnResult DirNodeStackGetEntry(DirNodeItr *pDni) {
|
||||||
|
#endif
|
||||||
|
WFSKrnLockMutex(&dnsg.mxMutex);
|
||||||
|
if ((s32)dnsg.nNumFreeDnsPoolEntries<=0) {
|
||||||
|
if ((s32)dnsg.nNumFreeDnsPoolEntries<0) {
|
||||||
|
WFSKrnOutputErrorStr("nNumFreeDnsPoolEntries < 0");
|
||||||
|
}
|
||||||
|
WFSKrnReturnOnError(DirAllocateMoreNodeStackEntries());
|
||||||
|
}
|
||||||
|
--dnsg.nNumFreeDnsPoolEntries;
|
||||||
|
DirNodeStack *pNewDnsEntry = dnsg.pDnsPoolFreeList;
|
||||||
|
dnsg.pDnsPoolFreeList = dnsg.pDnsPoolFreeList->pParent;
|
||||||
|
WFSKrnUnlockMutex(&dnsg.mxMutex);
|
||||||
|
pNewDnsEntry->pParent = pDni->pDns;
|
||||||
|
pDni->pDns = pNewDnsEntry;
|
||||||
|
++pDni->nDnsDepth;
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
if (bCheckDirNodeStack) {
|
||||||
|
dbg_output(MyOSReport("GetEntry: "));
|
||||||
|
DirNodeStackCheckAlloc(pDni);
|
||||||
|
DirNodeStackCheckFreeList();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
void _DirNodeStackFree(char *sFile, u32 nLine, DirNodeItr *pDni, DirNodeStack **ppParent) {
|
||||||
|
dnsg.nNumUsed -= pDni->nDnsDepth;
|
||||||
|
if (bCheckDirNodeStack)
|
||||||
|
MyOSReport("Dns:%d, %s Ln:%d Free\n", dnsg.nNumUsed, sFile, nLine);
|
||||||
|
if (bCheckDirNodeStack) {
|
||||||
|
dbg_output(MyOSReport("StackFree(%d) { ", pDni->nDnsDepth));
|
||||||
|
DirNodeStackCheckAlloc(pDni);
|
||||||
|
DirNodeStackCheckFreeList();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void DirNodeStackFree(DirNodeItr *pDni, DirNodeStack **ppParent) {
|
||||||
|
#endif
|
||||||
|
WFSKrnLockMutex(&dnsg.mxMutex);
|
||||||
|
dnsg.nNumFreeDnsPoolEntries += pDni->nDnsDepth;
|
||||||
|
*ppParent = dnsg.pDnsPoolFreeList;
|
||||||
|
dnsg.pDnsPoolFreeList = pDni->pDns;
|
||||||
|
WFSKrnUnlockMutex(&dnsg.mxMutex);
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
if (bCheckDirNodeStack) {
|
||||||
|
dbg_output(MyOSReport("} StackFree: "));
|
||||||
|
DirNodeStackCheckAlloc(pDni);
|
||||||
|
DirNodeStackCheckFreeList();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
WFSKrnResult _DirPushNodeStackEntry(char *sFile, u32 nLine, DirNodeItr *pDni, WFSBlkAdr nBlkAdr) {
|
||||||
|
++dnsg.nNumUsed;
|
||||||
|
if (bCheckDirNodeStack)
|
||||||
|
MyOSReport("Dns:%d, %s Ln:%d Push\n", dnsg.nNumUsed, sFile, nLine);
|
||||||
|
#if _DEBUG_DIR
|
||||||
|
if (nDirTest == nDirTestBreakPoint) {
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
WFSKrnResult DirPushNodeStackEntry(DirNodeItr *pDni, WFSBlkAdr nBlkAdr) {
|
||||||
|
#endif
|
||||||
|
#if _DEBUG_BREAK_POINT
|
||||||
|
static int c=0; c++; if(c == 2601){
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
if( pDni->pDns->nBlkAdr == nBlkAdr && pDni->pDns->nSubBlkOfs == *pDni->pOfs ){
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
WFSKrnLockMutex(&dnsg.mxMutex);
|
||||||
|
if (dnsg.nNumFreeDnsPoolEntries==0) {
|
||||||
|
WFSKrnUnlockMutex(&dnsg.mxMutex);
|
||||||
|
WFSKrnReturnOnError(DirAllocateMoreNodeStackEntries());
|
||||||
|
WFSKrnLockMutex(&dnsg.mxMutex);
|
||||||
|
}
|
||||||
|
--dnsg.nNumFreeDnsPoolEntries;
|
||||||
|
DirNodeStack *pNewDnsEntry = dnsg.pDnsPoolFreeList;
|
||||||
|
#if _WIN32
|
||||||
|
if ((u32)dnsg.pDnsPoolFreeList == 0xbaadf00d) {
|
||||||
|
WFSKrnOutputErrorStr("Bad Node Stack Entry");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
dnsg.pDnsPoolFreeList = dnsg.pDnsPoolFreeList->pParent;
|
||||||
|
pNewDnsEntry->pParent = pDni->pDns;
|
||||||
|
pDni->pDns = pNewDnsEntry;
|
||||||
|
++pDni->nDnsDepth;
|
||||||
|
WFSKrnUnlockMutex(&dnsg.mxMutex);
|
||||||
|
pNewDnsEntry->nBlkAdr = nBlkAdr;
|
||||||
|
pNewDnsEntry->nSubBlkOfs = *pDni->pOfs;
|
||||||
|
//}
|
||||||
|
pNewDnsEntry->nEntryIdx = (u8)pDni->nEntryIdx;
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
if (bCheckDirNodeStack) {
|
||||||
|
dbg_output(MyOSReport("PushEntry: "));
|
||||||
|
DirNodeStackCheckAlloc(pDni);
|
||||||
|
DirNodeStackCheckFreeList();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
void _DirPopNodeStackEntry(char *sFile, u32 nLine, DirNodeItr *pDni) {
|
||||||
|
--dnsg.nNumUsed;
|
||||||
|
if (bCheckDirNodeStack)
|
||||||
|
MyOSReport("Dns:%d, %s Ln:%d Pop\n", dnsg.nNumUsed, sFile, nLine);
|
||||||
|
#else
|
||||||
|
void DirPopNodeStackEntry(DirNodeItr *pDni) {
|
||||||
|
#endif
|
||||||
|
WFSKrnLockMutex(&dnsg.mxMutex);
|
||||||
|
DirNodeStack *pNewFreeEntry = pDni->pDns;
|
||||||
|
pDni->pDns = pNewFreeEntry->pParent;
|
||||||
|
pNewFreeEntry->pParent = dnsg.pDnsPoolFreeList;
|
||||||
|
dnsg.pDnsPoolFreeList = pNewFreeEntry;
|
||||||
|
--pDni->nDnsDepth;
|
||||||
|
++dnsg.nNumFreeDnsPoolEntries;
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
if (bCheckDirNodeStack) {
|
||||||
|
dbg_output(MyOSReport("PopEntry: "));
|
||||||
|
DirNodeStackCheckAlloc(pDni);
|
||||||
|
DirNodeStackCheckFreeList();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
WFSKrnUnlockMutex(&dnsg.mxMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DirConstructEntryNameFromNodeStack(WFSFileName *pKey, DirItr *pDi) {
|
||||||
|
// This function parses the node stack constructing the key name
|
||||||
|
// ToDo: This function simply concatenates the strings from SubBlks,
|
||||||
|
// but it should take account of the adjustment needed between blocks
|
||||||
|
#if (_DEBUG_DIR && _DEBUG_DIR_NODE_STACK)
|
||||||
|
if (nDirTest == nDirTestBreakPoint) {
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
DirBlkHdr *pBlkHdr = pDi->pBlkHdr;
|
||||||
|
DirNodeStack *pDns = pDi->dni.pDns;
|
||||||
|
u32 nI=pDi->dni.nDnsDepth;
|
||||||
|
pKey->nLen = pDns->nStrIdx;//nStrLen-1;
|
||||||
|
utf8 *pStr = pKey->sStr;
|
||||||
|
// Trace back through the leaf
|
||||||
|
u32 nMinStrIdx = WFS_MAX_FILE_NAME_SIZE;
|
||||||
|
do {
|
||||||
|
DirSubBlkHdr *pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + pDns->nSubBlkOfs);
|
||||||
|
nMinStrIdx = (u32)(pDns->nStrIdx - pSubBlkHdr->nStrLen);
|
||||||
|
pStr[pDns->nStrIdx] = pSubBlkHdr->aFirstChar[pSubBlkHdr->nStrLen + pDns->nEntryIdx-1];
|
||||||
|
memcpy(&pStr[nMinStrIdx], pSubBlkHdr->aFirstChar, pSubBlkHdr->nStrLen);
|
||||||
|
if (0 == --nI) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
} while (pDi->tba.nBlkAdr == pDns->nBlkAdr);
|
||||||
|
// Trace back through nodes
|
||||||
|
#if (DIR_PREFIX_SUPPRESSION)
|
||||||
|
pDi->tba.nBlkAdr = pDns->nBlkAdr;
|
||||||
|
#if AREA_ENABLE_BLK_CACHE
|
||||||
|
AreaBlkMap(pDi->tba.pAreaInfo, pDi->tba.nBlkAdr, TRUE, TRUE, TRUE, (void**) &pBlkHdr);
|
||||||
|
#else
|
||||||
|
TransGetAndPinBlk(&pDi->tba, &pBlkHdr);
|
||||||
|
#endif
|
||||||
|
while(nMinStrIdx) {
|
||||||
|
DirSubBlkHdr *pSubBlkHdr = (DirSubBlkHdr *)((u8*)pBlkHdr + pDns->nSubBlkOfs);
|
||||||
|
utf8 cChoiceChar = pSubBlkHdr->aFirstChar[pSubBlkHdr->nStrLen + pDns->nEntryIdx-1];
|
||||||
|
if (pDns->nStrIdx <= nMinStrIdx) {
|
||||||
|
if (pDns->nStrIdx < nMinStrIdx) {
|
||||||
|
pStr[pDns->nStrIdx] = cChoiceChar;
|
||||||
|
}
|
||||||
|
memcpy(&pStr[pDns->nStrIdx - pSubBlkHdr->nStrLen], pSubBlkHdr->aFirstChar, pSubBlkHdr->nStrLen);
|
||||||
|
nMinStrIdx = pDns->nStrIdx;
|
||||||
|
}
|
||||||
|
if (0 == --nI) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pDns = pDns->pParent;
|
||||||
|
if (pDi->tba.nBlkAdr != pDns->nBlkAdr) {
|
||||||
|
pDi->tba.nBlkAdr = pDns->nBlkAdr;
|
||||||
|
#if AREA_ENABLE_BLK_CACHE
|
||||||
|
AreaBlkUnpin(pDi->tba.pAreaInfo, pDi->tba.nBlkAdr);
|
||||||
|
AreaBlkMap(pDi->tba.pAreaInfo, pDns->nBlkAdr, TRUE, TRUE, TRUE, (void**) &pBlkHdr);
|
||||||
|
#else
|
||||||
|
TransGetAndPinBlk(&pDi->tba, &pBlkHdr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if AREA_ENABLE_BLK_CACHE
|
||||||
|
AreaBlkUnpin(pDi->tba.pAreaInfo, pDi->tba.nBlkAdr);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if _DEBUG_DIR_NODE_STACK
|
||||||
|
void _DirNodeStackCheckEmpty() {
|
||||||
|
if (dnsg.nNumUsed != 0) {
|
||||||
|
WFSKrnOutputErrorStr("Dir Node Stack Not Empty");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
1170
trunk/firmware/build/libraries/nfs/common/src/wfskrn_DirRxTree.cpp
Normal file
1170
trunk/firmware/build/libraries/nfs/common/src/wfskrn_DirRxTree.cpp
Normal file
File diff suppressed because it is too large
Load Diff
937
trunk/firmware/build/libraries/nfs/common/src/wfskrn_EPTree.cpp
Normal file
937
trunk/firmware/build/libraries/nfs/common/src/wfskrn_EPTree.cpp
Normal file
@ -0,0 +1,937 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_EPTree.cpp
|
||||||
|
|
||||||
|
Copyright 2007-2008 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_EPTree.cpp,v $
|
||||||
|
Revision 1.5 2008/12/18 08:53:11 ueno
|
||||||
|
Refactoring to avoid recursive call.
|
||||||
|
|
||||||
|
Revision 1.4 2008/12/17 05:06:49 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.3 2008/12/15 04:14:40 ueno
|
||||||
|
Cleanup.
|
||||||
|
|
||||||
|
Revision 1.2 2008/12/15 02:40:07 ueno
|
||||||
|
Added support for multi p-tree.
|
||||||
|
|
||||||
|
Revision 1.1 2008/12/02 04:55:13 ueno
|
||||||
|
Added EPTree to support multi-PTree.
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
#include "wfskrn_Area.h"
|
||||||
|
#include "wfskrn_FTree.h"
|
||||||
|
#include "wfskrn_FreeBlkAlloc.h"
|
||||||
|
|
||||||
|
#define ROUNDUP32BYTE(val) (((size_t)(val)+31)&~31)
|
||||||
|
#define ROUNDDOWN(val, unit) ((u32) (val) & ~((unit)-1))
|
||||||
|
#define ROUNDUP(val, unit) ((u32) ((val) + ((unit)-1)) & ~((unit)-1))
|
||||||
|
|
||||||
|
#define FBA_PTREE_MIN_HEIGHT 1
|
||||||
|
|
||||||
|
typedef struct _EPTreeChildInfo
|
||||||
|
{
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
u32 address;
|
||||||
|
u32 numEntries;
|
||||||
|
u32 subTreeType;
|
||||||
|
u32 firstKey;
|
||||||
|
} EPTreeChildInfo;
|
||||||
|
|
||||||
|
typedef struct _EPTreeSplitInfo
|
||||||
|
{
|
||||||
|
EPTreeChildInfo right;
|
||||||
|
EPTreeChildInfo left;
|
||||||
|
u32 splitKey;
|
||||||
|
u32 newChild;
|
||||||
|
u32 totalNumRecs;
|
||||||
|
} EPTreeSplitInfo;
|
||||||
|
|
||||||
|
EPTreeItr* EPTreeGetLastIter(MEPTreeItr* iter)
|
||||||
|
{
|
||||||
|
ASSERT(iter->eptreeHdr[0]);
|
||||||
|
u8 height = iter->eptreeHdr[0]->height;
|
||||||
|
EPTreeItr* last = &iter->epti[height-1];
|
||||||
|
return last;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void AllocatorInit(PTreeAllocator* allocator, EPTreeHdr* eptreeHdr)
|
||||||
|
{
|
||||||
|
allocator->pBase = GET_BLOCK_HEAD(eptreeHdr);
|
||||||
|
allocator->fpAllocNode = FTreeAllocEntry;
|
||||||
|
allocator->fpAllocNodes = FTreeAllocEntries;
|
||||||
|
allocator->fpFreeNode = FTreeFreeEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WFSKrnResult GetAndPinEPTreeHdr(AreaInfo* area,
|
||||||
|
MEPTreeItr* iter, u32 level, WFSBlkAdr addr, u32 flags)
|
||||||
|
{
|
||||||
|
WFSKrnResult result = WFSKRN_RESULT_OK;
|
||||||
|
void* block;
|
||||||
|
|
||||||
|
if (level == 0)
|
||||||
|
{
|
||||||
|
// root ptree block is already pinned.
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter->eptreeHdr[level] &&
|
||||||
|
iter->eptreeHdr[level]->addr == addr)
|
||||||
|
{
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iter->eptreeHdr[level])
|
||||||
|
{
|
||||||
|
ASSERT(iter->eptreeHdr[level]->addr != 0);
|
||||||
|
FBAUnpinCache(area, iter->eptreeHdr[level]->addr); // unpin old ptree block.
|
||||||
|
}
|
||||||
|
|
||||||
|
result = FBAGetCache(area, addr, flags, &block);
|
||||||
|
if (result == WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
iter->eptreeHdr[level] = GET_EPTREEHDR(block);
|
||||||
|
ASSERT(iter->eptreeHdr[level]->addr == addr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
iter->eptreeHdr[level] = 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
EPTreeHdr* EPTreeBlockInit(AreaInfo* area, void* block, WFSBlkAdr addr, u32 offset, u8 height)
|
||||||
|
{
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
FTreeSbaInit(area, block, sizeof(EPTreeHdr), offset);
|
||||||
|
eptreeHdr = GET_EPTREEHDR(block);
|
||||||
|
eptreeHdr->addr = addr;
|
||||||
|
eptreeHdr->height = height;
|
||||||
|
|
||||||
|
PTreeInit(&eptreeHdr->ptreeHdr, NULL); // 2nd argument is not used in PTreeInit().
|
||||||
|
return eptreeHdr; // keep pinning.
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
* initial state.
|
||||||
|
|
||||||
|
[ToDo] update the figures.
|
||||||
|
|
||||||
|
disk address (FBA_ROOT_BLK). (PLeaf in 8kB)
|
||||||
|
+----------+
|
||||||
|
| sbaHdr |
|
||||||
|
+----------+
|
||||||
|
| PTreeHdr |--->PLeaf
|
||||||
|
+----------+ +---+---+---+---+
|
||||||
|
| PLeaf | | 0 | 0 | 0 | 0 |
|
||||||
|
+----------+ +---+---+---+---+
|
||||||
|
: : | 1 | ? | ? | ? |
|
||||||
|
: : +---+---+---+---+
|
||||||
|
| |
|
||||||
|
+----------+
|
||||||
|
|
||||||
|
disk address (FBA_INITIAL_FTREE_BLK)
|
||||||
|
+----------+
|
||||||
|
| sbaHdr |
|
||||||
|
+- - - - - +
|
||||||
|
| FTreeHdr |
|
||||||
|
+----------+
|
||||||
|
: empty :
|
||||||
|
: :
|
||||||
|
| |
|
||||||
|
+----------+
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
WFSKrnResult EPTreeInit(AreaInfo* pAreaInfo, u32 offset)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
FTreeHdr* ftreeHdr;
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
void* cache;
|
||||||
|
void* eptreeBlock;
|
||||||
|
|
||||||
|
// FBA_ROOT_BLK is already pinned.
|
||||||
|
|
||||||
|
eptreeBlock = (u8*) pAreaInfo->pAflh - offset; // FBA_ROOT_BLK is already pinned.
|
||||||
|
eptreeHdr = EPTreeBlockInit(pAreaInfo, eptreeBlock, FBA_ROOT_BLK, ROUNDUP32BYTE(offset), FBA_PTREE_MIN_HEIGHT);
|
||||||
|
|
||||||
|
// create an F-tree block.
|
||||||
|
result = FBAGetCache(pAreaInfo, FBA_INITIAL_FTREE_BLK, BCACHE_FLAG_PINNED | BCACHE_FLAG_DIRTY, &cache);
|
||||||
|
|
||||||
|
if (result == WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
EPTreeItr epti;
|
||||||
|
|
||||||
|
ftreeHdr = FTreeBlockInit(pAreaInfo, cache);
|
||||||
|
BCacheUnpin(pAreaInfo->pVolInfo, pAreaInfo->nAbsStartBlkAdr + FBA_INITIAL_FTREE_BLK);
|
||||||
|
|
||||||
|
// +---+---+---+---+
|
||||||
|
// | 0 | 0 | 0 | 0 |
|
||||||
|
// +---+---+---+---+
|
||||||
|
// | 1 | ? | ? | ? |
|
||||||
|
// +---+---+---+---+
|
||||||
|
// A
|
||||||
|
// |
|
||||||
|
// FBA_INITIAL_FTREE_BLK
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeInsert(&eptreeHdr->ptreeHdr, &epti, 0, FBA_INITIAL_FTREE_BLK, &allocator);
|
||||||
|
WFSKRN_FTREE_ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the EP-tree block is pinned.
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult EPTreeReinit(AreaInfo* pAreaInfo, u32 offset)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
void* eptreeBlock;
|
||||||
|
|
||||||
|
// FBA_ROOT_BLK is already pinned.
|
||||||
|
|
||||||
|
eptreeBlock = (u8*) pAreaInfo->pAflh - offset; // FBA_ROOT_BLK is already pinned.
|
||||||
|
eptreeHdr = EPTreeBlockInit(pAreaInfo, eptreeBlock, FBA_ROOT_BLK, ROUNDUP32BYTE(offset), FBA_PTREE_MIN_HEIGHT);
|
||||||
|
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
EPTreeItr epti;
|
||||||
|
|
||||||
|
// +---+---+---+---+
|
||||||
|
// | 0 | 0 | 0 | 0 |
|
||||||
|
// +---+---+---+---+
|
||||||
|
// | 1 | ? | ? | ? |
|
||||||
|
// +---+---+---+---+
|
||||||
|
// A
|
||||||
|
// |
|
||||||
|
// FBA_INITIAL_FTREE_BLK
|
||||||
|
|
||||||
|
// FBA_INITIAL_FTREE_BLK is not initialized, because it may include some freeblocks.
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeInsert(&eptreeHdr->ptreeHdr, &epti, 0, FBA_INITIAL_FTREE_BLK, &allocator);
|
||||||
|
WFSKRN_FTREE_ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
// the EP-tree block is pinned.
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// determine the threshold block address.
|
||||||
|
static u32 GetSplitAddress(PTreeHdr* ptreeHdr, EPTreeItr* iter, PTreeAllocator* allocator)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
u32 halfNumRecs = ptreeHdr->nNumRecs / 2;
|
||||||
|
|
||||||
|
result = PTreeFirst(ptreeHdr, iter, allocator);
|
||||||
|
while (halfNumRecs--)
|
||||||
|
{
|
||||||
|
result = PTreeNext(ptreeHdr, iter, allocator);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PTREE_GET_KEY(iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WFSKrnResult GetNewControlBlock(AreaInfo* area, WFSBlkAdr nNGBlkAdr1, WFSBlkAdr nNGBlkAdr2, WFSBlkAdr nRefBlkAdr, FTreeExtent* extent, u32* subTreeIdx)
|
||||||
|
{
|
||||||
|
WFSKrnResult result = WFSKRN_RESULT_NOT_FOUND;
|
||||||
|
FBATreeItr iter;
|
||||||
|
FBAItrOpen(area, &iter);
|
||||||
|
|
||||||
|
u32 idx;
|
||||||
|
for (idx = FTREE_TYPE_A; idx < MAX_SUB_TREE; ++idx)
|
||||||
|
{
|
||||||
|
result = FreeBlkFind(area, &iter, nRefBlkAdr, FTreeBlkLog2Ofs[idx]);
|
||||||
|
while ((result == WFSKRN_RESULT_OK) &&
|
||||||
|
(nNGBlkAdr1 == FBA_RESULT_KEY(&iter) ||
|
||||||
|
nNGBlkAdr2 == FBA_RESULT_KEY(&iter)))
|
||||||
|
{
|
||||||
|
result = FreeBlkPrev(area, &iter);
|
||||||
|
}
|
||||||
|
if (result == WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
extent->start = FBA_RESULT_KEY(&iter);
|
||||||
|
extent->len = (FBA_RESULT_DATA(&iter) + 1) * (1<<FTreeBlkLog2Ofs[idx]);
|
||||||
|
*subTreeIdx = idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FBAItrClose(area, &iter);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EPTreeHdr* ControlBlockInit(AreaInfo* area, u32 addr, u8 height)
|
||||||
|
{
|
||||||
|
void* pBlock;
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
WFSKrnResult result;
|
||||||
|
|
||||||
|
result = FBAGetCache(area, addr, BCACHE_FLAG_DIRTY | BCACHE_FLAG_PINNED, &pBlock);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
u32 offset = (sizeof(WFSHashCode) + sizeof(WFSMetaDataHdr));
|
||||||
|
EPTreeBlockInit(area, pBlock, addr, offset, height);
|
||||||
|
|
||||||
|
eptreeHdr = GET_EPTREEHDR(pBlock);
|
||||||
|
eptreeHdr->addr = addr;
|
||||||
|
return eptreeHdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate 2 blocks. (must not remove them from FBA tree, because it may cause another p-tree splitting.)
|
||||||
|
static WFSKrnResult SplitTreeInit(AreaInfo* area, EPTreeHdr* eptreeHdr, EPTreeSplitInfo* info, PTreeAllocator* allocator)
|
||||||
|
{
|
||||||
|
EPTreeItr iter;
|
||||||
|
WFSKrnResult result;
|
||||||
|
FTreeExtent newCb;
|
||||||
|
u32 subTreeIdxNewCb;
|
||||||
|
|
||||||
|
// choose split key.
|
||||||
|
info->splitKey = GetSplitAddress(&eptreeHdr->ptreeHdr, &iter, allocator);
|
||||||
|
|
||||||
|
result = GetNewControlBlock(area, 0 /* no NG address */, 0 /* no NG address */,
|
||||||
|
info->splitKey, &newCb, &subTreeIdxNewCb);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
info->left.address = newCb.start;
|
||||||
|
info->left.subTreeType = subTreeIdxNewCb;
|
||||||
|
|
||||||
|
if (newCb.len == 1)
|
||||||
|
{
|
||||||
|
result = GetNewControlBlock(area, info->left.address, 0, newCb.start + 1, &newCb, &subTreeIdxNewCb);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
info->right.address = newCb.start;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
info->right.address = info->left.address + 1;
|
||||||
|
}
|
||||||
|
info->right.subTreeType = subTreeIdxNewCb;
|
||||||
|
|
||||||
|
// height field is only used by root ptree block.
|
||||||
|
info->left.eptreeHdr = ControlBlockInit(area, info->left.address, eptreeHdr->height);
|
||||||
|
info->right.eptreeHdr = ControlBlockInit(area, info->right.address, eptreeHdr->height);
|
||||||
|
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WFSKrnResult CreateChildBlocks(AreaInfo* area, EPTreeSplitInfo* info, PTreeHdr* ptreeHdr, PTreeAllocator* allocatorParent)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
PTreeItr ptiSearch;
|
||||||
|
PTreeItr ptiInsert;
|
||||||
|
|
||||||
|
// insert to left child.
|
||||||
|
result = PTreeFirst(ptreeHdr, &ptiSearch, allocatorParent);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, info->left.eptreeHdr); // [ToDo] single ptree.
|
||||||
|
|
||||||
|
info->left.firstKey = PTREE_GET_KEY(&ptiSearch);
|
||||||
|
int count = ptreeHdr->nNumRecs;
|
||||||
|
while ((int) (ptreeHdr->nNumRecs - ptreeHdr->nNumRecs / 2) < count)
|
||||||
|
{
|
||||||
|
ASSERT(PTREE_GET_KEY(&ptiSearch) < info->splitKey);
|
||||||
|
result = PTreeInsert(&info->left.eptreeHdr->ptreeHdr, &ptiInsert,
|
||||||
|
PTREE_GET_KEY(&ptiSearch), PTREE_GET_DATA(&ptiSearch), &allocator);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
goto ERROR_CREATECHILDBLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = PTreeNext(ptreeHdr, &ptiSearch, allocatorParent);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
goto ERROR_CREATECHILDBLOCKS;
|
||||||
|
}
|
||||||
|
--count;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
// insert to right child.
|
||||||
|
info->right.firstKey = PTREE_GET_KEY(&ptiSearch);
|
||||||
|
AllocatorInit(&allocator, info->right.eptreeHdr); // [ToDo] single ptree.
|
||||||
|
while (0 < count)
|
||||||
|
{
|
||||||
|
ASSERT(info->splitKey <= PTREE_GET_KEY(&ptiSearch));
|
||||||
|
result = PTreeInsert(&info->right.eptreeHdr->ptreeHdr, &ptiInsert,
|
||||||
|
PTREE_GET_KEY(&ptiSearch), PTREE_GET_DATA(&ptiSearch), &allocator);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
goto ERROR_CREATECHILDBLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (--count == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
result = PTreeNext(ptreeHdr, &ptiSearch, allocatorParent);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
goto ERROR_CREATECHILDBLOCKS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ERROR_CREATECHILDBLOCKS:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline WFSBool IsRootBlock(AreaInfo* area, EPTreeHdr* eptreeHdr)
|
||||||
|
{
|
||||||
|
FBATreeHdr* fbaTreeHdr = GET_FBATREE_HDR(area);
|
||||||
|
return ((u32) (eptreeHdr->height) == fbaTreeHdr->ptreeHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
static WFSKrnResult InsertToParentBlocks(AreaInfo* area, EPTreeHdr* eptreeHdr, EPTreeSplitInfo* info)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
EPTreeHdr* tempEptreeHdr;
|
||||||
|
PTreeItr pti;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
|
||||||
|
if (IsRootBlock(area, eptreeHdr) == (WFSBool) TRUE)
|
||||||
|
{
|
||||||
|
u32 offset;
|
||||||
|
u32 subTreeIdxTempCb;
|
||||||
|
u32 originalAddr;
|
||||||
|
FBATreeHdr* fbaTreeHdr = GET_FBATREE_HDR(area);
|
||||||
|
FTreeExtent tempCb;
|
||||||
|
|
||||||
|
// create a new level.
|
||||||
|
++fbaTreeHdr->ptreeHeight;
|
||||||
|
ASSERT(fbaTreeHdr->ptreeHeight <= EPTREE_MAX_HEIGHT);
|
||||||
|
|
||||||
|
|
||||||
|
result = GetNewControlBlock(area, info->left.address, info->right.address,
|
||||||
|
1, &tempCb, &subTreeIdxTempCb);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
tempEptreeHdr = ControlBlockInit(area, tempCb.start, (u8) (fbaTreeHdr->ptreeHeight));
|
||||||
|
|
||||||
|
// copy original parent ptree.
|
||||||
|
memmove((u8*) GET_BLOCK_FROM_EPTREEHDR(tempEptreeHdr), GET_BLOCK_FROM_EPTREEHDR(eptreeHdr), area->nBlkSize);
|
||||||
|
|
||||||
|
// clear all entries
|
||||||
|
offset = eptreeHdr->sbaHdr.offset;
|
||||||
|
EPTreeBlockInit(area, GET_BLOCK_FROM_EPTREEHDR(tempEptreeHdr), tempCb.start, offset, (u8) (fbaTreeHdr->ptreeHeight));
|
||||||
|
|
||||||
|
// insert child blocks into the parent.
|
||||||
|
AllocatorInit(&allocator, tempEptreeHdr);
|
||||||
|
|
||||||
|
result = PTreeInsert(&tempEptreeHdr->ptreeHdr, &pti, info->left.firstKey, info->left.address, &allocator);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
result = PTreeInsert(&tempEptreeHdr->ptreeHdr, &pti, info->right.firstKey, info->right.address, &allocator);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
originalAddr = eptreeHdr->addr;
|
||||||
|
memmove(GET_BLOCK_FROM_EPTREEHDR(eptreeHdr), GET_BLOCK_FROM_EPTREEHDR(tempEptreeHdr), area->nBlkSize); // remap
|
||||||
|
eptreeHdr->addr = originalAddr;
|
||||||
|
FBAFreeCache(area, tempCb.start); // unpin the temporary parent block.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// insert the split key into the parent block.
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeInsert(&eptreeHdr->ptreeHdr, &pti, info->splitKey, 1, &allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove left and right child blocks from the FBA tree.
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WFSKrnResult EPTreeSplit(AreaInfo* area, MEPTreeItr* iter, EPTreeHdr* eptreeHdr, EPTreeSplitInfo* info)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
|
||||||
|
if (EPTREE_MAX_HEIGHT == iter->eptreeHdr[0]->height)
|
||||||
|
{
|
||||||
|
return WFSKRN_RESULT_RESOURCE_LIMIT_EXCEEDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
|
||||||
|
result = SplitTreeInit(area, eptreeHdr, info, &allocator);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// split the original block to two children.
|
||||||
|
result = CreateChildBlocks(area, info, &eptreeHdr->ptreeHdr, &allocator);
|
||||||
|
|
||||||
|
FBAUnpinCache(area, info->left.address);
|
||||||
|
FBAUnpinCache(area, info->right.address);
|
||||||
|
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create new parent block and remap it to the original block.
|
||||||
|
result = InsertToParentBlocks(area, eptreeHdr, info);
|
||||||
|
if (result == WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
FBATreeItr iterDelete;
|
||||||
|
|
||||||
|
FBAItrOpen(area, &iterDelete);
|
||||||
|
iterDelete.fti.subTree = FTreeSelectSubTree(iterDelete.ftreeHdr, info->left.subTreeType);
|
||||||
|
|
||||||
|
// remove child block address from the FBA tree.
|
||||||
|
result = FreeBlkDelete(area, &iterDelete,
|
||||||
|
info->left.address, 1, FTreeBlkLog2Ofs[info->left.subTreeType]);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
iterDelete.fti.subTree = FTreeSelectSubTree(iterDelete.ftreeHdr, info->right.subTreeType);
|
||||||
|
result = FreeBlkDelete(area, &iterDelete,
|
||||||
|
info->right.address, 1, FTreeBlkLog2Ofs[info->right.subTreeType]);
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK);
|
||||||
|
|
||||||
|
FBAItrClose(area, &iterDelete);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult EPTreeFirst(AreaInfo* area, MEPTreeItr* iter)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
int level;
|
||||||
|
u8 ptreeHeight;
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, iter->eptreeHdr[0]);
|
||||||
|
result = PTreeFirst(&iter->eptreeHdr[0]->ptreeHdr, (PTreeItr*) &iter->epti[0], &allocator);
|
||||||
|
|
||||||
|
ptreeHeight = iter->eptreeHdr[0]->height;
|
||||||
|
for (level = 1; level < ptreeHeight; ++level)
|
||||||
|
{
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = GetAndPinEPTreeHdr(area, iter, level,
|
||||||
|
EPTREE_GET_DATA(&iter->epti[level-1]), BCACHE_FLAG_READ | BCACHE_FLAG_PINNED);
|
||||||
|
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, iter->eptreeHdr[level]);
|
||||||
|
result = PTreeFirst(&iter->eptreeHdr[level]->ptreeHdr, (PTreeItr*) &iter->epti[level], &allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult EPTreeLast(AreaInfo* area, MEPTreeItr* iter)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
int level;
|
||||||
|
u8 ptreeHeight;
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, iter->eptreeHdr[0]);
|
||||||
|
result = PTreeLast(&iter->eptreeHdr[0]->ptreeHdr, (PTreeItr*) &iter->epti[0], &allocator);
|
||||||
|
|
||||||
|
ptreeHeight = iter->eptreeHdr[0]->height;
|
||||||
|
for (level = 1; level < ptreeHeight; ++level)
|
||||||
|
{
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = GetAndPinEPTreeHdr(area, iter, level,
|
||||||
|
EPTREE_GET_DATA(&iter->epti[level-1]), BCACHE_FLAG_READ | BCACHE_FLAG_PINNED);
|
||||||
|
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, iter->eptreeHdr[level]);
|
||||||
|
result = PTreeLast(&iter->eptreeHdr[level]->ptreeHdr, (PTreeItr*) &iter->epti[level], &allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult EPTreeNext(AreaInfo* area, MEPTreeItr* iter)
|
||||||
|
{
|
||||||
|
WFSKrnResult result = WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
u8 ptreeHeight = iter->eptreeHdr[0]->height;
|
||||||
|
|
||||||
|
eptreeHdr = iter->eptreeHdr[ptreeHeight-1];
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeNext(&eptreeHdr->ptreeHdr, (PTreeItr*) &iter->epti[ptreeHeight-1], &allocator);
|
||||||
|
if (result == WFSKRN_RESULT_PTREE_ENTRY_FOUND)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// go back and lookup an entry in the next node.
|
||||||
|
int level = ptreeHeight;
|
||||||
|
while (result == WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND && --level)
|
||||||
|
{
|
||||||
|
eptreeHdr = iter->eptreeHdr[level-1];
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeNext(&eptreeHdr->ptreeHdr, (PTreeItr*) &iter->epti[level-1], &allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
for (;level < ptreeHeight; ++level)
|
||||||
|
{
|
||||||
|
result = GetAndPinEPTreeHdr(area, iter, level,
|
||||||
|
EPTREE_GET_DATA(&iter->epti[level-1]), BCACHE_FLAG_READ | BCACHE_FLAG_PINNED);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eptreeHdr = iter->eptreeHdr[level];
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeFirst(&eptreeHdr->ptreeHdr, (PTreeItr*) &iter->epti[level], &allocator);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult EPTreePrev(AreaInfo* area, MEPTreeItr* iter)
|
||||||
|
{
|
||||||
|
WFSKrnResult result = WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
u8 ptreeHeight = iter->eptreeHdr[0]->height;
|
||||||
|
|
||||||
|
eptreeHdr = iter->eptreeHdr[ptreeHeight-1];
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreePrev(&eptreeHdr->ptreeHdr, (PTreeItr*) &iter->epti[ptreeHeight-1], &allocator);
|
||||||
|
if (result == WFSKRN_RESULT_PTREE_ENTRY_FOUND)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// go back and lookup an entry in the next node.
|
||||||
|
int level = ptreeHeight;
|
||||||
|
while (result == WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND && --level)
|
||||||
|
{
|
||||||
|
eptreeHdr = iter->eptreeHdr[level-1];
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreePrev(&eptreeHdr->ptreeHdr, (PTreeItr*) &iter->epti[level-1], &allocator);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
for (;level < ptreeHeight; ++level)
|
||||||
|
{
|
||||||
|
result = GetAndPinEPTreeHdr(area, iter, level,
|
||||||
|
EPTREE_GET_DATA(&iter->epti[level-1]), BCACHE_FLAG_READ | BCACHE_FLAG_PINNED);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eptreeHdr = iter->eptreeHdr[level];
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeLast(&eptreeHdr->ptreeHdr, (PTreeItr*) &iter->epti[level], &allocator);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WFSKrnResult EPTreeInsertWithoutSplitting(AreaInfo* area, MEPTreeItr* iter, u32 key, u32 data)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
EPTreeItr* epti;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
u8 height;
|
||||||
|
|
||||||
|
result = EPTreeFind(area, iter, key);
|
||||||
|
if (result == WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
return WFSKRN_RESULT_ALREADY_EXISTS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
height = iter->eptreeHdr[0]->height;
|
||||||
|
epti = &iter->epti[height-1];
|
||||||
|
eptreeHdr = iter->eptreeHdr[height-1];
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeInsert(&eptreeHdr->ptreeHdr, (PTreeItr*) epti, key, data, &allocator);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult EPTreeInsert(AreaInfo* area, MEPTreeItr* iter, u32 key, u32 data)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
while (WFSKRN_RESULT_PTREE_FULL == (result = EPTreeInsertWithoutSplitting(area, iter, key, data)))
|
||||||
|
{
|
||||||
|
EPTreeSplitInfo info;
|
||||||
|
result = EPTreeSplit(area, (MEPTreeItr*) iter, iter->eptreeHdr[0], &info);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
#ifdef _DEBUG
|
||||||
|
OS_TPrintf("*** EPTreeInsert(): split error (%d) ***\n", result);
|
||||||
|
#endif // _DEBUG
|
||||||
|
ASSERT(result == WFSKRN_RESULT_OK ||
|
||||||
|
result == WFSKRN_RESULT_DIRECTORY_QUOTA);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WFSKrnResult DelteEmptyBlocks(AreaInfo* area, MEPTreeItr* iter, WFSBlkAdr* freeBlks)
|
||||||
|
{
|
||||||
|
WFSKrnResult result = WFSKRN_RESULT_OK;
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
EPTreeItr* epti;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
|
||||||
|
WFSBlkAdr addr;
|
||||||
|
int level;
|
||||||
|
int height = (int) iter->eptreeHdr[0]->height;
|
||||||
|
for (level = height - 2; 0 <= level; --level)
|
||||||
|
{
|
||||||
|
eptreeHdr = iter->eptreeHdr[level];
|
||||||
|
|
||||||
|
epti = &iter->epti[level];
|
||||||
|
addr = EPTREE_GET_DATA(epti);
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeDelete(&eptreeHdr->ptreeHdr, (PTreeItr*) epti, &allocator);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
iter->eptreeHdr[level+1] = 0;
|
||||||
|
FBAFreeCache(area, addr);
|
||||||
|
freeBlks[level] = addr; // save to insert it into FBA tree, later.
|
||||||
|
if (0 < eptreeHdr->ptreeHdr.nNumRecs)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult EPTreeShrink(AreaInfo* area, MEPTreeItr* iter, WFSBlkAdr* freeBlks)
|
||||||
|
{
|
||||||
|
WFSKrnResult result = EPTreeLast(area, iter);
|
||||||
|
if (result == WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
u32 height = (u32) iter->eptreeHdr[0]->height;
|
||||||
|
EPTreeItr* epti = EPTreeGetLastIter(iter);
|
||||||
|
if (EPTREE_GET_DATA(epti) == FBA_INITIAL_FTREE_BLK &&
|
||||||
|
EPTREE_GET_KEY(epti) == 0)
|
||||||
|
{
|
||||||
|
MEPTreeItr iterInsert;
|
||||||
|
iterInsert.eptreeHdr[0] = GET_EPTREEHDR_FROM_AREAINFO(area);
|
||||||
|
u32 level;
|
||||||
|
for (level = 1; level < EPTREE_MAX_HEIGHT; ++level)
|
||||||
|
{
|
||||||
|
iterInsert.eptreeHdr[level] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FBATreeHdr* fbaTreeHdr = GET_FBATREE_HDR(area);
|
||||||
|
fbaTreeHdr->ptreeHeight = 1;
|
||||||
|
u32 offset = area->nBlkSize - GET_FBATREE_HDR(area)->ofsEPtreeHdr - sizeof(EPTreeHdr);
|
||||||
|
EPTreeReinit(area, ROUNDUP32BYTE(offset));
|
||||||
|
|
||||||
|
for (level = 0; level < (int) height; ++level)
|
||||||
|
{
|
||||||
|
u32 addr = iter->epti[level].nData;
|
||||||
|
if (addr != FBA_INITIAL_FTREE_BLK)
|
||||||
|
{
|
||||||
|
FBAFreeCache(area, addr);
|
||||||
|
freeBlks[level + (EPTREE_MAX_HEIGHT-1)] = addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult EPTreeDelete(AreaInfo* area, MEPTreeItr* iter, u32 key, WFSBlkAdr* freeBlks)
|
||||||
|
{
|
||||||
|
WFSKrnResult result;
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
|
||||||
|
result = EPTreeFind(area, iter, key);
|
||||||
|
if (result == WFSKRN_RESULT_OK ||
|
||||||
|
result == WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND) // not found?
|
||||||
|
{
|
||||||
|
u8 height = iter->eptreeHdr[0]->height;
|
||||||
|
EPTreeItr* epti = &iter->epti[height-1];
|
||||||
|
eptreeHdr = iter->eptreeHdr[height-1];
|
||||||
|
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeDelete(&eptreeHdr->ptreeHdr, (PTreeItr*) epti, &allocator);
|
||||||
|
if (eptreeHdr->ptreeHdr.nNumRecs <= 1 && 2 <= height)
|
||||||
|
{
|
||||||
|
if (eptreeHdr->ptreeHdr.nNumRecs == 0)
|
||||||
|
{
|
||||||
|
result = DelteEmptyBlocks(area, iter, freeBlks);
|
||||||
|
if (result == WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
result = EPTreeShrink(area, iter, freeBlks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (epti->pLeaf->aKey[0] == 0 &&
|
||||||
|
epti->pLeaf->aData[0] == FBA_INITIAL_FTREE_BLK)
|
||||||
|
{
|
||||||
|
// eptreeHdr->ptreeHdr.nNumRecs == 1.
|
||||||
|
result = EPTreeShrink(area, iter, freeBlks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// search a P-tree by key.
|
||||||
|
/*
|
||||||
|
P-tree node
|
||||||
|
+-----------------+
|
||||||
|
| P-Tree |
|
||||||
|
|key: 100 |
|
||||||
|
| |
|
||||||
|
+-----------------+
|
||||||
|
| |
|
||||||
|
p-tree leaf V V p-tree leaf
|
||||||
|
+-----------------+ +-----------------+
|
||||||
|
| P-Tree | | P-Tree |
|
||||||
|
|key: 80 96 | |key: 110 116 119 |
|
||||||
|
| | | |
|
||||||
|
+-----------------+ +-----------------+
|
||||||
|
A A A A
|
||||||
|
| | | |
|
||||||
|
(1) (2) (3) (4)
|
||||||
|
|
||||||
|
key result pPti->nKey
|
||||||
|
(1) 101 => WFSKRN_RESULT_NOT_FOUND - (no value is set).
|
||||||
|
(2) 110 => WFSKRN_RESULT_OK 110
|
||||||
|
(3) 118 => WFSKRN_RESULT_OK 116
|
||||||
|
(4) 120 => WFSKRN_RESULT_OK 119
|
||||||
|
*/
|
||||||
|
WFSKrnResult EPTreeFind(AreaInfo* area, MEPTreeItr* iter, u32 key)
|
||||||
|
{
|
||||||
|
WFSKrnResult result = WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND;
|
||||||
|
PTreeAllocator allocator;
|
||||||
|
EPTreeHdr* eptreeHdr;
|
||||||
|
EPTreeItr* epti;
|
||||||
|
int level;
|
||||||
|
u8 ptreeHeight = iter->eptreeHdr[0]->height;
|
||||||
|
|
||||||
|
for (level = 0; level < ptreeHeight; ++level)
|
||||||
|
{
|
||||||
|
eptreeHdr = iter->eptreeHdr[level];
|
||||||
|
AllocatorInit(&allocator, eptreeHdr);
|
||||||
|
result = PTreeFind(&eptreeHdr->ptreeHdr, (PTreeItr*) &iter->epti[level], key, &allocator);
|
||||||
|
|
||||||
|
epti = &iter->epti[level];
|
||||||
|
if (result == WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND)
|
||||||
|
{
|
||||||
|
if (iter->eptreeHdr[level]->ptreeHdr.nNumRecs == 0)
|
||||||
|
{
|
||||||
|
result = WFSKRN_RESULT_PTREE_EMPTY;
|
||||||
|
goto RESULT_EPTREEFIND;
|
||||||
|
}
|
||||||
|
else if (epti->aEntryIdx[0] == 0)
|
||||||
|
{
|
||||||
|
// the key is smaller than the minimum key in this P-tree.
|
||||||
|
result = EPTreePrev(area, iter);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
result = WFSKRN_RESULT_NOT_FOUND;
|
||||||
|
goto RESULT_EPTREEFIND;
|
||||||
|
}
|
||||||
|
if (key == EPTREE_GET_KEY(epti))
|
||||||
|
{
|
||||||
|
result = WFSKRN_RESULT_PTREE_ENTRY_FOUND;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// In this case, PTreeFind() saved the nearest key.
|
||||||
|
--epti->aEntryIdx[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result != WFSKRN_RESULT_PTREE_ENTRY_FOUND &&
|
||||||
|
result != WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
epti->nKey = epti->pLeaf->aKey[epti->aEntryIdx[0]];
|
||||||
|
epti->nData = epti->pLeaf->aData[epti->aEntryIdx[0]];
|
||||||
|
|
||||||
|
if (level == ptreeHeight - 1)
|
||||||
|
{
|
||||||
|
// the bottom of multi EP-Tree.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = GetAndPinEPTreeHdr(area, iter, level + 1, EPTREE_GET_DATA(epti), BCACHE_FLAG_READ | BCACHE_FLAG_PINNED);
|
||||||
|
if (result != WFSKRN_RESULT_OK)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == WFSKRN_RESULT_PTREE_ENTRY_FOUND)
|
||||||
|
{
|
||||||
|
result = WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
RESULT_EPTREEFIND:
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
216
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Errors.cpp
Normal file
216
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Errors.cpp
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Errors.cpp
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Errors.cpp,v $
|
||||||
|
Revision 1.13 2008/09/28 23:32:04 kondo_masahiro
|
||||||
|
Fixed codes to use medium size user block.
|
||||||
|
|
||||||
|
Revision 1.12 2008/09/04 23:53:04 nakanose_jin
|
||||||
|
wfsdev has no pathcache.
|
||||||
|
|
||||||
|
Revision 1.11 2008/08/27 23:23:28 ooizumi
|
||||||
|
Fixed newline to CR+LF(Windows format).
|
||||||
|
|
||||||
|
Revision 1.10 2008/08/27 09:38:04 paul
|
||||||
|
Added error messages. small change to error output.
|
||||||
|
|
||||||
|
Revision 1.9 2008/07/11 18:04:54 paul
|
||||||
|
Updated to match latest error defs
|
||||||
|
|
||||||
|
Revision 1.8 2008/07/09 00:43:54 paul
|
||||||
|
Renamed some error messages. Added software breakpoint for nDbgCommandCount.
|
||||||
|
|
||||||
|
Revision 1.7 2008/07/02 06:34:57 nakanose_jin
|
||||||
|
temporary edit
|
||||||
|
|
||||||
|
Revision 1.6 2008/06/10 20:12:44 kondo_masahiro
|
||||||
|
Fixed WFSKrnCommandCountBreak.
|
||||||
|
|
||||||
|
Revision 1.5 2008/06/09 17:51:14 paul
|
||||||
|
Added support for logging calls to WFSSrv functions.
|
||||||
|
Added new error codes.
|
||||||
|
|
||||||
|
Revision 1.4 2008/05/10 03:59:34 kondo_masahiro
|
||||||
|
Merged and fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/25 17:35:50 kondo_masahiro
|
||||||
|
Fixed log information
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/25 12:07:44 nakanose_jin
|
||||||
|
add new errors
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.7 2008/04/25 04:35:37 nakanose_jin
|
||||||
|
add new errors
|
||||||
|
|
||||||
|
Revision 1.6 2008/04/22 23:22:39 paul
|
||||||
|
Made errors match laters wfskrn_Errors.h
|
||||||
|
|
||||||
|
Revision 1.5 2008/04/19 05:50:45 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.4 2008/04/04 21:18:58 paul
|
||||||
|
Added \n to error message
|
||||||
|
|
||||||
|
Revision 1.3 2008/02/27 07:24:29 paul
|
||||||
|
Updated error strings
|
||||||
|
|
||||||
|
Revision 1.2 2008/02/27 00:37:24 paul
|
||||||
|
Fixed a typo
|
||||||
|
|
||||||
|
Revision 1.1 2008/02/21 00:49:14 paul
|
||||||
|
*** empty log message ***
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "wfskrn_Defs.h"
|
||||||
|
#include "wfskrn_Errors.h"
|
||||||
|
|
||||||
|
#if _DEBUG
|
||||||
|
u32 nDbgCommandCount = 0;
|
||||||
|
u32 nDbgCommandOutputStart = 0; //15520; //(u32)-1;
|
||||||
|
u32 nDbgCommandOutputEnd = (u32)-1;
|
||||||
|
u32 nDbgCommandCountBreak = (u32)-1;
|
||||||
|
#if _WIN32
|
||||||
|
FILE *fpLog;
|
||||||
|
#endif
|
||||||
|
#endif //_DEBUG
|
||||||
|
|
||||||
|
const char *WFSKrnGetErrorString( WFSKrnResult nResult ) {
|
||||||
|
const char *p;
|
||||||
|
switch(nResult) {
|
||||||
|
case WFSKRN_RESULT_OK :p="OK" ; break;
|
||||||
|
case WFSKRN_RESULT_BUSY :p="BUSY" ; break;
|
||||||
|
case WFSKRN_RESULT_OUT_OF_MEMORY :p="OUT_OF_MEMORY" ; break;
|
||||||
|
case WFSKRN_RESULT_INVALID :p="INVALID" ; break;
|
||||||
|
case WFSKRN_RESULT_ACCESS :p="ACCESS" ; break;
|
||||||
|
case WFSKRN_RESULT_LIB_NOT_INITIALIZED :p="LIB_NOT_INITIALIZED" ; break;
|
||||||
|
case WFSKRN_RESULT_LIB_ALREADY_INITIALIZED :p="LIB_ALREADY_INITIALIZED" ; break;
|
||||||
|
case WFSKRN_RESULT_FILE_TOO_BIG :p="FILE_TOO_BIG" ; break;
|
||||||
|
case WFSKRN_RESULT_NO_CHANGE_SIZE :p="NO_CHANGE_SIZE" ; break;
|
||||||
|
case WFSKRN_RESULT_MEDIA_ERROR :p="MEDIA_ERROR" ; break;
|
||||||
|
case WFSKRN_RESULT_DEV_UNUSABLE :p="DEV_UNUSABLE" ; break;
|
||||||
|
case WFSKRN_RESULT_DEV_NOT_INITIALIZED :p="DEV_NOT_INITIALIZED" ; break;
|
||||||
|
case WFSKRN_RESULT_DEV_IN_USE :p="DEV_IN_USE" ; break;
|
||||||
|
case WFSKRN_RESULT_VOL_ID_ERROR :p="VOL_ID_ERROR" ; break;
|
||||||
|
case WFSKRN_RESULT_WRITE_PROTECTED :p="WRITE_PROTECTED" ; break;
|
||||||
|
case WFSKRN_RESULT_ALREADY_MOUNTED :p="ALREADY_MOUNTED" ; break;
|
||||||
|
case WFSKRN_RESULT_PERMISSION :p="PERMISSION" ; break;
|
||||||
|
case WFSKRN_RESULT_PERMISSION_CL :p="PERMISSION_CL" ; break;
|
||||||
|
case WFSKRN_RESULT_ACL_FULL :p="ACL_FULL" ; break;
|
||||||
|
case WFSKRN_RESULT_ACL_ENTRY_NOT_FOUND :p="ACL_ENTRY_NOT_FOUND" ; break;
|
||||||
|
case WFSKRN_RESULT_AUTHENTICATION :p="AUTHENTICATION" ; break;
|
||||||
|
case WFSKRN_RESULT_CORRUPTION :p="CORRUPTION" ; break;
|
||||||
|
case WFSKRN_RESULT_DIRECTORY_QUOTA :p="DIRECTORY_QUOTA" ; break;
|
||||||
|
case WFSKRN_RESULT_MAX_HANDLES :p="MAX_HANDLES" ; break;
|
||||||
|
case WFSKRN_RESULT_ALREADY_EXISTS :p="ALREADY_EXISTS" ; break;
|
||||||
|
case WFSKRN_RESULT_NOT_FOUND :p="NOT_FOUND" ; break;
|
||||||
|
case WFSKRN_RESULT_NOT_EMPTY :p="NOT_EMPTY" ; break;
|
||||||
|
case WFSKRN_RESULT_NOT_FILE :p="NOT_FILE" ; break;
|
||||||
|
case WFSKRN_RESULT_NOT_DIRECTORY :p="NOT_DIRECTORY" ; break;
|
||||||
|
case WFSKRN_RESULT_FILE_OPEN :p="FILE_OPEN" ; break;
|
||||||
|
case WFSKRN_RESULT_LOCKED :p="LOCKED" ; break;
|
||||||
|
case WFSKRN_RESULT_RESOURCE_LIMIT_EXCEEDED :p="RESOURCE_LIMIT_EXCEEDED" ; break;
|
||||||
|
case WFSKRN_RESULT_DIR_ENTRY_FOUND :p="DIR_ENTRY_FOUND" ; break;
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_STRING_PREFIX :p="DIR_NODE_STRING_PREFIX" ; break;
|
||||||
|
case WFSKRN_RESULT_DIR_CHOICE_PREFIX :p="DIR_CHOICE_PREFIX" ; break;
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_STRING_MISMATCH :p="DIR_NODE_STRING_MISMATCH" ; break;
|
||||||
|
case WFSKRN_RESULT_DIR_NODE_CHOICE_NOT_FOUND :p="DIR_NODE_CHOICE_NOT_FOUND" ; break;
|
||||||
|
case WFSKRN_RESULT_DIR_BLK_FULL :p="DIR_BLK_FULL" ; break;
|
||||||
|
case WFSKRN_RESULT_SRV_END_OF_PATH :p="SRV_END_OF_PATH" ; break;
|
||||||
|
case WFSKRN_RESULT_SRV_PATH_DEPTH_1 :p="SRV_PATH_DEPTH_1" ; break;
|
||||||
|
case WFSKRN_RESULT_SRV_PATH_DEV :p="SRV_PATH_DEV" ; break;
|
||||||
|
case WFSKRN_RESULT_SRV_PATH_VOL :p="SRV_PATH_VOL" ; break;
|
||||||
|
case WFSKRN_RESULT_SRV_PATH_VOL_ROOT :p="SRV_PATH_VOL_ROOT" ; break;
|
||||||
|
case WFSKRN_RESULT_PTREE_ENTRY_FOUND :p="PTREE_ENTRY_FOUND" ; break;
|
||||||
|
case WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND :p="PTREE_ENTRY_NOT_FOUND" ; break;
|
||||||
|
case WFSKRN_RESULT_PTREE_FULL :p="PTREE_FULL" ; break;
|
||||||
|
case WFSKRN_RESULT_DEVICE_ERROR :p="DEVICE_ERROR" ; break;
|
||||||
|
case WFSKRN_RESULT_DEVICE_INVALID_PARAMETER :p="DEVICE_INVALID_PARAMETER" ; break;
|
||||||
|
case WFSKRN_RESULT_DEVICE_NOT_FOUND :p="DEVICE_INVALID_PARAMETER" ; break;
|
||||||
|
case WFSKRN_RESULT_BLK_CACHE_ALLOC_FAILED :p="BLK_CACHE_ALLOC_FAILED" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_ERROR :p="BCACHE_ERROR" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_RESOURCE_LIMIT :p="BCACHE_RESOURCE_LIMIT" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_INVALID_PARAMETER :p="BCACHE_INVALID_PARAMETER" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_NO_MEMORY :p="BCACHE_NO_MEMORY" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_NOT_FOUND :p="BCACHE_NOT_FOUND" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_MAX_DEVICES :p="BCACHE_MAX_DEVICES" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_INVALID_DEVICE :p="BCACHE_INVALID_DEVICE" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_INVALID_HANDLE :p="BCACHE_INVALID_HANDLE" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_INVALID_VOLUME :p="BCACHE_INVALID_VOLUME" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_ALREADY_MAPPED :p="BCACHE_ALREADY_MAPPED" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_ALLOC :p="BCACHE_ALLOC" ; break;
|
||||||
|
case WFSKRN_RESULT_BCACHE_HASH_BLK_NOT_MAPPED :p="BCACHE_PMEM" ; break;
|
||||||
|
case WFSKRN_RESULT_VOLUME_ERROR :p="VOLUME_ERROR" ; break;
|
||||||
|
case WFSKRN_RESULT_VOLUME_INVALID_PARAMETER :p="VOLUME_INVALID_PARAMETER" ; break;
|
||||||
|
case WFSKRN_RESULT_VOLUME_BCACHE_ALLOC :p="VOLUME_BCACHE_ALLOC" ; break;
|
||||||
|
case WFSKRN_RESULT_VOLUME_BCACHE_CONFIG :p="VOLUME_BCACHE_CONFIG" ; break;
|
||||||
|
//case WFSKRN_RESULT_VOLUME_ID :p="VOLUME_ID" ; break;
|
||||||
|
//case WFSKRN_RESULT_VOLUME_CORRUPT_MR :p="VOLUME_CORRUPT_MR" ; break;
|
||||||
|
//case WFSKRN_RESULT_VOLUME_AREA_ALLOC :p="VOLUME_AREA_ALLOC" ; break;
|
||||||
|
//case WFSKRN_RESULT_VOLUME_DEVICE_PARAMETER :p="VOLUME_DEVICE_PARAMETER" ; break;
|
||||||
|
//case WFSKRN_RESULT_VOLUME_NOT_MAPPED :p="VOLUME_NOT_MAPPED" ; break;
|
||||||
|
case WFSKRN_RESULT_TRANSACTION_ERROR :p="TRANSACTION_ERROR" ; break;
|
||||||
|
case WFSKRN_RESULT_TRANSACTION_INVALID_PARAMETER:p="TRANSACTION_INVALID_PARAMETER"; break;
|
||||||
|
case WFSKRN_RESULT_ACL_ERROR :p="ACL_ERROR" ; break;
|
||||||
|
case WFSKRN_RESULT_ACL_INVALID_PARAMETER :p="ACL_INVALID_PARAMETER" ; break;
|
||||||
|
case WFSKRN_RESULT_ACL_MAX_ENTRIES :p="ACL_MAX_ENTRIES" ; break;
|
||||||
|
case WFSKRN_RESULT_ACL_CACHE :p="ACL_CACHE" ; break;
|
||||||
|
case WFSKRN_RESULT_ACL_FILE :p="ACL_FILE" ; break;
|
||||||
|
case WFSKRN_RESULT_ACL_FILENAME :p="ACL_FILENAME" ; break;
|
||||||
|
case WFSKRN_RESULT_ACL_HANDLE :p="ACL_HANDLE" ; break;
|
||||||
|
case WFSKRN_RESULT_AREA_ERROR :p="AREA_ERROR" ; break;
|
||||||
|
case WFSKRN_RESULT_AREA_INVALID_PARAMETER :p="AREA_INVALID_PARAMETER" ; break;
|
||||||
|
case WFSKRN_RESULT_AREA_BCACHE_ALLOC :p="AREA_BCACHE_ALLOC" ; break;
|
||||||
|
case WFSKRN_RESULT_NOT_IMPLEMENTED :p="NOT_IMPLEMENTED" ; break;
|
||||||
|
case WFSKRN_RESULT_UNKNOWN :p="UNKNOWN" ; break;
|
||||||
|
case WFSKRN_RESULT_FATAL_ERROR :p="FATAL_ERROR" ; break;
|
||||||
|
default: p="???" ;break ;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnOutputErrorCode(WFSKrnResult nResult) {
|
||||||
|
#if _DEBUG
|
||||||
|
MyOSReport("%d. Error: (%d) WFSKRN_RESULT_%s\n", nDbgCommandCount, nResult, WFSKrnGetErrorString(nResult) );
|
||||||
|
#endif
|
||||||
|
if (nResult != WFSKRN_RESULT_PTREE_ENTRY_NOT_FOUND) {
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
WFSKrnDbgOutputClose();
|
||||||
|
return nResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PathCacheDebugOutput();
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnOutputErrorStr(const char *pStr) {
|
||||||
|
#if _DEBUG
|
||||||
|
MyOSReport("%d. %s\n", nDbgCommandCount, pStr);
|
||||||
|
WFSKrnDbgOutputClose();
|
||||||
|
#endif
|
||||||
|
return WFSKRN_RESULT_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnCommandCountBreak() {
|
||||||
|
#if _DEBUG
|
||||||
|
if(nDbgCommandCount >= nDbgCommandCountBreak) {
|
||||||
|
#ifndef WFSDEV
|
||||||
|
PathCacheDebugOutput();
|
||||||
|
#endif
|
||||||
|
int a; a=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
2118
trunk/firmware/build/libraries/nfs/common/src/wfskrn_FTree.cpp
Normal file
2118
trunk/firmware/build/libraries/nfs/common/src/wfskrn_FTree.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
119
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Handles.cpp
Normal file
119
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Handles.cpp
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Handles.cpp - Module for file handles and search directory handles
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Handles.cpp,v $
|
||||||
|
Revision 1.2 2008/10/07 06:00:57 ueno
|
||||||
|
Modified WFSKrnFileInfoAlloc() to set WFSKRN_HANDLE_ALLOCATED in order to indicate the handle is allocated.
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/25 17:29:06 kondo_masahiro
|
||||||
|
Initial check-in
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/23 00:27:17 paul
|
||||||
|
Copied and modified from wfscli_Handles.cpp
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfskrn_Api.h"
|
||||||
|
|
||||||
|
static bool bMutexInitialized = false; // [check]
|
||||||
|
|
||||||
|
void WFSKrnInitHandles() {
|
||||||
|
if (!bMutexInitialized)
|
||||||
|
{
|
||||||
|
bMutexInitialized = true;
|
||||||
|
WFSKrnInitMutex(&wkg.hnd.mxAccessTheFileInfo);
|
||||||
|
WFSKrnInitMutex(&wkg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
}
|
||||||
|
wkg.hnd.nFileHandleCounter = 0;
|
||||||
|
wkg.hnd.nSearchDirHandleCounter = 0;
|
||||||
|
wkg.hnd.nFirstFreeFileHandle = 0;
|
||||||
|
wkg.hnd.nFirstFreeSearchDirHandle = 0;
|
||||||
|
wkg.hnd.nNumUsedFileHandles = 0;
|
||||||
|
wkg.hnd.nNumUsedSearchDirHandles = 0;
|
||||||
|
//wkg.hnd.nFirstUsedFileHandle = WFSKRN_MAX_FILE_HANDLES; // A value of WFSKRN_MAX_FILE_HANDLES is the list terminator
|
||||||
|
//wkg.hnd.nFirstUsedSearchDirHandle = WFSKRN_MAX_SEARCH_DIR_HANDLES; // A value of WFSKRN_MAX_SEARCH_DIR_HANDLES is the list terminator
|
||||||
|
u32 nI;
|
||||||
|
for(nI=0; nI<WFSKRN_MAX_FILE_HANDLES; nI++) {
|
||||||
|
wkg.hnd.aFileInfo[nI].nNext = nI+1;
|
||||||
|
}
|
||||||
|
for(nI=0; nI<WFSKRN_MAX_SEARCH_DIR_HANDLES; nI++) {
|
||||||
|
wkg.hnd.aSearchDirInfo[nI].nNext = nI+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnGetFileInfo(WFSKrnFileInfo **ppFi, WFSSrvFileHandle sfh) {
|
||||||
|
*ppFi = &wkg.hnd.aFileInfo[sfh&(WFSKRN_MAX_FILE_HANDLES-1)];
|
||||||
|
return ((*ppFi)->nHandle == sfh)?WFSKRN_RESULT_OK:WFSKRN_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnGetSearchDirInfo(WFSKrnSearchDirInfo **ppSdi, WFSSrvSearchDirectoryHandle ssdh) {
|
||||||
|
*ppSdi = &wkg.hnd.aSearchDirInfo[ssdh&(WFSKRN_MAX_SEARCH_DIR_HANDLES-1)];
|
||||||
|
return ((*ppSdi)->nHandle == ssdh)?WFSKRN_RESULT_OK:WFSKRN_RESULT_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnFileInfoAlloc(WFSKrnFileInfo **ppFi) {
|
||||||
|
WFSKrnLockMutex(&wkg.hnd.mxAccessTheFileInfo);
|
||||||
|
if (wkg.hnd.nFirstFreeFileHandle == WFSKRN_MAX_FILE_HANDLES) {
|
||||||
|
WFSKrnUnlockMutex(&wkg.hnd.mxAccessTheFileInfo);
|
||||||
|
return WFSKRN_RESULT_MAX_HANDLES;
|
||||||
|
}
|
||||||
|
wkg.hnd.nNumUsedFileHandles++;
|
||||||
|
u32 nIdx = wkg.hnd.nFirstFreeFileHandle;
|
||||||
|
wkg.hnd.nFirstFreeFileHandle = wkg.hnd.aFileInfo[nIdx].nNext;
|
||||||
|
wkg.hnd.aFileInfo[nIdx].nNext = WFSKRN_HANDLE_ALLOCATED;
|
||||||
|
*ppFi = &wkg.hnd.aFileInfo[nIdx];
|
||||||
|
wkg.hnd.aFileInfo[nIdx].nHandle = wkg.hnd.nFileHandleCounter | nIdx;
|
||||||
|
wkg.hnd.nFileHandleCounter += WFSKRN_FILE_HANDLE_INC;
|
||||||
|
wkg.hnd.nFileHandleCounter &= WFSKRN_HANDLE_COUNTER_MASK;
|
||||||
|
WFSKrnUnlockMutex(&wkg.hnd.mxAccessTheFileInfo);
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WFSKrnResult WFSKrnSearchDirInfoAlloc(WFSKrnSearchDirInfo **ppSdi) {
|
||||||
|
|
||||||
|
WFSKrnLockMutex(&wkg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
if (wkg.hnd.nFirstFreeSearchDirHandle == WFSKRN_MAX_SEARCH_DIR_HANDLES) {
|
||||||
|
WFSKrnUnlockMutex(&wkg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
return WFSKRN_RESULT_MAX_HANDLES;
|
||||||
|
}
|
||||||
|
wkg.hnd.nNumUsedSearchDirHandles++;
|
||||||
|
u32 nIdx = wkg.hnd.nFirstFreeSearchDirHandle;
|
||||||
|
wkg.hnd.nFirstFreeSearchDirHandle = wkg.hnd.aSearchDirInfo[nIdx].nNext;
|
||||||
|
wkg.hnd.aSearchDirInfo[nIdx].nNext = WFSKRN_HANDLE_ALLOCATED;
|
||||||
|
*ppSdi = &wkg.hnd.aSearchDirInfo[nIdx];
|
||||||
|
wkg.hnd.aSearchDirInfo[nIdx].nHandle = wkg.hnd.nSearchDirHandleCounter | nIdx;
|
||||||
|
wkg.hnd.nSearchDirHandleCounter += WFSKRN_SEARCH_DIR_HANDLE_INC;
|
||||||
|
wkg.hnd.nSearchDirHandleCounter &= WFSKRN_HANDLE_COUNTER_MASK;
|
||||||
|
WFSKrnUnlockMutex(&wkg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
return WFSKRN_RESULT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnFileInfoFree(WFSKrnFileInfo *pFi) {
|
||||||
|
WFSKrnLockMutex(&wkg.hnd.mxAccessTheFileInfo);
|
||||||
|
u32 nIdx = (u32)(pFi - wkg.hnd.aFileInfo);
|
||||||
|
pFi->nHandle ^= 0x5555; // ensures the deleted handle is invalid
|
||||||
|
pFi->nNext = wkg.hnd.nFirstFreeFileHandle;
|
||||||
|
wkg.hnd.nNumUsedFileHandles--;
|
||||||
|
wkg.hnd.nFirstFreeFileHandle = nIdx;
|
||||||
|
WFSKrnUnlockMutex(&wkg.hnd.mxAccessTheFileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnSearchDirInfoFree(WFSKrnSearchDirInfo *pSdi) {
|
||||||
|
WFSKrnLockMutex(&wkg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
u32 nIdx = (u32)(pSdi - wkg.hnd.aSearchDirInfo);
|
||||||
|
pSdi->nHandle ^= 0x5555; // ensures the deleted handle is invalid
|
||||||
|
pSdi->nNext = wkg.hnd.nFirstFreeSearchDirHandle;
|
||||||
|
wkg.hnd.nNumUsedSearchDirHandles--;
|
||||||
|
wkg.hnd.nFirstFreeSearchDirHandle = nIdx;
|
||||||
|
WFSKrnUnlockMutex(&wkg.hnd.mxAccessTheSearchDirInfo);
|
||||||
|
}
|
||||||
141
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Heap.cpp
Normal file
141
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Heap.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Heap.cpp
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Heap.cpp,v $
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.3 2008/04/19 05:50:40 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.2 2007/12/27 11:07:04 paul
|
||||||
|
fixed some copy-paste errors: changed WFS to WFSKrn
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/27 11:04:05 paul
|
||||||
|
similar to wfs_Heap.cpp, but will eventually support IOP, so will eventually be different
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfskrn_Heap.h"
|
||||||
|
#include "firm.h"
|
||||||
|
|
||||||
|
#undef dbg
|
||||||
|
#if _DEBUG_WFSKRN_ALLOC
|
||||||
|
#define dbg(s) s
|
||||||
|
#else
|
||||||
|
#define dbg(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
dbg(u32 nSizeAvaliable=0;)
|
||||||
|
|
||||||
|
void WFSKrnCreateHeap(WFSKrnHeap *pHeap, void *pBase, size_t nSize) {
|
||||||
|
*pHeap = HeapCreate(0, nSize, nSize);
|
||||||
|
dbg(nSizeAvaliable = nSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *WFSKrnHeapAlloc(WFSKrnHeap *pHeap, size_t nSize) {
|
||||||
|
void *pAddr = HeapAlloc(*pHeap, 0, nSize);
|
||||||
|
dbg(nSizeAvaliable -= nSize;
|
||||||
|
MyOSReport("A:Heap:%d\n", nSizeAvaliable));
|
||||||
|
return pAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnHeapFree(WFSKrnHeap *pHeap, void *pAddr) {
|
||||||
|
dbg(nSizeAvaliable += HeapSize(pHeap, NULL, pAddr);
|
||||||
|
MyOSReport("F:Heap:%d\n", nSizeAvaliable));
|
||||||
|
HeapFree(*pHeap, 0, pAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnHeapDestroy(WFSKrnHeap *pHeap) {
|
||||||
|
dbg(MyOSReport("WFSKrnHeapDestroy()\n"));
|
||||||
|
HeapDestroy(*pHeap);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-- twl modified
|
||||||
|
#elif _TWL
|
||||||
|
|
||||||
|
void WFSKrnCreateHeap(WFSKrnHeap *pHeap, void *pBase, size_t nSize) {
|
||||||
|
osTPrintf( "%s needs modify.\n", __FUNCTION__);
|
||||||
|
//main.c‚Å<E2809A>s‚Á‚Ä‚¢‚é
|
||||||
|
}
|
||||||
|
|
||||||
|
void *WFSKrnHeapAlloc(WFSKrnHeap *pHeap, size_t nSize) {
|
||||||
|
void *pAddr = osAlloc( nSize);
|
||||||
|
if( pAddr == NULL) {
|
||||||
|
osTPrintf( "%s error!\n", __FUNCTION__);
|
||||||
|
}
|
||||||
|
// void *pAddr = OS_AllocFromHeap( OS_ARENA_MAIN_SUBPRIV, *pHeap, nSize);
|
||||||
|
return pAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnHeapFree(WFSKrnHeap *pHeap, void *pAddr) {
|
||||||
|
osFree( pAddr);
|
||||||
|
// OS_FreeToHeap( OS_ARENA_MAIN_SUBPRIV, *pHeap, pAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnHeapDestroy(WFSKrnHeap *pHeap) {
|
||||||
|
osTPrintf( "%s needs modify.\n", __FUNCTION__);
|
||||||
|
// OS_DestroyHeap( OS_ARENA_MAIN_SUBPRIV, *pHeap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-- twl modified
|
||||||
|
|
||||||
|
#elif _RVL
|
||||||
|
|
||||||
|
void WFSKrnCreateHeap(WFSKrnHeap *pHeap, void *pBase, size_t nSize) {
|
||||||
|
pHeap->handle = MEMCreateExpHeap(pBase, nSize);
|
||||||
|
MEMInitAllocatorForExpHeap(&pHeap->allocator, pHeap->handle, WFS_HEAP_DEFAULT_ALIGNMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *WFSKrnHeapAlloc(WFSKrnHeap *pHeap, size_t nSize) {
|
||||||
|
// osTPrintf("==> %s:%d pHeap: 0x%08x size: %d\n", __FILE__, __LINE__, pHeap->pAllocator, nSize);
|
||||||
|
void *pAddr = MEMAllocFromAllocator(&pHeap->allocator, nSize);
|
||||||
|
// osTPrintf("==> %s:%d pAddr: 0x%08x\n", __FILE__, __LINE__, pAddr);
|
||||||
|
return pAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnHeapFree(WFSKrnHeap *pHeap, void *pAddr) {
|
||||||
|
MEMFreeToAllocator(&pHeap->allocator, pAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnHeapDestroy(WFSKrnHeap *pHeap) {
|
||||||
|
MEMDestroyExpHeap(pHeap->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif _IOP
|
||||||
|
|
||||||
|
void WFSKrnCreateHeap(WFSKrnHeap *pHeap, void *pBase, size_t nSize) {
|
||||||
|
*pHeap = IOS_CreateHeap(pBase, nSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *WFSKrnHeapAlloc(WFSKrnHeap *pHeap, size_t nSize) {
|
||||||
|
// osTPrintf("==> %s:%d pHeap: 0x%08x size: %d\n", __FILE__, __LINE__, pHeap, nSize);
|
||||||
|
void *pAddr = IOS_AllocAligned(*pHeap, nSize, 32);
|
||||||
|
// osTPrintf("==> %s:%d pAddr: 0x%08x\n", __FILE__, __LINE__, pAddr);
|
||||||
|
return pAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnHeapFree(WFSKrnHeap *pHeap, void *pAddr) {
|
||||||
|
IOS_Free(*pHeap, pAddr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnHeapDestroy(WFSKrnHeap *pHeap) {
|
||||||
|
IOS_DestroyHeap(*pHeap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
354
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Mutex.cpp
Normal file
354
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Mutex.cpp
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
/*---------------------------------------------------------------------------*
|
||||||
|
Project: wfs
|
||||||
|
File: wfskrn_Mutex.cpp
|
||||||
|
|
||||||
|
|
||||||
|
Copyright 2007 Nintendo. All rights reserved.
|
||||||
|
|
||||||
|
These coded instructions, statements, and computer programs contain
|
||||||
|
proprietary information of Nintendo of America Inc. and/or Nintendo
|
||||||
|
Company Ltd., and are protected by Federal copyright law. They may
|
||||||
|
not be disclosed to third parties or copied or duplicated in any form,
|
||||||
|
in whole or in part, without the prior written consent of Nintendo.
|
||||||
|
|
||||||
|
$Log: wfskrn_Mutex.cpp,v $
|
||||||
|
Revision 1.2 2008/04/25 17:28:54 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2008/04/22 04:39:08 kondo_masahiro
|
||||||
|
Fixed code to transfer the wfskrn project to RM_SDK tree
|
||||||
|
|
||||||
|
Revision 1.2 2008/04/19 05:50:34 kondo_masahiro
|
||||||
|
Fixed code to accept RM compiler
|
||||||
|
|
||||||
|
Revision 1.1 2007/12/27 11:11:58 paul
|
||||||
|
similar to wfs_Mutex.cpp, but will eventually need to support IOP
|
||||||
|
|
||||||
|
|
||||||
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "wfskrn_Mutex.h"
|
||||||
|
|
||||||
|
#undef dbg
|
||||||
|
#if _DEBUG_WFSKRN_MUTEX
|
||||||
|
#define dbg(s) s
|
||||||
|
#else
|
||||||
|
#define dbg(s)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
dbg(u32 aSignalCounter[0x2000]);
|
||||||
|
|
||||||
|
void WFSKrnInitMutex(WFSKrnMutex *pMx) {
|
||||||
|
pMx->hHandle = CreateMutex(NULL, false, NULL);
|
||||||
|
ReleaseMutex(pMx->hHandle);
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]=1;
|
||||||
|
MyOSReport("InitMutex(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnLockMutex(WFSKrnMutex *pMx) {
|
||||||
|
dbg(MyOSReport("Wait(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff]));
|
||||||
|
WaitForSingleObject(pMx->hHandle, INFINITE);
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]--);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnTryLockMutex(WFSKrnMutex *pMx) {
|
||||||
|
return (WaitForSingleObject(pMx->hHandle, 0) != WAIT_TIMEOUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnUnlockMutex(WFSKrnMutex *pMx) {
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]++;
|
||||||
|
MyOSReport("Release(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff]));
|
||||||
|
ReleaseMutex(pMx->hHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnInitCond(WFSKrnCond *pCond) {
|
||||||
|
pCond->hAutoResetEvent = CreateEvent(NULL, false, false, NULL);
|
||||||
|
dbg(aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]=0;
|
||||||
|
MyOSReport("InitCond(%x:%d)\n", pCond->hAutoResetEvent, aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]));
|
||||||
|
//ResetEvent(pCond->hAutoResetEvent);
|
||||||
|
//pCond->hManualResetEvent = CreateEvent(NULL, true, false, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnSignalCond(WFSKrnCond *pCond) {
|
||||||
|
//PulseEvent(pCond->hAutoResetEvent);
|
||||||
|
dbg(aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]++;
|
||||||
|
MyOSReport("Signal(%x:%d)\n", pCond->hAutoResetEvent, aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]));
|
||||||
|
SetEvent(pCond->hAutoResetEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnWaitCond(WFSKrnCond *pCond, WFSKrnMutex* pMx) {
|
||||||
|
#if 1
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]++;
|
||||||
|
MyOSReport("Signal(%x:%d) And Wait(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff], pCond->hAutoResetEvent, aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]));
|
||||||
|
//DWORD nRet = SignalObjectAndWait(pMx->hHandle, pCond->hAutoResetEvent, INFINITE, false);
|
||||||
|
dbg(aSignalCounter[(u32)pCond->hAutoResetEvent&0x1fff]--);
|
||||||
|
#else
|
||||||
|
ReleaseMutex(pMx->hHandle);
|
||||||
|
WaitForSingleObject(pCond->hAutoResetEvent, INFINITE);
|
||||||
|
#endif
|
||||||
|
dbg(MyOSReport("Wait(%x:%d)\n", pMx->hHandle, aSignalCounter[(u32)pMx->hHandle&0x1fff]));
|
||||||
|
WaitForSingleObject(pMx->hHandle, INFINITE);
|
||||||
|
dbg(aSignalCounter[(u32)pMx->hHandle&0x1fff]--);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnResetCond(WFSKrnCond *pCond) {
|
||||||
|
ResetEvent(pCond->hAutoResetEvent);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnCreateThread(WFSKrnThread *pThread,
|
||||||
|
WFSKrnThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority)
|
||||||
|
{
|
||||||
|
pThread->hThread = CreateThread(NULL, stackSize, (LPTHREAD_START_ROUTINE)threadFunc, param, CREATE_SUSPENDED, 0);
|
||||||
|
SetThreadPriority(pThread->hThread, 16-priority);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSKrnResumeThread(WFSKrnThread *pThread) {
|
||||||
|
return ResumeThread(pThread->hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnCancelThread(WFSKrnThread *pThread) {
|
||||||
|
// Note: On windows, this does not do any cleanup - should avoid using
|
||||||
|
TerminateThread(pThread->hThread, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnExitThread(void *pVal) {
|
||||||
|
ExitThread((DWORD)pVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSKrnSuspendThread(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
return SuspendThread(pThread->hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnIsThreadTerminated(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
switch (WaitForSingleObject(pThread->hThread, 0))
|
||||||
|
{
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
return false;
|
||||||
|
case WAIT_OBJECT_0: // the thread has exited.
|
||||||
|
case WAIT_ABANDONED: // [check]
|
||||||
|
case WAIT_FAILED: // the thread does not exist. [check] should check error code?
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnJoinThread(WFSKrnThread *pThread, void** val)
|
||||||
|
{
|
||||||
|
#pragma unused (val) // exit value is not supported.
|
||||||
|
switch (WaitForSingleObject(pThread->hThread, INFINITE))
|
||||||
|
{
|
||||||
|
case WAIT_OBJECT_0:
|
||||||
|
return true;
|
||||||
|
case WAIT_TIMEOUT:
|
||||||
|
case WAIT_ABANDONED:
|
||||||
|
case WAIT_FAILED:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif _RVL
|
||||||
|
|
||||||
|
|
||||||
|
bool WFSKrnCreateThread(WFSKrnThread *pThread,
|
||||||
|
WFSKrnThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority)
|
||||||
|
{
|
||||||
|
return OSCreateThread(pThread, threadFunc, param, (void*)((u32)stackBase+stackSize), stackSize, priority, OS_THREAD_ATTR_DETACH);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--- twl modified
|
||||||
|
#elif _TWL
|
||||||
|
typedef void (*MyThreadFunc)(void*);
|
||||||
|
bool WFSKrnCreateThread(WFSKrnThread *pThread,
|
||||||
|
WFSKrnThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority)
|
||||||
|
{
|
||||||
|
osCreateThread( pThread, (MyThreadFunc)threadFunc, param, (void*)((u32)stackBase+stackSize), stackSize, priority);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSKrnResumeThread(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
osWakeupThreadDirect( pThread);
|
||||||
|
#if 1
|
||||||
|
// osTPrintf( "Need TWL modifies.\n");
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
if(WFSKrnIsThreadTerminated(pThread)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(--pThread->count == 0){
|
||||||
|
IOS_StartThread(pThread->tid);
|
||||||
|
}
|
||||||
|
return pThread->count;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnCancelThread(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
osDestroyThread( pThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnExitThread(void *pVal)
|
||||||
|
{
|
||||||
|
osExitThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSKrnSuspendThread(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
osTPrintf( "Need TWL modifies.\n");
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
if(WFSKrnIsThreadTerminated(pThread)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(++pThread->count == 1){
|
||||||
|
IOS_StopThread(pThread->tid);
|
||||||
|
}
|
||||||
|
return pThread->count;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnIsThreadTerminated(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
return( osIsThreadTerminated( pThread));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnJoinThread(WFSKrnThread *pThread, void** val)
|
||||||
|
{
|
||||||
|
#pragma unused (val) // exit value is not supported.
|
||||||
|
osJoinThread( pThread);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void WFSKrnInitCond(WFSCond *pCond) {
|
||||||
|
osInitEvent( pCond);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnSignalCond(WFSCond *pCond) {
|
||||||
|
osSignalEvent( pCond, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnWaitCond(WFSCond *pCond, WFSMutex* pMx) {
|
||||||
|
osUnlockMutex( pMx);
|
||||||
|
osWaitEventEx( pCond, 1, OS_EVENT_MODE_OR, 1); //イベント待ち後にクリアを伴う
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnResetCond(WFSCond *pCond) {
|
||||||
|
osClearAllEvent( pCond);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//-- twl modified
|
||||||
|
|
||||||
|
#elif _IOP
|
||||||
|
|
||||||
|
void WFSKrnInitMutex(WFSKrnMutex *mutex)
|
||||||
|
{
|
||||||
|
mutex->mqid = IOS_CreateMessageQueue(mutex->mq, WFSKRN_MUTEX_Q_SIZE);
|
||||||
|
IOS_SendMessage(mutex->mqid, 0xabcd1234, IOS_MESSAGE_NOBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnLockMutex(WFSKrnMutex *mutex)
|
||||||
|
{
|
||||||
|
IOSMessage msg;
|
||||||
|
IOS_ReceiveMessage(mutex->mqid, &msg, IOS_MESSAGE_BLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnTryLockMutex(WFSKrnMutex *mutex)
|
||||||
|
{
|
||||||
|
IOSMessage msg;
|
||||||
|
if(IOS_ReceiveMessage(mutex->mqid, &msg, IOS_MESSAGE_NOBLOCK) == IOS_ERROR_OK )
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnUnlockMutex(WFSKrnMutex *mutex)
|
||||||
|
{
|
||||||
|
IOS_SendMessage(mutex->mqid, 0xabcd1234, IOS_MESSAGE_NOBLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnCreateThread(WFSKrnThread *pThread,
|
||||||
|
WFSKrnThreadFunc threadFunc,
|
||||||
|
void* param,
|
||||||
|
void* stackBase,
|
||||||
|
u32 stackSize,
|
||||||
|
OSPriority priority)
|
||||||
|
{
|
||||||
|
IOSError ie = IOS_CreateThread((IOSEntryProc)threadFunc, param, stackBase, stackSize, (u32)priority, IOS_THREAD_CREATE_JOINABLE);
|
||||||
|
if(ie < 0) return false;
|
||||||
|
pThread->tid = ie;
|
||||||
|
pThread->count = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSKrnResumeThread(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
if(WFSKrnIsThreadTerminated(pThread)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(--pThread->count == 0){
|
||||||
|
IOS_StartThread(pThread->tid);
|
||||||
|
}
|
||||||
|
return pThread->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnCancelThread(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
IOS_DestroyThread(pThread->tid, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WFSKrnExitThread(void *pVal)
|
||||||
|
{
|
||||||
|
IOS_DestroyThread(IOS_GetThreadId(), pVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 WFSKrnSuspendThread(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
if(WFSKrnIsThreadTerminated(pThread)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if(++pThread->count == 1){
|
||||||
|
IOS_StopThread(pThread->tid);
|
||||||
|
}
|
||||||
|
return pThread->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnIsThreadTerminated(WFSKrnThread *pThread)
|
||||||
|
{
|
||||||
|
if(IOS_GetThreadPriority(pThread->tid) >= 0)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WFSKrnJoinThread(WFSKrnThread *pThread, void** val)
|
||||||
|
{
|
||||||
|
if(IOS_JoinThread(pThread->tid, val) == IOS_ERROR_OK)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
1096
trunk/firmware/build/libraries/nfs/common/src/wfskrn_PTree.cpp
Normal file
1096
trunk/firmware/build/libraries/nfs/common/src/wfskrn_PTree.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1036
trunk/firmware/build/libraries/nfs/common/src/wfskrn_PathCache.cpp
Normal file
1036
trunk/firmware/build/libraries/nfs/common/src/wfskrn_PathCache.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1241
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Permission.cpp
Normal file
1241
trunk/firmware/build/libraries/nfs/common/src/wfskrn_Permission.cpp
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user